home *** CD-ROM | disk | FTP | other *** search
- #define MEM_C
- #ifndef WIN32 /* whole file */
- # include "jam.h"
- # include "def.h"
- # include "proto.h"
-
- /* THIS MODULE MUST BE BUILT LARGE MODEL BECAUSE I HAVE
- * NOT SET THE PROTOTYPES TO BE FAR FOR PARAMS OR RETURN ADDRESSES
- */
- # include <memory.h>
- /*********************************************************
- * Windows memory manglement - local heap list from GlobalAlloc
- * for Window 3.1 environment.
- */
- #ifdef SHARABLE
- # define LOCAL extern
- #else
- # define LOCAL static
- #endif
-
- #define STATIC static
- #define PRODUCTION
-
- #define MAX_NEAR 1024
- #define W3_MAX_SMALL_BLOCK (8*1024)
-
- void W3memLocalInitialize (void);
- void W3memLocalTerminate (void);
-
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- +
- + This functions are externed if this module built as a DLL, else local
- +
- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
-
- LOCAL void *W3LocalCheck(void);
- LOCAL void W3Free(unsigned char *ptr);
- LOCAL unsigned char *W3Malloc (unsigned long num_bytes);
- LOCAL unsigned char *W3Calloc (unsigned long count, unsigned long num_bytes);
- LOCAL unsigned char *W3Realloc (unsigned char *ptr, unsigned long num_bytes);
-
- /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- * Prototypes and defines needed for private routines
- *
- * Unit should be a power of two >= the first power of two larger than a
- * freed block
- ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
-
- #define W3_MEMBLK_UNIT 16
- #define W3_MEMBLK_MASK (~(W3_MEMBLK_UNIT-1))
- #define W3_MEMBLK_PREFIX (int)(sizeof(int))
- #define W3_MEMBLK_SUFFIX (int)(sizeof(int))
- #define W3_MEMBLK_OVERHEAD (int)(W3_MEMBLK_PREFIX + W3_MEMBLK_SUFFIX)
-
- #define W3_HEAP_PREFIX \
- (int)(sizeof(int)+sizeof(W3_QueEntry)+W3_MEMBLK_OVERHEAD)
-
- #define W3_HEAP_SUFFIX (W3_MEMBLK_OVERHEAD)
- #define W3_HEAP_OVERHEAD (W3_HEAP_PREFIX + W3_HEAP_SUFFIX)
- #define W3_HEAP_INCREMENT W3_MAX_SMALL_BLOCK + W3_HEAP_OVERHEAD
-
- typedef char W3_Boolean;
-
- typedef struct _que_entry
- {
- struct _que_entry *next;
- struct _que_entry *prev;
- } W3_QueEntry;
-
- typedef struct _mem_blk
- {
- int size; /* Positive - free; Negative - alloc'd */
- W3_QueEntry link; /* Start of content for alloc'd block */
- int mark; /* Used only in checking free blocks on the heap */
- /* Not shown here - a 2-byte size field in the last word of the block */
- } W3_MemBlk;
-
- typedef struct _heap
- {
- int size;
- W3_QueEntry link;
- char guard [W3_MEMBLK_OVERHEAD]; /* Guards are empty alloc'd memblks */
- W3_MemBlk first;
- /* Not shown here - an additional guard at the end of the heap */
- } W3_Heap;
-
- typedef struct _zone
- {
- W3_QueEntry avail;
- W3_QueEntry heaps;
- W3_QueEntry *cur;
- struct _zone *next;
- #ifdef SHAREABLE
- int zone_id;
- #endif
- } W3_Zone;
-
- /* Private only routines - support for external access points only
- */
- STATIC W3_MemBlk *W3FormMemBlk(void *, int);
- STATIC W3_MemBlk *W3SplitMemBlk(W3_MemBlk *, int);
- STATIC W3_Boolean W3JoinMemBlks(W3_MemBlk *, W3_MemBlk *);
- STATIC W3_MemBlk *W3FindMemBlk(W3_QueEntry *, int, W3_QueEntry *);
- STATIC void W3InsertMemBlk(W3_MemBlk *, W3_QueEntry *);
- STATIC void W3RemoveMemBlk(W3_MemBlk *);
- STATIC W3_MemBlk *W3NextMemBlk(W3_MemBlk *);
- STATIC W3_MemBlk *W3PrevMemBlk(W3_MemBlk *);
- STATIC W3_MemBlk *W3CreateHeap(int, W3_QueEntry *);
- STATIC void W3DestroyHeap(W3_Heap *);
- STATIC W3_Boolean W3HeapIsEmpty(W3_Heap *);
- STATIC void *W3LocalMalloc(int size);
- STATIC void *W3LocalRealloc(void *curaddr, int newsize);
- STATIC void *W3LocalCalloc (int items, int size);
- STATIC void W3LocalFree(void *addr);
- STATIC int W3LocalSize(void *addr);
-
- #ifdef SHAREABLE
- STATIC W3_Zone *W3FindZone(W3_Zone *root, int id);
- STATIC W3_Zone *W3CreateZone (W3_Zone *root, int id);
- #else
- STATIC W3_Zone *W3CreateZone (W3_Zone *root);
- #endif
-
- /* Local type definitions and constants
- */
- #define TRUE 1
- #define FALSE 0
-
- /* w3__zone points to entire memory mgmt structure
- */
- #ifdef SHAREABLE
- W3_Zone *w3__zone = NULL;
- #else
- static W3_Zone *w3__zone = NULL;
- #endif
-
- #define W3CheckGlobalInit() {if (w3__zone == NULL) W3memLocalInitialize();}
-
-
- /* Macros taking parameters */
-
- #define W3_QUEUE_MAKEEMPTY(item) {item.next = &item; item.prev = &item;}
- #define W3_ROUNDSIZE(size)\
- (((size)+W3_MEMBLK_UNIT-1) & W3_MEMBLK_MASK)
- #define W3_MEMBLK_SIZEADDR(blk,size)\
- ((int *)((char *)(blk)+(size)-W3_MEMBLK_SUFFIX))
- #define W3_HEAP_ENDGUARDADDR(heap,size)\
- ((W3_MemBlk *) ((char *)(heap)+(size)-W3_HEAP_SUFFIX))
-
-
- /********************* External Initialization points *****************
- */
- void W3memLocalInitialize (void) /* this call is optional ifndef SHARABLE */
- {
- if (w3__zone == NULL)
- {
- #ifdef SHAREABLE
- w3__zone = W3CreateZone (w3__zone, GetCurrentTask());
- #else
- w3__zone = W3CreateZone (w3__zone);
- #endif
- }
- }
- void W3memLocalTerminate(void)
- {
- W3_Heap *heap;
- W3_Zone *zone;
-
- for (zone = w3__zone; zone != NULL; zone = zone->next)
- while (zone->heaps.next != &(zone->heaps))
- {
- heap = (W3_Heap *) ((char *) zone->heaps.next - sizeof(int));
- zone->heaps.next = heap->link.next;
- W3DestroyHeap (heap);
- }
- w3__zone = NULL;
- }
- /********************* Normally private access points, **********************
- */
- /* akin to malloc, returns far ptr to memory
- */
- LOCAL unsigned char *W3Malloc (unsigned long num_bytes)
- {
- HANDLE mhnd;
- unsigned char *adr;
-
- W3CheckGlobalInit();
-
- mhnd = 0;
- if (num_bytes < MAX_NEAR )
- adr = W3LocalMalloc ((int)num_bytes);
- else
- {
- mhnd = GlobalAlloc (GMEM_MOVEABLE, num_bytes);
- if (mhnd == 0)
- return NULL;
- adr = (unsigned char *) GlobalLock (mhnd);
- }
- return adr;
- }
- /* akin to calloc, returns far ptr to memory
- */
- LOCAL unsigned char *W3Calloc (unsigned long count, unsigned long num_bytes)
- {
- HANDLE mhnd;
- unsigned long real_size;
- unsigned char *adr;
-
- W3CheckGlobalInit();
-
- real_size = count * num_bytes;
- if (real_size < MAX_NEAR )
- adr = W3LocalCalloc ((int) count, (int) num_bytes);
- else
- {
- mhnd = GlobalAlloc (GMEM_MOVEABLE | GMEM_ZEROINIT, real_size);
- if (mhnd == 0)
- return NULL;
- adr = (unsigned char *) GlobalLock (mhnd);
- }
- return adr;
- }
- /* akin to realloc, returns far ptr to memory
- */
- LOCAL unsigned char *W3Realloc (unsigned char *ptr, unsigned long num_bytes)
- {
- HANDLE mhnd,mhnd2;
- char *adr2;
- unsigned long move_len;
-
- W3CheckGlobalInit();
-
- if (LOWORD((long)ptr) != 0) /* If memory is not global */
- {
- if (num_bytes < MAX_NEAR ) /* Both old and new are local handles */
- ptr = W3LocalRealloc (ptr, (int) num_bytes);
- else
- {
- move_len = W3LocalSize (ptr);
- if ((unsigned long) num_bytes < move_len)
- move_len = num_bytes;
-
- mhnd2 = GlobalAlloc (GMEM_MOVEABLE, num_bytes);
- if (mhnd2 == 0)
- return NULL;
- adr2 = (unsigned char *) GlobalLock (mhnd2);
- memcpy (adr2, ptr, (int) move_len);
- W3LocalFree (ptr);
- ptr = adr2;
- } /* End of case where new one is too big for local */
- } /* End of cases where old block was local */
- else /* Always GlobalReAlloc if the memory was originally global */
- {
- if ((mhnd = LOWORD (GlobalHandle (HIWORD(ptr)))) == 0)
- return NULL;
- mhnd = GlobalReAlloc (mhnd, num_bytes, GMEM_MOVEABLE);
- if (mhnd == 0)
- return NULL;
- ptr = (unsigned char *) GlobalLock (mhnd);
- } /* End of case where old one was global */
- return ptr;
- }
- /* akin to free, returns memory alloced above
- */
- LOCAL void W3Free(unsigned char *ptr)
- {
- HANDLE mhnd;
-
- W3CheckGlobalInit();
- if (LOWORD((long)ptr) == 0) /* If memory is global */
- {
- if ((mhnd = LOWORD (GlobalHandle (HIWORD(ptr)))) == 0)
- return ;
- if (GlobalFree (mhnd) != 0)
- return ;
- }
- else
- W3LocalFree(ptr);
- }
- /* DEBUG ROUTINE TO CHECK HEAP STATE
- */
- LOCAL void *W3LocalCheck()
- {
- #ifndef PRODUCTION
- W3_Zone *zone;
- W3_Heap *h;
- W3_MemBlk *b;
- W3_QueEntry *hq, *q, *prev;
- int size;
-
- # ifdef SHAREABLE
- zone = W3FindZone (w3__zone);
- # else
- zone = w3__zone;
- # endif
-
- /* Check that blocks haven't overrun other blocks
- */
- for (hq = zone->heaps.next; hq != &(zone->heaps); hq = hq->next)
- {
- h = (W3_Heap *) ((char *)hq - sizeof(int));
- for (b = &h->first;
- (unsigned long) b <
- (unsigned long) W3_HEAP_ENDGUARDADDR (h, h->size);
- b = W3NextMemBlk (b))
- {
- if ((b->size > -16) && (b->size < 16))
- return b;
- if (b->size > 0)
- {
- b->mark = 0;
- size = b->size;
- if ((b->link.prev->next != &b->link) ||
- (b->link.next->prev != &b->link))
- return b;
- }
- else
- size = -(b->size);
- if (*(W3_MEMBLK_SIZEADDR (b, size)) != b->size)
- return b;
- }
- }
-
- /* Check the integrity of the free list, marking free blocks that appear */
-
- prev = &zone->avail;
- for (q = prev->next; q != &zone->avail; prev = q, q = q->next)
- {
- b = (W3_MemBlk *) ((char *)q-W3_MEMBLK_PREFIX);
- if (b->size < 16) /* Marked allocated */
- return b;
- b -> mark = 1;
- if (q->prev != prev)
- return b;
- }
-
- /* Check the integrity of the randomizing pointer */
-
- b = (W3_MemBlk *) ((char *)zone->cur-W3_MEMBLK_PREFIX);
- if (!b->mark)
- return b;
-
- /* Check for "lost" free nodes, which don't appear in the free list */
-
- for (hq = zone->heaps.next; hq != &zone->heaps; hq = hq->next)
- {
- h = (W3_Heap *) ((char *)hq - sizeof(int));
- for (b = &h->first; (unsigned long) b <
- (unsigned long) W3_HEAP_ENDGUARDADDR (h, h->size);
- b = W3NextMemBlk (b))
- if ((b->size > 0) && (b->mark != 1))
- return b;
- }
-
- /* The heap passed all tests */
-
- #endif /* PRODUCTION */
- return NULL;
- }
-
- /************** Private support routines, can't be EXTERNED ****************/
-
- /* make memory into know block
- */
- STATIC W3_MemBlk *W3FormMemBlk(void *addr, int size)
- {
- W3_MemBlk *result;
-
- result = (W3_MemBlk *) addr;
- result -> size = -size;
- *W3_MEMBLK_SIZEADDR (result,size) = -size;
- return result;
- }
- /* Split a free memory block in two, giving the first the specified size.
- */
- STATIC W3_MemBlk *W3SplitMemBlk(W3_MemBlk *block, int size)
- {
- W3_MemBlk *newblk;
- int new_blksize;
-
- if ((block->size <= W3_MEMBLK_OVERHEAD) || (size <= W3_MEMBLK_OVERHEAD))
- return NULL;
-
- new_blksize = block->size - size;
-
- newblk = (W3_MemBlk *) ((char *) block + size);
- newblk->size = new_blksize;
- *W3_MEMBLK_SIZEADDR (newblk,new_blksize) = new_blksize;
- newblk->link.prev = &block->link;
- newblk->link.next = block->link.next;
- newblk->link.next->prev = &newblk->link;
- newblk->link.prev->next = &newblk->link;
-
- block->size = size;
- *W3_MEMBLK_SIZEADDR (block,size) = size;
-
- return newblk;
- }
- /* join adjacent memory if possible
- */
- STATIC W3_Boolean W3JoinMemBlks(W3_MemBlk *first, W3_MemBlk *second)
- {
- if (((char *)second != (char *)first + first->size) ||
- (second-> size <= W3_MEMBLK_OVERHEAD) ||
- (first-> size <= W3_MEMBLK_OVERHEAD))
- return FALSE;
-
- second->link.prev->next = second->link.next;
- second->link.next->prev = second->link.prev;
- first->size += second->size;
- *W3_MEMBLK_SIZEADDR (first,first->size) = first->size;
- return TRUE;
- }
- /* find a free blk in heap
- */
- STATIC W3_MemBlk *W3FindMemBlk(W3_QueEntry *q, int size,
- W3_QueEntry *dummy)
- {
- W3_QueEntry *p;
- W3_MemBlk *curblock;
-
- for (p = q->next; ; p = p->next)
- {
- if (p != dummy) /* Skip over listhead */
- {
- curblock = (W3_MemBlk *) ((char *)p-W3_MEMBLK_PREFIX);
- if (curblock->size >= size)
- return curblock;
- }
- if (p == q)
- break;
- }
- return NULL;
- }
- /* insert a block into the free list, marking it as free.
- */
- STATIC void W3InsertMemBlk(W3_MemBlk *block, W3_QueEntry *q)
- {
- block->size = -block->size;
- *W3_MEMBLK_SIZEADDR(block,block->size) = block->size;
-
- block->link.next = q;
- block->link.prev = q->prev;
- block->link.next->prev = &block->link;
- block->link.prev->next = &block->link;
- }
- /* allocate a blk of memory
- */
- STATIC void W3RemoveMemBlk(W3_MemBlk *block)
- {
- block->size = -block->size;
- *W3_MEMBLK_SIZEADDR(block,(-block->size)) = block->size;
- block->link.prev->next = block->link.next;
- block->link.next->prev = block->link.prev;
- }
- /* find next blk
- */
- STATIC W3_MemBlk *W3NextMemBlk(W3_MemBlk *curr)
- {
- int size;
-
- size = curr->size;
- if (size < 0)
- size = -size;
- return (W3_MemBlk *) ((char *)curr+size);
- }
- /* find prev blk
- */
- STATIC W3_MemBlk *W3PrevMemBlk(W3_MemBlk *curr)
- {
- int size;
-
- size = *(int *)((char *)curr-W3_MEMBLK_SUFFIX);
- if (size < 0)
- size = -size;
- return (W3_MemBlk *) ((char *)curr-size);
- }
- /* create a heap, insert into list
- */
- STATIC W3_MemBlk *W3CreateHeap(int size, W3_QueEntry *after)
- {
- W3_Heap *result;
-
- {
- HANDLE mhnd;
-
- mhnd = GlobalAlloc (GMEM_MOVEABLE, (unsigned long) size);
- if (mhnd == 0)
- result = NULL;
- else
- result = (W3_Heap *) GlobalLock (mhnd);
- }
-
- if (result == NULL)
- return NULL;
- result->size = size;
- result->link.prev = after;
- result->link.next = after->next;
- result->link.next->prev = &result->link;
- result->link.prev->next = &result->link;
-
- W3FormMemBlk (&result->guard, W3_MEMBLK_OVERHEAD);
- W3FormMemBlk (&result->first, size-W3_HEAP_OVERHEAD);
- W3FormMemBlk (W3_HEAP_ENDGUARDADDR(result,size), W3_MEMBLK_OVERHEAD);
-
- return &result->first;
- }
- /* destroy heap, remove from list
- */
- STATIC void W3DestroyHeap(W3_Heap *heap)
- {
- HANDLE mhnd;
-
- heap->link.prev->next = heap->link.next;
- heap->link.next->prev = heap->link.prev;
- if ((mhnd = LOWORD (GlobalHandle (HIWORD(heap)))) != 0)
- GlobalFree (mhnd);
- }
- /* return if entire heap is one unused blk
- */
- STATIC W3_Boolean W3HeapIsEmpty(W3_Heap *heap)
- {
- return (W3_Boolean)((heap->first.size) == (heap->size-W3_HEAP_OVERHEAD));
- }
- #ifdef SHAREABLE
- /* find zone of memory with requested if
- */
- STATIC W3_Zone *W3FindZone(W3_Zone *root, int id)
- {
- W3_Zone *zone;
-
- for (zone = root; zone != NULL; zone = zone->next)
- if (zone -> zone_id == id)
- break;
- return zone;
- }
- #endif
- /* create a zone of memory, possible marked with id
- */
- #ifdef SHAREABLE
- W3_Zone *W3CreateZone (W3_Zone *root, int id)
- #else
- W3_Zone *W3CreateZone (W3_Zone *root)
- #endif
- {
- W3_Zone *zone;
- HANDLE hZone;
-
- if (root == NULL)
- {
- hZone = LocalAlloc (LMEM_FIXED, sizeof (W3_Zone));
- if (hZone == 0)
- zone = NULL;
- else
- zone = (W3_Zone *) (LocalLock (hZone));
- }
- else
- {
- for (zone = root; zone->next != NULL; zone = zone->next)
- ;
- hZone = LocalAlloc (LMEM_FIXED, sizeof (W3_Zone));
- if (hZone == 0)
- zone = NULL;
- else
- zone -> next = (W3_Zone *) LocalLock (hZone);
- zone = zone->next;
- }
-
- if (zone == NULL)
- return NULL;
- zone -> avail.prev = &(zone -> avail);
- zone -> avail.next = &(zone -> avail);
- zone -> heaps.prev = &(zone -> heaps);
- zone -> heaps.next = &(zone -> heaps);
- zone -> cur = &(zone -> avail);
- zone -> next = NULL;
- #ifdef SHAREABLE
- zone -> zone_id = id;
- #endif
- return zone;
- }
- /* malloc memory from existing stores
- */
- STATIC void *W3LocalMalloc(int size)
- {
- int actsize;
- W3_MemBlk *temp;
- W3_Zone *zone;
- #ifdef SHAREABLE
- int zoneid;
-
- zoneid = GetCurrentTask();
-
- if ((zone = W3FindZone (w3__zone, zoneid)) == NULL)
- if ((zone = W3CreateZone (w3__zone, zoneid)) == NULL)
- return NULL;
- #else
- if (!(zone = w3__zone))
- if ((zone = W3CreateZone (w3__zone)) == NULL)
- #endif
-
- if (size > W3_MAX_SMALL_BLOCK-W3_MEMBLK_OVERHEAD)
- return NULL;
-
- /* Leave room for overhead and ensure that no tiny fragments
- * which are too small to fit on the free list are generated.
- */
- actsize = W3_ROUNDSIZE (size + W3_MEMBLK_OVERHEAD);
- temp = W3FindMemBlk (zone->cur, actsize, &(zone->avail));
- if (temp == NULL)
- {
- temp = W3CreateHeap (W3_HEAP_INCREMENT, &(zone->heaps));
- if (temp == NULL)
- return NULL;
- W3InsertMemBlk (temp, zone->cur);
- }
- if (temp->size > actsize + W3_MEMBLK_OVERHEAD) /* If it can be split */
- W3SplitMemBlk (temp, actsize);
-
- zone->cur = temp->link.prev;
-
- W3RemoveMemBlk (temp);
- return ((void *) (&temp->link));
- }
- /* realloc memory from existing stores
- */
- STATIC void *W3LocalRealloc(void *curaddr, int newsize)
- {
- W3_MemBlk *curr, *newblk;
- W3_Zone *zone;
- char *newmem;
- int adjsize, incr;
-
- #ifdef SHAREABLE
- if ((zone = W3FindZone (w3__zone, GetCurrentTask())) == NULL)
- return NULL;
- #else
- if (!(zone = w3__zone))
- return NULL;
- #endif
- if (newsize > W3_MAX_SMALL_BLOCK-W3_MEMBLK_OVERHEAD)
- return NULL;
-
- curr = (W3_MemBlk *) ((char *)curaddr - W3_MEMBLK_PREFIX);
- if (curr->size > 0) /* If the block is free, go no further */
- return NULL;
-
- adjsize = W3_ROUNDSIZE (newsize + W3_MEMBLK_OVERHEAD);
- incr = adjsize - (-curr->size); /* remember - curr->size is negative */
-
- /* If the request is enough less than the current
- * allocation, free space
- */
- if (incr < 0)
- {
- curr->size = curr->size - incr;
- *W3_MEMBLK_SIZEADDR(curr, -curr->size) = curr->size;
- newblk = W3FormMemBlk ((char *)curr - curr->size, -incr);
- W3InsertMemBlk (newblk, zone->cur);
- }
-
- /* If caller wants more space & the next block is big
- * enough & free, use it
- */
- if (incr > 0)
- {
- newblk = W3NextMemBlk (curr);
- if (newblk->size > (2 * incr)) /* Too big to sacrifice the whole thing */
- W3SplitMemBlk (newblk, incr);
-
- if (newblk->size >= incr)
- {
- zone->cur = newblk->link.prev;
- newblk->link.prev -> next = newblk->link.next;
- newblk->link.next -> prev = newblk->link.prev;
- curr->size -= newblk->size;
- *W3_MEMBLK_SIZEADDR (curr,-curr->size) = curr->size;
- }
- else /* No such luck. We have to move the data */
- {
- newmem = W3LocalMalloc (newsize);
- if (newmem == NULL)
- curaddr = NULL;
- else
- {
- memcpy (newmem, curaddr, (-curr->size)-W3_MEMBLK_OVERHEAD);
- W3LocalFree (curaddr);
- curaddr = newmem;
- }
- }
- }
-
- /* Case when only a very little is being trimmed is
- * handled implicitly i.e. do nothing
- */
- return curaddr;
-
- }
- /* calloc memory from local stores
- */
- STATIC void *W3LocalCalloc (int items, int size)
- {
- void *temp;
-
- temp = W3LocalMalloc (items * size);
- if (temp != NULL)
- memset (temp, '\0', items * size);
- return temp;
- }
- /* free memory allocated from local stores
- */
- STATIC void W3LocalFree(void *addr)
- {
- W3_MemBlk *block, *other;
- W3_Zone *zone;
- W3_Heap *heap;
-
- #ifdef SHAREABLE
- if ((zone = W3FindZone (w3__zone, GetCurrentTask())) == NULL)
- return;
- #else
- if (!(zone = w3__zone))
- return;
- #endif
- block = (W3_MemBlk *) ((char *)addr - W3_MEMBLK_PREFIX);
- W3InsertMemBlk (block, &(zone->avail));
- W3JoinMemBlks(block,
- W3NextMemBlk(block)); /* Joins check before joining */
- other = W3PrevMemBlk(block); /* so just try it and see */
- if (W3JoinMemBlks(other, block))
- zone->cur = other->link.next;
- else
- zone->cur = block->link.next;
-
- heap = (W3_Heap *)((unsigned long)block & 0xFFFF0000L); /* Hack works */
- if (W3HeapIsEmpty (heap))
- {
- W3RemoveMemBlk (&heap->first);
- W3DestroyHeap (heap);
- }
- }
- /* return avali size at address
- */
- STATIC int W3LocalSize(void *addr)
- {
- W3_MemBlk *block;
- int size;
-
- block = (W3_MemBlk *) ((char *)addr - W3_MEMBLK_PREFIX);
- size = (block->size > 0) ? block->size : -block->size;
- size -= W3_MEMBLK_OVERHEAD;
- return size;
- }
-
- /****************************************************************************
- * Memory management functions REPLACING C-runtime malloc, calloc,
- * realloc and free. Only for use ifndef SHAREABLE. #define MAGIC, etc
- * to build guard code during debugging. If this module built as DLL,
- * then need to make W3Malloc, W3Calloc, W3Realloc and W3Free calls instead.
- *
- * Defining MAGIC requires fleshing out localprintf and localbeep (notGNU
- * provides entry points when linked/compiled nonshareable into notGNU.exe)
- *
- *****************************************************************************/
- #ifndef SHAREABLE
-
- /* TO TURN ON MEMORY MANAGLEMENT CHECKING...
- */
- #define MAGIC 0x4d4d4d4dL
- #define OLDMAGIC 0x46464646L
- #define CRASH 0x55
- #define NEWMEM 0x45
-
- #define localprintf ewprintf
- #define localbeep ttbeep
-
- /* COMMENT OUT TO TURN OFF */
-
- /* Struct at head of allocated block. Single GUARD word
- * appended at end as well.
- */
- typedef unsigned int GUARD;
- typedef struct _chunk
- {
- GUARD magic;
- long nbytes;
- } Chunk;
-
- #define nChunk sizeof(Chunk)
- #define nEnd sizeof(GUARD)
- #define Mem(pmem_) (Chunk *)(((char *)pmem_ - nChunk))
- #define End(p, q) (GUARD *)((char *)p + q->nbytes)
-
- /* Capture entry points; caller code thinks this is C runtime!
- */
- void CDECL free(void FAR *p)
- {
- #ifdef MAGIC
- Chunk *q;
- GUARD *eguard;
-
- if (!p)
- {
- localprintf("Free: pointer is NULL!");
- localbeep();
- sleep(1);
- return;
- }
-
- q = Mem(p);
- eguard = End(p, q);
-
- if (q->magic != (GUARD)MAGIC)
- {
- if (q->magic == (GUARD)OLDMAGIC)
- localprintf("Free: memory already freed!");
- else
- localprintf("Free: front guard gone!");
- localbeep();
- sleep(1);
- return;
- }
-
- if (*eguard != (GUARD)MAGIC)
- {
- localprintf("Free: end guard gone!");
- localbeep();
- sleep(1);
- return;
- }
-
- memset(p, CRASH, (size_t)q->nbytes); /* make it useless */
- q->magic = (GUARD)OLDMAGIC; /* mark freed */
- p = q; /* free the real allocated block */
- #endif /* MAGIC */
- W3Free((unsigned char *)p);
- }
- void * CDECL malloc(size_t n)
- {
- #ifdef MAGIC
- Chunk *q;
- char *p;
-
- q = (Chunk *)W3Malloc((unsigned long)n + nChunk + nEnd);
- p = (char *)q;
- if (p)
- {
- GUARD *eguard;
-
- q->magic = (GUARD)MAGIC;
- q->nbytes = (long)n;
- p += nChunk; /* user pointer value */
- eguard = End(p, q);
- *eguard = (GUARD)MAGIC;
- }
- memset(p, NEWMEM, n);
- return (p);
- #else /* MAGIC */
- return (W3Malloc((unsigned long)n));
- #endif /* MAGIC */
- }
- void * CDECL calloc(size_t c, size_t n)
- {
- #ifdef MAGIC
- char *p = malloc(c * n);
-
- if (p)
- memset(p, 0, c * n);
- return (p);
- #else /* MAGIC */
- return(W3Calloc((unsigned long)c, (unsigned long)n));
- #endif /* MAGIC */
- }
- void * CDECL realloc(void FAR * p, size_t n)
- {
- #ifdef MAGIC
- Chunk *q;
- char *s;
- GUARD *eguard;
-
- q = Mem(p);
- eguard = End(p, q);
-
- if (q->magic != (GUARD)MAGIC)
- {
- if (q->magic == (GUARD)OLDMAGIC)
- localprintf("Realloc: memory freed!");
- else
- localprintf("Realloc: no front guard!");
- localbeep();
- sleep(1);
- }
-
- if (*eguard != (GUARD)MAGIC)
- {
- localprintf("Realloc: no end guard!");
- localbeep();
- sleep(1);
- }
-
- /* cheap, realloc smaller doesn't do anything!
- */
- if (q->nbytes <= (long)n)
- return(p);
-
- s = malloc(n);
- if (!s)
- {
- free(p);
- return(NULL);
- }
-
- /* move used bytes to new block, free old block
- */
- memcpy(s, p, (size_t)(q->nbytes)); /* know that old size was smaller */
- free(q); /* free actual allocated block */
- return(s);
- #else
- return (W3Realloc((unsigned char *)p, (unsigned long)n));
- #endif
- }
- #endif /* ~SHAREABLE */
-
- #endif /* whole file */
-