version 1.20, 2002/05/12 15:27:54
|
version 1.31, 2002/09/01 18:18:23
|
|
|
//%///////////-*-c++-*-////////////////////////////////////////////////////// |
//%///////////////////////////////////////////////////////////////////////////// |
// | // |
// Copyright (c) 2000 - 2002 The Open group, BMC Software, Tivoli Systems, IBM |
// Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM, |
|
// The Open Group, Tivoli Systems |
// | // |
// Permission is hereby granted, free of charge, to any person obtaining a copy | // Permission is hereby granted, free of charge, to any person obtaining a copy |
// of this software and associated documentation files (the "Software"), to | // of this software and associated documentation files (the "Software"), to |
|
|
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
// | // |
//============================================================================ |
//============================================================================== |
// | // |
// Author: Mike Day (mdday@us.ibm.com) | // Author: Mike Day (mdday@us.ibm.com) |
// | // |
|
|
| |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
#include <Pegasus/suballoc/Linkage.h> | #include <Pegasus/suballoc/Linkage.h> |
|
#include <stdio.h> |
#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) | #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) |
#include <windows.h> | #include <windows.h> |
#include <process.h> | #include <process.h> |
#include <stdio.h> | #include <stdio.h> |
|
#include <malloc.h> |
|
#include <stdlib.h> |
|
|
#elif defined (PEGASUS_PLATFORM_LINUX_IX86_GNU) | #elif defined (PEGASUS_PLATFORM_LINUX_IX86_GNU) |
#include <pthread.h> | #include <pthread.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_AIX_RS_IBMCXX) | #elif defined (PEGASUS_PLATFORM_AIX_RS_IBMCXX) |
#include <sched.h> | #include <sched.h> |
#include <pthread.h> | #include <pthread.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_HPUX_PARISC_ACC) |
#elif defined (PEGASUS_PLATFORM_HPUX_ACC) |
#include <sched.h> | #include <sched.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <pthread.h> | #include <pthread.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX) | #elif defined (PEGASUS_PLATFORM_TRU64_ALPHA_DECCXX) |
#include <sched.h> | #include <sched.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <pthread.h> | #include <pthread.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_SOLARIS_SPARC_GNU) | #elif defined (PEGASUS_PLATFORM_SOLARIS_SPARC_GNU) |
#include <sched.h> | #include <sched.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <pthread.h> | #include <pthread.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) | #elif defined (PEGASUS_PLATFORM_ZOS_ZSERIES_IBM) |
#include <sched.h> | #include <sched.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <pthread.h> | #include <pthread.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
| |
#elif defined (PEGASUS_PLATFORM_LINUX_IA64_GNU) | #elif defined (PEGASUS_PLATFORM_LINUX_IA64_GNU) |
#include <sched.h> | #include <sched.h> |
#include <semaphore.h> | #include <semaphore.h> |
#include <pthread.h> | #include <pthread.h> |
#include <unistd.h> | #include <unistd.h> |
|
#include <malloc.h> |
|
|
|
#elif defined (PEGASUS_PLATFORM_OS400_ISERIES_IBM) |
|
#include <sched.h> |
|
#include <semaphore.h> |
|
#include <pthread.h> |
|
#include <unistd.cleinc> |
|
#include <stdlib.h> |
| |
#else | #else |
# error "<Pegasus/Common/Config.h>: Unsupported Platform" | # error "<Pegasus/Common/Config.h>: Unsupported Platform" |
|
|
#include <stdio.h> | #include <stdio.h> |
#include <string.h> | #include <string.h> |
#include <memory.h> | #include <memory.h> |
#include <malloc.h> |
|
#include <errno.h> | #include <errno.h> |
#include <signal.h> | #include <signal.h> |
|
#include <new.h> |
namespace | namespace |
{ | { |
static const int GUARD_SIZE = 0x10; | static const int GUARD_SIZE = 0x10; |
|
|
static const unsigned int AVAIL = 0x00000002; | static const unsigned int AVAIL = 0x00000002; |
static const unsigned int ARRAY_NODE = 0x00000004; | static const unsigned int ARRAY_NODE = 0x00000004; |
static const unsigned int CHECK_FAILED = 0x00000008; | static const unsigned int CHECK_FAILED = 0x00000008; |
|
static const unsigned int ALREADY_DELETED = 0x00000010; |
|
static const unsigned int OVERWRITE = 0x00000020; |
|
static const unsigned int CHECK_LEAK = 0x00000040; |
|
static const unsigned int HUGE_NODE = 0x00000080; |
} | } |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
class guardian; |
|
struct SUBALLOC_HANDLE; | struct SUBALLOC_HANDLE; |
| |
PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t); |
#if defined(PEGASUS_DEBUG_MEMORY) |
PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t, | PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t, |
void *, | void *, |
int type, | int type, |
const Sint8 *classname, | const Sint8 *classname, |
Sint8 *file, | Sint8 *file, |
Uint32 line ); | Uint32 line ); |
|
|
PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *dead, | PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *dead, |
void *, | void *, |
int type, | int type, |
Sint8 *classname, | Sint8 *classname, |
Sint8 *file, | Sint8 *file, |
Uint32 line); | Uint32 line); |
|
#else |
|
PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t); |
PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *); | PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *); |
|
#endif |
|
|
|
|
|
|
|
|
| |
#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) | #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) |
| |
|
|
| |
typedef pthread_mutex_t PEGASUS_MUTEX_T; | typedef pthread_mutex_t PEGASUS_MUTEX_T; |
| |
#elif defined (PEGASUS_PLATFORM_HPUX_PARISC_ACC) |
#elif defined (PEGASUS_PLATFORM_HPUX_ACC) |
| |
typedef pthread_mutex_t PEGASUS_MUTEX_T; | typedef pthread_mutex_t PEGASUS_MUTEX_T; |
| |
|
|
| |
typedef pthread_mutex_t PEGASUS_MUTEX_T; | typedef pthread_mutex_t PEGASUS_MUTEX_T; |
| |
|
#elif defined (PEGASUS_PLATFORM_OS400_ISERIES_IBM) |
|
|
|
typedef pthread_mutex_t PEGASUS_MUTEX_T; |
|
|
#endif | #endif |
| |
// to reduce the number of wasted bytes: | // to reduce the number of wasted bytes: |
|
|
| |
class peg_suballoc; | class peg_suballoc; |
| |
|
|
#if defined(PEGASUS_DEBUG_MEMORY) | #if defined(PEGASUS_DEBUG_MEMORY) |
#define PEGASUS_NEW(a) new((pegasus_alloc(sizeof(a), ((void *)0), NORMAL, (#a), __FILE__, __LINE__))) |
#define PEGASUS_NEW(a, h) new((pegasus_alloc(sizeof(a), ((void *)h), NORMAL, (#a), __FILE__, __LINE__))) |
#define PEGASUS_ARRAY_NEW(a, i) new(pegasus_alloc(sizeof(a) * (i), NULL, ARRAY, (#a), __FILE__, __LINE__)) (a) |
#define PEGASUS_ARRAY_NEW(a, i, h) new(pegasus_alloc(sizeof(a) * (i), ((void *)(h)), ARRAY, (#a), __FILE__, __LINE__)) a |
#define PEGASUS_DELETE(a) pegasus_free((a), NULL, NORMAL, (#a), __FILE__, __LINE__) | #define PEGASUS_DELETE(a) pegasus_free((a), NULL, NORMAL, (#a), __FILE__, __LINE__) |
#define PEGASUS_ARRAY_DELETE(a) pegasus_free(a, NULL, ARRAY, (#a), __FILE__, __LINE__) | #define PEGASUS_ARRAY_DELETE(a) pegasus_free(a, NULL, ARRAY, (#a), __FILE__, __LINE__) |
|
#define PEGASUS_CHECK_FOR_LEAKS(h) peg_suballocator::get_instance()->_UnfreedNodes((h)) |
|
#define PEGASUS_START_LEAK_CHECK() peg_suballocator::get_instance()->set_leak_mode(true) |
|
#define PEGASUS_STOP_LEAK_CHECK() peg_suballocator::get_instance()->set_leak_mode(false) |
|
#define PEGASUS_PRINT_NODE(a, b) peg_suballocator::PrintNodeInfo((void *)(a), (Sint8 *)(b), __FILE__, __LINE__) |
#else | #else |
#define PEGASUS_NEW(a) new |
#define PEGASUS_NEW(a, h) new |
#define PEGASUS_ARRAY_NEW(a, i) new (a)[(i)] |
#define PEGASUS_ARRAY_NEW(a, i, h) new a[(i)] |
#define PEGASUS_DELETE(a) ::operator delete((a)) |
#define PEGASUS_DELETE(a) delete((a)) |
#define PEGASUS_ARRAY_DELETE(a) ::operator delete [] ((a)) |
#define PEGASUS_ARRAY_DELETE(a) delete [] ((a)) |
|
#define PEGASUS_CHECK_FOR_LEAKS(h) |
|
#define PEGASUS_START_LEAK_CHECK() |
|
#define PEGASUS_STOP_LEAK_CHECK() |
|
#define PEGASUS_PRINT_NODE(a, b) |
#endif | #endif |
| |
| |
|
|
struct _subAllocNode *prev; | struct _subAllocNode *prev; |
Uint32 flags; | Uint32 flags; |
Uint32 allocSize; | Uint32 allocSize; |
|
Uint32 nodeSize; |
|
void *concurrencyHandle; |
|
#if defined(PEGASUS_DEBUG_MEMORY) |
Sint8 file[MAX_PATH_LEN + 1]; | Sint8 file[MAX_PATH_LEN + 1]; |
Sint8 line[MAX_LINE_LEN + 1]; |
Uint32 line; |
Sint8 classname[MAX_CLASS_LEN + 1]; | Sint8 classname[MAX_CLASS_LEN + 1]; |
Sint8 d_file[MAX_PATH_LEN + 1]; | Sint8 d_file[MAX_PATH_LEN + 1]; |
Sint8 d_line[MAX_LINE_LEN + 1]; |
Uint32 d_line; |
Sint8 d_classname[MAX_CLASS_LEN + 1]; | Sint8 d_classname[MAX_CLASS_LEN + 1]; |
void *concurrencyHandle; |
|
Uint8 guardPre[GUARD_SIZE]; | Uint8 guardPre[GUARD_SIZE]; |
|
#endif |
} SUBALLOC_NODE; | } SUBALLOC_NODE; |
| |
SUBALLOC_NODE *nodeListHeads[3][16]; | SUBALLOC_NODE *nodeListHeads[3][16]; |
|
|
PEGASUS_MUTEX_T init_mutex; | PEGASUS_MUTEX_T init_mutex; |
Boolean debug_mode; | Boolean debug_mode; |
Boolean abort_on_error; | Boolean abort_on_error; |
|
Boolean check_for_leaks; |
| |
public: | public: |
static int CREATE_MUTEX(PEGASUS_MUTEX_T *mut); | static int CREATE_MUTEX(PEGASUS_MUTEX_T *mut); |
|
|
SUBALLOC_NODE *GetHugeNode(Sint32 size); | SUBALLOC_NODE *GetHugeNode(Sint32 size); |
void PutNode(Sint32 vector, Sint32 index, SUBALLOC_NODE *node); | void PutNode(Sint32 vector, Sint32 index, SUBALLOC_NODE *node); |
void PutHugeNode(SUBALLOC_NODE *node); | void PutHugeNode(SUBALLOC_NODE *node); |
|
#if defined(PEGASUS_DEBUG_MEMORY) |
static const Uint8 guard[]; | static const Uint8 guard[]; |
static const Uint8 alloc_pattern; | static const Uint8 alloc_pattern; |
static const Uint8 delete_pattern; | static const Uint8 delete_pattern; |
|
|
static Boolean _CheckGuard(SUBALLOC_NODE *); | static Boolean _CheckGuard(SUBALLOC_NODE *); |
| |
| |
|
static Uint32 _CheckNode(void *m); |
|
SUBALLOC_NODE *_CheckNode(void *m, int type, Sint8 *file, Uint32 line); |
|
public: |
|
static Uint32 CheckMemory(void *); |
|
static void PrintNodeInfo(void *, Sint8 *, Sint8 *, Uint32); |
|
|
|
#endif |
public: | public: |
| |
peg_suballocator(void); | peg_suballocator(void); |
|
|
| |
Boolean InitializeSubAllocator(void); | Boolean InitializeSubAllocator(void); |
static SUBALLOC_HANDLE *InitializeProcessHeap(Sint8 *f = NULL); | static SUBALLOC_HANDLE *InitializeProcessHeap(Sint8 *f = NULL); |
|
#if defined(PEGASUS_DEBUG_MEMORY) |
void *vs_malloc(size_t size, void *handle, int type = NORMAL, const Sint8 *classname = 0, const Sint8 *f = 0, Uint32 l = 0); | void *vs_malloc(size_t size, void *handle, int type = NORMAL, const Sint8 *classname = 0, const Sint8 *f = 0, Uint32 l = 0); |
void *vs_calloc(size_t num, size_t size, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); | void *vs_calloc(size_t num, size_t size, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); |
void *vs_realloc(void *pblock, size_t newsize, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); | void *vs_realloc(void *pblock, size_t newsize, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); |
Sint8 * vs_strdup(const Sint8 *string, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); | Sint8 * vs_strdup(const Sint8 *string, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); |
void vs_free(void *m); |
|
void vs_free(void *m, void *handle, int type, Sint8 *classname, Sint8 *f, Uint32 l); | void vs_free(void *m, void *handle, int type, Sint8 *classname, Sint8 *f, Uint32 l); |
Boolean _UnfreedNodes(void *handle); | Boolean _UnfreedNodes(void *handle); |
|
Boolean get_mode(void) { return debug_mode; } |
|
void set_leak_mode(Boolean mode) { check_for_leaks = mode; } |
|
#else |
|
void *vs_malloc(size_t size); |
|
void *vs_calloc(size_t num, size_t size); |
|
void *vs_realloc(void *pblock, size_t newsize); |
|
Sint8 *vs_strdup(const Sint8 *str); |
|
void vs_free(void *m); |
|
Boolean get_mode(void) { return false; } |
|
void set_leak_mode(Boolean mode) { } |
|
#endif |
void DeInitSubAllocator(void *handle); | void DeInitSubAllocator(void *handle); |
SUBALLOC_NODE *_CheckNode(void *m, int type, Sint8 *file, Uint32 line); |
static peg_suballocator *get_instance(void); |
|
SUBALLOC_HANDLE & get_handle(void) { return internal_handle; } |
Boolean get_mode(void) |
|
{ |
|
return debug_mode; |
|
} |
|
|
|
SUBALLOC_HANDLE & get_handle(void) |
|
{ |
|
return internal_handle; |
|
} |
|
|
|
private: | private: |
_suballocHandle internal_handle; | _suballocHandle internal_handle; |
|
static peg_suballocator *_suballoc_instance; |
|
|
}; | }; |
| |
inline Boolean peg_suballocator::IS_ARRAY(SUBALLOC_NODE *x) | inline Boolean peg_suballocator::IS_ARRAY(SUBALLOC_NODE *x) |
|
|
return; | return; |
} | } |
| |
#elif defined (PEGASUS_PLATFORM_HPUX_PARISC_ACC) |
#elif defined (PEGASUS_PLATFORM_HPUX_ACC) |
| |
inline int peg_suballocator::CREATE_MUTEX(PEGASUS_MUTEX_T *mut) | inline int peg_suballocator::CREATE_MUTEX(PEGASUS_MUTEX_T *mut) |
{ | { |
|
|
return; | return; |
} | } |
| |
|
#elif defined (PEGASUS_PLATFORM_OS400_ISERIES_IBM) |
|
|
|
inline int peg_suballocator::CREATE_MUTEX(PEGASUS_MUTEX_T *mut) |
|
{ |
|
return(pthread_mutex_init(mut, NULL)); |
|
} |
|
|
|
inline void peg_suballocator::WAIT_MUTEX(PEGASUS_MUTEX_T *mut, Uint32 msec, int *result) |
|
{ |
|
*result = pthread_mutex_lock(mut); |
|
return; |
|
} |
|
|
|
inline void peg_suballocator::WAIT_MUTEX(PEGASUS_MUTEX_T *mut) |
|
{ |
|
pthread_mutex_lock(mut); |
|
} |
|
|
|
inline void peg_suballocator::RELEASE_MUTEX(PEGASUS_MUTEX_T *mut) |
|
{ |
|
pthread_mutex_unlock(mut); |
|
return; |
|
} |
|
|
|
inline void peg_suballocator::CLOSE_MUTEX(PEGASUS_MUTEX_T *mut) |
|
{ |
|
pthread_mutex_destroy(mut); |
|
return; |
|
} |
|
|
#elif defined (PEGASUS_PLATFORM_NSK_NONSTOP_NMCPLUS) | #elif defined (PEGASUS_PLATFORM_NSK_NONSTOP_NMCPLUS) |
| |
inline int peg_suballocator::CREATE_MUTEX(PEGASUS_MUTEX_T *mut) | inline int peg_suballocator::CREATE_MUTEX(PEGASUS_MUTEX_T *mut) |
|
|
#endif /* SUBALLOC_INCLUDE */ | #endif /* SUBALLOC_INCLUDE */ |
| |
| |
// how to debug a specific object: |
|
// add an operator new to the object such that |
|
// void * operator new(size_t size, peg_suballocator::_sub_handle = 0); |
|
// void operator delete(void *dead, size_t size); |
|
// have operator delete check for unfreed nodes by calling sub->unfreed_nodes |
|
|
|