
/***************************************************************************
**
**    $Header:   D:/EP196/SRC/LOG/SYMSVR/SYMHEAP.CPP   1.0   15 Aug 1997 14:04:12   ZJRD  $
**
**    $Log:   D:/EP196/SRC/LOG/SYMSVR/SYMHEAP.CPP  $
** 
**    Rev 1.0   15 Aug 1997 14:04:12   ZJRD
** Initial revision.
** 
****************************************************************************/

/****************************************************************************
**
**  Name:  SYMHEAP.CPP
**
**  Description:
**     This module implements a simple heap manager for malloc/free style
**  memory management.  It works with FAR pointers, so pointers can be freely
**  shared between applications and DLLs.  Allocation size is limited to <64K.
**  The primary advantage to using this heap manager is that few window 
**  handles are used.
**
**  Status: CODED         ( PRELIMINARY | CODED | REVIEWED | TESTED )
**
**  $Log$
** 
**  $Header:   D:/EP196/SRC/LOG/SYMSVR/SYMHEAP.CPP   1.0   15 Aug 1997 14:04:12   ZJRD  $
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
**  IMPLEMENTATION NOTES:
**  This implementation is a set of 64K heaps.  Within a heap, a boundary tag
**  scheme and first fit strategy is used (see "An Implementation of New and
**  Dispose using Boundary Tags", Branko J. Gerovac,  Pascal News # 19, 
**  September 1980).
**
**  Management of GlobalAlloc()'ed memory is done here.  Memory management
**  within individual 64K heap chunks is private to "chunk.c".
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"                      
#include "symwind.h"
#include "symerrs.h"
#include "symheap.h"


                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

				
#define ALLOC_FLAGS (GMEM_MOVEABLE | GMEM_ZEROINIT )


                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/
/* None */
                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/



                       /****************************
                        *                          *
                        *     LOCAL VARIABLES      *
                        *                          *
                        ****************************/

/* Area information */

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/****************************************************************************
**
**  TFree -- free memory alloc'ed via Malloc()
**
*****************************************************************************/
RETCODE WINAPI TFree( LPSTR randomPointer ) {
   HANDLE *hPtr;
   HANDLE handle;

   hPtr = (HANDLE *)(randomPointer - sizeof(HANDLE));
   handle = *hPtr;
   if (GlobalFree(handle) == NULL)  
      return GOOD;
   else return ER_HEAP_CORRUPT;   
}


/****************************************************************************
**
**  TMalloc -- allocate numBytes of memory or fail
**
*****************************************************************************/

LPSTR WINAPI TMalloc( U32 numBytes ) {
   HANDLE handle;
   LPU8 ptr;
   HANDLE *hPtr;
   LPU8 bytePtr;
   U32 actualSize;
#ifdef TEST_CASE
   int i;
   U8 *testPtr;
#endif

   handle = GlobalAlloc( ALLOC_FLAGS, numBytes+sizeof(HANDLE));
   if (handle == (HANDLE)NULL) {
      return(NULL);
   }
   ptr = (LPU8)GlobalLock(handle);
   if (ptr==(LPU8)NULL) {
      return(NULL);
   }
   actualSize = GlobalSize(handle);
   
   /* move to the end to check limit */
   bytePtr = ptr + actualSize - numBytes - sizeof(HANDLE);

   /* keep handle as part of data so it can be freed eventually */
   hPtr = (HANDLE *)bytePtr;
   *hPtr = handle;
#ifdef TEST_CASE
   testPtr = ptr + actualSize - 1; /* set on last valid byte */
   for(i=0; i<100; i++) {
      *testPtr = 0x55; /* first should be ok, second should fail */
      testPtr++;
   }
#endif
   return((LPSTR)(bytePtr+sizeof(HANDLE)));
}

/******************************** E O F ***********************************/
