test_mem.c 4.1 KB

/*************************************************************

  test_mem.c : Nintendo 64 Music Tools Library Sample
  (c) Copyright 1998, Software Creations (Holdings) Ltd.

  Version 3.11

  N64DD demo memory manager source file. 

**************************************************************/

/* include system header files */
#ifndef F3DEX_GBI
#define F3DEX_GBI
#endif

#include <ultra64.h>

/* mimimum fragment size to maintain */
#define MINSIZE	1024+16

/* alignment - must be a power of two */
#define PADDING	16		/* cache align */


/* must be multiple of 16 bytes long */
typedef struct _malloc_s_
{
  struct _malloc_s_ *previous;
  struct _malloc_s_ *next;
  unsigned long size;
  unsigned long used;
} malloc_t;

static malloc_t *current;

/* free memory starts at end of code segment */
extern char _codeSegmentEnd[];

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
  [GLOBAL FUNCTION]
  MemInit()

  [Explantion]
  Initialise memory manager.

  [Return value]
  NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

void MemInit(void)
{
  unsigned long start,end;
  unsigned long memsize;

  /* start position is end of code segment */
  start = (unsigned long) &_codeSegmentEnd[0];
  start = (start+(PADDING-1))&(~(PADDING-1));
  /* now calc length */
  end   = (start&0xff000000)+(unsigned long)osMemSize;

  current = (malloc_t *)start;
  current->size = end-start;
  current->previous = NULL;
  current->next = NULL;
  current->used = 0;
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
  [GLOBAL FUNCTION]
  MemMalloc(size)
  
  [Parameters]
  size	    number of bytes requested

  [Explantion]
  Claim a block of memory from the applications heap.

  [Return value]
  Address of memory block or NULL if not enough memory is free
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

void *MemMalloc(unsigned long size)
{
  unsigned long claimsize, free;
  malloc_t *list, *next;

  claimsize = ((size+(PADDING-1))&(~(PADDING-1)))+sizeof(malloc_t);
  list = current;

  while ((list->used || list->size<claimsize) && list->next)
    list=list->next;
  if (!list->used && list->size>=claimsize)
  {
    free = list->size-claimsize;
    if (free<MINSIZE)	
    {
      claimsize=list->size;
      free = 0;
    }
    list->used = size;
    list->size = claimsize;
    if (free)
    {
      next = (malloc_t *)((unsigned long)list+claimsize);
      next->previous = list;
      next->next = list->next;
      list->next = next;
      next->used = 0;
      next->size = free;
    }
    return ((void *)(list+1));    
  }
  return (NULL);
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
  [GLOBAL FUNCTION]
  MemFree(memory)
  
  [Parameters]
  memory    address of a memory block returned from MemMalloc()

  [Explantion]
  Free a block of memory previously claimed from the applications heap.

  [Return value]
  NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

void MemFree(void *memory)
{
  malloc_t *thisone, *previous, *next;
  
  thisone = memory;
  thisone->used = 0;
  previous = thisone->previous;
  next = previous->next;
  if (previous && !previous->used)
  {
    previous->size += thisone->size;
    previous->next = next;
    thisone = previous;
    previous=thisone->previous;
  }
  if (next && !next->used)
  {
    thisone->size += next->size;
    thisone->next = next->next;    
  }  
}

/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
  [GLOBAL FUNCTION]
  MemShowStatus()
  
  [Explantion]
  Display current status of applications heap.

  [Return value]
  NONE
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/

void MemShowStatus(void)
{
  malloc_t *thisone;

  thisone = current;
  while (thisone)
  {
    if (thisone->used)
      osSyncPrintf("USED 0x%08x size=0x%08x used=0x%08x\n",thisone,thisone->size,thisone->used);
    else
      osSyncPrintf("FREE 0x%08x size=0x%08x\n",thisone,thisone->size);
    thisone = thisone->next;
  }
}


/* end of file */