summaryrefslogtreecommitdiffstats
path: root/vespamalloc/src/tests/allocfree
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/allocfree
Publish
Diffstat (limited to 'vespamalloc/src/tests/allocfree')
-rw-r--r--vespamalloc/src/tests/allocfree/.gitignore14
-rw-r--r--vespamalloc/src/tests/allocfree/CMakeLists.txt23
-rw-r--r--vespamalloc/src/tests/allocfree/DESC1
-rw-r--r--vespamalloc/src/tests/allocfree/FILES1
-rw-r--r--vespamalloc/src/tests/allocfree/allocfree.cpp115
-rwxr-xr-xvespamalloc/src/tests/allocfree/allocfree_benchmark.sh151
-rwxr-xr-xvespamalloc/src/tests/allocfree/allocfree_test.sh17
-rw-r--r--vespamalloc/src/tests/allocfree/creatingmanythreads.cpp39
-rwxr-xr-xvespamalloc/src/tests/allocfree/generate_testtable.sh22
-rw-r--r--vespamalloc/src/tests/allocfree/linklist.cpp188
-rw-r--r--vespamalloc/src/tests/allocfree/producerconsumer.cpp95
-rw-r--r--vespamalloc/src/tests/allocfree/producerconsumer.h58
-rw-r--r--vespamalloc/src/tests/allocfree/queue.h86
-rw-r--r--vespamalloc/src/tests/allocfree/realloc.cpp23
-rw-r--r--vespamalloc/src/tests/allocfree/testnames.all162
-rw-r--r--vespamalloc/src/tests/allocfree/testtype.all162
-rwxr-xr-xvespamalloc/src/tests/allocfree/timeusage.sh3
-rw-r--r--vespamalloc/src/tests/allocfree/vespamalloc.conf13
18 files changed, 1173 insertions, 0 deletions
diff --git a/vespamalloc/src/tests/allocfree/.gitignore b/vespamalloc/src/tests/allocfree/.gitignore
new file mode 100644
index 00000000000..a80a52d808a
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/.gitignore
@@ -0,0 +1,14 @@
+.depend
+Makefile
+allocfree_shared_test
+allocfree_static_test
+allocfree_static_testd
+allocfree_test
+linklist_test
+realloc_test
+realloc_testd
+/creatingmanythreads_test
+vespamalloc_allocfree_shared_test_app
+vespamalloc_creatingmanythreads_test_app
+vespamalloc_linklist_test_app
+vespamalloc_realloc_test_app
diff --git a/vespamalloc/src/tests/allocfree/CMakeLists.txt b/vespamalloc/src/tests/allocfree/CMakeLists.txt
new file mode 100644
index 00000000000..1dc36f8dec7
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/CMakeLists.txt
@@ -0,0 +1,23 @@
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+vespa_add_executable(vespamalloc_creatingmanythreads_test_app
+ SOURCES
+ creatingmanythreads.cpp
+)
+vespa_add_executable(vespamalloc_allocfree_shared_test_app
+ SOURCES
+ allocfree.cpp
+ producerconsumer.cpp
+)
+vespa_add_test(NAME vespamalloc_allocfree_shared_test_app NO_VALGRIND COMMAND sh allocfree_test.sh BENCHMARK)
+vespa_add_executable(vespamalloc_realloc_test_app
+ SOURCES
+ realloc.cpp
+)
+vespa_add_executable(vespamalloc_linklist_test_app
+ SOURCES
+ linklist.cpp
+ producerconsumer.cpp
+ ../../vespamalloc/malloc/allocchunk.cpp
+ ../../vespamalloc/malloc/common.cpp
+ $<TARGET_OBJECTS:vespamalloc_util>
+)
diff --git a/vespamalloc/src/tests/allocfree/DESC b/vespamalloc/src/tests/allocfree/DESC
new file mode 100644
index 00000000000..4f3ca4d4d97
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/DESC
@@ -0,0 +1 @@
+This is a unittest of vespamalloc.
diff --git a/vespamalloc/src/tests/allocfree/FILES b/vespamalloc/src/tests/allocfree/FILES
new file mode 100644
index 00000000000..4b14c586dd4
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/FILES
@@ -0,0 +1 @@
+testatomic.cpp
diff --git a/vespamalloc/src/tests/allocfree/allocfree.cpp b/vespamalloc/src/tests/allocfree/allocfree.cpp
new file mode 100644
index 00000000000..0f7b4d53c6f
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/allocfree.cpp
@@ -0,0 +1,115 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/log/log.h>
+#include <vespa/fastos/fastos.h>
+#include <vespa/vespalib/testkit/testapp.h>
+#include "producerconsumer.h"
+#include <map>
+
+using vespalib::Consumer;
+using vespalib::Producer;
+using vespalib::ProducerConsumer;
+
+LOG_SETUP("allocfree_test");
+
+TEST_SETUP(Test);
+
+//-----------------------------------------------------------------------------
+
+class FreeWorker : public Consumer {
+public:
+ FreeWorker(uint32_t maxQueue, bool inverse)
+ : Consumer (maxQueue, inverse) {}
+private:
+ virtual void consume(void * p) { free(p); }
+};
+
+//-----------------------------------------------------------------------------
+
+class MallocWorker : public Producer {
+public:
+ MallocWorker(uint32_t size, uint32_t cnt, FreeWorker &target)
+ : Producer(cnt, target), _size(size) {}
+private:
+ uint32_t _size;
+ virtual void * produce() { return malloc(_size); }
+};
+
+//-----------------------------------------------------------------------------
+
+class MallocFreeWorker : public ProducerConsumer {
+public:
+ MallocFreeWorker(uint32_t size, uint32_t cnt, bool inverse)
+ : ProducerConsumer(cnt, inverse), _size(size) { }
+private:
+ uint32_t _size;
+ virtual void * produce() { return malloc(_size); }
+ virtual void consume(void * p) { free(p); }
+};
+
+//-----------------------------------------------------------------------------
+
+int Test::Main() {
+ int duration = 10;
+ int numCrossThreadAlloc(2);
+ int numSameThreadAlloc(2);
+ if (_argc > 1) {
+ duration = atoi(_argv[1]);
+ }
+ if (_argc > 2) {
+ numCrossThreadAlloc = atoi(_argv[2]);
+ }
+ if (_argc > 3) {
+ numSameThreadAlloc = atoi(_argv[3]);
+ }
+ TEST_INIT("allocfree_test");
+
+ FastOS_ThreadPool pool(128000);
+
+ std::map<int, std::shared_ptr<FreeWorker> > freeWorkers;
+ std::map<int, std::shared_ptr<MallocWorker> > mallocWorkers;
+ std::map<int, std::shared_ptr<MallocFreeWorker> > mallocFreeWorkers;
+ for (int i(0); i < numCrossThreadAlloc; i++) {
+ freeWorkers[i] = std::shared_ptr<FreeWorker>(new FreeWorker(1024, (i%2) ? true : false));
+ mallocWorkers[i] = std::shared_ptr<MallocWorker>(new MallocWorker(400, 256, *freeWorkers[i]));
+ }
+ for(int i(0); i < numSameThreadAlloc; i++) {
+ mallocFreeWorkers[i] = std::shared_ptr<MallocFreeWorker>(new MallocFreeWorker(200, 16, (i%2) ? true : false));
+ }
+
+
+ for(std::map<int, std::shared_ptr<FreeWorker> >::iterator it(freeWorkers.begin()), mt(freeWorkers.end()); it != mt; it++) {
+ ASSERT_TRUE(pool.NewThread(it->second.get(), NULL) != NULL);
+ }
+ for(std::map<int, std::shared_ptr<MallocWorker> >::iterator it(mallocWorkers.begin()), mt(mallocWorkers.end()); it != mt; it++) {
+ ASSERT_TRUE(pool.NewThread(it->second.get(), NULL) != NULL);
+ }
+ for(std::map<int, std::shared_ptr<MallocFreeWorker> >::iterator it(mallocFreeWorkers.begin()), mt(mallocFreeWorkers.end()); it != mt; it++) {
+ ASSERT_TRUE(pool.NewThread(it->second.get(), NULL) != NULL);
+ }
+
+ for (; duration > 0; --duration) {
+ LOG(info, "%d seconds left...", duration);
+ FastOS_Thread::Sleep(1000);
+ }
+ pool.Close();
+ size_t numFreeOperations(0);
+ size_t numMallocOperations(0);
+ size_t numSameThreadMallocFreeOperations(0);
+ for(std::map<int, std::shared_ptr<FreeWorker> >::iterator it(freeWorkers.begin()), mt(freeWorkers.end()); it != mt; it++) {
+ numFreeOperations += it->second->operations();
+ }
+ for(std::map<int, std::shared_ptr<MallocWorker> >::iterator it(mallocWorkers.begin()), mt(mallocWorkers.end()); it != mt; it++) {
+ numMallocOperations += it->second->operations();
+ }
+ for(std::map<int, std::shared_ptr<MallocFreeWorker> >::iterator it(mallocFreeWorkers.begin()), mt(mallocFreeWorkers.end()); it != mt; it++) {
+ numSameThreadMallocFreeOperations += it->second->operationsConsumed();
+ }
+ EXPECT_EQUAL(numFreeOperations, numMallocOperations);
+ const size_t numCrossThreadMallocFreeOperations(numMallocOperations);
+
+ fprintf(stderr, "Did %" PRIu64 " Cross thread malloc/free operations\n", numCrossThreadMallocFreeOperations);
+ fprintf(stderr, "Did %" PRIu64 " Same thread malloc/free operations\n", numSameThreadMallocFreeOperations);
+ fprintf(stderr, "Did %" PRIu64 " Total operations\n", numCrossThreadMallocFreeOperations + numSameThreadMallocFreeOperations);
+
+ TEST_DONE();
+}
diff --git a/vespamalloc/src/tests/allocfree/allocfree_benchmark.sh b/vespamalloc/src/tests/allocfree/allocfree_benchmark.sh
new file mode 100755
index 00000000000..51165dfce71
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/allocfree_benchmark.sh
@@ -0,0 +1,151 @@
+#!/bin/bash
+
+TIME=/usr/bin/time
+
+VESPA_MALLOC_SO=../../../src/vespamalloc/libvespamalloc.so
+LIBDIR=$LIBDIR
+
+$TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+$TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+$TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+$TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+$TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+$TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+$TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+$TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libtcmalloc_minimal.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libjemalloc_mt.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libptmalloc3.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libnedmalloc.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libhoard.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 0
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 1
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 2
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 4
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 8
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 16
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 0 32
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 1 1
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 2 2
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 4 4
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 8 8
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 16 16
+LD_PRELOAD=$LIBDIR/libtlsf.so $TIME ./vespamalloc_allocfree_shared_test_app 5 32 32
diff --git a/vespamalloc/src/tests/allocfree/allocfree_test.sh b/vespamalloc/src/tests/allocfree/allocfree_test.sh
new file mode 100755
index 00000000000..ac864dc891b
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/allocfree_test.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+TIME=/usr/bin/time
+
+VESPA_MALLOC_SO=../../../src/vespamalloc/libvespamalloc.so
+VESPA_MALLOC_SO_D=../../../src/vespamalloc/libvespamalloc_vespamallocd.so
+
+LD_PRELOAD=$VESPA_MALLOC_SO ./vespamalloc_realloc_test_app
+LD_PRELOAD=$VESPA_MALLOC_SO_D ./vespamalloc_realloc_test_app
+$TIME ./vespamalloc_linklist_test_app 3
+LD_PRELOAD=$VESPA_MALLOC_SO $TIME ./vespamalloc_allocfree_shared_test_app 3
+LD_PRELOAD=$VESPA_MALLOC_SO_D $TIME ./vespamalloc_allocfree_shared_test_app 3
+$TIME ./vespamalloc_allocfree_shared_test_app 3
+VESPA_MALLOC_MADVISE_LIMIT=0x200000 LD_PRELOAD=$VESPA_MALLOC_SO_D $TIME ./vespamalloc_allocfree_shared_test_app 3
+LD_PRELOAD=$VESPA_MALLOC_SO_D $TIME ./vespamalloc_allocfree_shared_test_app 3
+VESPA_MALLOC_MADVISE_LIMIT=0x200000 VESPA_MALLOC_HUGEPAGES=on LD_PRELOAD=$VESPA_MALLOC_SO_D $TIME ./vespamalloc_allocfree_shared_test_app 3
+VESPA_MALLOC_HUGEPAGES=on LD_PRELOAD=$VESPA_MALLOC_SO_D $TIME ./vespamalloc_allocfree_shared_test_app 3
diff --git a/vespamalloc/src/tests/allocfree/creatingmanythreads.cpp b/vespamalloc/src/tests/allocfree/creatingmanythreads.cpp
new file mode 100644
index 00000000000..53de3f274cc
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/creatingmanythreads.cpp
@@ -0,0 +1,39 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/log/log.h>
+#include <vespa/fastos/fastos.h>
+#include <vespa/vespalib/testkit/testapp.h>
+
+LOG_SETUP("creatingmanythreads_test");
+
+TEST_SETUP(Test);
+
+void * thread_alloc(void * arg)
+{
+ char * v = new char [*static_cast<int *>(arg)];
+ delete [] v;
+ return NULL;
+}
+
+int Test::Main() {
+ int numThreads(10000);
+ int allocSize(256);
+ if (_argc > 1) {
+ numThreads = atoi(_argv[1]);
+ }
+ if (_argc > 2) {
+ allocSize = atoi(_argv[2]);
+ }
+ TEST_INIT("creatingmanythreads_test");
+
+ LOG(info, "Will create and run %d threads each allocating a single block of memory of %d size\n", numThreads, allocSize);
+ for (int i(0); i < numThreads; ) {
+ for (int j(0); (i < numThreads) && j < 10000; i++, j++) {
+ pthread_t thread;
+ ASSERT_EQUAL(0, pthread_create(&thread, NULL, thread_alloc, &allocSize));
+ ASSERT_EQUAL(0, pthread_join(thread, NULL));
+ }
+ LOG(info, "Completed %d tests", i);
+ }
+
+ TEST_DONE();
+}
diff --git a/vespamalloc/src/tests/allocfree/generate_testtable.sh b/vespamalloc/src/tests/allocfree/generate_testtable.sh
new file mode 100755
index 00000000000..5763024c086
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/generate_testtable.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+base=$1
+
+echo "No threads test. Test difference of static linkage, shared and debug versus glibc"
+cat $base | ./timeusage.sh > t1
+cat $base | grep time | grep allocfree_ | cut -d'5' -f2 | awk '{print $1*2 + $2 ";"}' > t2
+cat $base | grep "Total" | awk '{print $2}' > t3
+paste testnames.all testtype.all t2 t1 t3 > t4
+
+for t in "cross thread" "same thread" "same + cross"
+do
+ echo $t
+
+ for f in "glibc" "vespamallostatic" "vespamalloc" "tcmalloc" "jemalloc" "ptmalloc3" "nedmalloc" "hoard" "tlsf"
+ do
+ grep "$t" t4 | grep "$f" | cut -d';' -f7 | xargs echo $f | sed "s/ /;/g"
+ done
+done
+
+cat t4
+
diff --git a/vespamalloc/src/tests/allocfree/linklist.cpp b/vespamalloc/src/tests/allocfree/linklist.cpp
new file mode 100644
index 00000000000..5ad31d481f9
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/linklist.cpp
@@ -0,0 +1,188 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/log/log.h>
+#include <vespa/fastos/fastos.h>
+#include <vespa/vespalib/testkit/testapp.h>
+#include "producerconsumer.h"
+#include <vespamalloc/malloc/allocchunk.h>
+#include <vespamalloc/util/callstack.h>
+
+using vespalib::Consumer;
+using vespalib::Producer;
+using vespalib::ProducerConsumer;
+
+LOG_SETUP("linklist_test");
+
+TEST_SETUP(Test);
+
+//-----------------------------------------------------------------------------
+
+template <size_t MinSizeClassC, size_t MaxSizeClassMultiAllocC>
+class MemBlockT : public vespamalloc::CommonT<MinSizeClassC>
+{
+public:
+ typedef vespamalloc::StackEntry<vespamalloc::StackReturnEntry> Stack;
+ enum {
+ MaxSizeClassMultiAlloc = MaxSizeClassMultiAllocC,
+ SizeClassSpan = (MaxSizeClassMultiAllocC-MinSizeClassC)
+ };
+ MemBlockT() : _ptr(NULL) { }
+ MemBlockT(void * p) : _ptr(p) { }
+ MemBlockT(void * p, size_t /*sz*/) : _ptr(p) { }
+ void *ptr() { return _ptr; }
+ const void *ptr() const { return _ptr; }
+ bool validAlloc() const { return _ptr != NULL; }
+ bool validFree() const { return _ptr != NULL; }
+ void setExact(size_t ) { }
+ void alloc(bool ) { }
+ void threadId(int ) { }
+ void free() { }
+ size_t size() const { return 0; }
+ bool allocated() const { return false; }
+ int threadId() const { return 0; }
+ void info(FILE *, unsigned level=0) const { level = 0; }
+ Stack * callStack() { return NULL; }
+ size_t callStackLen() const { return 0; }
+
+ static size_t adjustSize(size_t sz) { return sz; }
+ static size_t unAdjustSize(size_t sz) { return sz; }
+ static void dumpInfo(size_t level);
+private:
+ void * _ptr;
+};
+
+typedef MemBlockT<5, 20> DummyMemBlock;
+
+typedef vespamalloc::AFList<DummyMemBlock> List;
+
+const size_t NumBlocks((64*(32+2)+16)*2);
+
+List globalList[NumBlocks];
+
+class LinkIn : public Consumer {
+public:
+ LinkIn(List::HeadPtr & list, uint32_t maxQueue, bool inverse);
+private:
+ List::HeadPtr & _head;
+ virtual void consume(void * p) {
+ List * l((List *) p);
+ if ( ! ((l >= &globalList[0]) && (l < &globalList[NumBlocks]))) { abort(); }
+ List::linkIn(_head, l, l);
+ }
+};
+
+LinkIn::LinkIn(List::HeadPtr & list, uint32_t maxQueue, bool inverse) :
+ Consumer (maxQueue, inverse),
+ _head(list)
+{
+}
+
+//-----------------------------------------------------------------------------
+
+class LinkOut : public Producer {
+public:
+ LinkOut(List::HeadPtr & list, uint32_t cnt, LinkIn &target)
+ : Producer(cnt, target), _head(list) {}
+private:
+ List::HeadPtr & _head;
+ virtual void * produce() {
+ void *p = List::linkOut(_head);
+ List *l((List *)p);
+ if ( ! ((l >= &globalList[0]) && (l < &globalList[NumBlocks]))) { abort(); }
+ return p;
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+class LinkInOutAndIn : public ProducerConsumer {
+public:
+ LinkInOutAndIn(List::HeadPtr & list, uint32_t cnt, bool inverse)
+ : ProducerConsumer(cnt, inverse), _head(list) { }
+private:
+ List::HeadPtr & _head;
+ virtual void * produce() {
+ void *p = List::linkOut(_head);
+ List *l((List *)p);
+ if ( !((l >= &globalList[0]) && (l < &globalList[NumBlocks]))) { abort(); }
+ return p;
+ }
+ virtual void consume(void * p) {
+ List * l((List *) p);
+ if ( !((l >= &globalList[0]) && (l < &globalList[NumBlocks]))) { abort(); }
+ List::linkIn(_head, l, l);
+ }
+};
+
+//-----------------------------------------------------------------------------
+
+int Test::Main() {
+ int duration = 10;
+ if (_argc > 1) {
+ duration = atoi(_argv[1]);
+ }
+ TEST_INIT("allocfree_test");
+
+ ASSERT_EQUAL(1024ul, sizeof(List));
+
+ FastOS_ThreadPool pool(128000);
+ List::HeadPtr sharedList;
+ sharedList._tag = 1;
+ List::init();
+ List::enableThreadSupport();
+ fprintf(stderr, "Start populating list\n");
+ for (size_t i=0; i < NumBlocks; i++) {
+ List * l(&globalList[i]);
+ List::linkIn(sharedList, l, l);
+ }
+ fprintf(stderr, "Finished populating list with %ld elements\n", NumBlocks);
+ fprintf(stderr, "Start verifying result 1.\n");
+ for (size_t i=0; i < NumBlocks; i++) {
+ List *l = List::linkOut(sharedList);
+ ASSERT_TRUE((l >= &globalList[0]) && (l < &globalList[NumBlocks]));
+ }
+ List *n = List::linkOut(sharedList);
+ ASSERT_TRUE(n == NULL);
+
+ sharedList._tag = 1;
+ fprintf(stderr, "Start populating list\n");
+ for (size_t i=0; i < NumBlocks; i++) {
+ List * l(&globalList[i]);
+ List::linkIn(sharedList, l, l);
+ }
+ fprintf(stderr, "Finished populating list with %ld elements\n", NumBlocks);
+ LinkIn c1(sharedList, 64, false);
+ LinkIn c2(sharedList, 64, true);
+ LinkOut p1(sharedList, 32, c1);
+ LinkOut p2(sharedList, 32, c2);
+ LinkInOutAndIn pc1(sharedList, 16, false);
+ LinkInOutAndIn pc2(sharedList, 16, true);
+
+ ASSERT_TRUE(pool.NewThread(&c1, NULL) != NULL);
+ ASSERT_TRUE(pool.NewThread(&c2, NULL) != NULL);
+ ASSERT_TRUE(pool.NewThread(&p1, NULL) != NULL);
+ ASSERT_TRUE(pool.NewThread(&p2, NULL) != NULL);
+ ASSERT_TRUE(pool.NewThread(&pc1, NULL) != NULL);
+ ASSERT_TRUE(pool.NewThread(&pc2, NULL) != NULL);
+
+ for (; duration > 0; --duration) {
+ LOG(info, "%d seconds left...", duration);
+ FastOS_Thread::Sleep(1000);
+ }
+ pool.Close();
+ fprintf(stderr, "Did (%" PRIu64 " + %" PRIu64 ") = %" PRIu64 " linkIn operations\n",
+ c1.operations(), c2.operations(), c1.operations() + c2.operations());
+ fprintf(stderr, "Did (%" PRIu64 " + %" PRIu64 ") = %" PRIu64 " linkOut operations\n",
+ p1.operations(), p2.operations(), p1.operations() + p2.operations());
+ fprintf(stderr, "Did (%" PRIu64 " + %" PRIu64 ") = %" PRIu64 " linkInOut operations\n",
+ pc1.operationsConsumed(), pc2.operationsConsumed(), pc1.operationsConsumed() + pc2.operationsConsumed());
+ fprintf(stderr, "Did %" PRIu64 " Total operations\n",
+ c1.operations() + c2.operations() + p1.operations() + p2.operations() + pc1.operationsConsumed() + pc2.operationsConsumed());
+ fprintf(stderr, "Start verifying result 2.\n");
+ for (size_t i=0; i < NumBlocks; i++) {
+ List *l = List::linkOut(sharedList);
+ ASSERT_TRUE((l >= &globalList[0]) && (l < &globalList[NumBlocks]));
+ }
+ n = List::linkOut(sharedList);
+ ASSERT_TRUE(n == NULL);
+ TEST_DONE();
+}
diff --git a/vespamalloc/src/tests/allocfree/producerconsumer.cpp b/vespamalloc/src/tests/allocfree/producerconsumer.cpp
new file mode 100644
index 00000000000..38c52993762
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/producerconsumer.cpp
@@ -0,0 +1,95 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "producerconsumer.h"
+
+namespace vespalib {
+
+Consumer::Consumer(uint32_t maxQueue, bool inverse) :
+ _queue(NULL, maxQueue),
+ _inverse(inverse),
+ _operations(0)
+{
+}
+
+Consumer::~Consumer()
+{
+}
+
+Producer::Producer(uint32_t cnt, Consumer &target) :
+ _target(target),
+ _cnt(cnt),
+ _operations(0)
+{
+}
+
+Producer::~Producer()
+{
+}
+
+ProducerConsumer::ProducerConsumer(uint32_t cnt, bool inverse) :
+ _cnt(cnt),
+ _inverse(inverse),
+ _operationsConsumed(0),
+ _operationsProduced(0)
+{
+}
+
+ProducerConsumer::~ProducerConsumer()
+{
+}
+
+
+void Consumer::Run(FastOS_ThreadInterface *, void *) {
+ for (;;) {
+ MemList ml = _queue.dequeue();
+ if (ml == NULL) {
+ return;
+ }
+ if (_inverse) {
+ for (uint32_t i = ml->size(); i > 0; --i) {
+ consume((*ml)[i - 1]);
+ _operations++;
+ }
+ } else {
+ for (uint32_t i = 0; i < ml->size(); ++i) {
+ consume((*ml)[i]);
+ _operations++;
+ }
+ }
+ delete ml;
+ }
+}
+
+void Producer::Run(FastOS_ThreadInterface *t, void *) {
+ while (!t->GetBreakFlag()) {
+ MemList ml = new MemListImpl();
+ for (uint32_t i = 0; i < _cnt; ++i) {
+ ml->push_back(produce());
+ _operations++;
+ }
+ _target.enqueue(ml);
+ }
+ _target.close();
+}
+
+void ProducerConsumer::Run(FastOS_ThreadInterface *t, void *) {
+ while (!t->GetBreakFlag()) {
+ MemListImpl ml;
+ for (uint32_t i = 0; i < _cnt; ++i) {
+ ml.push_back(produce());
+ _operationsProduced++;
+ }
+ if (_inverse) {
+ for (uint32_t i = ml.size(); i > 0; --i) {
+ consume(ml[i - 1]);
+ _operationsConsumed++;
+ }
+ } else {
+ for (uint32_t i = 0; i < ml.size(); ++i) {
+ consume(ml[i]);
+ _operationsConsumed++;
+ }
+ }
+ }
+}
+
+}
diff --git a/vespamalloc/src/tests/allocfree/producerconsumer.h b/vespamalloc/src/tests/allocfree/producerconsumer.h
new file mode 100644
index 00000000000..daa0173af98
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/producerconsumer.h
@@ -0,0 +1,58 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vector>
+#include "queue.h"
+
+namespace vespalib {
+
+typedef std::vector<void *> MemListImpl;
+typedef MemListImpl * MemList;
+typedef vespalib::Queue<MemList> MemQueue;
+
+class Consumer : public FastOS_Runnable {
+private:
+ MemQueue _queue;
+ bool _inverse;
+ uint64_t _operations;
+ virtual void consume(void *) = 0;
+public:
+ Consumer(uint32_t maxQueue, bool inverse);
+ virtual ~Consumer();
+ void enqueue(const MemList &mem) { _queue.enqueue(mem); }
+ void close() { _queue.close(); }
+ void Run(FastOS_ThreadInterface *t, void *);
+ uint64_t operations() const { return _operations; }
+};
+
+class Producer : public FastOS_Runnable {
+private:
+ Consumer & _target;
+ uint32_t _cnt;
+ uint64_t _operations;
+ virtual void * produce() = 0;
+public:
+ Producer(uint32_t cnt, Consumer &target);
+ virtual ~Producer();
+ void Run(FastOS_ThreadInterface *t, void *);
+ uint64_t operations() const { return _operations; }
+};
+
+class ProducerConsumer : public FastOS_Runnable {
+private:
+ uint32_t _cnt;
+ bool _inverse;
+ uint64_t _operationsConsumed;
+ uint64_t _operationsProduced;
+ virtual void * produce() = 0;
+ virtual void consume(void *) = 0;
+public:
+ ProducerConsumer(uint32_t cnt, bool inverse);
+ virtual ~ProducerConsumer();
+ void Run(FastOS_ThreadInterface *t, void *);
+ uint64_t operationsConsumed() const { return _operationsConsumed; }
+ uint64_t operationsProduced() const { return _operationsProduced; }
+};
+
+}
+
diff --git a/vespamalloc/src/tests/allocfree/queue.h b/vespamalloc/src/tests/allocfree/queue.h
new file mode 100644
index 00000000000..ce5c18d33f2
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/queue.h
@@ -0,0 +1,86 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#pragma once
+
+#include <vespa/vespalib/util/guard.h>
+#include <vespa/vespalib/util/sync.h>
+#include <queue>
+
+namespace vespalib {
+
+template <typename T>
+class Queue {
+private:
+ std::queue<T> _q;
+ Monitor _cond;
+ int _waitRead;
+ int _waitWrite;
+ uint32_t _maxSize;
+ bool _closed;
+ T _nil;
+ Queue(const Queue &);
+ Queue &operator=(const Queue &);
+public:
+ Queue(const T &nil, uint32_t maxSize);
+ ~Queue();
+ void enqueue(const T &entry);
+ void close();
+ T dequeue();
+};
+
+template <typename T>
+Queue<T>::Queue(const T &nil, uint32_t maxSize) :
+ _q(),
+ _cond(),
+ _waitRead(0),
+ _waitWrite(0),
+ _maxSize(maxSize),
+ _closed(false),
+ _nil(nil)
+{
+}
+
+template <typename T>
+Queue<T>::~Queue()
+{
+}
+
+template <typename T>
+void Queue<T>::enqueue(const T &entry) {
+ MonitorGuard guard(_cond);
+ while (_q.size() >= _maxSize) {
+ CounterGuard cntGuard(_waitWrite);
+ guard.wait();
+ }
+ _q.push(entry);
+ if (_waitRead > 0) {
+ guard.signal();
+ }
+}
+template <typename T>
+void Queue<T>::close() {
+ MonitorGuard guard(_cond);
+ _closed = true;
+ if (_waitRead > 0) {
+ guard.signal();
+ }
+}
+template <typename T>
+T Queue<T>::dequeue() {
+ MonitorGuard guard(_cond);
+ while (_q.empty() && !_closed) {
+ CounterGuard cntGuard(_waitRead);
+ guard.wait();
+ }
+ if (_q.empty()) {
+ return _nil;
+ }
+ T tmp = _q.front();
+ _q.pop();
+ if (_waitWrite > 0) {
+ guard.signal();
+ }
+ return tmp;
+}
+
+}
+
diff --git a/vespamalloc/src/tests/allocfree/realloc.cpp b/vespamalloc/src/tests/allocfree/realloc.cpp
new file mode 100644
index 00000000000..8cfd50d0132
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/realloc.cpp
@@ -0,0 +1,23 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include <vespa/log/log.h>
+#include <vespa/fastos/fastos.h>
+#include <vespa/vespalib/testkit/testapp.h>
+
+LOG_SETUP("realloc_test");
+
+TEST_SETUP(Test);
+
+int Test::Main() {
+ char * v = static_cast<char *>(malloc(0x400001));
+ char * nv = static_cast<char *>(realloc(v, 0x500001));
+ ASSERT_TRUE(v == nv);
+ v = static_cast<char *>(realloc(nv, 0x600001));
+ ASSERT_TRUE(v != nv);
+ free(v);
+
+ char *t = static_cast<char *>(malloc(70));
+ free (t+7);
+ t = static_cast<char *>(malloc(0x400001));
+ free (t+7);
+ return 0;
+}
diff --git a/vespamalloc/src/tests/allocfree/testnames.all b/vespamalloc/src/tests/allocfree/testnames.all
new file mode 100644
index 00000000000..eb51eeefa31
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/testnames.all
@@ -0,0 +1,162 @@
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+glibc;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamallostatic;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+vespamalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+tcmalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+jemalloc;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+ptmalloc3;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+nedmalloc;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+hoard;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
+tlsf;
diff --git a/vespamalloc/src/tests/allocfree/testtype.all b/vespamalloc/src/tests/allocfree/testtype.all
new file mode 100644
index 00000000000..a70eb05bde7
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/testtype.all
@@ -0,0 +1,162 @@
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+cross thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same thread;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
+same + cross;
diff --git a/vespamalloc/src/tests/allocfree/timeusage.sh b/vespamalloc/src/tests/allocfree/timeusage.sh
new file mode 100755
index 00000000000..58fdc47104a
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/timeusage.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+# Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+grep "CPU" |grep "elapsed" | sed "s/user / user /g" | sed "s/system / system /g" | sed "s/elapsed / elapsed /g" | sed "s/CPU / CPU /g" | awk '{print $1 ";\t" $3 ";\t" $7 ";"}'
diff --git a/vespamalloc/src/tests/allocfree/vespamalloc.conf b/vespamalloc/src/tests/allocfree/vespamalloc.conf
new file mode 100644
index 00000000000..5c82d46d94b
--- /dev/null
+++ b/vespamalloc/src/tests/allocfree/vespamalloc.conf
@@ -0,0 +1,13 @@
+#Config file for vespa malloc
+#loglevel = 0 should mean no logging. Only level 1 is implemented.
+# logfile vespamalloc.log # default(stderr) This is the file to where log is written (stderr, stdout, filename)
+sigprof_loglevel 2 # default(0) Loglevel used at SIGPROF signal.
+atend_loglevel 2 # default(1) Loglevel used when application stops.
+atnomem_loglevel 2 # default(1) Loglevel used when datasegment is exhausted.
+atdoubledelete_loglevel 2 # default(1) Loglevel used when vespa_malloc discovers a double delete.
+atinvalid_loglevel 2 # default(1) Loglevel used when vespa_malloc discovers logical error.
+bigsegment_loglevel 0 # default(1) Loglevel used when datasegment passes a boundary.
+bigsegment_limit 0x80000000 # default(0x20000000) First level the datasegment must reach before logging is started
+bigsegment_increment 0x10000000 # default(0x4000000) At what increment it will log next time.
+bigblocklimit 0x800000 # default(0x800000) Limit for when to log new/deletes wuth stack trace. Only mallocdst.so
+allocs2show 8