// ============================================================================ // // = LIBRARY // ULib - c++ library // // = FILENAME // memory_pool.h // // = AUTHOR // Stefano Casazza // // ============================================================================ #ifndef ULIB_MEMORY_POOL_H #define ULIB_MEMORY_POOL_H 1 // --------------------------------------------------------------------------------------------------------------- // U_MAX_SIZE_PREALLOCATE: richiesta massima soddisfatta con metodo di preallocazione altrimenti chiamata a malloc #define U_MAX_SIZE_PREALLOCATE 4096U // U_STACK_TYPE_* 'tipi' stack per cui la richiesta viene gestita tramite preallocazione #ifdef HAVE_ARCH64 /* ========================= ** NO DEBUG (64 bit) ** ------------------------- 1 sizeof(UMagic) 1 sizeof(UNotifier) 8 sizeof(UCrl) 8 sizeof(UPKCS10) 8 sizeof(UString) <== 8 sizeof(UCertificate) ------------------------- U_STACK_TYPE_0 12 sizeof(UProcess) 16 sizeof(UTimer) 16 sizeof(UPKCS7) 16 sizeof(UTimeVal) 16 sizeof(UTimeDate) 16 sizeof(UXMLParser) 16 sizeof(USemaphore) 16 sizeof(URDBServer) 16 sizeof(UVector) 16 sizeof(UServer) 24 sizeof(ULock) 24 sizeof(UStringRep) <== 24 sizeof(USOAPObject) ------------------------- U_STACK_TYPE_1 32 sizeof(ULDAPEntry) 32 sizeof(UQueryNode) 32 sizeof(USOAPFault) 32 sizeof(UTokenizer) 32 sizeof(UHashMapNode) <== 32 sizeof(UXMLAttribute) 32 sizeof(UTree) ------------------------- U_STACK_TYPE_2 40 sizeof(Url) 40 sizeof(ULDAP) 40 sizeof(UCache) 40 sizeof(UHashMap) 48 sizeof(UCURL) 48 sizeof(UDialog) 48 sizeof(UMimeHeader) 48 sizeof(UMimeEntity) 48 sizeof(UXMLElement) 48 sizeof(UQueryParser) 48 sizeof(USOAPEncoder) 48 sizeof(USOAPGenericMethod) 56 sizeof(UOptions) 56 sizeof(UIPAddress) 56 sizeof(UPlugIn) 56 sizeof(UHTTP::UFileCacheData) <== ------------------------- U_STACK_TYPE_3 64 sizeof(UPCRE) 64 sizeof(UCommand) 64 sizeof(UApplication) 64 sizeof(UClientImage) 72 sizeof(UMimePKCS7) 80 sizeof(UZIP) 88 sizeof(UMimeMultipartMsg) 96 sizeof(UMimeMessage) 128 sizeof(USOAPParser) 128 sizeof(UMimeMultipart) ------------------------- U_STACK_TYPE_4 144 sizeof(USocket) 144 sizeof(UTCPSocket) 144 sizeof(UUDPSocket) 176 sizeof(USSLSocket) 184 sizeof(UFile) 216 sizeof(UBison) 216 sizeof(UFlexer) 232 sizeof(ULog) 232 sizeof(USmtpClient) 248 sizeof(URDBClient) 256 sizeof(UFileConfig) ------------------------- U_STACK_TYPE_5 304 sizeof(UHttpClient) 328 sizeof(UCDB) 360 sizeof(UFtpClient) 384 sizeof(USOAPClient) 512 ------------------------- U_STACK_TYPE_6 568 sizeof(URDB) ========================= ** DEBUG (64 bit) ** ------------------------- 1 sizeof(UNotifier) 8 sizeof(UMagic) 8 sizeof(UString) <== ------------------------- U_STACK_TYPE_0 16 sizeof(UCrl) 16 sizeof(UPKCS10) 16 sizeof(UCertificate) 24 sizeof(UTimer) 24 sizeof(UPKCS7) 24 sizeof(UProcess) 24 sizeof(UTimeVal) 24 sizeof(UTimeDate) 24 sizeof(URDBServer) 24 sizeof(USemaphore) 24 sizeof(UVector) 24 sizeof(UServer) 32 sizeof(ULock) 40 sizeof(UQueryNode) 40 sizeof(USOAPFault) 40 sizeof(UStringRep) <== 40 sizeof(UTokenizer) 40 sizeof(USOAPObject) 40 sizeof(UHashMapNode) <== 40 sizeof(UTree) ------------------------- U_STACK_TYPE_1 48 sizeof(Url) 48 sizeof(UHashMap) ------------------------- U_STACK_TYPE_2 56 sizeof(UDialog) 56 sizeof(UMimeEntity) 56 sizeof(USOAPGenericMethod) 64 sizeof(UCache) 64 sizeof(UOptions) 64 sizeof(UIPAddress) 64 sizeof(UMimeHeader) 64 sizeof(UQueryParser) 64 sizeof(USOAPEncoder) 64 sizeof(UPlugIn) 64 sizeof(UHTTP::UFileCacheData) <== ------------------------- U_STACK_TYPE_3 72 sizeof(UPCRE) 72 sizeof(UCommand) 80 sizeof(UApplication) 80 sizeof(UClientImage) 88 sizeof(UZIP) 88 sizeof(UMimePKCS7) 104 sizeof(UMimeMultipartMsg) 112 sizeof(UMimeMessage) 128 ------------------------- U_STACK_TYPE_4 144 sizeof(UMimeMultipart) 168 sizeof(USocket) 168 sizeof(UTCPSocket) 168 sizeof(UUDPSocket) 168 sizeof(USOAPParser) 192 sizeof(UFile) 200 sizeof(USSLSocket) 216 sizeof(UBison) 216 sizeof(UFlexer) 240 sizeof(ULog) 256 sizeof(USmtpClient) 256 ------------------------- U_STACK_TYPE_5 264 sizeof(URDBClient) 272 sizeof(UFileConfig) 320 sizeof(UHttpClient) 336 sizeof(UCDB) 408 sizeof(UFtpClient) 440 sizeof(USOAPClient) 512 ------------------------- U_STACK_TYPE_6 592 sizeof(URDB) ========================= */ #else /* ========================= ** NO DEBUG (32 bit) ** ------------------------- 1 sizeof(UMagic) 1 sizeof(UNotifier) 4 sizeof(UCrl) 4 sizeof(UPKCS10) 4 sizeof(UString) <== 4 sizeof(UCertificate) ------------------------- U_STACK_TYPE_0 8 sizeof(UTimer) 8 sizeof(UPKCS7) 8 sizeof(UTimeVal) 8 sizeof(USemaphore) 12 sizeof(ULock) 12 sizeof(UProcess) 12 sizeof(URDBServer) 12 sizeof(UVector) 12 sizeof(UServer) 16 sizeof(UTimeDate) 16 sizeof(UXMLParser) 16 sizeof(UQueryNode) 16 sizeof(USOAPFault) 16 sizeof(UTokenizer) 16 sizeof(UStringRep) <== 16 sizeof(USOAPObject) 16 sizeof(UHashMapNode) <== ------------------------- U_STACK_TYPE_1 20 sizeof(UCache) 20 sizeof(UTree) 24 sizeof(UQueryParser) 24 sizeof(USOAPGenericMethod) 28 sizeof(UCURL) 28 sizeof(UDialog) 28 sizeof(UMimeEntity) 28 sizeof(USOAPEncoder) 28 sizeof(UPlugIn) 32 sizeof(UOptions) 32 sizeof(UHashMap) 36 sizeof(Url) 36 sizeof(UMimeHeader) 36 sizeof(UApplication) 40 sizeof(UPCRE) 40 sizeof(UCommand) 40 sizeof(UMimePKCS7) 40 sizeof(UHTTP::UFileCacheData) <== ------------------------- U_STACK_TYPE_2 44 sizeof(UZIP) 44 sizeof(UClientImage) 48 sizeof(UIPAddress) 56 sizeof(UMimeMessage) 64 ------------------------- U_STACK_TYPE_3 68 sizeof(USOAPParser) 80 sizeof(UMimeMultipart) 80 sizeof(UMimeMultipartMsg) 120 sizeof(UFile) 124 sizeof(USocket) 124 sizeof(UTCPSocket) 124 sizeof(UUDPSocket) 128 ------------------------- U_STACK_TYPE_4 144 sizeof(USSLSocket) 148 sizeof(ULog) 148 sizeof(URDBClient) 172 sizeof(UFileConfig) 176 sizeof(USmtpClient) 180 sizeof(UHttpClient) 212 sizeof(UModNoCatPeer) 216 sizeof(UCDB) 220 sizeof(USOAPClient) 256 ------------------------- U_STACK_TYPE_5 300 sizeof(UFtpClient) 364 sizeof(URDB) 512 ------------------------- U_STACK_TYPE_6 ========================= ** DEBUG (32 bit) ** ------------------------- 1 sizeof(UNotifier) 4 sizeof(UMagic) 4 sizeof(UString) <== ------------------------- U_STACK_TYPE_0 8 sizeof(UCrl) 8 sizeof(UPKCS10) 8 sizeof(UCertificate) 12 sizeof(UTimer) 12 sizeof(UPKCS7) 12 sizeof(UTimeVal) 12 sizeof(USemaphore) 16 sizeof(ULock) 16 sizeof(UProcess) 16 sizeof(URDBServer) 16 sizeof(UVector) 16 sizeof(UServer) 20 sizeof(UTimeDate) 20 sizeof(UQueryNode) 20 sizeof(USOAPFault) 20 sizeof(UTokenizer) 20 sizeof(UHashMapNode) <== 24 sizeof(USOAPObject) 24 sizeof(UTree) 28 sizeof(UStringRep) <== 28 sizeof(USOAPGenericMethod) ------------------------- U_STACK_TYPE_1 32 sizeof(UCache) 32 sizeof(UDialog) 32 sizeof(UMimeEntity) 32 sizeof(UQueryParser) 32 sizeof(UPlugIn) 36 sizeof(UOptions) 36 sizeof(USOAPEncoder) 36 sizeof(UHashMap) 40 sizeof(Url) 44 sizeof(UPCRE) 44 sizeof(UCommand) 44 sizeof(UMimeHeader) 44 sizeof(UApplication) 44 sizeof(UHTTP::UFileCacheData) <== ------------------------- U_STACK_TYPE_2 48 sizeof(UZIP) 48 sizeof(UMimePKCS7) 48 sizeof(UClientImage) 52 sizeof(UIPAddress) 64 sizeof(UMimeMessage) ------------------------- U_STACK_TYPE_3 88 sizeof(USOAPParser) 88 sizeof(UMimeMultipart) 88 sizeof(UMimeMultipartMsg) 124 sizeof(UFile) 128 ------------------------- U_STACK_TYPE_4 136 sizeof(USocket) 136 sizeof(UTCPSocket) 136 sizeof(UUDPSocket) 152 sizeof(ULog) 156 sizeof(USSLSocket) 156 sizeof(URDBClient) 180 sizeof(UFileConfig) 188 sizeof(USmtpClient) 188 sizeof(UHttpClient) 220 sizeof(UCDB) 248 sizeof(USOAPClient) ------------------------- U_STACK_TYPE_5 324 sizeof(UFtpClient) 376 sizeof(URDB) 512 ------------------------- U_STACK_TYPE_6 ========================= */ #endif /* 1024 ------------------------- U_STACK_TYPE_7 2048 ------------------------- U_STACK_TYPE_8 4096 ------------------------- U_STACK_TYPE_9 */ #ifdef HAVE_ARCH64 # define U_STACK_TYPE_0 8U # ifndef DEBUG # define U_STACK_TYPE_1 24U # define U_STACK_TYPE_2 32U # define U_STACK_TYPE_3 56U # else # define U_STACK_TYPE_1 40U # define U_STACK_TYPE_2 48U # define U_STACK_TYPE_3 64U # endif #else # define U_STACK_TYPE_0 4U # define U_STACK_TYPE_3 64U # ifndef DEBUG # define U_STACK_TYPE_1 16U # define U_STACK_TYPE_2 40U # else # define U_STACK_TYPE_1 28U # define U_STACK_TYPE_2 44U # endif #endif // NB: con U_NUM_ENTRY_MEM_BLOCK == 32 sono necessari i tipi stack // multipli di 2 a partire da 128 per i blocchi puntatori per 32bit arch... #define U_STACK_TYPE_4 128U #define U_STACK_TYPE_5 256U #define U_STACK_TYPE_6 512U #define U_STACK_TYPE_7 1024U #define U_STACK_TYPE_8 2048U #define U_STACK_TYPE_9 U_MAX_SIZE_PREALLOCATE // U_NUM_STACK_TYPE: numero 'tipi' stack per cui la richiesta viene gestita tramite preallocazione #define U_NUM_STACK_TYPE 10 // Implements a simple stack allocator #define U_SIZE_TO_STACK_INDEX(sz) ((sz) <= U_STACK_TYPE_0 ? 0 : \ (sz) <= U_STACK_TYPE_1 ? 1 : \ (sz) <= U_STACK_TYPE_2 ? 2 : \ (sz) <= U_STACK_TYPE_3 ? 3 : \ (sz) <= U_STACK_TYPE_4 ? 4 : \ (sz) <= U_STACK_TYPE_5 ? 5 : \ (sz) <= U_STACK_TYPE_6 ? 6 : \ (sz) <= U_STACK_TYPE_7 ? 7 : \ (sz) <= U_STACK_TYPE_8 ? 8 : 9) class UStringRep; class UServer_Base; class UNoCatPlugIn; class UStackMemoryPool; template class UVector; // This avoids memory fragmentation and the overhead of heap traversal that malloc incurs class U_EXPORT UMemoryPool { public: // ------------------------------------------------------------------- // NB: allocazione area di memoria <= U_MAX_SIZE_PREALLOCATE // ritorna area di memoria preallocata su stack predefiniti // (non garantito azzerata a meno di azzerare le deallocazioni...) // ------------------------------------------------------------------- static void* pop( int stack_index); static void push(void* ptr, int stack_index); // ------------------------------------------------------------------- static void allocateMemoryBlocks(const char* list); static void _free(void* ptr, uint32_t num, uint32_t type_size = 1); static void* _malloc( uint32_t num, uint32_t type_size = 1, bool bzero = false); static void* _malloc( uint32_t* pnum, uint32_t type_size = 1, bool bzero = false); #ifdef DEBUG static const char* obj_class; static const char* func_call; static bool check(void* ptr); # ifdef U_STDCPP_ENABLE # ifdef __clang__ static void printInfo( ostream& os); # else static void printInfo(std::ostream& os); # endif static void writeInfoTo(const char* format, ...); # endif #endif private: static void deallocate(void* ptr, uint32_t length); static void allocateMemoryBlocks(int stack_index, uint32_t n); #ifdef U_COMPILER_DELETE_MEMBERS UMemoryPool(const UMemoryPool&) = delete; UMemoryPool& operator=(const UMemoryPool&) = delete; #else UMemoryPool(const UMemoryPool&) {} UMemoryPool& operator=(const UMemoryPool&) { return *this; } #endif friend class UStringRep; friend class UServer_Base; friend class UNoCatPlugIn; friend class UStackMemoryPool; template friend class UVector; }; #ifdef DEBUG template bool u_check_memory_vector(T* _vec, uint32_t n) { U_TRACE(0+256, "u_check_memory_vector(%p,%u)", _vec, n) for (uint32_t i = 0; i < n; ++i) if (_vec[i].check_memory() == false) U_RETURN(false); U_RETURN(true); } #endif #ifdef ENABLE_MEMPOOL # define U_MALLOC_TYPE( type) (type*)UMemoryPool::pop( U_SIZE_TO_STACK_INDEX(sizeof(type)));U_INTERNAL_ASSERT(sizeof(type)<=U_MAX_SIZE_PREALLOCATE) # define U_FREE_TYPE(ptr,type) { UMemoryPool::push(ptr,U_SIZE_TO_STACK_INDEX(sizeof(type)));U_INTERNAL_ASSERT(sizeof(type)<=U_MAX_SIZE_PREALLOCATE) } # define U_MEMORY_ALLOCATOR \ void* operator new( size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); return UMemoryPool::pop(U_SIZE_TO_STACK_INDEX(sz)); } \ void* operator new[](size_t sz) { return UMemoryPool::_malloc(sz); } # define U_MEMORY_DEALLOCATOR \ void operator delete( void* _ptr, size_t sz) { U_INTERNAL_ASSERT(sz <= U_MAX_SIZE_PREALLOCATE); UMemoryPool::push( _ptr, U_SIZE_TO_STACK_INDEX(sz)); } \ void operator delete[](void* _ptr, size_t sz) { UMemoryPool::_free(_ptr, sz); } #else # define U_MALLOC_TYPE( type) (type*)malloc(sizeof(type)) # define U_FREE_TYPE(ptr,type) { free(ptr); } # define U_MEMORY_ALLOCATOR # define U_MEMORY_DEALLOCATOR #endif #endif