PageRenderTime 39ms CodeModel.GetById 12ms RepoModel.GetById 0ms 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. #include "wad.h"
  32. static char cvs[] = "$Header$";
  33. typedef struct _WadMemory {
  34. int npages; /* Number of pages */
  35. int last; /* Last offset in page */
  36. struct _WadMemory *next; /* Pointer to next allocation */
  37. } WadMemory;
  38. static WadMemory *current = 0; /* Current memory block */
  39. static int pagesize = 0; /* System page size */
  40. static int devzero = 0;
  41. static int npalloc = 8; /* Number of pages per alloc */
  42. /* -----------------------------------------------------------------------------
  43. * wad_memory_init()
  44. *
  45. * Initialize the WAD allocator.
  46. * ----------------------------------------------------------------------------- */
  47. int wad_memory_init() {
  48. pagesize = getpagesize();
  49. devzero = open("/dev/zero", O_RDWR);
  50. if (devzero < 0) {
  51. wad_printf("WAD: couldn't open /dev/zero.\n");
  52. return -1;
  53. }
  54. return 0;
  55. }
  56. /* -----------------------------------------------------------------------------
  57. * wad_page_alloc()
  58. *
  59. * Allocate pages using mmap
  60. * ----------------------------------------------------------------------------- */
  61. void *wad_page_alloc(int npages) {
  62. void *m;
  63. m = mmap(NULL, npages*pagesize, PROT_READ | PROT_WRITE, MAP_PRIVATE, devzero, 0);
  64. if (((long) m) == -1) return 0;
  65. /* printf("page_alloc: %x - %x\n", m, ((char *) m) + npages*pagesize); */
  66. return m;
  67. }
  68. /* -----------------------------------------------------------------------------
  69. * wad_malloc()
  70. *
  71. * Allocate memory using mmap(). If the allocation is smaller than half a page,
  72. * We'll look at current to see if there is enough space. If so, we'll just
  73. * use that memory. Otherwise, we'll allocate a new page. If the allocation
  74. * request is larger than a page, we'll round up to the nearest page size and
  75. * do a special allocation.
  76. * ----------------------------------------------------------------------------- */
  77. void *wad_malloc(int nbytes) {
  78. void *ptr;
  79. WadMemory *wm;
  80. char *c;
  81. int npages;
  82. /* wad_printf("wad_malloc: %d\n", nbytes); */
  83. if (nbytes >= ((npalloc*pagesize) >> 2)) {
  84. /* Large allocation. */
  85. npages = ((nbytes + sizeof(WadMemory))/pagesize) + 1;
  86. ptr = wad_page_alloc(npages);
  87. if (!ptr) return 0;
  88. wm = (WadMemory *)ptr;
  89. wm->npages = npages;
  90. wm->last = sizeof(WadMemory) + 8;
  91. wm->next = current;
  92. current = wm;
  93. c = (char *) current + (current->last);
  94. current->last += ((nbytes & ~0x7) + 8);
  95. return c;
  96. }
  97. /* Small allocation. See if there are any regions big enough */
  98. wm = current;
  99. while (wm) {
  100. if (((wm->npages*pagesize) - wm->last) > nbytes) {
  101. /* Yep. Found a region */
  102. break;
  103. }
  104. wm = wm->next;
  105. }
  106. if (!wm) {
  107. /* wad_printf("wad_malloc: new page\n", nbytes);*/
  108. wm = (WadMemory *) wad_page_alloc(npalloc);
  109. if (!wm) return 0;
  110. wm->npages = npalloc;
  111. wm->last = sizeof(WadMemory) + 8;
  112. wm->next = current;
  113. current = wm;
  114. }
  115. c = ((char *) wm) + (wm->last);
  116. wm->last += ((nbytes & ~0x7) + 8);
  117. return c;
  118. }
  119. /* -----------------------------------------------------------------------------
  120. * wad_strdup()
  121. *
  122. * Duplicate a string
  123. * ----------------------------------------------------------------------------- */
  124. char *wad_strdup(const char *c) {
  125. char *t;
  126. if (!c) c = "";
  127. t = (char *) wad_malloc(strlen(c)+1);
  128. wad_strcpy(t,c);
  129. return t;
  130. }
  131. /* -----------------------------------------------------------------------------
  132. * wad_memcpy()
  133. * ----------------------------------------------------------------------------- */
  134. void wad_memcpy(void *t, const void *s, unsigned len) {
  135. char *tc, *sc;
  136. int i;
  137. tc = (char *) t;
  138. sc = (char *) s;
  139. for (i = 0; i < len; i++, tc++, sc++)
  140. *tc = *sc;
  141. }
  142. /* -----------------------------------------------------------------------------
  143. * wad_memory_debug()
  144. * ----------------------------------------------------------------------------- */
  145. void wad_memory_debug() {
  146. int total_alloc = 0;
  147. int inuse = 0;
  148. WadMemory *m;
  149. if (wad_debug_mode & DEBUG_MEMORY) {
  150. m = current;
  151. while (m) {
  152. total_alloc += (m->npages)*pagesize;
  153. inuse += m->last;
  154. m = m->next;
  155. }
  156. wad_printf("WAD: memory allocated %d bytes (%d bytes used).\n", total_alloc, inuse);
  157. }
  158. }