home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD1.bin
/
new
/
game
/
think
/
chaos
/
src
/
memory.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-14
|
7KB
|
273 lines
/* Chaos: The Chess HAppening Organisation System V5.3
Copyright (C) 1993 Jochen Wiedmann
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
$RCSfile: Memory.c,v $
$Revision: 3.1 $
$Date: 1994/03/23 15:45:41 $
This file contains the memory functions.
Computer: Amiga 1200 Compiler: Dice 2.07.54 (3.0)
Author: Jochen Wiedmann
Am Eisteich 9
72555 Metzingen
Tel. 07123 / 14881
Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
*/
/*
Memory is organized in a list of lists. The elements of the latter lists
are memory chunks obtained by a call to GetMem. This allows us to return
either
- one memory chunk (by a call to PutMem)
- a memory list for example when deleting a tournament (by a call to
PutMemList)
- all memory ever occupied when the program terminates (by a call to
PutMemAll)
These functions are shouldn't be system dependent as there are no
differences except for using AllocMem() on the Amiga and calloc() on
other systems.
*/
/*
Include files we need.
*/
#ifndef CHAOS_H
#include "Chaos.h"
#endif /* !CHAOS_H */
#ifndef AMIGA
#include <stdlib.h>
#define AllocMem(size,flags) calloc((size),1)
#define FreeMem(ptr,size) free(ptr)
#endif /* !AMIGA */
/*
The structures we deal with.
*/
#ifndef AMIGA
struct MinList {
struct MinNode *mlh_Head;
struct MinNode *mlh_Tail;
struct MinNode *mlh_TailPred;
}; /* longword aligned */
struct MinNode {
struct MinNode *mln_Succ;
struct MinNode *mln_Pred;
};
#endif
struct MyMemChunk
{ struct MinNode node;
ULONG Size;
};
struct MyMemList
{ struct MinNode node;
struct MinList list;
};
/*
There's only one static variable, initialized with NULL.
*/
static struct MinList *MainMemList = NULL;
/*
The GetMem() function occupies one chunk of memory.
Inputs: Key - A pointer to a list pointer. If the latter pointer is
NULL, a list is allocated and inserted into the list
of memory lists. The latter pointed gets modified in
that case. (That's why we need a pointer to a pointer.)
Size - The number of bytes the memory chunk should have.
Results: A pointer to a memory chunk or NULL indicating an error.
Note that the chunk is guaranteed to be at least long
word bounded!
*/
void *GetMem(void **List, ULONG Size)
{ struct MyMemChunk *mmc;
struct MyMemList *mml;
/* Check if MainMemList was already initialized and allocate it */
/* otherwise. */
if (MainMemList == NULL)
{ if ((MainMemList = AllocMem(sizeof(struct MinList), MEMF_CLEAR|MEMF_ANY))
== NULL)
{ MemError();
return(NULL);
}
NewList((struct List *) MainMemList);
}
/* Check if the list was already allocated and allocate it otherwise. */
if ((mml = (struct MyMemList *) *List) == NULL)
{ *List = mml = AllocMem(sizeof(*mml), MEMF_ANY|MEMF_CLEAR);
if (!mml)
{ MemError();
return(NULL);
}
NewList((struct List *) &mml->list);
AddTail((struct List *) MainMemList, (struct Node *) mml);
}
if ((mmc = AllocMem(sizeof(*mmc)+Size, MEMF_ANY|MEMF_CLEAR)) == NULL)
{ MemError();
return(NULL);
}
AddTail((struct List *) &mml->list, (struct Node *) mmc);
mmc->Size = Size;
return(mmc+1);
}
/*
The GetStringMem() function occupies memory for a string and copies the
string into it.
Inputs: Key - See GetMem()
str - pointer to a NUL terminated string
Results: See GetMem()
*/
char *GetStringMem(void **Key, char *str)
{ char *result;
if ((result = GetMem(Key, strlen(str)+1)) != NULL)
{ strcpy (result, str);
}
return(result);
}
/*
The PutMem() function returns one chunk of memory to the system.
Inputs: ptr - a pointer to a memory chunk obtained by a recent call
to GetMem(); NULL is a valid argument indicating that
the function should do nothing.
*/
void PutMem(void *ptr)
{ struct MyMemChunk *mmc;
if (ptr != NULL)
{ mmc = ((struct MyMemChunk *) ptr) - 1;
Remove((struct Node *) mmc);
FreeMem(mmc, sizeof(*mmc)+mmc->Size);
}
}
/*
The PutMemList() function returns a list of memory chunks to the system.
Inputs: list - a pointer to a pointer to a memory list; the latter may
be NULL indicating that the list was never used and
the function should do nothing.
The latter pointer will be set to NULL after the function
is executed. (That's why we need a pointer to a pointer.)
*/
void PutMemList(void **List)
{ struct MyMemList *mml = *List;
struct MyMemChunk *mmc;
if (mml != NULL)
{ while ((mmc = (struct MyMemChunk *) mml->list.mlh_Head)->node.mln_Succ
!= NULL)
{ PutMem(mmc+1);
}
Remove((struct Node *) mml);
FreeMem(mml, sizeof(*mml));
*List = NULL;
}
}
/*
The PutMemAll() function returns all memory to the system that was
occupied before. (This should normally only be called when the program
terminates.
*/
void PutMemAll(void)
{ struct MyMemList *mml;
if (MainMemList != NULL)
{ while((mml = (struct MyMemList *) MainMemList->mlh_Head)->node.mln_Succ
!= NULL)
{ PutMemList((void **) &mml);
}
FreeMem(MainMemList, sizeof(struct MinList));
}
MainMemList = NULL;
}
/*
The MoveMemList() function transfers the allocated memory from one list
to the other.
Inputs: source - the list, from where the memory will be removed
dest - the list, where it will be enqueued
*/
void MoveMemList(void **source, void **dest)
{ struct MyMemList *src = *source;
struct MyMemList *dst = *dest;
struct MyMemChunk *mmc;
/*
Make sure, that dst is not NULL. (Additionally a VERY fast
possibility, if it is...
*/
if (dst == NULL)
{ *dest = src;
*source = NULL;
}
else
{ while ((mmc = (struct MyMemChunk *) src->list.mlh_Head)->node.mln_Succ
!= NULL)
{ Remove((struct Node *) mmc);
AddTail((struct List *) &dst->list, (struct Node *) mmc);
}
PutMemList(source);
}
}