home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / pd / programming / gnuc / library / rcs / malloc.c,v < prev    next >
Encoding:
Text File  |  1992-09-14  |  9.0 KB  |  413 lines

  1. head    1.4;
  2. access;
  3. symbols
  4.     version39-41:1.2;
  5. locks;
  6. comment    @ *  @;
  7.  
  8.  
  9. 1.4
  10. date    92.09.14.01.44.41;    author mwild;    state Exp;
  11. branches;
  12. next    1.3;
  13.  
  14. 1.3
  15. date    92.08.09.20.58.57;    author amiga;    state Exp;
  16. branches;
  17. next    1.2;
  18.  
  19. 1.2
  20. date    92.05.22.01.43.07;    author mwild;    state Exp;
  21. branches;
  22. next    1.1;
  23.  
  24. 1.1
  25. date    92.05.14.19.55.40;    author mwild;    state Exp;
  26. branches;
  27. next    ;
  28.  
  29.  
  30. desc
  31. @local (task-private) allocator, does *not* use MEMF_PUBLIC
  32. @
  33.  
  34.  
  35. 1.4
  36. log
  37. @reduce magic cookie information by one long. By this, gcc's obstack will
  38. allocate in neat 4k blocks, which makes GigaMem happy (GigaMem is a commercial
  39. VMem package for AmigaDOS).
  40. @
  41. text
  42. @/*
  43.  *  This file is part of ixemul.library for the Amiga.
  44.  *  Copyright (C) 1991, 1992  Markus M. Wild
  45.  *
  46.  *  This library is free software; you can redistribute it and/or
  47.  *  modify it under the terms of the GNU Library General Public
  48.  *  License as published by the Free Software Foundation; either
  49.  *  version 2 of the License, or (at your option) any later version.
  50.  *
  51.  *  This library is distributed in the hope that it will be useful,
  52.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  53.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  54.  *  Library General Public License for more details.
  55.  *
  56.  *  You should have received a copy of the GNU Library General Public
  57.  *  License along with this library; if not, write to the Free
  58.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  59.  *
  60.  *  $Id: malloc.c,v 1.3 1992/08/09 20:58:57 amiga Exp $
  61.  *
  62.  *  $Log: malloc.c,v $
  63.  *  Revision 1.3  1992/08/09  20:58:57  amiga
  64.  *  add cast
  65.  *
  66.  *  Revision 1.2  1992/05/22  01:43:07  mwild
  67.  *  use buddy-alloc memory management
  68.  *
  69.  * Revision 1.1  1992/05/14  19:55:40  mwild
  70.  * Initial revision
  71.  *
  72.  */
  73.  
  74. #define KERNEL
  75. #include "ixemul.h"
  76. #include <stddef.h>
  77.  
  78. #undef DEBUG
  79.  
  80. #ifdef DEBUG
  81. #define DP(a) kprintf a
  82. #else
  83. #define DP(a)
  84. #endif
  85.  
  86. #ifndef BARE_ALLOCMEM
  87. #define AllocMem    b_alloc
  88. #define FreeMem        b_free
  89. #endif
  90.  
  91. #define mem_list (u_save.u_md.md_list)
  92. #define mem_used (u_save.u_md.md_malloc_sbrk_used)
  93.  
  94. #define MAGIC1 0x55555555
  95. #define MAGIC2 0xaaaaaaaa
  96.  
  97. /* use only one magic cookie at the end, since then the most frequently
  98.    done allocation of gcc, 4072 byte, fits neatly into 4096 when we've added
  99.    our information. Gigamem will thank you that it doesn't have to give
  100.    you an additional page for 4 byte ;-)) */
  101.  
  102. struct mem_block {
  103.   struct mem_block *next, *prev;
  104.   u_int           size;
  105.   u_int           magic[2];
  106.   u_int           realblock[1];
  107.   /* realblock should really be [0], and at the end we'd have a magic2[1] */
  108. };
  109.  
  110. struct memalign_ptr {
  111.   u_char    magic;
  112.   u_int        alignment:24;
  113. };
  114.  
  115. #define MEMALIGN_MAGIC 0xdd
  116.  
  117. /* perhaps important later ;-) */
  118. #define PAGESIZE 2048
  119.  
  120. void *
  121. malloc (size_t size)
  122. {
  123.   struct mem_block *res;
  124.  
  125.   /* guarantee long sizes (so we can use CopyMemQuick in realloc) */
  126.   size = (size + 3) & ~3;
  127.   
  128.   /* include management information */
  129.   res = (struct mem_block *) AllocMem (size + sizeof (struct mem_block), 0); /* not MEMF_PUBLIC ! */
  130.   
  131.   if (res)
  132.     {
  133.       u_int *lp = &res->size;
  134.       *lp++ = size;
  135.       *lp++ = MAGIC1; *lp++ = MAGIC1;
  136.       lp = (u_int *)((u_char *)lp + size);
  137.       *lp++ = MAGIC2; 
  138.       
  139.       Forbid ();
  140.       AddTail ((struct List *) &mem_list, (struct Node *) res);
  141.       Permit ();
  142.  
  143. DP(("malloc (%ld) = $%lx.\n",size,&res->realblock));
  144.  
  145.       mem_used += size;
  146.       return &res->realblock;
  147.     }
  148.  
  149.   return 0;
  150. }
  151.  
  152. void *
  153. memalign (size_t alignment, size_t size)
  154. {
  155.   u_char *p = (u_char *) malloc (size + alignment + sizeof (struct memalign_ptr));
  156.   struct memalign_ptr *al_start;
  157.  
  158.   if (! p)
  159.     return p;
  160.  
  161.   /* if the block is already aligned right, just return it */
  162.   if (! ((u_int)p & (alignment - 1)))
  163.     return p;
  164.  
  165.   /* else find the start of the aligned block in our larger block */
  166.   al_start = (struct memalign_ptr *)(((u_int)p + alignment - 1) & -alignment);
  167.  
  168.   /* this could be problematic on 68000, when an odd alignment is requested,
  169.    * should I just don't allow odd alignments?? */
  170.   al_start[-1].magic = MEMALIGN_MAGIC;
  171.   al_start[-1].alignment = (u_char *)al_start - p;
  172.  
  173. DP(("memalign (%ld, %ld) = $%lx. real = $%lx, magic = $%lx.\n", alignment, size,
  174.    al_start, p, al_start[-1]));
  175.  
  176.   return al_start;
  177. }
  178.  
  179. void *
  180. valloc (size_t size)
  181. {
  182.   return (void *) memalign (PAGESIZE, size);
  183. }
  184.  
  185. void
  186. free (void *mem)
  187. {
  188.   struct mem_block *block;
  189.   u_int *end_magic;
  190.  
  191.   /* this seems to be standard... don't like it though ! */
  192.   if (! mem)
  193.     return;
  194.  
  195.   block = (struct mem_block *)((u_char *)mem - offsetof (struct mem_block, realblock));
  196.  
  197. DP(("free ($%lx). block = $%lx, ", mem, block));
  198.   
  199.   if (((struct memalign_ptr *)mem - 1)->magic == MEMALIGN_MAGIC)
  200.     {
  201.       block = (struct mem_block *)
  202.           ((u_char *)block - ((struct memalign_ptr *)mem - 1)->alignment);
  203. DP(("-> block = $%lx, ", block));
  204.     }
  205.  
  206. DP(("size = %ld\n", block->size));
  207.    
  208.  
  209.   if (((u_int)block & 1) ||
  210.       (block->magic[0] != MAGIC1 || block->magic[1] != MAGIC1))
  211.     {
  212. DP(("  m1 = $%lx, m2 = $%lx.\n", block->magic[0], block->magic[1]));
  213.       ix_panic ("free: start of block corrupt!");
  214.       syscall (SYS_exit, 20);
  215.     }
  216.  
  217.   end_magic = (u_int *)((u_char *)&block->realblock + block->size);
  218.   if (end_magic[0] != MAGIC2)
  219.     {
  220. DP(("  endmagic1 = $%lx, endmagic2 = $%lx.\n", end_magic[0], end_magic[1]));
  221.       ix_panic ("free: end of block corrupt!");
  222.       syscall (SYS_exit, 20);
  223.     }
  224.  
  225.   Forbid ();
  226.   Remove ((struct Node *) block);
  227.   Permit ();
  228.  
  229.   mem_used -= block->size;
  230.   FreeMem (block, block->size + sizeof (struct mem_block));
  231. }
  232.  
  233.  
  234. void
  235. all_free ()
  236. {
  237.   struct mem_block *b, *nb;
  238.   
  239. DP(("all_free'ing.. "));
  240.   for (b  = (struct mem_block *) mem_list.mlh_Head;
  241.        nb = b->next;
  242.        b  = nb)
  243.     {
  244.       FreeMem (b, b->size + sizeof (struct mem_block));
  245. #ifdef DEBUG
  246.       mem_used -= b->size;
  247. #endif
  248.     }
  249.  
  250. #ifdef DEBUG
  251.   if (mem_used != 0)
  252.     kprintf ("\aALL_FREE: $%lx bytes not freed!\n", mem_used);
  253. #endif
  254.  
  255.   /* this makes it possible to call all_free() more than once */
  256.   NewList ((struct List *) &mem_list);
  257. DP(("done\n"));
  258. }
  259.  
  260. void *
  261. realloc (void *mem, size_t size)
  262. {
  263.   struct mem_block *block;
  264.   u_int *end_magic;
  265.   void *res;
  266.  
  267.   if (! mem)
  268.     return (void *) malloc (size);
  269.     
  270.   block = (struct mem_block *)((u_char *)mem - offsetof (struct mem_block, realblock));
  271.  
  272. DP(("realloc ($%lx, %ld). block = $%lx, ", mem, size, block));
  273.   
  274.   /* duplicate the code in free() here so we don't have to check those magic
  275.    * numbers twice */
  276.   
  277.   if (((struct memalign_ptr *)mem - 1)->magic == MEMALIGN_MAGIC)
  278.     {
  279.       block = (struct mem_block *)
  280.           ((u_char *)block - ((struct memalign_ptr *)mem - 1)->alignment);
  281. DP(("-> block = $%lx, ", block));
  282.     }
  283.  
  284. DP(("size = %ld\n", block->size));
  285.    
  286.   if (((u_int)block & 1) ||
  287.       (block->magic[0] != MAGIC1 || block->magic[1] != MAGIC1))
  288.     {
  289. DP(("  magic1 = $%lx, magic2 = $%lx.\n", block->magic[0], block->magic[1]));
  290.       ix_panic ("realloc: start of block corrupt!");
  291.       syscall (SYS_exit, 20);
  292.     }
  293.  
  294.   end_magic = (u_int *)((u_char *)&block->realblock + block->size);
  295.   if (end_magic[0] != MAGIC2)
  296.     {
  297. DP(("  endmagic1 = $%lx. ", end_magic[0]));
  298.       ix_panic ("realloc: end of block corrupt!");
  299.       syscall (SYS_exit, 20);
  300.     }
  301.  
  302.   /* now that the block is validated, check whether we have to really
  303.    * realloc, or if we just can return the old block */
  304.   if (block->size >= size)
  305.     res = mem;
  306.   else
  307.     {
  308.       res = (void *) malloc (size);
  309.       if (res)
  310.     {
  311.       Forbid ();
  312.           Remove ((struct Node *) block);
  313.           Permit ();
  314.  
  315.       CopyMemQuick (mem, res, block->size);
  316.  
  317.       /* according to the manpage, the old buffer should only be
  318.        * freed, if the allocation of the new buffer was successful */
  319.       mem_used -= block->size;
  320.       FreeMem (block, block->size + sizeof (struct mem_block));
  321.     }
  322.     }
  323.  
  324. DP((" result = $%lx.\n", res));
  325.   return res;
  326. }
  327. @
  328.  
  329.  
  330. 1.3
  331. log
  332. @add cast
  333. @
  334. text
  335. @d19 1
  336. a19 1
  337.  *  $Id: malloc.c,v 1.2 1992/05/22 01:43:07 mwild Exp $
  338. d22 3
  339. d56 5
  340. d65 2
  341. a66 2
  342.   u_int           realblock[2];
  343.   /* realblock should really be [0], and at the end we'd have a magic2[2] */
  344. d96 1
  345. a96 1
  346.       *lp++ = MAGIC2; *lp   = MAGIC2;
  347. d177 1
  348. a177 1
  349.   if (end_magic[0] != MAGIC2 || end_magic[1] != MAGIC2)
  350. d254 1
  351. a254 1
  352.   if (end_magic[0] != MAGIC2 || end_magic[1] != MAGIC2)
  353. d256 1
  354. a256 1
  355. DP(("  endmagic1 = $%lx, endmagic2 = $%lx. ", end_magic[0], end_magic[1]));
  356. @
  357.  
  358.  
  359. 1.2
  360. log
  361. @use buddy-alloc memory management
  362. @
  363. text
  364. @d19 1
  365. a19 1
  366.  *  $Id: malloc.c,v 1.1 1992/05/14 19:55:40 mwild Exp $
  367. d22 3
  368. d47 2
  369. a48 2
  370. #define mem_list (u.u_md.md_list)
  371. #define mem_used (u.u_md.md_malloc_sbrk_used)
  372. d80 1
  373. a80 1
  374.   res = AllocMem (size + sizeof (struct mem_block), 0); /* not MEMF_PUBLIC ! */
  375. @
  376.  
  377.  
  378. 1.1
  379. log
  380. @Initial revision
  381. @
  382. text
  383. @d19 1
  384. a19 1
  385.  *  $Id$
  386. d21 4
  387. a24 1
  388.  *  $Log$
  389. d39 5
  390. d103 1
  391. a103 2
  392.   u_char *p = (u_char *)syscall (SYS_malloc, 
  393.                  size + alignment + sizeof (struct memalign_ptr));
  394. d130 1
  395. a130 1
  396.   return (void *) syscall (SYS_memalign, PAGESIZE, size);
  397. d191 6
  398. a196 1
  399.     FreeMem (b, b->size + sizeof (struct mem_block));
  400. d198 5
  401. d216 1
  402. a216 1
  403.     return (void *) syscall (SYS_malloc, size);
  404. d256 1
  405. a256 5
  406.       Forbid ();
  407.       Remove ((struct Node *) block);
  408.       Permit ();
  409.  
  410.       res = (void *) syscall (SYS_malloc, size);
  411. d259 4
  412. @
  413.