/**********************************************************************
 
	Copyright (C) 2003 Hirohisa MORI <joshua@nichibun.ac.jp>
 
	This program is free software; you can redistribute it 
	and/or modify it under the terms of the GLOBALBASE 
	Library General Public License (G-LGPL) as published by 

	http://www.globalbase.org/
 
	This program is distributed in the hope that it will be 
	useful, but WITHOUT ANY WARRANTY; without even the 
	implied warranty of MERCHANTABILITY or FITNESS FOR A 
	PARTICULAR PURPOSE.

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


#ifdef MEMORY_DEBUG

#include	"memory_debug.h"
#include	"task.h"

extern THREAD_BLOCK tb[THREAD_BLOCK_SIZE];

#define PRE 0x24681357

#define X_ALIGN	sizeof(double)
#define X_OFS	(X_ALIGN/sizeof(int))

int
check_critics(void * p,int s)
{
unsigned int _p;
unsigned int _tb,_tb_last;
	_p = (unsigned int)p;
	_tb = (unsigned int)tb;
	_tb_last = (unsigned int)&tb[THREAD_BLOCK_SIZE];
	if ( _p >= _tb_last )
		return 0;
	if ( _p + s + X_ALIGN + sizeof(int) <= _tb )
		return 0;
	return -1;
}


void *
_x_malloc(int size)
{
int * ptr;
int ss,sss;

	if ( size%X_ALIGN )
		ss = X_ALIGN-(size%X_ALIGN)+size;
	else	ss = size;
	ptr = malloc(ss+X_ALIGN+sizeof(int));
	if ( check_critics(ptr,ss) )
		er_panic("_x_malloc(1)");
	ptr[0] = ss;
	ptr[(ss/sizeof(int))+X_OFS] = PRE;
	return (void*)&ptr[X_OFS];
}

void *
_x_realloc(void * p,int size)
{
int * ptr;
int ss;
	ptr = p;
	ptr = ptr - X_OFS;
	ss = ptr[0];
	if ( ss < 0 )
		er_panic("_x_realloc(1)");
	if ( check_critics(ptr,ss) )
		er_panic("_x_realloc(2)");
	if ( ptr[(ss/sizeof(int))+X_OFS] != PRE )
		er_panic("_x_realloc(3)");
	ptr[(ss/sizeof(int))+X_OFS] = 0;
	if ( size%X_ALIGN )
		ss = X_ALIGN-(size%X_ALIGN)+size;
	else	ss = size;
	ptr = realloc(ptr,ss+X_ALIGN+sizeof(int));
	ptr[0] = ss;
	ptr[(ss/sizeof(int))+X_OFS] = PRE;
	return (void*)&ptr[X_OFS];
}

void
_x_free(void * ptr)
{
int * p;
int ss;
	p = ptr;
	p = p-X_OFS;
	ss = p[0];
	if ( ss < 0 )
		er_panic("_x_free(1)");
	if ( check_critics(p,ss) )
		er_panic("_x_free(2)");
	if ( p[(ss/sizeof(int))+X_OFS] != PRE )
		er_panic("_x_free(3)");
	free(p);
}

void *
_x_calloc(int size,int el)
{
char * ptr, * p;
int i;
	ptr = _x_malloc(size*el);
	p = ptr;
	for ( i = size*el ; i ; i -- )
		*p ++ = 0;
	return (void *)ptr;
}


#endif

