#include "cdefs.h"
#include "mem.h"

static char* h[128];
static cint tot_free;

void init_mem(){
  cint i;
  for (i = 0; i<128; i++) {h[i] = 0;};
  tot_free = 0;
}

void mem_reclaim(){
  cint i; char* p;
  for (i = 0; i<128; i++){
    p = h[i];
    while (p) {h[i] = *((char**)p); free(p); p = h[i];};
  };
  tot_free = 0;
}

void* mem_malloc(cint siz){
  char* r;
  if (siz < 1 | siz > 128){
    r = (char*)malloc(siz+4); 
    if (!r) {mem_reclaim(); r = (char*)malloc(siz+4);}
    if (!r) exit(255);
  }else{
    tot_free -= siz;
    r = h[siz-1];
    if (r == 0){
      if (tot_free > 32000000) mem_reclaim();
      r = (char*)malloc(siz+4); 
      if (!r) {mem_reclaim(); r = (char*)malloc(siz+4);}
      if (!r) exit(255);
    }else{
      h[siz-1] = *((void**)r);
    };
  };
  *((cint*)r) = siz; return r+4;
}

void mem_free(cint p){
  char* q = (char*)p; cint siz;
  *((cint*)p) = -1234;
  q -= 4;
  siz = *((cint*)q);
  if (siz < 1 | siz > 128) {free(q); return;};
  *((char**)q) = h[siz-1];
  h[siz-1] = q;
  tot_free += siz;
}



