arena.c
资源名称:c.rar [点击查看]
上传用户:shmaik
上传日期:2014-06-01
资源大小:45093k
文件大小:2k
源码类别:

VC书籍

开发平台:

C/C++

  1. static char rcsid[] = "$Id: H:/drh/idioms/book/RCS/arena.doc,v 1.10 1997/02/21 19:45:19 drh Exp $";
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include "assert.h"
  5. #include "except.h"
  6. #include "arena.h"
  7. #define T Arena_T
  8. const Except_T Arena_NewFailed =
  9. { "Arena Creation Failed" };
  10. const Except_T Arena_Failed    =
  11. { "Arena Allocation Failed" };
  12. #define THRESHOLD 10
  13. struct T {
  14. T prev;
  15. char *avail;
  16. char *limit;
  17. };
  18. union align {
  19. #ifdef MAXALIGN
  20. char pad[MAXALIGN];
  21. #else
  22. int i;
  23. long l;
  24. long *lp;
  25. void *p;
  26. void (*fp)(void);
  27. float f;
  28. double d;
  29. long double ld;
  30. #endif
  31. };
  32. union header {
  33. struct T b;
  34. union align a;
  35. };
  36. static T freechunks;
  37. static int nfree;
  38. T Arena_new(void) {
  39. T arena = malloc(sizeof (*arena));
  40. if (arena == NULL)
  41. RAISE(Arena_NewFailed);
  42. arena->prev = NULL;
  43. arena->limit = arena->avail = NULL;
  44. return arena;
  45. }
  46. void Arena_dispose(T *ap) {
  47. assert(ap && *ap);
  48. Arena_free(*ap);
  49. free(*ap);
  50. *ap = NULL;
  51. }
  52. void *Arena_alloc(T arena, long nbytes,
  53. const char *file, int line) {
  54. assert(arena);
  55. assert(nbytes > 0);
  56. nbytes = ((nbytes + sizeof (union align) - 1)/
  57. (sizeof (union align)))*(sizeof (union align));
  58. while (nbytes > arena->limit - arena->avail) {
  59. T ptr;
  60. char *limit;
  61. if ((ptr = freechunks) != NULL) {
  62. freechunks = freechunks->prev;
  63. nfree--;
  64. limit = ptr->limit;
  65. } else {
  66. long m = sizeof (union header) + nbytes + 10*1024;
  67. ptr = malloc(m);
  68. if (ptr == NULL)
  69. {
  70. if (file == NULL)
  71. RAISE(Arena_Failed);
  72. else
  73. Except_raise(&Arena_Failed, file, line);
  74. }
  75. limit = (char *)ptr + m;
  76. }
  77. *ptr = *arena;
  78. arena->avail = (char *)((union header *)ptr + 1);
  79. arena->limit = limit;
  80. arena->prev  = ptr;
  81. }
  82. arena->avail += nbytes;
  83. return arena->avail - nbytes;
  84. }
  85. void *Arena_calloc(T arena, long count, long nbytes,
  86. const char *file, int line) {
  87. void *ptr;
  88. assert(count > 0);
  89. ptr = Arena_alloc(arena, count*nbytes, file, line);
  90. memset(ptr, '', count*nbytes);
  91. return ptr;
  92. }
  93. void Arena_free(T arena) {
  94. assert(arena);
  95. while (arena->prev) {
  96. struct T tmp = *arena->prev;
  97. if (nfree < THRESHOLD) {
  98. arena->prev->prev = freechunks;
  99. freechunks = arena->prev;
  100. nfree++;
  101. freechunks->limit = arena->limit;
  102. } else
  103. free(arena->prev);
  104. *arena = tmp;
  105. }
  106. assert(arena->limit == NULL);
  107. assert(arena->avail == NULL);
  108. }