memarena.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Public Domain.
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <sys/mman.h>
  7. #include "memarena.h"
  8. MemArena* MemArena_allocArena(size_t maxsize) {
  9. MemArena* ma;
  10. ma = calloc(1, sizeof(*ma));
  11. MemArena_initArena(ma, maxsize);
  12. return ma;
  13. }
  14. void MemArena_initArena(MemArena* ma, size_t maxSize) {
  15. ma->maxSize = maxSize;
  16. int flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE;
  17. ma->arena = mmap(NULL, maxSize, PROT_READ | PROT_WRITE, flags, 0, 0);
  18. if(ma->arena == MAP_FAILED) {
  19. fprintf(stderr, "mmap failed in %s: %s\n", __func__, strerror(errno));
  20. exit(1);
  21. }
  22. ma->top = ma->arena;
  23. }
  24. void MemArena_destroyArena(MemArena* ma) {
  25. munmap(ma->arena, ma->maxSize);
  26. ma->maxSize = 0;
  27. ma->arena = NULL;
  28. ma->top = NULL;
  29. }
  30. void MemArena_freeArena(MemArena* ma) {
  31. MemArena_destroyArena(ma);
  32. free(ma);
  33. }
  34. // ----------------------------------------
  35. void* MemArena_malloc(MemArena* ma, size_t size) {
  36. #ifndef STI_MEMARENA_NO_MALLOC_BOUNDS_CHECK
  37. if((char*)ma->top >= (char*)ma->arena + ma->maxSize + size) {
  38. fprintf(stderr, "MemArena overflowed size of %ld\n", ma->maxSize);
  39. return NULL;
  40. }
  41. #endif
  42. void* t = ma->top;
  43. ma->top = (char*)ma->top + size;
  44. #ifndef STI_MEMARENA_NO_HWM
  45. ma->hwm = (ma->hwm < ma->top) ? ma->top : ma->hwm;
  46. #endif
  47. return t;
  48. }
  49. void* MemArena_calloc(MemArena* ma, size_t size) {
  50. void* p = MemArena_malloc(ma, size);
  51. memset(p, 0, size);
  52. return p;
  53. }
  54. void* MemArena_alignedAlloc(MemArena* ma, size_t alignment, size_t size) {
  55. size_t t = (size_t)ma->top;
  56. size_t rem = t % alignment;
  57. size_t o = alignment - rem;
  58. void* p = (char*)ma->top + o;
  59. ma->top = (char*)p + size;
  60. return p;
  61. }
  62. // void* MemArena_realloc(MemArena* ma, size_t size) {
  63. //
  64. // }
  65. // zero on success, non-zero otherwise
  66. int MemArena_freeAfter(MemArena* ma, void* ptr) {
  67. // check to see if this pointer is inside the arena
  68. if(ptr < ma->arena) return 1;
  69. if(ptr >= ma->top) return 2;
  70. ma->top = ptr;
  71. return 0;
  72. }
  73. void MemArena_reset(MemArena* ma) {
  74. ma->top = ma->arena;
  75. ma->hwm = ma->arena;
  76. }
  77. size_t MemArena_getUsedSize(MemArena* ma) {
  78. return (size_t)ma->top - (size_t)ma->arena;
  79. }
  80. size_t MemArena_getFreeSize(MemArena* ma) {
  81. return ma->maxSize - ((size_t)ma->top - (size_t)ma->arena);
  82. }
  83. size_t MemArena_getHighWaterMark(MemArena* ma) {
  84. #ifndef STI_MEMARENA_NO_HWM
  85. return (size_t)ma->hwm - (size_t)ma->arena;
  86. #else
  87. return 0;
  88. #endif
  89. }