THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

146 lines
3.1KB

  1. /*
  2. * Memory Pool implementation logic.
  3. */
  4. #include "cache.h"
  5. #include "mem-pool.h"
  6. #define BLOCK_GROWTH_SIZE 1024*1024 - sizeof(struct mp_block);
  7. /*
  8. * Allocate a new mp_block and insert it after the block specified in
  9. * `insert_after`. If `insert_after` is NULL, then insert block at the
  10. * head of the linked list.
  11. */
  12. static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc, struct mp_block *insert_after)
  13. {
  14. struct mp_block *p;
  15. mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
  16. p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
  17. p->next_free = (char *)p->space;
  18. p->end = p->next_free + block_alloc;
  19. if (insert_after) {
  20. p->next_block = insert_after->next_block;
  21. insert_after->next_block = p;
  22. } else {
  23. p->next_block = mem_pool->mp_block;
  24. mem_pool->mp_block = p;
  25. }
  26. return p;
  27. }
  28. void mem_pool_init(struct mem_pool **mem_pool, size_t initial_size)
  29. {
  30. struct mem_pool *pool;
  31. if (*mem_pool)
  32. return;
  33. pool = xcalloc(1, sizeof(*pool));
  34. pool->block_alloc = BLOCK_GROWTH_SIZE;
  35. if (initial_size > 0)
  36. mem_pool_alloc_block(pool, initial_size, NULL);
  37. *mem_pool = pool;
  38. }
  39. void mem_pool_discard(struct mem_pool *mem_pool, int invalidate_memory)
  40. {
  41. struct mp_block *block, *block_to_free;
  42. block = mem_pool->mp_block;
  43. while (block)
  44. {
  45. block_to_free = block;
  46. block = block->next_block;
  47. if (invalidate_memory)
  48. memset(block_to_free->space, 0xDD, ((char *)block_to_free->end) - ((char *)block_to_free->space));
  49. free(block_to_free);
  50. }
  51. free(mem_pool);
  52. }
  53. void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
  54. {
  55. struct mp_block *p = NULL;
  56. void *r;
  57. /* round up to a 'uintmax_t' alignment */
  58. if (len & (sizeof(uintmax_t) - 1))
  59. len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
  60. if (mem_pool->mp_block &&
  61. mem_pool->mp_block->end - mem_pool->mp_block->next_free >= len)
  62. p = mem_pool->mp_block;
  63. if (!p) {
  64. if (len >= (mem_pool->block_alloc / 2))
  65. return mem_pool_alloc_block(mem_pool, len, mem_pool->mp_block);
  66. p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc, NULL);
  67. }
  68. r = p->next_free;
  69. p->next_free += len;
  70. return r;
  71. }
  72. void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size)
  73. {
  74. size_t len = st_mult(count, size);
  75. void *r = mem_pool_alloc(mem_pool, len);
  76. memset(r, 0, len);
  77. return r;
  78. }
  79. int mem_pool_contains(struct mem_pool *mem_pool, void *mem)
  80. {
  81. struct mp_block *p;
  82. /* Check if memory is allocated in a block */
  83. for (p = mem_pool->mp_block; p; p = p->next_block)
  84. if ((mem >= ((void *)p->space)) &&
  85. (mem < ((void *)p->end)))
  86. return 1;
  87. return 0;
  88. }
  89. void mem_pool_combine(struct mem_pool *dst, struct mem_pool *src)
  90. {
  91. struct mp_block *p;
  92. /* Append the blocks from src to dst */
  93. if (dst->mp_block && src->mp_block) {
  94. /*
  95. * src and dst have blocks, append
  96. * blocks from src to dst.
  97. */
  98. p = dst->mp_block;
  99. while (p->next_block)
  100. p = p->next_block;
  101. p->next_block = src->mp_block;
  102. } else if (src->mp_block) {
  103. /*
  104. * src has blocks, dst is empty.
  105. */
  106. dst->mp_block = src->mp_block;
  107. } else {
  108. /* src is empty, nothing to do. */
  109. }
  110. dst->pool_alloc += src->pool_alloc;
  111. src->pool_alloc = 0;
  112. src->mp_block = NULL;
  113. }