home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
READER
/
ALLOC.C
next >
Wrap
C/C++ Source or Header
|
1996-07-11
|
15KB
|
665 lines
/*
* データ確領域処理関数
*
* 1989.12.10
* Copyright T.Kobayashi
*
*/
#include <stdio.h>
#include <stdlib.h>
#ifdef X68000
#include <doslib.h>
#endif
#ifdef __BORLANDC__
#include <malloc.h>
#include <memory.h>
#include <alloc.h>
#endif
#ifdef MSC
#include <malloc.h>
#include <memory.h>
#endif
#include <assert.h>
#include "reader.h"
#define ALLOC_DATA_ID 12345
#define ALLOC_TEMP_ID 23456
/*#define ERR(sss) {FILE *fp;fp=fopen("tmp.log","a");sss;fclose(fp);}*/
#ifndef ERR
#define ERR(sss)
#endif
#define HEAPSIZE (64 * 1024) /*V70のときだけ有効*/
#define STACKSIZE (64 * 1024) /*V70のときだけ有効*/
/* メモリ管理領域 */
typedef struct {
short id ;
long size ;
}
MMA ;
static char HUGE *allocend = NULL ;
static char HUGE *allocbuf = NULL ;
static char HUGE *nextbuf ;
static short allocids[2] = { ALLOC_DATA_ID, ALLOC_TEMP_ID } ;
static void allocerror( char* );
#ifdef ONDEMANDMALLOC
#define ARRAYSIZE 1024
#define MAXMARK 1024
#define BUFFERLIMIT (1024)
#define BUFFERSIZE (1024*1024)
/*#define BUFFERCHECK 1024*/
#ifndef BUFFERCHECK
#define BUFFERCHECK 0
#endif
typedef struct _MMAarray{
void *mma[ARRAYSIZE];
#if BUFFERCHECK
int length[ARRAYSIZE];
#endif
struct _MMAarray *next;
} MMAarray;
typedef struct _MMAbuf {
char buffer[BUFFERSIZE];
struct _MMAbuf *next;
} MMAbuf;
typedef struct {
MMAarray *array;
int index;
MMAbuf *buf;
int bufremain;
void *bufpointer;
int totalalloc;
} MMAmark;
static MMAarray *top, *cur;
static int curindex;
static MMAbuf *buftop, *bufcur;
static void *bufpointer;
static int bufremain;
static MMAmark markdata[MAXMARK];
static int currentmark;
static long totalalloc;
#if BUFFERCHECK
static void setMagic1(unsigned char *p)
{
int i;
for (i = 0; i < BUFFERCHECK; i++) {
*p++ = (i % 256);
}
}
static void setMagic2(unsigned char *p)
{
int i;
for (i = 0; i < BUFFERCHECK; i++) {
*p++ = ((BUFFERCHECK-i) % 256);
}
}
static void checkMagic1(unsigned char *p)
{
int i;
for (i = 0; i < BUFFERCHECK; i++) {
if (*p++ != (i%256)) {
ERR(fputc('1', fp));
return;
}
}
ERR(fputc('P', fp));
}
static void checkMagic2(unsigned char *p)
{
int i;
for (i = 0; i < BUFFERCHECK; i++) {
if (*p++ != ((BUFFERCHECK-i)%256)) {
ERR(fputc('2', fp));
return;
}
}
ERR(fputc('N', fp));
}
#endif
void meminit( long memsize )
{
top = malloc(sizeof(MMAarray));
if (top == NULL) {
allocerror("メモリ初期化に失敗しました。");
}
cur = top;
cur->next = NULL;
curindex = 0;
buftop = malloc(sizeof(MMAbuf));
if (buftop == NULL) {
allocerror("メモリ初期化に失敗しました。");
}
bufcur = buftop;
bufcur->next = NULL;
bufpointer = buftop->buffer;
bufremain = BUFFERSIZE;
currentmark = 0;
totalalloc = 0;
}
/* 領域の確保 */
void *memalloc( size )
int size ;
{
void HUGE *h ;
assert( top != NULL );
assert( size >= 0 );
assert( size > 0);
assert(( size % 2 ) == 0 );
size = ((size+3)/4) * 4;
if (size <= BUFFERLIMIT) {
if (bufremain <= size) {
bufcur->next = malloc(sizeof(MMAbuf));
if (bufcur->next == NULL) {
allocerror( "データ領域が足りません(malloc)。" );
}
bufcur = bufcur->next;
bufcur->next = NULL;
bufpointer = bufcur->buffer;
bufremain = BUFFERSIZE;
}
h = bufpointer;
bufremain -= size;
bufpointer = ((char*)bufpointer) + size;
} else {
ERR(fprintf(fp, "malloc %08x:%4d (%6d) : ", cur, curindex, size));
cur->mma[curindex] = malloc(size + BUFFERCHECK*2);
if (cur->mma[curindex] == NULL) {
allocerror( "データ領域が足りません(malloc)。" );
}
h = (char*)cur->mma[curindex] + BUFFERCHECK;
#if BUFFERCHECK
cur->length[curindex] = size;
setMagic1(cur->mma[curindex]);
setMagic2((char*)cur->mma[curindex] + BUFFERCHECK + size);
#endif
ERR(fprintf(fp, "%08x\n", h));
if (++curindex == ARRAYSIZE) {
cur->next = malloc(sizeof(MMAarray));
if (cur->next == NULL) {
allocerror("メモリ再確保に失敗しました。");
}
cur = cur->next;
cur->next = NULL;
curindex = 0;
}
}
totalalloc += size;
return h;
}
/* 配列の確保 */
void *memaryalloc( count, size )
int count, size ;
{
MMA HUGE *h ;
long tsize;
assert( top != NULL );
assert( size >= 0 );
assert( size > 0 && ( size % 2 ) == 0 );
size = ((size+3)/4) * 4;
tsize = (long)size * (long)count;
if (tsize <= BUFFERLIMIT) {
if (bufremain <= tsize) {
bufcur->next = malloc(sizeof(MMAbuf));
if (bufcur->next == NULL) {
allocerror( "データ領域が足りません(malloc)。" );
}
bufcur = bufcur->next;
bufcur->next = NULL;
bufpointer = bufcur->buffer;
bufremain = BUFFERSIZE;
}
h = bufpointer;
bufremain -= tsize;
bufpointer = ((char*)bufpointer) + tsize;
} else {
ERR(fprintf(fp, "maryoc %08x:%4d (%6d) : ", cur, curindex, size*count));
cur->mma[curindex] = malloc((long)size * (long)count + BUFFERCHECK*2);
if (cur->mma[curindex] == NULL) {
allocerror( "データ領域が足りません(malloc)。" );
}
h = (char*)cur->mma[curindex] + BUFFERCHECK;
#if BUFFERCHECK
cur->length[curindex] = (long)size * (long)count;
setMagic1(cur->mma[curindex]);
setMagic2((char*)cur->mma[curindex] + BUFFERCHECK + cur->length[curindex]);
#endif
ERR(fprintf(fp, "%08x\n", h));
if (++curindex == ARRAYSIZE) {
cur->next = malloc(sizeof(MMAarray));
if (cur->next == NULL) {
allocerror("メモリ再確保に失敗しました。");
}
cur = cur->next;
cur->next = NULL;
curindex = 0;
}
}
totalalloc += (long)size * (long)count;
return h;
}
/* マーク */
char *memmark()
{
markdata[currentmark].array = cur;
markdata[currentmark].index = curindex;
markdata[currentmark].buf = bufcur;
markdata[currentmark].bufpointer = bufpointer;
markdata[currentmark].bufremain = bufremain;
markdata[currentmark].totalalloc = totalalloc;
ERR(fprintf(fp, "mark %08x\n", (char FAR*)&markdata[currentmark+1]));
return( (char FAR*)&markdata[currentmark++] );
}
/* 領域の開放 */
void memrelease( markp )
char *markp ;
{
int i, j;
MMAarray *p, *q;
MMAmark *mp = (MMAmark*)markp;
assert( markdata <= mp && mp <= markdata + MAXMARK );
ERR(fprintf(fp, "release %08x\n", markp));
if (mp->array == cur) {
ERR(fprintf(fp, "loop %d to %d\n", mp->index, curindex));
for (i = mp->index; i < curindex; ++i) {
ERR(fprintf(fp, "free %08x:%4d : %08x", cur, i, cur->mma[i]));
#if BUFFERCHECK
checkMagic1(cur->mma[i]);
checkMagic2((char*)cur->mma[i] + BUFFERCHECK + cur->length[i]);
#endif
free(cur->mma[i]);
ERR(fprintf(fp, " ok.\n"));
}
} else {
p = mp->array;
ERR(fprintf(fp, "loop %d to %d\n", mp->index, ARRAYSIZE));
for (i = mp->index; i < ARRAYSIZE; ++i) {
ERR(fprintf(fp, "free %08x:%4d : %08x", p, i, p->mma[i]));
#if BUFFERCHECK
checkMagic1(p->mma[i]);
checkMagic2((char*)p->mma[i] + BUFFERCHECK + p->length[i]);
#endif
free(p->mma[i]);
ERR(fprintf(fp, " ok.\n"));
}
for (p = p->next; p != NULL && p != cur;p = q) {
ERR(fprintf(fp, "loop %d to %d\n", 0, ARRAYSIZE));
for (i = 0; i < ARRAYSIZE; ++i) {
ERR(fprintf(fp, "free %08x:%4d : %08x", p, i, p->mma[i]));
#if BUFFERCHECK
checkMagic1(p->mma[i]);
checkMagic2((char*)p->mma[i] + BUFFERCHECK + p->length[i]);
#endif
free(p->mma[i]);
ERR(fprintf(fp, " ok.\n"));
}
q = p->next;
free(p);
}
if (p == cur) {
ERR(fprintf(fp, "loop %d to %d\n", 0, curindex));
for (i = 0; i < curindex; ++i) {
ERR(fprintf(fp, "free %08x:%4d : %08x", p, i, p->mma[i]));
#if BUFFERCHECK
checkMagic1(p->mma[i]);
checkMagic2((char*)p->mma[i] + BUFFERCHECK + p->length[i]);
#endif
free(p->mma[i]);
ERR(fprintf(fp, " ok.\n"));
}
free(p);
}
}
cur = mp->array;
cur->next = NULL;
curindex = mp->index;
bufpointer = mp->bufpointer;
bufremain = mp->bufremain;
bufcur = mp->buf;
if (bufcur->next != NULL) {
MMAbuf *pbuf, *pnext = NULL;
for (pbuf = bufcur->next; pbuf != NULL;pbuf = pnext) {
ERR(fprintf(fp, "free %x\n", pbuf));
pnext = pbuf->next;
free(pbuf);
}
bufcur->next = NULL;
}
totalalloc = mp->totalalloc;
currentmark = mp - markdata;
}
/* 使用領域サイズを返す */
long memsize()
{
return totalalloc;
}
long memgetsize(void)
{
return 0;
}
#else
/*
* データバッファの処理関数
*/
/* データバッファの初期化 */
void meminit( memsize )
long memsize ;
{
long n ;
char *errormsg = "データ領域が確保できません。" ;
if (memsize < 0) {
#if defined(X68000)
#ifdef V70
n = SBRK(0x10000000);
SBRK(n - 0x81000000 - STACKSIZE);
n = (int)MALLOC( 0x1000000 ) - 0x81000000 - HEAPSIZE;
#else
n = (int)MALLOC( 0x1000000 ) - 0x81000000 ;
#endif
n -= -memsize;
allocbuf = (char*)MALLOC( n );
assert( 0 < allocbuf && allocbuf < 0x1000000 );
#elif defined(DJ) || defined(UNIX) || defined(__WIN32__)
n = 16 * 1024 * 1024;
allocbuf = malloc(n);
/* assert( 0 < allocbuf && allocbuf < 0x1000000 );*/
#elif defined(MSC)
n = 400L * 1024L;
do {
n -= 1024L * 10L;
allocbuf = halloc(n, 1);
} while (allocbuf == NULL && n > 0);
hfree(allocbuf);
n -= -memsize;
allocbuf = halloc(n, 1);
assert( allocbuf != NULL);
/* assert( 0 < allocbuf && allocbuf < 0x1000000L );*/
#elif defined(__BORLANDC__)
n = 400L * 1024L;
do {
n -= 1024L * 10L;
allocbuf = farmalloc(n);
} while (allocbuf == NULL && n > 0);
farfree(allocbuf);
n -= -memsize;
allocbuf = farmalloc(n);
assert( allocbuf != NULL);
/* assert( 0 < allocbuf && allocbuf < 0x1000000L );*/
#endif
}
else if ( memsize == 0 )
{
/* とれるだけとる */
#if defined(X68000)
#ifdef V70
n = SBRK(0x10000000);
SBRK(n - 0x81000000 - STACKSIZE);
n = (int)MALLOC( 0x1000000 ) - 0x81000000 - HEAPSIZE;
#else
n = (int)MALLOC( 0x1000000 ) - 0x81000000 ;
#endif
allocbuf = MALLOC( n );
assert( 0 < allocbuf && allocbuf < 0x1000000 );
#elif defined(DJ) || defined(UNIX) || defined (__WIN32__)
n = 16 * 1024 * 1024;
allocbuf = malloc(n);
assert( 0 < allocbuf && allocbuf < 0x1000000 );
#elif defined(MSC)
n = 400L * 1024L;
do {
n -= 1024L * 10L;
allocbuf = halloc(n, 1);
} while (allocbuf == NULL && n > 0);
assert( allocbuf != NULL);
#elif defined(__BORLANDC__)
n = 400L * 1024L;
do {
n -= 1024L * 10L;
allocbuf = farmalloc(n);
} while (allocbuf == NULL && n > 0);
assert( allocbuf != NULL);
#endif
}
else
{
n = memsize ;
#if defined(X68000)
allocbuf = (char*)MALLOC( n );
if ( allocbuf <= 0 || 0x1000000 <= allocbuf )
allocerror( errormsg );
#elif defined(DJ) || defined(UNIX) || defined(__WIN32__)
allocbuf = malloc( n );
if ( allocbuf == NULL )
allocerror( errormsg );
#elif defined(MSC)
allocbuf = halloc( n, 1 );
if ( allocbuf == NULL )
allocerror( errormsg );
#elif defined(__BORLANDC__)
allocbuf = farmalloc( n );
if ( allocbuf == NULL )
allocerror( errormsg );
#endif
}
allocend = allocbuf + n ;
nextbuf = allocbuf ;
/*
printf("allocbuf=%04x:%04x\n", FP_SEG(allocbuf), FP_OFF(allocbuf));
printf("allocend=%04x:%04x\n", FP_SEG(allocend), FP_OFF(allocend));
printf("nextbuf =%04x:%04x\n", FP_SEG(nextbuf), FP_OFF(nextbuf));
*/
}
long memgetsize(void)
{
return (unsigned long)allocend - (unsigned long)nextbuf;
}
/* 領域の確保 */
void *memalloc( size )
int size ;
{
MMA HUGE *h ;
assert( allocbuf != NULL );
assert( size > 0 && ( size % 2 ) == 0 );
/* printf("memalloc:%d\n", size);*/
/* バッファの確保 */
h = (MMA*)nextbuf ;
/* printf("nextbuf: %04X:%04X -> ", FP_SEG(nextbuf), FP_OFF(nextbuf));*/
nomalize_pointer( h );
nextbuf += size + sizeof( MMA ) ;
/* printf("%04X:%04X\n", FP_SEG(nextbuf), FP_OFF(nextbuf));*/
if ( nextbuf > allocend )
{
allocerror( "データ領域が足りません(malloc)。" );
}
h->id = ALLOC_DATA_ID ;
h->size = (long)size ;
return( (void*)( h + 1 ) );
}
/* 配列の確保 */
void *memaryalloc( count, size )
int count, size ;
{
MMA *h ;
assert( allocbuf != NULL );
assert( size > 0 && ( size % 2 ) == 0 );
/* バッファの確保 */
h = (MMA*)nextbuf ;
nomalize_pointer( h );
h->id = ALLOC_DATA_ID ;
h->size = (long)size * (long)count ;
nextbuf += h->size + (long)sizeof( MMA ) ;
if ( nextbuf > allocend )
allocerror( "データ領域が足りません(arraymalloc)。" );
return( (void*)( h + 1 ) );
}
/* マーク */
char *memmark()
{
return( (char FAR*)nextbuf );
}
/* 領域の開放 */
void memrelease( p )
char *p ;
{
assert( allocbuf <= (char HUGE*)p && (char HUGE*)p <= nextbuf );
nextbuf = (char HUGE*)p ;
}
/* 使用領域サイズを返す */
long memsize()
{
return( (unsigned long)( nextbuf - allocbuf ) );
}
/* 使用可能サイズを返す */
long memallsize()
{
return( (unsigned long)( allocend - nextbuf ) );
}
#endif
/*
* ワーク領域(ヒープ)の処理関数
*/
/* ワークバッファの確保 */
void *tempalloc( size )
int size ;
{
MMA *h ;
assert( size > 0 );
assert( size < 32000 );
assert( ( size % 2 ) == 0 );
h = (MMA*)malloc( size + sizeof( MMA ) );
if ( h == NULL )
allocerror( "ヒープ領域が足りません。" );
h->id = ALLOC_TEMP_ID ;
h->size = size ;
return( (void*)( h + 1 ) );
}
/* ワークバッファの開放 */
void tempfree( p )
void *p ;
{
MMA *h ;
assert( memcheck( p, p, ALLOC_TYPE_TEMP ) );
h = (MMA*)p - 1 ;
free( (char*)h );
}
/* ワークバッファの再確保 */
void *temprealloc( p, size )
void *p ;
int size ;
{
void *pp ;
pp = tempalloc( size );
memcpy( pp, p, size );
tempfree( p );
return( pp );
}
/*
* その他の関数
*/
/* エラーメッセージ出力 */
static void allocerror( msg )
char *msg ;
{
#ifdef MESSAGE
extern int printwarning(const char *format, ...);
printwarning( "%s", msg);
#endif
fprintf( stderr, "\n\7%s\n\n", msg );
exit( 1 );
}
/* 領域のチェック */
int memcheck( top, refer, flag )
void *top ;
void *refer ;
int flag ;
{
long size ;
MMA HUGE *h ;
h = (MMA*)top ;
h -- ;
if ( h->id != allocids[ flag ] )
{
fprintf( stderr,
"\n\7メモリ管理領域が破壊されました。!!\n\n" );
return( FALSE );
}
size = (char HUGE *)refer - (char HUGE *)top ;
if ( size < 0L || h->size <= size )
{
fprintf( stderr,
"\n\7不正なアドレスを参照しようとしています。!!\n\n" );
return( FALSE );
}
return( TRUE );
}