PageRenderTime 12ms CodeModel.GetById 6ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/wad-0-2-1/SWIG/Tools/WAD/Wad/memory.c

#
C | 174 lines | 92 code | 16 blank | 66 comment | 13 complexity | 5a426c89cdffafe00844f5374cbfc1e2 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1/* ----------------------------------------------------------------------------- 
  2 * memory.c
  3 *
  4 *     This file provides simple mmap() based memory management for WAD.  Since
  5 *     the process heap-allocator might be corrupted when WAD is invoked, we
  6 *     have to do all of our own memory management.  However, since WAD mostly
  7 *     just collects data, we only provide the function wad_malloc().  To
  8 *     release all allocated memory, the wad_release_memory() function should
  9 *     be used.
 10 * 
 11 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
 12 *
 13 * Copyright (C) 2000.  The University of Chicago. 
 14 *
 15 * This library is free software; you can redistribute it and/or
 16 * modify it under the terms of the GNU Lesser General Public
 17 * License as published by the Free Software Foundation; either
 18 * version 2.1 of the License, or (at your option) any later version.
 19 *
 20 * This library is distributed in the hope that it will be useful,
 21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 23 * Lesser General Public License for more details.
 24 *
 25 * You should have received a copy of the GNU Lesser General Public
 26 * License along with this library; if not, write to the Free Software
 27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 28 * 
 29 * See the file COPYING for a complete copy of the LGPL.
 30 * ----------------------------------------------------------------------------- */
 31
 32#include "wad.h"
 33
 34static char cvs[] = "$Header$";
 35
 36typedef struct _WadMemory {
 37  int                npages;          /* Number of pages            */
 38  int                last;            /* Last offset in page        */ 
 39  struct _WadMemory *next;            /* Pointer to next allocation */
 40} WadMemory;
 41
 42static WadMemory *current = 0;                /* Current memory block        */
 43static int        pagesize = 0;               /* System page size            */
 44static int        devzero = 0;
 45static int        npalloc = 8;                 /* Number of pages per alloc   */
 46
 47/* -----------------------------------------------------------------------------
 48 * wad_memory_init()
 49 *
 50 * Initialize the WAD allocator.
 51 * ----------------------------------------------------------------------------- */
 52
 53int wad_memory_init() {
 54  pagesize = getpagesize();
 55  devzero = open("/dev/zero", O_RDWR);
 56  if (devzero < 0) {
 57    wad_printf("WAD: couldn't open /dev/zero.\n");
 58    return -1;
 59  }
 60  return 0;
 61}
 62
 63/* -----------------------------------------------------------------------------
 64 * wad_page_alloc()
 65 *
 66 * Allocate pages using mmap
 67 * ----------------------------------------------------------------------------- */
 68
 69void *wad_page_alloc(int npages) {
 70  void *m;
 71  m = mmap(NULL, npages*pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, devzero, 0);
 72  if (((long) m) == -1) return 0;
 73  /*  printf("page_alloc: %x - %x\n", m, ((char *) m) + npages*pagesize); */
 74  return m;
 75}
 76
 77/* -----------------------------------------------------------------------------
 78 * wad_malloc()
 79 *
 80 * Allocate memory using mmap().   If the allocation is smaller than half a page,
 81 * We'll look at current to see if there is enough space.  If so, we'll just
 82 * use that memory.  Otherwise, we'll allocate a new page.  If the allocation
 83 * request is larger than a page, we'll round up to the nearest page size and
 84 * do a special allocation.
 85 * ----------------------------------------------------------------------------- */
 86
 87void *wad_malloc(int nbytes) {
 88  void *ptr;
 89  WadMemory *wm;
 90  char      *c;
 91  int npages;
 92  /*  wad_printf("wad_malloc: %d\n", nbytes); */
 93  if (nbytes >= ((npalloc*pagesize) >> 2)) {
 94    /* Large allocation. */
 95    npages = ((nbytes + sizeof(WadMemory))/pagesize) + 1;
 96    ptr = wad_page_alloc(npages);
 97    if (!ptr) return 0;
 98    wm = (WadMemory *)ptr;
 99    wm->npages = npages;
100    wm->last = sizeof(WadMemory) + 8;
101    wm->next = current;
102    current = wm;
103    c = (char *) current + (current->last);
104    current->last += ((nbytes & ~0x7) + 8);
105    return c;
106  }
107  /* Small allocation.  See if there are any regions big enough */
108  wm = current;
109  while (wm) {
110    if (((wm->npages*pagesize) - wm->last) > nbytes) {
111      /* Yep. Found a region */
112      break;
113    }
114    wm = wm->next;
115  }
116  if (!wm) {
117    /*    wad_printf("wad_malloc: new page\n", nbytes);*/
118    wm = (WadMemory *) wad_page_alloc(npalloc);
119    if (!wm) return 0;
120    wm->npages = npalloc;
121    wm->last = sizeof(WadMemory) + 8;
122    wm->next = current;
123    current = wm;
124  }
125  c = ((char *) wm) + (wm->last);
126  wm->last += ((nbytes & ~0x7) + 8);
127  return c;
128}  
129
130/* -----------------------------------------------------------------------------
131 * wad_strdup()
132 *
133 * Duplicate a string 
134 * ----------------------------------------------------------------------------- */
135
136char *wad_strdup(const char *c) {
137  char *t;
138  if (!c) c = "";
139  t = (char *) wad_malloc(strlen(c)+1);
140  wad_strcpy(t,c);
141  return t;
142}
143
144/* -----------------------------------------------------------------------------
145 * wad_memcpy()
146 * ----------------------------------------------------------------------------- */
147
148void wad_memcpy(void *t, const void *s, unsigned len) {
149  char *tc, *sc;
150  int i;
151  tc = (char *) t;
152  sc = (char *) s;
153  for (i = 0; i < len; i++, tc++, sc++)
154    *tc = *sc;
155}
156
157/* -----------------------------------------------------------------------------
158 * wad_memory_debug()
159 * ----------------------------------------------------------------------------- */
160
161void wad_memory_debug() {
162  int   total_alloc = 0;
163  int   inuse = 0;
164  WadMemory *m;
165  if (wad_debug_mode & DEBUG_MEMORY) {
166    m = current;
167    while (m) {
168      total_alloc += (m->npages)*pagesize;
169      inuse += m->last;
170      m = m->next;
171    }
172    wad_printf("WAD: memory allocated %d bytes (%d bytes used).\n", total_alloc, inuse);
173  }
174}