home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / new / game / think / chaos / src / memory.c < prev    next >
C/C++ Source or Header  |  1994-10-14  |  7KB  |  273 lines

  1. /*  Chaos:            The Chess HAppening Organisation System    V5.3
  2.     Copyright (C)   1993    Jochen Wiedmann
  3.  
  4.     This program is free software; you can redistribute it and/or modify
  5.     it under the terms of the GNU General Public License as published by
  6.     the Free Software Foundation; either version 2 of the License, or
  7.     (at your option) any later version.
  8.  
  9.     This program is distributed in the hope that it will be useful,
  10.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.     GNU General Public License for more details.
  13.  
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18.  
  19.     $RCSfile: Memory.c,v $
  20.     $Revision: 3.1 $
  21.     $Date: 1994/03/23 15:45:41 $
  22.  
  23.     This file contains the memory functions.
  24.  
  25.     Computer:    Amiga 1200            Compiler:    Dice 2.07.54 (3.0)
  26.  
  27.     Author:    Jochen Wiedmann
  28.         Am Eisteich 9
  29.       72555 Metzingen
  30.         Tel. 07123 / 14881
  31.         Internet: wiedmann@mailserv.zdv.uni-tuebingen.de
  32. */
  33.  
  34.  
  35. /*
  36.     Memory is organized in a list of lists. The elements of the latter lists
  37.     are memory chunks obtained by a call to GetMem. This allows us to return
  38.     either
  39.     - one memory chunk  (by a call to PutMem)
  40.     - a memory list for example when deleting a tournament (by a call to
  41.       PutMemList)
  42.     - all memory ever occupied when the program terminates (by a call to
  43.       PutMemAll)
  44.  
  45.     These functions are shouldn't be system dependent as there are no
  46.     differences except for using AllocMem() on the Amiga and calloc() on
  47.     other systems.
  48. */
  49.  
  50.  
  51. /*
  52.     Include files we need.
  53. */
  54. #ifndef CHAOS_H
  55. #include "Chaos.h"
  56. #endif    /*  !CHAOS_H            */
  57.  
  58. #ifndef AMIGA
  59. #include <stdlib.h>
  60. #define AllocMem(size,flags) calloc((size),1)
  61. #define FreeMem(ptr,size) free(ptr)
  62. #endif    /*  !AMIGA            */
  63.  
  64.  
  65. /*
  66.     The structures we deal with.
  67. */
  68. #ifndef AMIGA
  69. struct MinList {
  70.    struct  MinNode *mlh_Head;
  71.    struct  MinNode *mlh_Tail;
  72.    struct  MinNode *mlh_TailPred;
  73. };    /* longword aligned */
  74. struct MinNode {
  75.     struct MinNode *mln_Succ;
  76.     struct MinNode *mln_Pred;
  77. };
  78. #endif
  79.  
  80. struct MyMemChunk
  81. { struct MinNode node;
  82.   ULONG Size;
  83. };
  84. struct MyMemList
  85. { struct MinNode node;
  86.   struct MinList list;
  87. };
  88.  
  89.  
  90. /*
  91.     There's only one static variable, initialized with NULL.
  92. */
  93. static struct MinList *MainMemList    = NULL;
  94.  
  95.  
  96.  
  97.  
  98. /*
  99.     The GetMem() function occupies one chunk of memory.
  100.  
  101.     Inputs: Key -   A pointer to a list pointer. If the latter pointer is
  102.             NULL, a list is allocated and inserted into the list
  103.             of memory lists. The latter pointed gets modified in
  104.             that case. (That's why we need a pointer to a pointer.)
  105.         Size -  The number of bytes the memory chunk should have.
  106.  
  107.     Results:        A pointer to a memory chunk or NULL indicating an error.
  108.             Note that the chunk is guaranteed to be at least long
  109.             word bounded!
  110. */
  111. void *GetMem(void **List, ULONG Size)
  112.  
  113. { struct MyMemChunk *mmc;
  114.   struct MyMemList *mml;
  115.  
  116.   /*    Check if MainMemList was already initialized and allocate it        */
  117.   /*    otherwise.                                */
  118.   if (MainMemList == NULL)
  119.   { if ((MainMemList = AllocMem(sizeof(struct MinList), MEMF_CLEAR|MEMF_ANY))
  120.              ==  NULL)
  121.     { MemError();
  122.       return(NULL);
  123.     }
  124.     NewList((struct List *) MainMemList);
  125.   }
  126.  
  127.   /*    Check if the list was already allocated and allocate it otherwise.  */
  128.   if ((mml = (struct MyMemList *) *List) == NULL)
  129.   { *List = mml = AllocMem(sizeof(*mml), MEMF_ANY|MEMF_CLEAR);
  130.     if (!mml)
  131.     { MemError();
  132.       return(NULL);
  133.     }
  134.     NewList((struct List *) &mml->list);
  135.     AddTail((struct List *) MainMemList, (struct Node *) mml);
  136.   }
  137.  
  138.   if ((mmc = AllocMem(sizeof(*mmc)+Size, MEMF_ANY|MEMF_CLEAR))  ==  NULL)
  139.   { MemError();
  140.     return(NULL);
  141.   }
  142.   AddTail((struct List *) &mml->list, (struct Node *) mmc);
  143.   mmc->Size = Size;
  144.   return(mmc+1);
  145. }
  146.  
  147.  
  148.  
  149.  
  150. /*
  151.     The GetStringMem() function occupies memory for a string and copies the
  152.     string into it.
  153.  
  154.     Inputs: Key -   See GetMem()
  155.         str -   pointer to a NUL terminated string
  156.  
  157.     Results: See GetMem()
  158. */
  159. char *GetStringMem(void **Key, char *str)
  160.  
  161. { char *result;
  162.  
  163.   if ((result = GetMem(Key, strlen(str)+1))  !=  NULL)
  164.   { strcpy (result, str);
  165.   }
  166.   return(result);
  167. }
  168.  
  169.  
  170.  
  171.  
  172. /*
  173.     The PutMem() function returns one chunk of memory to the system.
  174.  
  175.     Inputs: ptr - a pointer to a memory chunk obtained by a recent call
  176.           to GetMem(); NULL is a valid argument indicating that
  177.           the function should do nothing.
  178. */
  179. void PutMem(void *ptr)
  180.  
  181. { struct MyMemChunk *mmc;
  182.  
  183.   if (ptr != NULL)
  184.   { mmc = ((struct MyMemChunk *) ptr) - 1;
  185.     Remove((struct Node *) mmc);
  186.     FreeMem(mmc, sizeof(*mmc)+mmc->Size);
  187.   }
  188. }
  189.  
  190.  
  191.  
  192.  
  193. /*
  194.     The PutMemList() function returns a list of memory chunks to the system.
  195.  
  196.     Inputs: list - a pointer to a pointer to a memory list; the latter may
  197.            be NULL indicating that the list was never used and
  198.            the function should do nothing.
  199.            The latter pointer will be set to NULL after the function
  200.            is executed. (That's why we need a pointer to a pointer.)
  201. */
  202. void PutMemList(void **List)
  203.  
  204. { struct MyMemList *mml = *List;
  205.   struct MyMemChunk *mmc;
  206.  
  207.   if (mml != NULL)
  208.   { while ((mmc = (struct MyMemChunk *) mml->list.mlh_Head)->node.mln_Succ
  209.                                 !=  NULL)
  210.     { PutMem(mmc+1);
  211.     }
  212.     Remove((struct Node *) mml);
  213.     FreeMem(mml, sizeof(*mml));
  214.     *List = NULL;
  215.   }
  216. }
  217.  
  218.  
  219.  
  220.  
  221. /*
  222.     The PutMemAll() function returns all memory to the system that was
  223.     occupied before. (This should normally only be called when the program
  224.     terminates.
  225. */
  226. void PutMemAll(void)
  227.  
  228. { struct MyMemList *mml;
  229.  
  230.   if (MainMemList != NULL)
  231.   { while((mml = (struct MyMemList *) MainMemList->mlh_Head)->node.mln_Succ
  232.                                     !=    NULL)
  233.     { PutMemList((void **) &mml);
  234.     }
  235.     FreeMem(MainMemList, sizeof(struct MinList));
  236.   }
  237.   MainMemList = NULL;
  238. }
  239.  
  240.  
  241.  
  242.  
  243. /*
  244.     The MoveMemList() function transfers the allocated memory from one list
  245.     to the other.
  246.  
  247.     Inputs: source - the list, from where the memory will be removed
  248.         dest   - the list, where it will be enqueued
  249. */
  250. void MoveMemList(void **source, void **dest)
  251.  
  252. { struct MyMemList *src = *source;
  253.   struct MyMemList *dst = *dest;
  254.   struct MyMemChunk *mmc;
  255.  
  256.   /*
  257.       Make sure, that dst is not NULL. (Additionally a VERY fast
  258.       possibility, if it is...
  259.   */
  260.   if (dst == NULL)
  261.   { *dest = src;
  262.     *source = NULL;
  263.   }
  264.   else
  265.   { while ((mmc = (struct MyMemChunk *) src->list.mlh_Head)->node.mln_Succ
  266.                                     !=    NULL)
  267.     { Remove((struct Node *) mmc);
  268.       AddTail((struct List *) &dst->list, (struct Node *) mmc);
  269.     }
  270.     PutMemList(source);
  271.   }
  272. }
  273.