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/allocfree/allocfree.cpp |
Publish
Diffstat (limited to 'vespamalloc/src/tests/allocfree/allocfree.cpp')
-rw-r--r-- | vespamalloc/src/tests/allocfree/allocfree.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
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(); +} |