
/* substitutes for structs, malloc() and free()

   add this file to your source code; do NOT use as #include 

   example of usage:

   struct QElt  {
      int X;
      struct QElt *Next;
   } *QHead,*QTail;
   int QLock=0;
   ...
   ...
   AddToQueue(K)
      int K;
   LOCK(QLock);
   Q = (struct QElt *) Malloc(3);
   Q->X = K;
   Q->Next = 0;
   if (QHead != 0)  {
      QTail->Next = Q;
      QTail = Q;
   }
   else QHead = QTail = Q;
   UNLOCK(QLock);
}  */

#define MAX_HEAP 1000  /* expand as needed for your app */

int MallocLock,
    MallocHeap[MAX_HEAP],  /* where memory is allocated from */
    MallocUse[MAX_HEAP];  /* states which parts are now in use */

MallocInit()  /* REQUIRED call at the outset of a program */

{  int I;

   for (I = 0; I < MAX_HEAP; I++) MallocUse[I] = 0;
}

void *Malloc(W)  /* this is "malloc()"; allocates W words */ 
   int W;

{  int I,J;

   LOCK(MallocLock);
   for (I = 0; I+W-1 < MAX_HEAP; I++)  {
      for (J = 0; J < W; J++) if (MallocUse[I+J]) break;  
      if (J == W)  {
         for (J = 0; J < W; J++) MallocUse[I+J] = 1; 
         UNLOCK(MallocLock);
         return MallocHeap+I;
      }
   }
   print_str("Malloc failure\n");
   return 0;
}

Free(P,W)  /* this is "free()" */
   int *P,W;

{  int I,K;

   K = (int) P - (int) MallocHeap;
   LOCK(MallocLock);
   for (I = K; I < K+W; I++) MallocUse[I] = 0;
   UNLOCK(MallocLock);
}

