Metropoli BBS
VIEWER: memory.c MODE: TEXT (ASCII)
/*
   MEMORY.C

	Memory Manager, Ad Lib Inc.

   Functions BLDMEM(), GETMEM() & RLSMEM() of Lattice C are used.

	Each function sets a global variable, 'memErr', for indicating
	the error code.
	The function 'MemErr()' returns this code.

	The maximum allocatable block is 64K.

	If compiling with Lattice, 'LATTICE' must be defined for MEMORY.C.
	For Microsoft, 'MICROSOFT', must be defined.
	Refer to convert.c as well.

*/

#include "mem.h"

Handle _hfstfree;       /* master pointer free list */
int    _moremast;       /* # of master pointers to be allocated each time
							the free list is empty. */
int	memErr;

#ifdef LATTICE
#include <stdio.h>

#ifdef LPTR         /* LARGE DATA PTR ... */
#define MyGetMem(a) getml(a)
#define MyRlsMem(a, b) rlsml(a, b)
#else
#define MyGetMem(a) getmem(a)
#define MyRlsMem(a, b) rlsmem(a, b)
#endif

extern char * getmem();
extern char * getml();
extern int		rlsmem();
extern int		rlsml();
extern int		bldmem();
       
extern char * getmem();
extern long lseek();
#endif

#ifdef MICROSOFT
#include  <malloc.h>
#include  <string.h>
#include  <io.h>
#include  <stdio.h>

#define  MyGetMem(a)    malloc(a)
#define  rlsmem(x,y)    free(x)
#define  rlsml(x,y)     free(x)
#define  getmem(x)      malloc(x)
#define  getml(x)       malloc(x)
#define  setmem(x,y,z)  memset(x,z,y)
#define  movmem(x,y,z)  memmove(y,x,z)
#define  min(x,y)       ((x < y) ? x:y)
#endif



/*---------------------------- InitMemory() ----------------------------
	Initialize the memory manager. 'mastercount' is the number of
	master pointers to be allocated when needed.
*/
InitMemory( mastercount)
   int mastercount;
{
   memErr = NoErr;
   _hfstfree = NULL;
   _moremast = mastercount;
#ifdef LATTICE
   if ( 0 != bldmem( 0))        /* allocate remaining space */
       {
       memErr = MemInitErr;
	   }
#endif
}  /* InitMemory()   */


/* ----------------------------- Moremasters() ------------------------
	Allocate '_moremast' master pointers and add them to the free list.
*/
MoreMasters()
{
   Ptr    blockptr;
   Handle debut,
          premier;
   Size size;
   int    j;

   memErr = NoErr;
   size = _moremast * sizeof( Ptr) + sizeof ( Size);
   if( NULL == ( blockptr = MyGetMem( size)))
       {
       memErr = MemFullErr;
       return;
       }
   *( Size *) blockptr = size;
   premier = debut = (Handle) (blockptr + sizeof ( Size));
   for ( j = 1; j < _moremast; j++)
       {
       *debut = ( Ptr)( debut +1);
       debut++;
       }
   *debut = (Ptr)_hfstfree;
   _hfstfree = premier;
}  /* Moremasters() */


   
/* ---------------------------- Getmaster() --------------------------
   INTERNAL USE ONLY.
	Return the first free master pointer, NULL if none.
*/
static Handle Getmaster()
{
   Handle tmp;

   if ( NULL == _hfstfree)
       MoreMasters();
   tmp = _hfstfree;
   if ( tmp != NULL)
       _hfstfree = ( Handle)* _hfstfree;
   return tmp;
}  /* Getmaster()  */



/* ---------------------------- Putmaster() --------------------------
   INTERNAL USE ONLY.
	Add the master pointer to the free list.
*/
static Putmaster( hndl)
   Handle hndl;
{
   *hndl = (Ptr)_hfstfree;
   _hfstfree = hndl;
}  /* Putmaster()  */


/* ---------------------------- NewPtr() -----------------------------
	Allocate a block of 'dim' + sizeof( Size) bytes. The first bytes
	(sizeof( Size)) are used to hold the total block size.
   Return NULL if error.
*/
Ptr NewPtr( dim)
   Size dim;
{
   Size  size;
   Ptr     tmp;

   memErr = NoErr;
   size = dim +sizeof( Size);
#ifdef LPTR

#else
	if( (long)size >= 65536L) {
		memErr = MemBlocTooBigErr;
		return NULL;
		}
#endif
   tmp = MyGetMem( size);
   if (tmp != NULL)
       {
       *( Size *) tmp = size;
       tmp = tmp + sizeof( Size);
       }
   else
       memErr = MemFullErr;
   return tmp;
}  /* Newptr() */



/* ---------------------------- DisposPtr() -----------------------
	Recover the block pointed to by 'pointer'.
*/
DisposPtr( pointer)
   Ptr pointer;
{
   Ptr     debut;

   memErr = NoErr;
   debut = pointer - sizeof ( Size);
   if ( NULL == pointer)
       {
       memErr = NilPtrErr;
       }
#ifdef MICROSOFT
   free ((void *) debut);
#else
   if( 0 != MyRlsMem (debut, (*(Size *)debut)))
       {
       memErr = MemBlockErr;
       }
#endif
}  /* DisposePtr() */



/* ---------------------------- GetPtrSize() ---------------------------
	Return the size of the block pointed to by 'pointer'.
*/
Size GetPtrSize( pointer)
   Ptr pointer;
{
   memErr = NoErr;
   if ( pointer == NULL)
       {
       memErr = NilPtrErr;
       }
   return ( Size)*( Size *) (pointer - sizeof ( Size)) - sizeof ( Size);
}  /* GetPtrSize() */




/* ------------------------------ SetHandleSize() ---------------------
	Change the size of the handle 'hndl'.
*/
SetHandleSize( hndl, newsize)
	Handle hndl;
	Size newsize;
{
	Size	size;
	Ptr		theNewPtr;

	size = GetHandleSize( hndl);
	if ( memErr != NoErr)
		return;
	theNewPtr = NewPtr( newsize);
	if ( memErr != NoErr)
		return;
	movmem( *hndl, theNewPtr, (unsigned)min( size, newsize));
	DisposPtr( *hndl);
	*hndl = theNewPtr;
}	/* SEtHandleSize()	*/




/* ------------------------------ NewHandle() -------------------------
	Return a pointer to a pointer ( Handle) to a block of 'dim'
	bytes.
	Return NULL if error.
*/
Handle NewHandle( dim)
   Size dim;
{
   Ptr      blockptr;
   Handle   hndl;

	if( !(blockptr = NewPtr( dim)))
		return NULL;
   if( !(hndl = Getmaster()))
		{
       memErr = MemFullErr;
       return NULL;
       }
   *hndl = blockptr;
   return hndl;
}  /* NewHandle()  */


/* ----------------------------- DisposHandle() -----------------------
	Recover the block pointed by 'hndl'.
	The master pointer is added to the free list.
*/
DisposHandle( hndl)
   Handle  hndl;
{
   Ptr     block;

   memErr = NoErr;
   if ( NULL != hndl && NULL != * hndl)
       {
       block = * hndl - sizeof ( Size);
#ifdef MICROSOFT
	   free ((void *) block);
	   Putmaster( hndl);
	   return;
#else
	   if ( 0 == MyRlsMem( block, (*(Size *) block)))
           {
           Putmaster( hndl);
           return;
           }
       else
           memErr = MemBlockErr;
#endif
       }
   else
       memErr = NilHandleErr;
}  /* DisposHandle()  */


/* ----------------------------- GetHandleSize() -----------------------
	Return the block size of 'hndl'.
*/
Size GetHandleSize( hndl)
   Handle  hndl;
{
   memErr = NoErr;
   if ( hndl != NULL)
       return GetPtrSize( *hndl);
   memErr = NilHandleErr;
}  /* GetHandleSize()  */



int MemError()
	{
	return memErr;
	}


[ RETURN TO DIRECTORY ]