diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-01-03 09:39:16 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-01-03 09:39:16 +0100 |
commit | 2071c5dcfb59d592bf37f190c92eb3bd8eeb2cb9 (patch) | |
tree | 53d0771b3d487d342d150e54d7174c13ce392588 /common | |
parent | a135624e2769c87ebb0125821d8427edd5ad9fb4 (diff) | |
parent | c09fdea2c0f7fd4c27b029a3c4b76bb161f63dca (diff) | |
download | barebox-2071c5dcfb59d592bf37f190c92eb3bd8eeb2cb9.tar.gz barebox-2071c5dcfb59d592bf37f190c92eb3bd8eeb2cb9.tar.xz |
Merge branch 'pu/tlsf' into next
Diffstat (limited to 'common')
-rw-r--r-- | common/tlsf.c | 17 | ||||
-rw-r--r-- | common/tlsf_malloc.c | 25 | ||||
-rw-r--r-- | common/tlsfbits.h | 55 |
3 files changed, 85 insertions, 12 deletions
diff --git a/common/tlsf.c b/common/tlsf.c index b3de9765c4..c810e8dafe 100644 --- a/common/tlsf.c +++ b/common/tlsf.c @@ -1,20 +1,17 @@ -#ifndef __BAREBOX__ -#include <assert.h> -#include <limits.h> -#endif #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <linux/stringify.h> #include "tlsf.h" #include "tlsfbits.h" -#ifdef __BAREBOX__ -#ifndef _DEBUG -#define _DEBUG 0 -#endif -#define tlsf_assert(expr) ((void) (0)) +#ifdef DEBUG +#define tlsf_assert(expr) \ + ((expr) ? (void)(0) : printf("%s\n", __stringify(expr))) +#else +#define tlsf_assert(expr) (void)(0) #endif /* @@ -759,7 +756,7 @@ tlsf_pool tlsf_create(void* mem, size_t bytes) const size_t pool_bytes = align_down(bytes - pool_overhead, ALIGN_SIZE); pool_t* pool = tlsf_cast(pool_t*, mem); -#if _DEBUG +#ifdef DEBUG /* Verify ffs/fls work properly. */ int rv = 0; rv += (tlsf_ffs(0) == -1) ? 0 : 0x1; diff --git a/common/tlsf_malloc.c b/common/tlsf_malloc.c index a6f82ba58d..2fe443bf2b 100644 --- a/common/tlsf_malloc.c +++ b/common/tlsf_malloc.c @@ -71,8 +71,29 @@ void *memalign(size_t alignment, size_t bytes) } EXPORT_SYMBOL(memalign); -#ifdef CONFIG_CMD_MEMINFO +struct malloc_stats { + size_t free; + size_t used; +}; + +static void malloc_walker(void* ptr, size_t size, int used, void *user) +{ + struct malloc_stats *s = user; + + if (used) + s->used += size; + else + s->free += size; +} + void malloc_stats(void) { + struct malloc_stats s; + + s.used = 0; + s.free = 0; + + tlsf_walk_heap(tlsf_mem_pool, malloc_walker, &s); + + printf("used: %10d\nfree: %10d\n", s.used, s.free); } -#endif /* CONFIG_CMD_MEMINFO */ diff --git a/common/tlsfbits.h b/common/tlsfbits.h new file mode 100644 index 0000000000..93466e46a8 --- /dev/null +++ b/common/tlsfbits.h @@ -0,0 +1,55 @@ +#ifndef INCLUDED_tlsfbits +#define INCLUDED_tlsfbits + +#include <linux/bitops.h> + +/* +** Architecture-specific bit manipulation routines. +** +** TLSF achieves O(1) cost for malloc and free operations by limiting +** the search for a free block to a free list of guaranteed size +** adequate to fulfill the request, combined with efficient free list +** queries using bitmasks and architecture-specific bit-manipulation +** routines. +** +** Most modern processors provide instructions to count leading zeroes +** in a word, find the lowest and highest set bit, etc. These +** specific implementations will be used when available, falling back +** to a reasonably efficient generic implementation. +** +** NOTE: TLSF spec relies on ffs/fls returning value 0..31. +** ffs/fls return 1-32 by default, returning 0 for error. +*/ + +static int tlsf_ffs(unsigned int word) +{ + return ffs(word) - 1; +} + +static int tlsf_fls(unsigned int word) +{ + return fls(word) - 1; +} + +/* Possibly 64-bit version of tlsf_fls. */ +#if defined (TLSF_64BIT) +tlsf_decl int tlsf_fls_sizet(size_t size) +{ + int high = (int)(size >> 32); + int bits = 0; + if (high) + { + bits = 32 + tlsf_fls(high); + } + else + { + bits = tlsf_fls((int)size & 0xffffffff); + + } + return bits; +} +#else +#define tlsf_fls_sizet tlsf_fls +#endif + +#endif |