diff options
author | Josh Blum | 2012-10-02 20:47:54 -0700 |
---|---|---|
committer | Josh Blum | 2012-10-02 20:47:54 -0700 |
commit | ac18fcf142dadaa967cf9ad116048e00c65c2d02 (patch) | |
tree | 753c53e496a17acff9a1e809970fddbdf87563ba /lib/theron_allocator.cpp | |
parent | cd9494ea5ab089ff0594b22b36e28362a59961c4 (diff) | |
download | sandhi-ac18fcf142dadaa967cf9ad116048e00c65c2d02.tar.gz sandhi-ac18fcf142dadaa967cf9ad116048e00c65c2d02.tar.bz2 sandhi-ac18fcf142dadaa967cf9ad116048e00c65c2d02.zip |
register messages, and custom allocator for performance
Diffstat (limited to 'lib/theron_allocator.cpp')
-rw-r--r-- | lib/theron_allocator.cpp | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lib/theron_allocator.cpp b/lib/theron_allocator.cpp new file mode 100644 index 0000000..b8f875f --- /dev/null +++ b/lib/theron_allocator.cpp @@ -0,0 +1,90 @@ +// +// Copyright 2012 Josh Blum +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with io_sig program. If not, see <http://www.gnu.org/licenses/>. + +/*********************************************************************** + * There is allocation overhead for sending messages. + * Want per worker-allocator for message allocation... + * But until thats possible, install a new global allocator. + * This allocator uses a fixed pool for small sized buffers, + * and otherwise the regular malloc/free for larger buffers. + **********************************************************************/ + +#include <gras_impl/debug.hpp> +#include <Theron/Detail/Threading/SpinLock.h> +#include <Theron/IAllocator.h> +#include <Theron/AllocatorManager.h> +#include <boost/circular_buffer.hpp> + +#define MY_ALLOCATOR_CHUNK_SIZE 88 //Theron asks for a lot of 88-byte buffers +#define MY_ALLOCATOR_POOL_SIZE (MY_ALLOCATOR_CHUNK_SIZE * 4096) + +static struct WorkerAllocator : Theron::IAllocator +{ + WorkerAllocator(void) + { + const size_t N = MY_ALLOCATOR_POOL_SIZE/MY_ALLOCATOR_CHUNK_SIZE; + queue.resize(N); + for (size_t i = 0; i < N; i++) + { + const ptrdiff_t pool_ptr = ptrdiff_t(pool) + i*MY_ALLOCATOR_CHUNK_SIZE; + queue.push_back((void *)pool_ptr); + } + Theron::AllocatorManager::Instance().SetAllocator(this); + } + + ~WorkerAllocator(void) + { + //NOP + } + + void *Allocate(const SizeType size) + { + if (size <= MY_ALLOCATOR_CHUNK_SIZE) + { + mSpinLock.Lock(); + ASSERT(not queue.empty()); + void *memory = queue.front(); + queue.pop_front(); + mSpinLock.Unlock(); + return memory; + } + else + { + //std::cout << "malloc size " << size << std::endl; + return std::malloc(size); + } + } + + void Free(void *const memory) + { + const bool in_pool = ptrdiff_t(memory) >= ptrdiff_t(pool) and ptrdiff_t(memory) < (ptrdiff_t(pool) + MY_ALLOCATOR_POOL_SIZE); + if (in_pool) + { + mSpinLock.Lock(); + queue.push_front(memory); + mSpinLock.Unlock(); + } + else + { + std::free(memory); + } + } + + boost::circular_buffer<void *> queue; + long pool[MY_ALLOCATOR_POOL_SIZE/sizeof(long)]; + Theron::Detail::SpinLock mSpinLock; + +} my_alloc; |