From b5679818431e5a70f3c402342e9fc0f9697626b5 Mon Sep 17 00:00:00 2001 From: beveloper Date: Mon, 3 May 2004 23:29:46 +0000 Subject: [PATCH] A simple memory pool that is used the the mbuf support. Can be called from within an interrupt handler, and wastes pretty much memory. Knows only about two different block sizes, and implements them by using a simple free list. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7398 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/network/ipro1000/mempool.c | 143 ++++++++++++++++++ .../kernel/drivers/network/ipro1000/mempool.h | 16 ++ 2 files changed, 159 insertions(+) create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/mempool.c create mode 100644 src/add-ons/kernel/drivers/network/ipro1000/mempool.h diff --git a/src/add-ons/kernel/drivers/network/ipro1000/mempool.c b/src/add-ons/kernel/drivers/network/ipro1000/mempool.c new file mode 100644 index 0000000000..1cdacafd45 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/mempool.c @@ -0,0 +1,143 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#include +#include +#include "mempool.h" +#include "if_compat.h" +#include "debug.h" + +spinlock pool_lock = 0; + +void *mbuf_pool = 0; +void *chunk_pool = 0; + +void *mbuf_head = 0; +void *chunk_head = 0; + +void * +area_malloc(int size) +{ + void *p; + size = (size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1); + + if (create_area("area_malloc", &p, B_ANY_KERNEL_ADDRESS, size, B_FULL_LOCK,0) < 0) + return 0; + return p; +} + +void +area_free(void *p) +{ + delete_area(area_for(p)); +} + +int +mempool_init(int count) +{ + int chunk_size = 2048; + int mbuf_size = (sizeof(struct mbuf) + 15) & ~15; + + int chunk_alloc_size = chunk_size * (count + 1); + int mbuf_alloc_size = mbuf_size * (count + 1); + + char *chunk_base; + char *mbuf_base; + + int i; + + TRACE("chunk_size %d, mbuf_size %d\n", chunk_size, mbuf_size); + TRACE("chunk_alloc_size %d, mbuf_alloc_size %d\n", chunk_alloc_size, mbuf_alloc_size); + + chunk_pool = area_malloc(chunk_alloc_size); + if (!chunk_pool) { + TRACE("failed to allocate chunk storage of %d bytes\n", chunk_alloc_size); + return -1; + } + mbuf_pool = area_malloc(mbuf_alloc_size); + if (!mbuf_pool) { + TRACE("failed to allocate mbuf storage of %d bytes\n", mbuf_alloc_size); + area_free(chunk_pool); + return -1; + } + + chunk_base = (char *)(((unsigned long)chunk_pool + 2047) & ~2047); + mbuf_base = (char *)(((unsigned long)mbuf_pool + 15) & ~15); + + for (i = 0; i < count; i++) { + chunk_pool_put(chunk_base + i * chunk_size); + mbuf_pool_put(mbuf_base + i * mbuf_size); + } + + TRACE("mempool init success\n"); + return 0; +} + +void +mempool_exit() +{ + area_free(chunk_pool); + area_free(mbuf_pool); +} + +void * +mbuf_pool_get() +{ + void *p; + cpu_status s; + s = disable_interrupts(); + acquire_spinlock(&pool_lock); + + p = mbuf_head; + if (p) + mbuf_head = *(void **)p; + + release_spinlock(&pool_lock); + restore_interrupts(s); + return p; +} + +void +mbuf_pool_put(void *p) +{ + cpu_status s; + s = disable_interrupts(); + acquire_spinlock(&pool_lock); + + *(void **)p = mbuf_head; + mbuf_head = p; + + release_spinlock(&pool_lock); + restore_interrupts(s); +} + +void * +chunk_pool_get() +{ + void *p; + cpu_status s; + s = disable_interrupts(); + acquire_spinlock(&pool_lock); + + p = chunk_head; + if (p) + chunk_head = *(void **)p; + + release_spinlock(&pool_lock); + restore_interrupts(s); + return p; +} + +void +chunk_pool_put(void *p) +{ + cpu_status s; + s = disable_interrupts(); + acquire_spinlock(&pool_lock); + + *(void **)p = chunk_head; + chunk_head = p; + + release_spinlock(&pool_lock); + restore_interrupts(s); +} diff --git a/src/add-ons/kernel/drivers/network/ipro1000/mempool.h b/src/add-ons/kernel/drivers/network/ipro1000/mempool.h new file mode 100644 index 0000000000..c2019c4f61 --- /dev/null +++ b/src/add-ons/kernel/drivers/network/ipro1000/mempool.h @@ -0,0 +1,16 @@ +/* Intel PRO/1000 Family Driver + * Copyright (C) 2004 Marcus Overhagen . All rights reserved. + */ +#ifndef __MEMPOOL_H +#define __MEMPOOL_H + +int mempool_init(int count); +void mempool_exit(); + +void *mbuf_pool_get(); +void *chunk_pool_get(); + +void chunk_pool_put(void *p); +void mbuf_pool_put(void *p); + +#endif