forked from len0rd/rockbox
Now memory-page and memory-misc compile fine (others are in stage-development)
Conventions : * Public headers : memory.h,config.h,defines.h,inlines.h,types.h,functions.h * Private headers : memory-page.h,memory-slab.h (here you can find prototypes functions or structures we want to share only between memory-page.c, memory-slab.c, memory-block.c, memory-misc.c). * Public or private codes in : memory-page.c,memory-slab.c,memory-block.c,memory-misc.c git-svn-id: svn://svn.rockbox.org/rockbox/trunk@126 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
454be44f8d
commit
c25510f944
10 changed files with 273 additions and 207 deletions
|
@ -16,13 +16,12 @@
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#ifndef __LIBRARY_MEMORY_C__
|
#if 0
|
||||||
# error "This header file must be included ONLY from memory.c."
|
#include <memory.h>
|
||||||
#endif
|
#include "memory-page.h"
|
||||||
#ifndef __LIBRARY_MEMORY_BLOCK_H__
|
#include "memory-slab.h"
|
||||||
# define __LIBRARY_MEMORY_BLOCK_H__
|
|
||||||
|
|
||||||
static struct memory_cache *free_block_cache[MEMORY_PAGE_MINIMAL_ORDER - 2];
|
static struct memory_cache *__memory_free_block_cache[MEMORY_PAGE_MINIMAL_ORDER - 2];
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// MEMORY BLOCK :
|
// MEMORY BLOCK :
|
||||||
|
@ -32,15 +31,15 @@ static struct memory_cache *free_block_cache[MEMORY_PAGE_MINIMAL_ORDER - 2];
|
||||||
// - memory_release_block : release a power-of-2-sized block (or a page)
|
// - memory_release_block : release a power-of-2-sized block (or a page)
|
||||||
//
|
//
|
||||||
|
|
||||||
static inline void *allocate_small_block (int order)
|
static inline void *__memory_allocate_block (int order)
|
||||||
{
|
{
|
||||||
struct memory_cache *cache = free_block_cache[order - 2];
|
struct memory_cache *cache = __memory_free_block_cache[order - 2];
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if (cache)
|
if (cache)
|
||||||
return memory_cache_allocate (cache);
|
return memory_cache_allocate (cache);
|
||||||
}
|
}
|
||||||
while ((free_block_cache[order] = cache = memory_create_cache (size,0,0)));
|
while ((__memory_free_block_cache[order] = cache = memory_create_cache (size,0,0)));
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,15 +48,15 @@ void *memory_allocate_block (int order)
|
||||||
if (order < 2)
|
if (order < 2)
|
||||||
order = 2;
|
order = 2;
|
||||||
if (order < MEMORY_PAGE_MINIMAL_ORDER)
|
if (order < MEMORY_PAGE_MINIMAL_ORDER)
|
||||||
return allocate_small_block (order);
|
return __memory_allocate_block (order);
|
||||||
if (order < MEMORY_PAGE_MAXIMAL_ORDER)
|
if (order < MEMORY_PAGE_MAXIMAL_ORDER)
|
||||||
return memory_allocate_page (order);
|
return memory_allocate_page (order);
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int release_block (int order,void *address)
|
static inline int __memory_release_block (int order,void *address)
|
||||||
{
|
{
|
||||||
struct memory_cache *cache = free_block_cache[order - 2];
|
struct memory_cache *cache = __memory_free_block_cache[order - 2];
|
||||||
if (cache)
|
if (cache)
|
||||||
return memory_cache_release (cache,address);
|
return memory_cache_release (cache,address);
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
|
@ -68,7 +67,7 @@ int memory_release_block (int order,void *address)
|
||||||
if (order < 2)
|
if (order < 2)
|
||||||
order = 2;
|
order = 2;
|
||||||
if (order < MEMORY_PAGE_MINIMAL_ORDER)
|
if (order < MEMORY_PAGE_MINIMAL_ORDER)
|
||||||
return release_block (order);
|
return __memory_release_block (order);
|
||||||
if (order < MEMORY_PAGE_MAXIMAL_ORDER)
|
if (order < MEMORY_PAGE_MAXIMAL_ORDER)
|
||||||
return memory_release_page (address);
|
return memory_release_page (address);
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
|
|
0
firmware/test/memory/memory-block.txt
Normal file
0
firmware/test/memory/memory-block.txt
Normal file
|
@ -17,6 +17,10 @@
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
#include "memory-page.h"
|
||||||
|
#if 0
|
||||||
|
#include "memory-slab.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* NOT VERY OPTIMIZED AT ALL BUT WE WILL DO IT WHEN PRIORITY COMES */
|
/* NOT VERY OPTIMIZED AT ALL BUT WE WILL DO IT WHEN PRIORITY COMES */
|
||||||
void memory_copy (void *target,void const *source,unsigned int count)
|
void memory_copy (void *target,void const *source,unsigned int count)
|
||||||
|
@ -35,10 +39,10 @@ void memory_set (void *target,int byte,unsigned int count)
|
||||||
void memory_setup (void)
|
void memory_setup (void)
|
||||||
{
|
{
|
||||||
#if 1
|
#if 1
|
||||||
memory_set (free_page,0,MEMORY_TOTAL_BYTES);
|
memory_set (__memory_free_page,0,MEMORY_TOTAL_BYTES);
|
||||||
memory_set (free_page_bin,0,MEMORY_TOTAL_ORDERS *sizeof (struct memory_free_page *));
|
memory_set (__memory_free_page_bin,0,MEMORY_TOTAL_ORDERS *sizeof (struct memory_free_page *));
|
||||||
memory_set (free_page_order + 1,0,MEMORY_TOTAL_PAGES);
|
memory_set (__memory_free_page_order + 1,0,MEMORY_TOTAL_PAGES);
|
||||||
#endif
|
#endif
|
||||||
free_page_order[0] = MEMORY_TOTAL_ORDERS - 1;
|
__memory_free_page_order[0] = MEMORY_TOTAL_ORDERS - 1;
|
||||||
free_page_bin[MEMORY_TOTAL_ORDERS - 1] = free_page;
|
__memory_free_page_bin[MEMORY_TOTAL_ORDERS - 1] = __memory_free_page;
|
||||||
}
|
}
|
||||||
|
|
0
firmware/test/memory/memory-misc.txt
Normal file
0
firmware/test/memory/memory-misc.txt
Normal file
|
@ -16,86 +16,70 @@
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#ifndef __LIBRARY_MEMORY_C__
|
#include <memory.h>
|
||||||
# error "This header file must be included ONLY from memory.c."
|
#include "memory-page.h"
|
||||||
|
#if 0
|
||||||
|
#include "memory-slab.h"
|
||||||
#endif
|
#endif
|
||||||
#ifndef __LIBRARY_MEMORY_PAGE_H__
|
|
||||||
# define __LIBRARY_MEMORY_PAGE_H__
|
|
||||||
|
|
||||||
struct memory_free_page
|
|
||||||
{
|
|
||||||
struct memory_free_page
|
|
||||||
*less,*more;
|
|
||||||
char
|
|
||||||
reserved[MEMORY_PAGE_MINIMAL_SIZE - 2*sizeof (struct memory_free_page *)];
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LESS -1
|
|
||||||
#define MORE +1
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|
||||||
struct memory_free_page free_page[MEMORY_TOTAL_PAGES];
|
|
||||||
|
|
||||||
static inline unsigned int get_offset (int order)
|
|
||||||
{
|
|
||||||
return (2 << order);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IA32 has no problem with shift operation
|
// IA32 has no problem with shift operation
|
||||||
static inline unsigned int get_size (int order)
|
static inline unsigned int __memory_get_size (int order)
|
||||||
{
|
{
|
||||||
return (MEMORY_PAGE_MINIMAL_SIZE << order);
|
return (MEMORY_PAGE_MINIMAL_SIZE << order);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arghhhh ! I cannot align 'free_page' on 512-byte boundary (max is 16-byte for Cygwin)
|
// Arghhhh ! I cannot align 'free_page' on 512-byte boundary (max is 16-byte for Cygwin)
|
||||||
static inline struct memory_free_page *get_neighbour (struct memory_free_page *node,unsigned int size)
|
static inline struct memory_free_page *__memory_get_neighbour (struct memory_free_page *node,unsigned int size)
|
||||||
{
|
{
|
||||||
return ((struct memory_free_page *)((unsigned)free_page + (((unsigned)node - (unsigned)free_page) ^ size)));
|
return ((struct memory_free_page *)((unsigned)__memory_free_page + (((unsigned)node - (unsigned)__memory_free_page) ^ size)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
extern struct memory_free_page free_page[MEMORY_TOTAL_PAGES] asm("dram");
|
|
||||||
|
|
||||||
static inline unsigned int get_offset (int order)
|
|
||||||
{
|
|
||||||
static unsigned short offset [MEMORY_TOTAL_ORDERS] =
|
|
||||||
{ 2,4,8,16,32,64,128,256,512,1024,2048,4096,8192 };
|
|
||||||
return offset[order];
|
|
||||||
}
|
|
||||||
|
|
||||||
// SH1 has very poor shift instructions (only <<1,>>1,<<2,>>2,<<8,>>8,<<16 and >>16).
|
// SH1 has very poor shift instructions (only <<1,>>1,<<2,>>2,<<8,>>8,<<16 and >>16).
|
||||||
// so we should use a lookup table to speedup.
|
// so we should use a lookup table to speedup.
|
||||||
static inline unsigned int get_size (int order)
|
static inline unsigned int __memory_get_size (int order)
|
||||||
{
|
{
|
||||||
return (get_offset (order))<<8;
|
static unsigned short size [MEMORY_TOTAL_ORDERS] =
|
||||||
|
{
|
||||||
|
1<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
2<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
4<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
8<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
16<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
32<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
64<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
128<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
256<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
512<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
1024<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
2048<<MEMORY_PAGE_MINIMAL_ORDER,
|
||||||
|
4096<<MEMORY_PAGE_MINIMAL_ORDER
|
||||||
|
};
|
||||||
|
return size[order];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_free_page *get_neighbour (struct memory_free_page *node,unsigned int size)
|
static inline struct memory_free_page *__memory_get_neighbour (struct memory_free_page *node,unsigned int size)
|
||||||
{
|
{
|
||||||
return ((struct memory_free_page *)((unsigned)node ^ size));
|
return ((struct memory_free_page *)((unsigned)node ^ size));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char free_page_order[MEMORY_TOTAL_PAGES];
|
static inline int __memory_get_order (struct memory_free_page *node)
|
||||||
static struct memory_free_page *free_page_bin[MEMORY_TOTAL_ORDERS];
|
|
||||||
|
|
||||||
static inline int get_order (struct memory_free_page *node)
|
|
||||||
{
|
{
|
||||||
return free_page_order[node - free_page];
|
return __memory_free_page_order[node - __memory_free_page];
|
||||||
}
|
}
|
||||||
static inline void set_order (struct memory_free_page *node,int order)
|
static inline void __memory_set_order (struct memory_free_page *node,int order)
|
||||||
{
|
{
|
||||||
free_page_order[node - free_page] = order;
|
__memory_free_page_order[node - __memory_free_page] = order;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MEMORY_PAGE_USE_SPLAY_TREE
|
#if MEMORY_PAGE_USE_SPLAY_TREE
|
||||||
|
|
||||||
# include <stdio.h>
|
static struct memory_free_page *__memory_splay_page (struct memory_free_page *root,struct memory_free_page *node)
|
||||||
|
|
||||||
static struct memory_free_page *splay_page (struct memory_free_page *root,struct memory_free_page *node)
|
|
||||||
{
|
{
|
||||||
struct memory_free_page *down;
|
struct memory_free_page *down;
|
||||||
struct memory_free_page *less;
|
struct memory_free_page *less;
|
||||||
|
@ -153,15 +137,15 @@ static struct memory_free_page *splay_page (struct memory_free_page *root,struct
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void insert_page (int order,struct memory_free_page *node)
|
static inline void __memory_insert_page (int order,struct memory_free_page *node)
|
||||||
{
|
{
|
||||||
struct memory_free_page *root = free_page_bin[order];
|
struct memory_free_page *root = __memory_free_page_bin[order];
|
||||||
if (!root)
|
if (!root)
|
||||||
{
|
{
|
||||||
node->less =
|
node->less =
|
||||||
node->more = 0;
|
node->more = 0;
|
||||||
}
|
}
|
||||||
else if (node < (root = splay_page (root,node)))
|
else if (node < (root = __memory_splay_page (root,node)))
|
||||||
{
|
{
|
||||||
node->less = root->less;
|
node->less = root->less;
|
||||||
node->more = root;
|
node->more = root;
|
||||||
|
@ -173,91 +157,91 @@ static inline void insert_page (int order,struct memory_free_page *node)
|
||||||
node->more = root->more;
|
node->more = root->more;
|
||||||
node->more = 0;
|
node->more = 0;
|
||||||
}
|
}
|
||||||
free_page_bin[order] = node;
|
__memory_free_page_bin[order] = node;
|
||||||
set_order (node,order);
|
__memory_set_order (node,order);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_free_page *pop_page (int order,int want)
|
static inline struct memory_free_page *__memory_pop_page (int order,int want)
|
||||||
{
|
{
|
||||||
struct memory_free_page *root = free_page_bin[order];
|
struct memory_free_page *root = __memory_free_page_bin[order];
|
||||||
if (root)
|
if (root)
|
||||||
{
|
{
|
||||||
root = splay_page (root,free_page);
|
root = __memory_splay_page (root,__memory_free_page);
|
||||||
free_page_bin[order] = root->more;
|
__memory_free_page_bin[order] = root->more;
|
||||||
set_order (root,~want);
|
__memory_set_order (root,~want);
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void remove_page (int order,struct memory_free_page *node)
|
static inline void __memory_remove_page (int order,struct memory_free_page *node)
|
||||||
{
|
{
|
||||||
struct memory_free_page *root = free_page_bin[order];
|
struct memory_free_page *root = __memory_free_page_bin[order];
|
||||||
root = splay_page (root,node);
|
root = __memory_splay_page (root,node);
|
||||||
if (root->less)
|
if (root->less)
|
||||||
{
|
{
|
||||||
node = splay_page (root->less,node);
|
node = __memory_splay_page (root->less,node);
|
||||||
node->more = root->more;
|
node->more = root->more;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
node = root->more;
|
node = root->more;
|
||||||
free_page_bin[order] = node;
|
__memory_free_page_bin[order] = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
static inline void insert_page (int order,struct memory_free_page *node)
|
static inline void __memory_insert_page (int order,struct memory_free_page *node)
|
||||||
{
|
{
|
||||||
struct memory_free_page *head = free_page_bin[order];
|
struct memory_free_page *head = __memory_free_page_bin[order];
|
||||||
node->less = 0;
|
node->less = 0;
|
||||||
node->more = head;
|
node->more = head;
|
||||||
if (head)
|
if (head)
|
||||||
head->less = node;
|
head->less = node;
|
||||||
free_page_bin[order] = node;
|
__memory_free_page_bin[order] = node;
|
||||||
set_order (node,order);
|
__memory_set_order (node,order);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_free_page *pop_page (int order,int want)
|
static inline struct memory_free_page *pop_page (int order,int want)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node = free_page_bin[order];
|
struct memory_free_page *node = __memory_free_page_bin[order];
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
free_page_bin[order] = node->more;
|
__memory_free_page_bin[order] = node->more;
|
||||||
if (node->more)
|
if (node->more)
|
||||||
node->more->less = 0;
|
node->more->less = 0;
|
||||||
set_order (node,~want);
|
__memory_set_order (node,~want);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void remove_page (int order,struct memory_free_page *node)
|
static inline void __memory_remove_page (int order,struct memory_free_page *node)
|
||||||
{
|
{
|
||||||
if (node->less)
|
if (node->less)
|
||||||
node->less->more = node->more;
|
node->less->more = node->more;
|
||||||
else
|
else
|
||||||
free_page_bin[order] = node->more;
|
__memory_free_page_bin[order] = node->more;
|
||||||
if (node->more)
|
if (node->more)
|
||||||
node->more->less = node->less;
|
node->more->less = node->less;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void push_page (int order,struct memory_free_page *node)
|
static inline void __memory_push_page (int order,struct memory_free_page *node)
|
||||||
{
|
{
|
||||||
node->less = 0;
|
node->less = 0;
|
||||||
node->more = 0;
|
node->more = 0;
|
||||||
free_page_bin[order] = node;
|
__memory_free_page_bin[order] = node;
|
||||||
set_order (node,order);
|
__memory_set_order (node,order);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct memory_free_page *allocate_page (unsigned int size,int order)
|
static struct memory_free_page *__memory_allocate_page (unsigned int size,int order)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node;
|
struct memory_free_page *node;
|
||||||
int min = order;
|
int min = order;
|
||||||
while ((unsigned)order <= (MEMORY_TOTAL_ORDERS - 1))
|
while ((unsigned)order <= (MEMORY_TOTAL_ORDERS - 1))
|
||||||
// order is valid ?
|
// order is valid ?
|
||||||
{
|
{
|
||||||
if (!(node = pop_page (order,min)))
|
if (!(node = __memory_pop_page (order,min)))
|
||||||
// no free page of this order ?
|
// no free page of this order ?
|
||||||
{
|
{
|
||||||
++order; size <<= 1;
|
++order; size <<= 1;
|
||||||
|
@ -267,39 +251,39 @@ static struct memory_free_page *allocate_page (unsigned int size,int order)
|
||||||
// split our larger page in smaller pages
|
// split our larger page in smaller pages
|
||||||
{
|
{
|
||||||
--order; size >>= 1;
|
--order; size >>= 1;
|
||||||
push_page (order,(struct memory_free_page *)((unsigned int)node + size));
|
__memory_push_page (order,(struct memory_free_page *)((unsigned int)node + size));
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void release_page (struct memory_free_page *node,unsigned int size,int order)
|
static inline void __memory_release_page (struct memory_free_page *node,unsigned int size,int order)
|
||||||
{
|
{
|
||||||
struct memory_free_page *neighbour;
|
struct memory_free_page *neighbour;
|
||||||
while ((order <= (MEMORY_TOTAL_ORDERS - 1)) &&
|
while ((order <= (MEMORY_TOTAL_ORDERS - 1)) &&
|
||||||
((neighbour = get_neighbour (node,size)),
|
((neighbour = __memory_get_neighbour (node,size)),
|
||||||
(get_order (neighbour) == order)))
|
(__memory_get_order (neighbour) == order)))
|
||||||
// merge our released page with its contiguous page into a larger page
|
// merge our released page with its contiguous page into a larger page
|
||||||
{
|
{
|
||||||
remove_page (order,neighbour);
|
__memory_remove_page (order,neighbour);
|
||||||
++order; size <<= 1;
|
++order; size <<= 1;
|
||||||
if (neighbour < node)
|
if (neighbour < node)
|
||||||
node = neighbour;
|
node = neighbour;
|
||||||
}
|
}
|
||||||
insert_page (order,node);
|
__memory_insert_page (order,node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* PUBLIC FUNCTIONS */
|
/* PUBLIC FUNCTIONS */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void *memory_allocate_page (int order)
|
void *memory_allocate_page (int order)
|
||||||
{
|
{
|
||||||
if (order < 0)
|
if (order < 0)
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
return allocate_page (get_size (order),order);
|
return __memory_allocate_page (__memory_get_size (order),order);
|
||||||
}
|
}
|
||||||
|
|
||||||
// release a page :
|
// release a page :
|
||||||
|
@ -309,10 +293,10 @@ void *memory_allocate_page (int order)
|
||||||
int memory_release_page (void *address)
|
int memory_release_page (void *address)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node = (struct memory_free_page *)address;
|
struct memory_free_page *node = (struct memory_free_page *)address;
|
||||||
int order = ~get_order (node);
|
int order = ~__memory_get_order (node);
|
||||||
if (order < 0)
|
if (order < 0)
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
release_page (node,get_size (order),order);
|
__memory_release_page (node,__memory_get_size (order),order);
|
||||||
return MEMORY_RETURN_SUCCESS;
|
return MEMORY_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,58 +306,58 @@ int memory_release_page (void *address)
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
# if MEMORY_PAGE_USE_SPLAY_TREE
|
# if MEMORY_PAGE_USE_SPLAY_TREE
|
||||||
|
|
||||||
static void dump_splay_node (struct memory_free_page *node,int level)
|
void __memory_dump_splay_node (struct memory_free_page *node,int level)
|
||||||
{
|
{
|
||||||
if (!node)
|
if (!node)
|
||||||
return;
|
return;
|
||||||
dump_splay_node (node->less,level+1);
|
__memory_dump_splay_node (node->less,level+1);
|
||||||
printf ("\n%*s[%d-%d]",level,"",(node - free_page),(node - free_page) + (1 << get_order (node)) - 1);
|
printf ("\n%*s[%d-%d]",level,"",(node - __memory_free_page),(node - __memory_free_page) + (1 << __memory_get_order (node)) - 1);
|
||||||
dump_splay_node (node->more,level+1);
|
__memory_dump_splay_node (node->more,level+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_splay_tree (struct memory_free_page *root)
|
void __memory_dump_splay_tree (struct memory_free_page *root)
|
||||||
{
|
{
|
||||||
dump_splay_node (root,2); fflush (stdout);
|
__memory_dump_splay_node (root,2); fflush (stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
void memory_spy_page (void *address)
|
void __memory_spy_page (void *address)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node = (struct memory_free_page *)address;
|
struct memory_free_page *node = (struct memory_free_page *)address;
|
||||||
int order,used;
|
int order,used;
|
||||||
if (node)
|
if (node)
|
||||||
{
|
{
|
||||||
order = get_order (node);
|
order = __memory_get_order (node);
|
||||||
used = order < 0;
|
used = order < 0;
|
||||||
if (used)
|
if (used)
|
||||||
order = ~order;
|
order = ~order;
|
||||||
printf("\n(%s,%2d,%7d)",(used ? "used" : "free"),order,get_size (order));
|
printf("\n(%s,%2d,%7d)",(used ? "used" : "free"),order,__memory_get_size (order));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_dump (int order)
|
void __memory_dump (int order)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node = free_page_bin[order];
|
struct memory_free_page *node = __memory_free_page_bin[order];
|
||||||
printf("\n(%s,%2d,%7d)",node ? "free" : "none",order,get_size (order));
|
printf("\n(%s,%2d,%7d)",node ? "free" : "none",order,__memory_get_size (order));
|
||||||
# if MEMORY_PAGE_USE_SPLAY_TREE
|
# if MEMORY_PAGE_USE_SPLAY_TREE
|
||||||
dump_splay_tree (node);
|
__memory_dump_splay_tree (node);
|
||||||
# else
|
# else
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
printf("[%d-%d]",(node - free_page),(node - free_page) + (1<<order) - 1);
|
printf("[%d-%d]",(node - __memory_free_page),(node - __memory_free_page) + (1<<order) - 1);
|
||||||
node = node->more;
|
node = node->more;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void memory_check (int order)
|
void __memory_check (int order)
|
||||||
{
|
{
|
||||||
struct memory_free_page *node[4096],*swap;
|
struct memory_free_page *node[4096],*swap;
|
||||||
unsigned int i = 0,j = 0;
|
unsigned int i = 0,j = 0;
|
||||||
while (i <= 12)
|
while (i <= 12)
|
||||||
memory_dump (i++);
|
__memory_dump (i++);
|
||||||
i = 0;
|
i = 0;
|
||||||
printf ("\nallocating...\n");
|
printf ("\nallocating...\n");
|
||||||
while (order >= 0)
|
while (order >= 0)
|
||||||
|
@ -382,31 +366,31 @@ void memory_check (int order)
|
||||||
while ((swap = memory_allocate_page (j)))
|
while ((swap = memory_allocate_page (j)))
|
||||||
{
|
{
|
||||||
node[i++] = swap;
|
node[i++] = swap;
|
||||||
printf("[%d-%d]",(swap - free_page),(swap - free_page) + ((1 << j)-1));
|
printf("[%d-%d]",(swap - __memory_free_page),(swap - __memory_free_page) + ((1 << j)-1));
|
||||||
for (j += (rand () & 15); j > (unsigned int)order; j -= order);
|
for (j += (rand () & 15); j > (unsigned int)order; j -= order);
|
||||||
}
|
}
|
||||||
--order;
|
--order;
|
||||||
}
|
}
|
||||||
node[i] = 0;
|
node[i] = 0;
|
||||||
while (j <= 12)
|
while (j <= 12)
|
||||||
memory_dump (j++);
|
__memory_dump (j++);
|
||||||
j = 0;
|
j = 0;
|
||||||
printf ("\nreleasing...");
|
printf ("\nreleasing...");
|
||||||
--i;
|
--i;
|
||||||
while (i > 0)
|
while (i > 0)
|
||||||
{
|
{
|
||||||
unsigned int k = 0;
|
unsigned int k = 0;
|
||||||
#if 0
|
# if 0
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
#endif
|
# endif
|
||||||
swap = node[k++];
|
swap = node[k++];
|
||||||
#if 0
|
# if 0
|
||||||
while (swap)
|
while (swap)
|
||||||
{
|
{
|
||||||
printf("[%d-%d]",(swap - free_page),(swap - free_page) + ((1 << ~get_order (swap))-1));
|
printf("[%d-%d]",(swap - __memory_free_page),(swap - __memory_free_page) + ((1 << ~__memory_get_order (swap))-1));
|
||||||
swap = node[k++];
|
swap = node[k++];
|
||||||
}
|
}
|
||||||
#endif
|
# endif
|
||||||
for (j += 1 + (rand () & 15); j >= i; j -= i);
|
for (j += 1 + (rand () & 15); j >= i; j -= i);
|
||||||
swap = node[j];
|
swap = node[j];
|
||||||
node[j] = node[i];
|
node[j] = node[i];
|
||||||
|
@ -417,9 +401,8 @@ void memory_check (int order)
|
||||||
memory_release_page (node[0]);
|
memory_release_page (node[0]);
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i <= 12)
|
while (i <= 12)
|
||||||
memory_dump (i++);
|
__memory_dump (i++);
|
||||||
printf("\n\n%s !",(get_order (free_page) == 12) ? "SUCCESS" : "FAILURE");
|
printf("\n\n%s !",(__memory_get_order (__memory_free_page) == 12) ? "SUCCESS" : "FAILURE");
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
59
firmware/test/memory/memory-page.h
Normal file
59
firmware/test/memory/memory-page.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Alan Korr
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __LIBRARY_MEMORY_PAGE_H__
|
||||||
|
#define __LIBRARY_MEMORY_PAGE_H__
|
||||||
|
|
||||||
|
struct memory_free_page
|
||||||
|
{
|
||||||
|
struct memory_free_page
|
||||||
|
*less,*more;
|
||||||
|
char
|
||||||
|
reserved[MEMORY_PAGE_MINIMAL_SIZE - 2*sizeof (struct memory_free_page *)];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LESS -1
|
||||||
|
#define MORE +1
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
|
||||||
|
struct memory_free_page __memory_free_page[MEMORY_TOTAL_PAGES];
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
extern struct memory_free_page __memory_free_page[MEMORY_TOTAL_PAGES] asm("dram");
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char __memory_free_page_order[MEMORY_TOTAL_PAGES];
|
||||||
|
struct memory_free_page *__memory_free_page_bin[MEMORY_TOTAL_ORDERS];
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
# if MEMORY_PAGE_USE_SPLAY_TREE
|
||||||
|
|
||||||
|
void __memory_dump_splay_node (struct memory_free_page *node,int level);
|
||||||
|
void __memory_dump_splay_tree (struct memory_free_page *root);
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
void __memory_spy_page (void *address);
|
||||||
|
void __memory_dump (int order);
|
||||||
|
void __memory_check (int order);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
0
firmware/test/memory/memory-page.txt
Normal file
0
firmware/test/memory/memory-page.txt
Normal file
|
@ -16,17 +16,10 @@
|
||||||
* KIND, either express or implied.
|
* KIND, either express or implied.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
#ifndef __LIBRARY_MEMORY_C__
|
#if 0
|
||||||
# error "This header file must be included ONLY from memory.c."
|
#include <memory.h>
|
||||||
#endif
|
#include "memory-page.h"
|
||||||
#ifndef __LIBRARY_MEMORY_PAGE_H__
|
#include "memory-slab.h"
|
||||||
# define __LIBRARY_MEMORY_PAGE_H__
|
|
||||||
|
|
||||||
struct memory_free_block
|
|
||||||
{
|
|
||||||
struct memory_free_block
|
|
||||||
*link;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
// MEMORY SLAB :
|
// MEMORY SLAB :
|
||||||
|
@ -34,17 +27,7 @@ struct memory_free_block
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
struct memory_slab
|
static inline struct memory_slab *__memory_push_slab (struct memory_slab *head,struct memory_slab *node)
|
||||||
{
|
|
||||||
struct memory_slab
|
|
||||||
*less,*more;
|
|
||||||
unsigned int // left == number of free blocks left
|
|
||||||
left;
|
|
||||||
struct memory_free_block
|
|
||||||
*free;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct memory_slab *push_slab (struct memory_slab *head,struct memory_slab *node)
|
|
||||||
{
|
{
|
||||||
node->less = head;
|
node->less = head;
|
||||||
if (head)
|
if (head)
|
||||||
|
@ -57,14 +40,14 @@ static inline struct memory_slab *push_slab (struct memory_slab *head,struct mem
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_slab *pop_slab (struct memory_slab *head,struct memory_slab *node)
|
static inline struct memory_slab *__memory_pop_slab (struct memory_slab *head,struct memory_slab *node)
|
||||||
{
|
{
|
||||||
if (head)
|
if (head)
|
||||||
head->more = node->more;
|
head->more = node->more;
|
||||||
return node->more;
|
return node->more;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_slab *move_slab (struct memory_slab **from,struct memory_slab **to)
|
static inline struct memory_slab *__memory_move_slab (struct memory_slab **from,struct memory_slab **to)
|
||||||
{
|
{
|
||||||
struct memory_slab *head = *from;
|
struct memory_slab *head = *from;
|
||||||
*from = (*from)->more;
|
*from = (*from)->more;
|
||||||
|
@ -87,33 +70,9 @@ static inline struct memory_slab *move_slab (struct memory_slab **from,struct me
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
struct memory_cache
|
|
||||||
{
|
|
||||||
struct memory_cache
|
|
||||||
*less,*more,*same;
|
|
||||||
unsigned int
|
|
||||||
left; // number of free slabs
|
|
||||||
struct memory_slab
|
|
||||||
*used;
|
|
||||||
struct memory_slab
|
|
||||||
*free;
|
|
||||||
struct memory_slab
|
|
||||||
*reap;
|
|
||||||
unsigned int
|
|
||||||
size,original_size;
|
|
||||||
unsigned int
|
|
||||||
page_size;
|
|
||||||
unsigned int
|
|
||||||
blocks_per_slab;
|
|
||||||
int
|
|
||||||
page_order;
|
|
||||||
unsigned int
|
|
||||||
flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct memory_cache *cache_tree;
|
static struct memory_cache *cache_tree;
|
||||||
|
|
||||||
static inline int get_order (unsigned size)
|
static inline int __memory_get_order (unsigned size)
|
||||||
{
|
{
|
||||||
int order = 0;
|
int order = 0;
|
||||||
size = (size + sizeof(struct memory_free_block) - 1) & - sizeof(struct memory_free_block);
|
size = (size + sizeof(struct memory_free_block) - 1) & - sizeof(struct memory_free_block);
|
||||||
|
@ -124,7 +83,7 @@ static inline int get_order (unsigned size)
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_slab *get_slab (struct memory_cache *cache,void *address)
|
static inline struct memory_slab *__memory_get_slab (struct memory_cache *cache,void *address)
|
||||||
{
|
{
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
return (struct memory_slab *)((((unsigned)address + cache->page_size) & -cache->page_size) - sizeof (struct memory_slab));
|
return (struct memory_slab *)((((unsigned)address + cache->page_size) & -cache->page_size) - sizeof (struct memory_slab));
|
||||||
|
@ -133,7 +92,7 @@ static inline struct memory_slab *get_slab (struct memory_cache *cache,void *add
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct memory_cache *splay_cache (struct memory_cache *root,unsigned int left)
|
static struct memory_cache *__memory_splay_cache (struct memory_cache *root,unsigned int left)
|
||||||
{
|
{
|
||||||
struct memory_cache *down;
|
struct memory_cache *down;
|
||||||
struct memory_cache *less;
|
struct memory_cache *less;
|
||||||
|
@ -191,14 +150,14 @@ static struct memory_cache *splay_cache (struct memory_cache *root,unsigned int
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_cache *insert_cache (struct memory_cache *root,struct memory_cache *node)
|
static inline struct memory_cache *__memory_insert_cache (struct memory_cache *root,struct memory_cache *node)
|
||||||
{
|
{
|
||||||
node->less =
|
node->less =
|
||||||
node->more =
|
node->more =
|
||||||
node->same = 0;
|
node->same = 0;
|
||||||
if (root)
|
if (root)
|
||||||
{
|
{
|
||||||
if (node->left == ((root = splay_cache (root,node))->left))
|
if (node->left == ((root = __memory_splay_cache (root,node))->left))
|
||||||
{
|
{
|
||||||
node->less = root.less;
|
node->less = root.less;
|
||||||
node->more = root.more;
|
node->more = root.more;
|
||||||
|
@ -221,11 +180,11 @@ static inline struct memory_cache *insert_cache (struct memory_cache *root,struc
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_cache *remove_cache (struct memory_cache *root,struct memory_cache *node)
|
static inline struct memory_cache *__memory_remove_cache (struct memory_cache *root,struct memory_cache *node)
|
||||||
{
|
{
|
||||||
if (root)
|
if (root)
|
||||||
{
|
{
|
||||||
root = splay_cache (root,node);
|
root = __memory_splay_cache (root,node);
|
||||||
if (root != node)
|
if (root != node)
|
||||||
{
|
{
|
||||||
node->less->same = node->same;
|
node->less->same = node->same;
|
||||||
|
@ -235,7 +194,7 @@ static inline struct memory_cache *remove_cache (struct memory_cache *root,struc
|
||||||
}
|
}
|
||||||
if (root->less)
|
if (root->less)
|
||||||
{
|
{
|
||||||
node = splay_page (root->less,node);
|
node = __memory_splay_page (root->less,node);
|
||||||
node->more = root->more;
|
node->more = root->more;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -244,12 +203,12 @@ static inline struct memory_cache *remove_cache (struct memory_cache *root,struc
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct memory_cache *move_cache (struct memory_cache *root,struct memory_cache *node,int delta)
|
static inline struct memory_cache *__memory_move_cache (struct memory_cache *root,struct memory_cache *node,int delta)
|
||||||
{
|
{
|
||||||
if ((root = remove_cache (root,node)))
|
if ((root = __memory_remove_cache (root,node)))
|
||||||
{
|
{
|
||||||
node->left += delta;
|
node->left += delta;
|
||||||
root = insert_cache (root,node);
|
root = __memory_insert_cache (root,node);
|
||||||
}
|
}
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
@ -291,15 +250,15 @@ struct memory_slab *memory_grow_cache (struct memory_cache *cache)
|
||||||
}
|
}
|
||||||
*link = 0;
|
*link = 0;
|
||||||
cache->blocks_per_slab = slab->free;
|
cache->blocks_per_slab = slab->free;
|
||||||
cache->reap = push_slab (cache->reap,slab);
|
cache->reap = __memory_push_slab (cache->reap,slab);
|
||||||
cache_tree = move_cache (cache_tree,cache,+1);
|
cache_tree = __memory_move_cache (cache_tree,cache,+1);
|
||||||
return slab;
|
return slab;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shrink_cache (struct memory_cache *cache,int all,int move)
|
static int __memory_shrink_cache (struct memory_cache *cache,int all,int move)
|
||||||
{
|
{
|
||||||
struct memory_slab *slab;
|
struct memory_slab *slab;
|
||||||
unsigned int slabs = 0;
|
unsigned int slabs = 0;
|
||||||
|
@ -308,12 +267,12 @@ static int shrink_cache (struct memory_cache *cache,int all,int move)
|
||||||
while ((slab = cache->reap))
|
while ((slab = cache->reap))
|
||||||
{
|
{
|
||||||
++slabs;
|
++slabs;
|
||||||
cache->reap = pop_slab (cache->reap,slab);
|
cache->reap = __memory_pop_slab (cache->reap,slab);
|
||||||
memory_release_page ((void *)slab);
|
memory_release_page ((void *)slab);
|
||||||
if (all)
|
if (all)
|
||||||
continue;
|
continue;
|
||||||
if (move)
|
if (move)
|
||||||
cache_tree = move_cache (cache_tree,cache,-slabs);
|
cache_tree = __memory_move_cache (cache_tree,cache,-slabs);
|
||||||
return MEMORY_RETURN_SUCCESS;
|
return MEMORY_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -322,7 +281,7 @@ static int shrink_cache (struct memory_cache *cache,int all,int move)
|
||||||
|
|
||||||
int memory_shrink_cache (struct memory_cache *cache,int all)
|
int memory_shrink_cache (struct memory_cache *cache,int all)
|
||||||
{
|
{
|
||||||
return shrink_cache (cache,all,1 /* move cache in cache_tree */);
|
return __memory_shrink_cache (cache,all,1 /* move cache in cache_tree */);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct memory_cache *memory_create_cache (unsigned int size,int align,int flags)
|
struct memory_cache *memory_create_cache (unsigned int size,int align,int flags)
|
||||||
|
@ -382,7 +341,7 @@ struct memory_cache *memory_create_cache (unsigned int size,int align,int flags)
|
||||||
cache->page_size = page_size;
|
cache->page_size = page_size;
|
||||||
cache->page_order = page_order;
|
cache->page_order = page_order;
|
||||||
|
|
||||||
cache_tree = insert_cache (cache_tree,cache);
|
cache_tree = __memory_insert_cache (cache_tree,cache);
|
||||||
|
|
||||||
return cache;
|
return cache;
|
||||||
}
|
}
|
||||||
|
@ -392,8 +351,8 @@ int memory_destroy_cache (struct memory_cache *cache)
|
||||||
/* FIX ME : this function shouldn't be called if there are still used blocks */
|
/* FIX ME : this function shouldn't be called if there are still used blocks */
|
||||||
if (cache && !cache->free && !cache->used)
|
if (cache && !cache->free && !cache->used)
|
||||||
{
|
{
|
||||||
cache_tree = remove_cache (cache_tree,cache);
|
cache_tree = __memory_remove_cache (cache_tree,cache);
|
||||||
if (shrink_cache (cache,1 /* release all free slabs */,0 /* don't move in cache_tree */))
|
if (__memory_shrink_cache (cache,1 /* release all free slabs */,0 /* don't move in cache_tree */))
|
||||||
return memory_cache_release (&cache_cache,cache);
|
return memory_cache_release (&cache_cache,cache);
|
||||||
}
|
}
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
|
@ -413,33 +372,33 @@ void *memory_cache_allocate (struct memory_cache *cache)
|
||||||
ok: struct memory_free_block *block = slab->free;
|
ok: struct memory_free_block *block = slab->free;
|
||||||
slab->free = block->link;
|
slab->free = block->link;
|
||||||
if (--slab->left == 0)
|
if (--slab->left == 0)
|
||||||
move_slab (&cache->free,&cache->used);
|
__memory_move_slab (&cache->free,&cache->used);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cache->reap)
|
if (cache->reap)
|
||||||
{
|
{
|
||||||
slab = move_slab (&cache->reap,&cache->free);
|
slab = __memory_move_slab (&cache->reap,&cache->free);
|
||||||
cache_tree = move_cache (cache_tree,cache,-1);
|
cache_tree = __memory_move_cache (cache_tree,cache,-1);
|
||||||
goto ok;
|
goto ok;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (grow_cache (cache));
|
while (__memory_grow_cache (cache));
|
||||||
}
|
}
|
||||||
return MEMORY_RETURN_FAILURE;
|
return MEMORY_RETURN_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memory_cache_release (struct memory_cache *cache,void *address)
|
int memory_cache_release (struct memory_cache *cache,void *address)
|
||||||
{
|
{
|
||||||
struct memory_slab *slab = get_slab (cache,address);
|
struct memory_slab *slab = __memory_get_slab (cache,address);
|
||||||
((struct memory_free_block *)address)->link = slab->free;
|
((struct memory_free_block *)address)->link = slab->free;
|
||||||
slab->free = (struct memory_free_block *)address;
|
slab->free = (struct memory_free_block *)address;
|
||||||
if (slab->left++ == 0)
|
if (slab->left++ == 0)
|
||||||
move_slab (&cache->used,&cache->free);
|
__memory_move_slab (&cache->used,&cache->free);
|
||||||
else if (slab->left == cache->blocks_per_slab)
|
else if (slab->left == cache->blocks_per_slab)
|
||||||
{
|
{
|
||||||
move_slab (&cache->free,&cache->reap);
|
__memory_move_slab (&cache->free,&cache->reap);
|
||||||
cache_tree = move_cache (cache_tree,cache,+1);
|
cache_tree = __memory_move_cache (cache_tree,cache,+1);
|
||||||
}
|
}
|
||||||
return MEMORY_RETURN_SUCCESS;
|
return MEMORY_RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
62
firmware/test/memory/memory-slab.h
Normal file
62
firmware/test/memory/memory-slab.h
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id:
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Alan Korr
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#ifndef __LIBRARY_MEMORY_SLAB_H__
|
||||||
|
#define __LIBRARY_MEMORY_SLAB_H__
|
||||||
|
|
||||||
|
struct memory_free_block
|
||||||
|
{
|
||||||
|
struct memory_free_block
|
||||||
|
*link;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct memory_slab
|
||||||
|
{
|
||||||
|
struct memory_slab
|
||||||
|
*less,*more;
|
||||||
|
unsigned int // left == number of free blocks left
|
||||||
|
left;
|
||||||
|
struct memory_free_block
|
||||||
|
*free;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct memory_cache
|
||||||
|
{
|
||||||
|
struct memory_cache
|
||||||
|
*less,*more,*same;
|
||||||
|
unsigned int
|
||||||
|
left; // number of free slabs
|
||||||
|
struct memory_slab
|
||||||
|
*used;
|
||||||
|
struct memory_slab
|
||||||
|
*free;
|
||||||
|
struct memory_slab
|
||||||
|
*reap;
|
||||||
|
unsigned int
|
||||||
|
size,original_size;
|
||||||
|
unsigned int
|
||||||
|
page_size;
|
||||||
|
unsigned int
|
||||||
|
blocks_per_slab;
|
||||||
|
int
|
||||||
|
page_order;
|
||||||
|
unsigned int
|
||||||
|
flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
0
firmware/test/memory/memory-slab.txt
Normal file
0
firmware/test/memory/memory-slab.txt
Normal file
Loading…
Add table
Add a link
Reference in a new issue