diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2016-06-15 23:09:44 +0200 |
commit | 72231250ed81e10d66bfe70701e64fa5fe50f712 (patch) | |
tree | 2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespamalloc/src/tests/test1 |
Publish
Diffstat (limited to 'vespamalloc/src/tests/test1')
-rw-r--r-- | vespamalloc/src/tests/test1/.gitignore | 4 | ||||
-rw-r--r-- | vespamalloc/src/tests/test1/CMakeLists.txt | 7 | ||||
-rw-r--r-- | vespamalloc/src/tests/test1/DESC | 1 | ||||
-rw-r--r-- | vespamalloc/src/tests/test1/FILES | 1 | ||||
-rw-r--r-- | vespamalloc/src/tests/test1/testatomic.cpp | 118 |
5 files changed, 131 insertions, 0 deletions
diff --git a/vespamalloc/src/tests/test1/.gitignore b/vespamalloc/src/tests/test1/.gitignore new file mode 100644 index 00000000000..b7fab5d205c --- /dev/null +++ b/vespamalloc/src/tests/test1/.gitignore @@ -0,0 +1,4 @@ +.depend +Makefile +testatomic +vespamalloc_testatomic_app diff --git a/vespamalloc/src/tests/test1/CMakeLists.txt b/vespamalloc/src/tests/test1/CMakeLists.txt new file mode 100644 index 00000000000..dc0217b139a --- /dev/null +++ b/vespamalloc/src/tests/test1/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +vespa_add_executable(vespamalloc_testatomic_app + SOURCES + testatomic.cpp + DEPENDS +) +vespa_add_test(NAME vespamalloc_testatomic_app NO_VALGRIND COMMAND vespamalloc_testatomic_app) diff --git a/vespamalloc/src/tests/test1/DESC b/vespamalloc/src/tests/test1/DESC new file mode 100644 index 00000000000..4f3ca4d4d97 --- /dev/null +++ b/vespamalloc/src/tests/test1/DESC @@ -0,0 +1 @@ +This is a unittest of vespamalloc. diff --git a/vespamalloc/src/tests/test1/FILES b/vespamalloc/src/tests/test1/FILES new file mode 100644 index 00000000000..4b14c586dd4 --- /dev/null +++ b/vespamalloc/src/tests/test1/FILES @@ -0,0 +1 @@ +testatomic.cpp diff --git a/vespamalloc/src/tests/test1/testatomic.cpp b/vespamalloc/src/tests/test1/testatomic.cpp new file mode 100644 index 00000000000..1222493446c --- /dev/null +++ b/vespamalloc/src/tests/test1/testatomic.cpp @@ -0,0 +1,118 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +#include <vespa/fastos/fastos.h> +#include <vespa/vespalib/testkit/testapp.h> +#include <vespa/vespalib/util/atomic.h> +#include <vector> + +using vespalib::Atomic; + +class Test : public vespalib::TestApp +{ +public: + int Main(); +private: + template<typename T> + void testSwap(T initial); + template<typename T> + void testSwapStress(T v, int numThreads); +}; + +template <typename T> +class Stress : public FastOS_Runnable +{ +private: + void Run(FastOS_ThreadInterface * ti, void * arg); + void stressSwap(T & value); +public: + Stress(T * value) : _value(value), _successCount(0), _failedCount(0) { } + void wait() { _wait.Lock(); _wait.Unlock(); } + FastOS_Mutex _wait; + T * _value; + size_t _successCount; + size_t _failedCount; +}; + +TEST_APPHOOK(Test); + +template<typename T> +void Test::testSwap(T initial) +{ + T value(initial); + + ASSERT_TRUE(Atomic::cmpSwap(&value, initial+1, initial)); + ASSERT_TRUE(value == initial+1); + + ASSERT_TRUE(!Atomic::cmpSwap(&value, initial+2, initial)); + ASSERT_TRUE(value == initial+1); +} + +template<typename T> +void Test::testSwapStress(T v, int numThreads) +{ + T old(v); + std::vector<Stress<T> *> contexts; + std::vector<FastOS_ThreadInterface *> threads; + FastOS_ThreadPool threadPool(512*1024); + + for(int i=0; i < numThreads; i++) { + contexts.push_back(new Stress<T>(&v)); + } + + for(size_t i = 0; i < contexts.size(); i++) { + threads.push_back(threadPool.NewThread(contexts[i])); + } + FastOS_Thread::Sleep(1000); + size_t succesCount(0); + size_t failedCount(0); + for(size_t i = 0; i < contexts.size(); i++) { + Stress<T> * s = contexts[i]; + s->wait(); + succesCount += s->_successCount; + failedCount += s->_failedCount; + } + ASSERT_TRUE(v == 0); + ASSERT_TRUE(old == succesCount); + fprintf(stderr, "%ld threads counting down from %" PRIu64 " had %ld succesfull and %ld unsuccessful attempts\n", + contexts.size(), uint64_t(old), succesCount, failedCount); + for(size_t i = 0; i < contexts.size(); i++) { + delete contexts[i]; + } +} + +template <typename T> +void Stress<T>::Run(FastOS_ThreadInterface *, void *) +{ + _wait.Lock(); + stressSwap(*_value); + _wait.Unlock(); +} + +template <typename T> +void Stress<T>::stressSwap(T & value) +{ + for (T old = value; old > 0; old = value) { + if (Atomic::cmpSwap(&value, old-1, old)) { + _successCount++; + } else { + _failedCount++; + } + } +} + +int Test::Main() +{ + TEST_INIT("atomic"); + + testSwap<uint32_t>(6); + testSwap<uint32_t>(7); + testSwap<uint32_t>(uint32_t(-6)); + testSwap<uint32_t>(uint32_t(-7)); + testSwap<uint64_t>(6); + testSwap<uint64_t>(7); + testSwap<uint64_t>(uint64_t(-6)); + testSwap<uint64_t>(uint64_t(-7)); + testSwapStress<uint64_t>(0x1000000, 4); + testSwapStress<uint32_t>(0x1000000, 4); + + TEST_DONE(); +} |