1
0
mirror of https://github.com/stefanocasazza/ULib.git synced 2025-09-28 19:05:55 +08:00
ULib/include/ulib/internal/memory_pool.h
2015-12-01 19:58:59 +01:00

546 lines
14 KiB
C++

// ============================================================================
//
// = 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<UString>)
16 sizeof(UServer<UTCPSocket>)
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<UString>)
-------------------------
U_STACK_TYPE_2
40 sizeof(Url)
40 sizeof(ULDAP)
40 sizeof(UCache)
40 sizeof(UHashMap<UString>)
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<void*>)
56 sizeof(UHTTP::UFileCacheData) <==
-------------------------
U_STACK_TYPE_3
64 sizeof(UPCRE)
64 sizeof(UCommand)
64 sizeof(UApplication)
64 sizeof(UClientImage<UTCPSocket>)
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<UTCPSocket>)
256 sizeof(UFileConfig)
-------------------------
U_STACK_TYPE_5
304 sizeof(UHttpClient<UTCPSocket>)
328 sizeof(UCDB)
360 sizeof(UFtpClient)
384 sizeof(USOAPClient<UTCPSocket>)
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<UString>)
24 sizeof(UServer<UTCPSocket>)
32 sizeof(ULock)
40 sizeof(UQueryNode)
40 sizeof(USOAPFault)
40 sizeof(UStringRep) <==
40 sizeof(UTokenizer)
40 sizeof(USOAPObject)
40 sizeof(UHashMapNode) <==
40 sizeof(UTree<UString>)
-------------------------
U_STACK_TYPE_1
48 sizeof(Url)
48 sizeof(UHashMap<UString>)
-------------------------
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<void*>)
64 sizeof(UHTTP::UFileCacheData) <==
-------------------------
U_STACK_TYPE_3
72 sizeof(UPCRE)
72 sizeof(UCommand)
80 sizeof(UApplication)
80 sizeof(UClientImage<UTCPSocket>)
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<UTCPSocket>)
272 sizeof(UFileConfig)
320 sizeof(UHttpClient<UTCPSocket>)
336 sizeof(UCDB)
408 sizeof(UFtpClient)
440 sizeof(USOAPClient<UTCPSocket>)
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<UString>)
12 sizeof(UServer<UTCPSocket>)
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<UString>)
24 sizeof(UQueryParser)
24 sizeof(USOAPGenericMethod)
28 sizeof(UCURL)
28 sizeof(UDialog)
28 sizeof(UMimeEntity)
28 sizeof(USOAPEncoder)
28 sizeof(UPlugIn<void*>)
32 sizeof(UOptions)
32 sizeof(UHashMap<UString>)
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<UTCPSocket>)
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<UTCPSocket>)
172 sizeof(UFileConfig)
176 sizeof(USmtpClient)
180 sizeof(UHttpClient<UTCPSocket>)
212 sizeof(UModNoCatPeer)
216 sizeof(UCDB)
220 sizeof(USOAPClient<UTCPSocket>)
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<UString>)
16 sizeof(UServer<UTCPSocket>)
20 sizeof(UTimeDate)
20 sizeof(UQueryNode)
20 sizeof(USOAPFault)
20 sizeof(UTokenizer)
20 sizeof(UHashMapNode) <==
24 sizeof(USOAPObject)
24 sizeof(UTree<UString>)
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<void*>)
36 sizeof(UOptions)
36 sizeof(USOAPEncoder)
36 sizeof(UHashMap<UString>)
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<UTCPSocket>)
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<UTCPSocket>)
180 sizeof(UFileConfig)
188 sizeof(USmtpClient)
188 sizeof(UHttpClient<UTCPSocket>)
220 sizeof(UCDB)
248 sizeof(USOAPClient<UTCPSocket>)
-------------------------
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 T> 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;
friend void check_mmap(uint32_t);
template <class T> friend class UVector;
};
#ifdef DEBUG
template <class T> bool u_check_memory_vector(T* _vec, uint32_t n)
{
U_TRACE(0+256, "u_check_memory_vector<T>(%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