- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# lib/mempool.c

Go to the documentation of this file.

    00001
    00057 #include <assert.h>
    00058 #include <debug.h>
    00059 #include <interrupt.h>
    00060 #include <mempool.h>
    00061 #include <physmem.h>
    00062 #include <util.h>
    00063
    00064 struct mem_pool_object {
    00065         struct mem_pool_object  *next;
    00066 };
    00067
    00088 void mem_pool_init(struct mem_pool *pool, void *start, size_t size,
    00089                 size_t objsize, unsigned int align_order)
    00090 {
    00091         struct mem_pool_object  *obj;
    00092         struct mem_pool_object  *prev_obj;
    00093         void                    *aligned_start;
    00094         unsigned int            offset;
    00095
    00096         assert(pool);
    00097         assert(start);
    00098         assert((unsigned long)start + size > (unsigned long)start);
    00099
    00100         aligned_start = (void *)round_up((unsigned long)start, align_order);
    00101         size -= ((unsigned long)aligned_start - (unsigned long)start);
    00102         objsize = round_up(objsize, align_order);
    00103
    00104         assert(objsize >= sizeof(struct mem_pool_object));
    00105         assert(size >= objsize);
    00106
    00107         prev_obj = aligned_start;
    00108         pool->freelist = prev_obj;
    00109
    00110         for (offset = objsize; (offset + objsize) <= size; offset += objsize) {
    00111                 obj = aligned_start + offset;
    00112                 prev_obj->next = obj;
    00113                 prev_obj = obj;
    00114         }
    00115         obj->next = NULL;
    00116
    00117         dbg_printf("mempool @ %p initialized with %lu objects of size %lu\n",
    00118                         start, size / objsize, objsize);
    00119 }
    00120
    00139 void mem_pool_init_physmem(struct mem_pool *mempool,
    00140                 struct physmem_pool *phys_pool, unsigned int nr_objects,
    00141                 size_t objsize, unsigned int align_order)
    00142 {
    00143         phys_addr_t     pool_addr;
    00144         size_t          pool_size;
    00145         size_t          block_size;
    00146         void            *pool_vaddr;
    00147
    00148         assert(mempool);
    00149         assert(phys_pool);
    00150         assert(nr_objects > 0);
    00151
    00152         block_size = round_up(objsize, align_order);
    00153         pool_size = nr_objects * block_size;
    00154
    00155         pool_addr = physmem_alloc(phys_pool, pool_size, align_order);
    00156         assert(pool_addr != PHYSMEM_ALLOC_ERR);
    00157
    00158         pool_vaddr = physmem_map(pool_addr, pool_size,
    00159                         PHYS_MAP_WRBUF | PHYS_MAP_WRBACK);
    00160         mem_pool_init(mempool, pool_vaddr, pool_size, objsize, align_order);
    00161 }
    00162
    00170 void *mem_pool_alloc(struct mem_pool *pool)
    00171 {
    00172         struct mem_pool_object  *obj;
    00173         unsigned long           iflags;
    00174
    00175         assert(pool);
    00176
    00177         iflags = cpu_irq_save();
    00178         obj = pool->freelist;
    00179         if (obj)
    00180                 pool->freelist = obj->next;
    00181         cpu_irq_restore(iflags);
    00182
    00183         return obj;
    00184 }
    00185
    00202 void mem_pool_free(struct mem_pool *pool, const void *obj)
    00203 {
    00204         struct mem_pool_object  *free_obj;
    00205         unsigned long           iflags;
    00206
    00207         assert(pool);
    00208
    00209         if (!obj)
    00210                 return;
    00211
    00212         free_obj = (struct mem_pool_object *)obj;
    00213
    00214         iflags = cpu_irq_save();
    00215         free_obj->next = pool->freelist;
    00216         pool->freelist = free_obj;
    00217         cpu_irq_restore(iflags);
    00218 }