Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * on the rights to use, copy, modify, merge, publish, distribute, sub
  8.  * license, and/or sell copies of the Software, and to permit persons to whom
  9.  * the Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  18.  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  19.  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  20.  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  21.  * USE OR OTHER DEALINGS IN THE SOFTWARE. */
  22.  
  23. #include "memory_pool.h"
  24.  
  25. #include <assert.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29.  
  30. #define POOL_LARGE_ALLOC 4096
  31. #define POOL_ALIGN 8
  32.  
  33.  
  34. struct memory_block {
  35.         struct memory_block * next;
  36. };
  37.  
  38. void memory_pool_init(struct memory_pool * pool)
  39. {
  40.         memset(pool, 0, sizeof(struct memory_pool));
  41. }
  42.  
  43.  
  44. void memory_pool_destroy(struct memory_pool * pool)
  45. {
  46.         while(pool->blocks) {
  47.                 struct memory_block * block = pool->blocks;
  48.                 pool->blocks = block->next;
  49.                 free(block);
  50.         }
  51. }
  52.  
  53. static void refill_pool(struct memory_pool * pool)
  54. {
  55.         unsigned int blocksize = pool->total_allocated;
  56.         struct memory_block * newblock;
  57.  
  58.         if (!blocksize)
  59.                 blocksize = 2*POOL_LARGE_ALLOC;
  60.  
  61.         newblock = malloc(blocksize);
  62.         newblock->next = pool->blocks;
  63.         pool->blocks = newblock;
  64.  
  65.         pool->head = (unsigned char*)(newblock + 1);
  66.         pool->end = ((unsigned char*)newblock) + blocksize;
  67.         pool->total_allocated += blocksize;
  68. }
  69.  
  70.  
  71. void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes)
  72. {
  73.         if (bytes < POOL_LARGE_ALLOC) {
  74.                 void * ptr;
  75.  
  76.                 if (pool->head + bytes > pool->end)
  77.                         refill_pool(pool);
  78.  
  79.                 assert(pool->head + bytes <= pool->end);
  80.  
  81.                 ptr = pool->head;
  82.  
  83.                 pool->head += bytes;
  84.                 pool->head = (unsigned char*)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
  85.  
  86.                 return ptr;
  87.         } else {
  88.                 struct memory_block * block = malloc(bytes + sizeof(struct memory_block));
  89.  
  90.                 block->next = pool->blocks;
  91.                 pool->blocks = block;
  92.  
  93.                 return (block + 1);
  94.         }
  95. }
  96.  
  97.  
  98.