home *** CD-ROM | disk | FTP | other *** search
- head 1.4;
- access;
- symbols
- version39-41:1.2;
- locks;
- comment @ * @;
-
-
- 1.4
- date 92.09.14.01.44.41; author mwild; state Exp;
- branches;
- next 1.3;
-
- 1.3
- date 92.08.09.20.58.57; author amiga; state Exp;
- branches;
- next 1.2;
-
- 1.2
- date 92.05.22.01.43.07; author mwild; state Exp;
- branches;
- next 1.1;
-
- 1.1
- date 92.05.14.19.55.40; author mwild; state Exp;
- branches;
- next ;
-
-
- desc
- @local (task-private) allocator, does *not* use MEMF_PUBLIC
- @
-
-
- 1.4
- log
- @reduce magic cookie information by one long. By this, gcc's obstack will
- allocate in neat 4k blocks, which makes GigaMem happy (GigaMem is a commercial
- VMem package for AmigaDOS).
- @
- text
- @/*
- * This file is part of ixemul.library for the Amiga.
- * Copyright (C) 1991, 1992 Markus M. Wild
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: malloc.c,v 1.3 1992/08/09 20:58:57 amiga Exp $
- *
- * $Log: malloc.c,v $
- * Revision 1.3 1992/08/09 20:58:57 amiga
- * add cast
- *
- * Revision 1.2 1992/05/22 01:43:07 mwild
- * use buddy-alloc memory management
- *
- * Revision 1.1 1992/05/14 19:55:40 mwild
- * Initial revision
- *
- */
-
- #define KERNEL
- #include "ixemul.h"
- #include <stddef.h>
-
- #undef DEBUG
-
- #ifdef DEBUG
- #define DP(a) kprintf a
- #else
- #define DP(a)
- #endif
-
- #ifndef BARE_ALLOCMEM
- #define AllocMem b_alloc
- #define FreeMem b_free
- #endif
-
- #define mem_list (u_save.u_md.md_list)
- #define mem_used (u_save.u_md.md_malloc_sbrk_used)
-
- #define MAGIC1 0x55555555
- #define MAGIC2 0xaaaaaaaa
-
- /* use only one magic cookie at the end, since then the most frequently
- done allocation of gcc, 4072 byte, fits neatly into 4096 when we've added
- our information. Gigamem will thank you that it doesn't have to give
- you an additional page for 4 byte ;-)) */
-
- struct mem_block {
- struct mem_block *next, *prev;
- u_int size;
- u_int magic[2];
- u_int realblock[1];
- /* realblock should really be [0], and at the end we'd have a magic2[1] */
- };
-
- struct memalign_ptr {
- u_char magic;
- u_int alignment:24;
- };
-
- #define MEMALIGN_MAGIC 0xdd
-
- /* perhaps important later ;-) */
- #define PAGESIZE 2048
-
- void *
- malloc (size_t size)
- {
- struct mem_block *res;
-
- /* guarantee long sizes (so we can use CopyMemQuick in realloc) */
- size = (size + 3) & ~3;
-
- /* include management information */
- res = (struct mem_block *) AllocMem (size + sizeof (struct mem_block), 0); /* not MEMF_PUBLIC ! */
-
- if (res)
- {
- u_int *lp = &res->size;
- *lp++ = size;
- *lp++ = MAGIC1; *lp++ = MAGIC1;
- lp = (u_int *)((u_char *)lp + size);
- *lp++ = MAGIC2;
-
- Forbid ();
- AddTail ((struct List *) &mem_list, (struct Node *) res);
- Permit ();
-
- DP(("malloc (%ld) = $%lx.\n",size,&res->realblock));
-
- mem_used += size;
- return &res->realblock;
- }
-
- return 0;
- }
-
- void *
- memalign (size_t alignment, size_t size)
- {
- u_char *p = (u_char *) malloc (size + alignment + sizeof (struct memalign_ptr));
- struct memalign_ptr *al_start;
-
- if (! p)
- return p;
-
- /* if the block is already aligned right, just return it */
- if (! ((u_int)p & (alignment - 1)))
- return p;
-
- /* else find the start of the aligned block in our larger block */
- al_start = (struct memalign_ptr *)(((u_int)p + alignment - 1) & -alignment);
-
- /* this could be problematic on 68000, when an odd alignment is requested,
- * should I just don't allow odd alignments?? */
- al_start[-1].magic = MEMALIGN_MAGIC;
- al_start[-1].alignment = (u_char *)al_start - p;
-
- DP(("memalign (%ld, %ld) = $%lx. real = $%lx, magic = $%lx.\n", alignment, size,
- al_start, p, al_start[-1]));
-
- return al_start;
- }
-
- void *
- valloc (size_t size)
- {
- return (void *) memalign (PAGESIZE, size);
- }
-
- void
- free (void *mem)
- {
- struct mem_block *block;
- u_int *end_magic;
-
- /* this seems to be standard... don't like it though ! */
- if (! mem)
- return;
-
- block = (struct mem_block *)((u_char *)mem - offsetof (struct mem_block, realblock));
-
- DP(("free ($%lx). block = $%lx, ", mem, block));
-
- if (((struct memalign_ptr *)mem - 1)->magic == MEMALIGN_MAGIC)
- {
- block = (struct mem_block *)
- ((u_char *)block - ((struct memalign_ptr *)mem - 1)->alignment);
- DP(("-> block = $%lx, ", block));
- }
-
- DP(("size = %ld\n", block->size));
-
-
- if (((u_int)block & 1) ||
- (block->magic[0] != MAGIC1 || block->magic[1] != MAGIC1))
- {
- DP((" m1 = $%lx, m2 = $%lx.\n", block->magic[0], block->magic[1]));
- ix_panic ("free: start of block corrupt!");
- syscall (SYS_exit, 20);
- }
-
- end_magic = (u_int *)((u_char *)&block->realblock + block->size);
- if (end_magic[0] != MAGIC2)
- {
- DP((" endmagic1 = $%lx, endmagic2 = $%lx.\n", end_magic[0], end_magic[1]));
- ix_panic ("free: end of block corrupt!");
- syscall (SYS_exit, 20);
- }
-
- Forbid ();
- Remove ((struct Node *) block);
- Permit ();
-
- mem_used -= block->size;
- FreeMem (block, block->size + sizeof (struct mem_block));
- }
-
-
- void
- all_free ()
- {
- struct mem_block *b, *nb;
-
- DP(("all_free'ing.. "));
- for (b = (struct mem_block *) mem_list.mlh_Head;
- nb = b->next;
- b = nb)
- {
- FreeMem (b, b->size + sizeof (struct mem_block));
- #ifdef DEBUG
- mem_used -= b->size;
- #endif
- }
-
- #ifdef DEBUG
- if (mem_used != 0)
- kprintf ("\aALL_FREE: $%lx bytes not freed!\n", mem_used);
- #endif
-
- /* this makes it possible to call all_free() more than once */
- NewList ((struct List *) &mem_list);
- DP(("done\n"));
- }
-
- void *
- realloc (void *mem, size_t size)
- {
- struct mem_block *block;
- u_int *end_magic;
- void *res;
-
- if (! mem)
- return (void *) malloc (size);
-
- block = (struct mem_block *)((u_char *)mem - offsetof (struct mem_block, realblock));
-
- DP(("realloc ($%lx, %ld). block = $%lx, ", mem, size, block));
-
- /* duplicate the code in free() here so we don't have to check those magic
- * numbers twice */
-
- if (((struct memalign_ptr *)mem - 1)->magic == MEMALIGN_MAGIC)
- {
- block = (struct mem_block *)
- ((u_char *)block - ((struct memalign_ptr *)mem - 1)->alignment);
- DP(("-> block = $%lx, ", block));
- }
-
- DP(("size = %ld\n", block->size));
-
- if (((u_int)block & 1) ||
- (block->magic[0] != MAGIC1 || block->magic[1] != MAGIC1))
- {
- DP((" magic1 = $%lx, magic2 = $%lx.\n", block->magic[0], block->magic[1]));
- ix_panic ("realloc: start of block corrupt!");
- syscall (SYS_exit, 20);
- }
-
- end_magic = (u_int *)((u_char *)&block->realblock + block->size);
- if (end_magic[0] != MAGIC2)
- {
- DP((" endmagic1 = $%lx. ", end_magic[0]));
- ix_panic ("realloc: end of block corrupt!");
- syscall (SYS_exit, 20);
- }
-
- /* now that the block is validated, check whether we have to really
- * realloc, or if we just can return the old block */
- if (block->size >= size)
- res = mem;
- else
- {
- res = (void *) malloc (size);
- if (res)
- {
- Forbid ();
- Remove ((struct Node *) block);
- Permit ();
-
- CopyMemQuick (mem, res, block->size);
-
- /* according to the manpage, the old buffer should only be
- * freed, if the allocation of the new buffer was successful */
- mem_used -= block->size;
- FreeMem (block, block->size + sizeof (struct mem_block));
- }
- }
-
- DP((" result = $%lx.\n", res));
- return res;
- }
- @
-
-
- 1.3
- log
- @add cast
- @
- text
- @d19 1
- a19 1
- * $Id: malloc.c,v 1.2 1992/05/22 01:43:07 mwild Exp $
- d22 3
- d56 5
- d65 2
- a66 2
- u_int realblock[2];
- /* realblock should really be [0], and at the end we'd have a magic2[2] */
- d96 1
- a96 1
- *lp++ = MAGIC2; *lp = MAGIC2;
- d177 1
- a177 1
- if (end_magic[0] != MAGIC2 || end_magic[1] != MAGIC2)
- d254 1
- a254 1
- if (end_magic[0] != MAGIC2 || end_magic[1] != MAGIC2)
- d256 1
- a256 1
- DP((" endmagic1 = $%lx, endmagic2 = $%lx. ", end_magic[0], end_magic[1]));
- @
-
-
- 1.2
- log
- @use buddy-alloc memory management
- @
- text
- @d19 1
- a19 1
- * $Id: malloc.c,v 1.1 1992/05/14 19:55:40 mwild Exp $
- d22 3
- d47 2
- a48 2
- #define mem_list (u.u_md.md_list)
- #define mem_used (u.u_md.md_malloc_sbrk_used)
- d80 1
- a80 1
- res = AllocMem (size + sizeof (struct mem_block), 0); /* not MEMF_PUBLIC ! */
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d19 1
- a19 1
- * $Id$
- d21 4
- a24 1
- * $Log$
- d39 5
- d103 1
- a103 2
- u_char *p = (u_char *)syscall (SYS_malloc,
- size + alignment + sizeof (struct memalign_ptr));
- d130 1
- a130 1
- return (void *) syscall (SYS_memalign, PAGESIZE, size);
- d191 6
- a196 1
- FreeMem (b, b->size + sizeof (struct mem_block));
- d198 5
- d216 1
- a216 1
- return (void *) syscall (SYS_malloc, size);
- d256 1
- a256 5
- Forbid ();
- Remove ((struct Node *) block);
- Permit ();
-
- res = (void *) syscall (SYS_malloc, size);
- d259 4
- @
-