/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ /* *************************************************************************** * * FastFlow is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version 3 as * published by the Free Software Foundation. * Starting from version 3.0.1 FastFlow is dual licensed under the GNU LGPLv3 * or MIT License (https://github.com/ParaGroup/WindFlow/blob/vers3.x/LICENSE.MIT) * * 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 General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., 59 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * As a special exception, you may use this file as part of a free software * library without restriction. Specifically, if other files instantiate * templates or use macros or inline functions from this file, or you compile * this file and link it with other files to produce an executable, this file * does not by itself cause the resulting executable to be covered by the GNU * General Public License. This exception does not however invalidate any * other reasons why the executable file might be covered by the GNU General * Public License. * * **************************************************************************/ #ifndef FF_STATIC_ALLOCATOR_HPP #define FF_STATIC_ALLOCATOR_HPP #include #include #include #include #include /* Author: Massimo Torquati * December 2020 */ namespace ff { class StaticAllocator { public: StaticAllocator(const size_t _nslot, const size_t slotsize, const int nchannels=1): ssize(slotsize), nchannels(nchannels), cnts(nchannels,0), segment(nullptr) { assert(nchannels>0); assert(slotsize>0); ssize = slotsize + sizeof(long*); // rounding up nslot to be multiple of nchannels nslot = ((_nslot + nchannels -1) / nchannels) * nchannels; slotsxchannel = nslot / nchannels; } ~StaticAllocator() { if (segment) munmap(segment, nslot*ssize); segment=nullptr; } int init() { void* result = 0; result = mmap(NULL, nslot*ssize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (result == MAP_FAILED) return -1; segment = (char*)result; // initialize the "header" char* p = segment; for(size_t i=0; i void alloc(T*& p, int channel=0) { assert(channel>=0 && channel static inline void dealloc(T* p) { p->~T(); long** _p = (long**)((char*)p-sizeof(long*)); _p[0] = (long*)FF_GO_ON; // the slot is free and can be re-used } template void realloc(T* in, S*& out) { in->~T(); char* mp = reinterpret_cast(in); out = new (mp) S(); } private: size_t nslot; // total number of slots in the data segment size_t slotsxchannel; // how many slots for each sub data segment size_t ssize; // size of a data slot (real size + sizeof(long*)) int nchannels; // number of sub data segments std::vector cnts; // counters char *segment; // data segment }; }; #endif /* FF_STATIC_ALLOCATOR_HPP */