mirror of
https://github.com/stefanocasazza/ULib.git
synced 2025-09-28 19:05:55 +08:00
546 lines
14 KiB
C++
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
|