summaryrefslogtreecommitdiffstats
path: root/vespamalloc/src/tests/test1
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
committerJon Bratseth <bratseth@yahoo-inc.com>2016-06-15 23:09:44 +0200
commit72231250ed81e10d66bfe70701e64fa5fe50f712 (patch)
tree2728bba1131a6f6e5bdf95afec7d7ff9358dac50 /vespamalloc/src/tests/test1
Publish
Diffstat (limited to 'vespamalloc/src/tests/test1')
-rw-r--r--vespamalloc/src/tests/test1/.gitignore4
-rw-r--r--vespamalloc/src/tests/test1/CMakeLists.txt7
-rw-r--r--vespamalloc/src/tests/test1/DESC1
-rw-r--r--vespamalloc/src/tests/test1/FILES1
-rw-r--r--vespamalloc/src/tests/test1/testatomic.cpp118
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();
+}