voron

experimental ARM OS
git clone git://git.2f30.org/voron
Log | Files | Refs | README | LICENSE

pool.c (2242B)


      1 #include <kernel.h>
      2 #include <mmu.h>
      3 #include <alloc.h>
      4 #include <spinlock.h>
      5 #include <pool.h>
      6 
      7 enum item_state {
      8 	ITEM_UNUSED,
      9 	ITEM_USED,
     10 };
     11 
     12 struct item {
     13 	item_id id;
     14 	void *mem;
     15 	size_t siz;
     16 	enum item_state state;
     17 };
     18 
     19 struct pool {
     20 	struct item *item;
     21 	size_t siz;
     22 	spinlock_t lock;
     23 };
     24 
     25 static int ndebug = 0;
     26 
     27 struct pool *
     28 init_pool(void)
     29 {
     30 	struct pool *pool;
     31 
     32 	pool = kmalloc(sizeof(struct pool));
     33 	if (!pool)
     34 		return NULL;
     35 	pool->item = NULL;
     36 	pool->siz = 0;
     37 	spinlock_init(&pool->lock);
     38 	return pool;
     39 }
     40 
     41 void
     42 free_pool(struct pool *pool)
     43 {
     44 	struct item *item;
     45 	size_t i;
     46 
     47 	for (i = 0; i < pool->siz; i++) {
     48 		item = &pool->item[i];
     49 		kfree(item->mem);
     50 	}
     51 	kfree(pool->item);
     52 	kfree(pool);
     53 }
     54 
     55 /* Allocate an item in the pool of size `n' with `id'.
     56  * If there is an unused item of sufficient size with the same
     57  * `id' then it will be re-used. */
     58 void *
     59 alloc_item(struct pool *pool, size_t n, item_id id)
     60 {
     61 	struct item *tmp;
     62 	struct item *item;
     63 	size_t i;
     64 
     65 	spinlock_lock(&pool->lock);
     66 	for (i = 0; i < pool->siz; i++) {
     67 		item = &pool->item[i];
     68 		if (item->id == id) {
     69 			if (ndebug > 0)
     70 				kprintf("Found possible unused item: %d\n", item->id);
     71 			if (item->state == ITEM_UNUSED && item->siz >= n) {
     72 				if (ndebug > 0)
     73 					kprintf("Found unused item: %d of size %zu bytes\n",
     74 						item->id, item->siz);
     75 				item->state = ITEM_USED;
     76 				spinlock_unlock(&pool->lock);
     77 				return item->mem;
     78 			}
     79 		}
     80 	}
     81 
     82 	if (ndebug > 0)
     83 		kprintf("Allocating new item: %d of size %zu bytes\n",
     84 			id, n);
     85 
     86 	tmp = krealloc(pool->item, sizeof(struct item) * (pool->siz + 1));
     87 	if (!tmp)
     88 		panic("out of memory");
     89 	pool->item = tmp;
     90 	item = &pool->item[pool->siz];
     91 	item->id = id;
     92 	item->mem = kmalloc(n);
     93 	if (!item->mem)
     94 		panic("out of memory");
     95 	item->siz = n;
     96 	item->state = ITEM_USED;
     97 	pool->siz++;
     98 	spinlock_unlock(&pool->lock);
     99 	return item->mem;
    100 }
    101 
    102 /* Free all items with `id'.  This does not actually
    103  * free the underlying memory, it just marks those items
    104  * as unused. */
    105 void
    106 free_items(struct pool *pool, item_id id)
    107 {
    108 	struct item *item;
    109 	size_t i;
    110 
    111 	spinlock_lock(&pool->lock);
    112 	for (i = 0; i < pool->siz; i++) {
    113 		item = &pool->item[i];
    114 		if (item->id == id)
    115 			item->state = ITEM_UNUSED;
    116 	}
    117 	spinlock_unlock(&pool->lock);
    118 }