/tags/Root-branch-php-utl/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}