version 1.12, 2002/05/07 12:05:00
|
version 1.19, 2002/05/12 02:20:46
|
|
|
// 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) |
// | // |
|
|
#define PEGASUS_SUBALLOC_INCLUDE 1 | #define PEGASUS_SUBALLOC_INCLUDE 1 |
| |
#include <Pegasus/Common/Config.h> | #include <Pegasus/Common/Config.h> |
|
#include <Pegasus/suballoc/Linkage.h> |
| |
#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) | #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) |
#include <windows.h> | #include <windows.h> |
|
|
static const int GUARD_SIZE = 0x10; | static const int GUARD_SIZE = 0x10; |
static const int MAX_PATH_LEN = 0xff; | static const int MAX_PATH_LEN = 0xff; |
static const int MAX_LINE_LEN = 0x14; | static const int MAX_LINE_LEN = 0x14; |
|
static const int MAX_CLASS_LEN = 0x40; |
static const int PRE_ALLOCATE = 0x00; | static const int PRE_ALLOCATE = 0x00; |
static const int STEP_ALLOCATE = 0x01; | static const int STEP_ALLOCATE = 0x01; |
static const int AVAILABLE = 0x00; | static const int AVAILABLE = 0x00; |
static const int NORMAL = 0x01; |
static const int NORMAL = 0x00; |
static const int ARRAY = 0x02; |
static const int ARRAY = 0x01; |
|
static const unsigned int IS_HEAD_NODE = 0x00000001; |
|
static const unsigned int AVAIL = 0x00000002; |
|
static const unsigned int ARRAY_NODE = 0x00000004; |
|
static const unsigned int CHECK_FAILED = 0x00000008; |
} | } |
| |
PEGASUS_NAMESPACE_BEGIN | PEGASUS_NAMESPACE_BEGIN |
| |
|
class guardian; |
|
struct SUBALLOC_HANDLE; |
|
|
PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t ); | PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t ); |
|
PEGASUS_SUBALLOC_LINKAGE void * pegasus_alloc(size_t, |
|
void *, |
|
int type, |
|
const Sint8 *classname, |
|
Sint8 *file, |
|
Uint32 line ); |
|
PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *dead, |
|
void *, |
|
int type, |
|
Sint8 *classname, |
|
Sint8 *file, |
|
Uint32 line); |
|
|
PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *); | PEGASUS_SUBALLOC_LINKAGE void pegasus_free(void *); |
| |
#if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) | #if defined(PEGASUS_PLATFORM_WIN32_IX86_MSVC) |
|
|
| |
#endif | #endif |
| |
|
|
// to reduce the number of wasted bytes: | // to reduce the number of wasted bytes: |
// reduce GUARD_SIZE | // reduce GUARD_SIZE |
// eliminate guard checking from SUBALLOC_NODEs | // eliminate guard checking from SUBALLOC_NODEs |
// | // |
| |
|
class peg_suballoc; |
|
|
|
|
|
#if defined(PEGASUS_DEBUG_MEMORY) |
|
#define PEGASUS_NEW(a) new((pegasus_alloc(sizeof(a), ((void *)0), NORMAL, (#a), __FILE__, __LINE__))) |
|
#define PEGASUS_ARRAY_NEW(a, i) new(pegasus_alloc(sizeof(a) * (i), NULL, ARRAY, (#a), __FILE__, __LINE__)) (a) |
|
#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__) |
|
#else |
|
#define PEGASUS_NEW(a) new |
|
#define PEGASUS_ARRAY_NEW(a, i) new (a)[(i)] |
|
#define PEGASUS_DELETE(a) ::operator delete((a)) |
|
#define PEGASUS_ARRAY_DELETE(a) ::operator delete [] ((a)) |
|
#endif |
|
|
|
|
class PEGASUS_SUBALLOC_LINKAGE peg_suballocator | class PEGASUS_SUBALLOC_LINKAGE peg_suballocator |
{ | { |
private: | private: |
peg_suballocator(const peg_suballocator &); | peg_suballocator(const peg_suballocator &); |
peg_suballocator & operator = (const peg_suballocator &); | peg_suballocator & operator = (const peg_suballocator &); |
Boolean _debug; | Boolean _debug; |
|
|
typedef struct _subAllocTemplate { |
|
struct _subAllocNode *next; |
|
struct _subAllocNode *prev; |
|
Boolean isHead; |
|
Boolean avail; |
|
Uint32 allocSize; |
|
Uint8 guardPre[GUARD_SIZE]; |
|
} SUB_TEMPLATE; |
|
|
|
typedef struct _subAllocNode { | typedef struct _subAllocNode { |
struct _subAllocNode *next; | struct _subAllocNode *next; |
struct _subAllocNode *prev; | struct _subAllocNode *prev; |
Boolean isHead; |
Uint32 flags; |
int avail; |
|
Uint32 allocSize; | Uint32 allocSize; |
Uint8 guardPre[GUARD_SIZE]; |
|
void *allocPtr; |
|
Uint8 guardPost[GUARD_SIZE]; |
|
Sint8 file[MAX_PATH_LEN + 1]; | Sint8 file[MAX_PATH_LEN + 1]; |
Sint8 line[MAX_LINE_LEN + 1]; | Sint8 line[MAX_LINE_LEN + 1]; |
|
Sint8 classname[MAX_CLASS_LEN + 1]; |
|
Sint8 d_file[MAX_PATH_LEN + 1]; |
|
Sint8 d_line[MAX_LINE_LEN + 1]; |
|
Sint8 d_classname[MAX_CLASS_LEN + 1]; |
void *concurrencyHandle; | void *concurrencyHandle; |
|
Uint8 guardPre[GUARD_SIZE]; |
} SUBALLOC_NODE; | } SUBALLOC_NODE; |
| |
|
|
SUBALLOC_NODE *nodeListHeads[3][16]; | SUBALLOC_NODE *nodeListHeads[3][16]; |
| |
PEGASUS_MUTEX_T globalSemHandle; | PEGASUS_MUTEX_T globalSemHandle; |
|
|
Sint32 init_count; | Sint32 init_count; |
PEGASUS_MUTEX_T init_mutex; | PEGASUS_MUTEX_T init_mutex; |
Boolean debug_mode; | Boolean debug_mode; |
|
Boolean abort_on_error; |
| |
|
public: |
|
static int CREATE_MUTEX(PEGASUS_MUTEX_T *mut); |
int CREATE_MUTEX(PEGASUS_MUTEX_T *mut); |
static void WAIT_MUTEX(PEGASUS_MUTEX_T *mut, Uint32 msec, int *result); |
void WAIT_MUTEX(PEGASUS_MUTEX_T *mut, Uint32 msec, int *result); |
static void WAIT_MUTEX(PEGASUS_MUTEX_T *mut); |
void WAIT_MUTEX(PEGASUS_MUTEX_T *mut); |
static void RELEASE_MUTEX(PEGASUS_MUTEX_T *mut); |
void RELEASE_MUTEX(PEGASUS_MUTEX_T *mut); |
static void CLOSE_MUTEX(PEGASUS_MUTEX_T *mut); |
void CLOSE_MUTEX(PEGASUS_MUTEX_T *mut); |
private: |
|
static Boolean IS_ARRAY(SUBALLOC_NODE *x); |
Boolean IS_HEAD(SUBALLOC_NODE *x); |
static Boolean IS_HEAD(SUBALLOC_NODE *x); |
void INSERT(SUBALLOC_NODE *new_node, SUBALLOC_NODE *after); |
static void INSERT(SUBALLOC_NODE *new_node, SUBALLOC_NODE *after); |
void INSERT_AFTER(SUBALLOC_NODE *new_node, SUBALLOC_NODE *after); |
static void INSERT_AFTER(SUBALLOC_NODE *new_node, SUBALLOC_NODE *after); |
void INSERT_BEFORE(SUBALLOC_NODE *new_node, SUBALLOC_NODE *before); |
static void INSERT_BEFORE(SUBALLOC_NODE *new_node, SUBALLOC_NODE *before); |
void _DELETE(SUBALLOC_NODE *x); |
static void _DELETE(SUBALLOC_NODE *x); |
Boolean IS_LAST(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
static Boolean IS_LAST(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
Boolean IS_FIRST(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
static Boolean IS_FIRST(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
Boolean IS_ONLY(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
static Boolean IS_ONLY(SUBALLOC_NODE *head, SUBALLOC_NODE *node); |
inline Boolean IS_EMPTY(SUBALLOC_NODE *h) ; |
static Boolean IS_EMPTY(SUBALLOC_NODE *h) ; |
| |
Boolean _Allocate(Sint32, Sint32, Sint32); | Boolean _Allocate(Sint32, Sint32, Sint32); |
void _DeAllocate(Sint32 vector, Sint32 index); | void _DeAllocate(Sint32 vector, Sint32 index); |
|
|
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); |
| |
static const Sint8 dumpFileName[]; |
|
Sint8 global_log_filename[MAX_PATH_LEN + 1]; |
|
FILE *dumpFile ; |
|
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; |
|
|
public: | public: |
| |
peg_suballocator(void); | peg_suballocator(void); |
peg_suballocator(Sint8 *log_filename, Boolean mode = true); |
peg_suballocator(Boolean mode = true); |
virtual ~peg_suballocator(void); | virtual ~peg_suballocator(void); |
| |
inline Boolean PEGASUS_DEBUG_ALLOC(void) { return _debug; } | inline Boolean PEGASUS_DEBUG_ALLOC(void) { return _debug; } |
| |
typedef class _suballocHandle |
typedef class PEGASUS_SUBALLOC_LINKAGE _suballocHandle |
{ | { |
public: | public: |
Sint8 logpath[MAX_PATH_LEN + 1]; | Sint8 logpath[MAX_PATH_LEN + 1]; |
_suballocHandle(Sint8 *log_path = 0) |
Sint8 classname[MAX_CLASS_LEN + 1]; |
|
_suballocHandle(const Sint8 *log_path = 0) |
{ | { |
if(log_path) | if(log_path) |
snprintf(logpath, MAX_PATH_LEN, "%s", log_path); | snprintf(logpath, MAX_PATH_LEN, "%s", log_path); |
|
|
| |
}SUBALLOC_HANDLE; | }SUBALLOC_HANDLE; |
| |
Boolean InitializeSubAllocator(Sint8 *f = NULL); |
Boolean InitializeSubAllocator(void); |
SUBALLOC_HANDLE *InitializeProcessHeap(Sint8 *f = NULL); |
static SUBALLOC_HANDLE *InitializeProcessHeap(Sint8 *f = NULL); |
void *vs_malloc(size_t size, void *handle, int type = NORMAL, Sint8 *f = 0, Sint32 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, Sint32 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, Sint32 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, Sint32 l = 0); |
Sint8 * vs_strdup(const Sint8 *string, void *handle, int type = NORMAL, Sint8 *f = 0, Uint32 l = 0); |
void vs_free(void *m, int type = NORMAL); |
void vs_free(void *m); |
|
void vs_free(void *m, void *handle, int type, Sint8 *classname, Sint8 *f, Uint32 l); |
Boolean _UnfreedNodes(void *handle); | Boolean _UnfreedNodes(void *handle); |
void DeInitSubAllocator(void *handle); | void DeInitSubAllocator(void *handle); |
static void _CheckNode(void *m); |
SUBALLOC_NODE *_CheckNode(void *m, int type, Sint8 *file, Uint32 line); |
| |
Boolean get_mode(void) | Boolean get_mode(void) |
{ | { |
|
|
return internal_handle; | return internal_handle; |
} | } |
| |
|
|
private: | private: |
_suballocHandle internal_handle; | _suballocHandle internal_handle; |
}; | }; |
| |
|
inline Boolean peg_suballocator::IS_ARRAY(SUBALLOC_NODE *x) |
|
{ |
|
return (x->flags & ARRAY_NODE) ? true : false ; |
|
} |
| |
|
inline Boolean peg_suballocator::IS_HEAD(SUBALLOC_NODE *x) |
inline Boolean peg_suballocator::IS_HEAD(SUBALLOC_NODE *x) { return x->isHead; } |
{ |
|
return (x->flags & IS_HEAD_NODE) ? true : false ; |
|
} |
| |
inline Boolean peg_suballocator::IS_EMPTY(SUBALLOC_NODE *h) | inline Boolean peg_suballocator::IS_EMPTY(SUBALLOC_NODE *h) |
{ | { |