Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals | Related Pages

rtl_malloc.c File Reference

#include "rtl_malloc.h"
#include "arch/bits.h"

Include dependency graph for rtl_malloc.c:

Go to the source code of this file.

Data Structures

struct  block_header_struct
struct  fl_array_struct
struct  free_ptr_struct
struct  TLSF_struct

Defines

#define INIT_THREAD_MUTEX()
#define THREAD_LOCK()
#define THREAD_UNLOCK()
#define TLSF_WORD_SIZE   4
#define LOG2_TLSF_WORD_SIZE   2
#define MIN_LOG2_SIZE   2
#define MIN_SIZE   4
#define TLSF_WORDS2BYTES(x)   ((x) << LOG2_TLSF_WORD_SIZE)
#define BYTES2TLSF_WORDS(x)   ((x) >> LOG2_TLSF_WORD_SIZE)
#define USED_BLOCK   0x80000000
#define FREE_BLOCK   ~USED_BLOCK
#define LAST_BLOCK   0x40000000
#define NOT_LAST_BLOCK   ~LAST_BLOCK
#define IS_USED_BLOCK(x)   ((x -> size & USED_BLOCK) == USED_BLOCK)
#define IS_LAST_BLOCK(x)   ((x -> size & LAST_BLOCK) == LAST_BLOCK)
#define GET_BLOCK_SIZE(x)   (x -> size & FREE_BLOCK & NOT_LAST_BLOCK)
#define SET_USED_BLOCK(x)   (x -> size |= USED_BLOCK)
#define SET_FREE_BLOCK(x)   (x -> size &= FREE_BLOCK)
#define SET_LAST_BLOCK(x)   (x -> size |= LAST_BLOCK)
#define SET_NOT_LAST_BLOCK(x)   (x -> size &= NOT_LAST_BLOCK)
#define MAGIC_NUMBER   0x2A59FA59
#define TLSF__set_bit(num, mem)   mem |= (1 << num)
#define TLSF__clear_bit(num, mem)   mem &= ~(1 << num)

Typedefs

typedef free_ptr_struct free_ptr_t
typedef block_header_struct block_header_t
typedef fl_array_struct fl_array_t
typedef TLSF_struct TLSF_t

Functions

__s32 log2size (size_t size, size_t *new_size)
__s32 mapping_function (size_t size, __s32 *fl, __s32 *sl, TLSF_t *ptr_TLSF)
int init_memory_pool (int max_size, int max_sl_log2_index, char *block_ptr)
void destroy_memory_pool (char *block_ptr)
void * rtl_malloc_ex (size_t size, char *block_ptr)
void rtl_free_ex (void *ptr, char *block_ptr)
void * rtl_realloc_ex (void *p, size_t new_len, char *block_ptr)
void * rtl_calloc_ex (size_t nelem, size_t elem_size, char *block_ptr)
void print_block (block_header_t *b)
void structure_status (char *block_ptr)
void free_blocks_status (char *block_ptr)
void dump_memory_region (unsigned char *mem_ptr, unsigned int size)

Variables

__s32 beg_header_overhead = 0
char * main_buffer = NULL


Define Documentation

#define BYTES2TLSF_WORDS  )     ((x) >> LOG2_TLSF_WORD_SIZE)
 

Definition at line 108 of file rtl_malloc.c.

Referenced by init_memory_pool(), and rtl_malloc_ex().

#define FREE_BLOCK   ~USED_BLOCK
 

Definition at line 139 of file rtl_malloc.c.

Referenced by print_block().

#define GET_BLOCK_SIZE  )     (x -> size & FREE_BLOCK & NOT_LAST_BLOCK)
 

Definition at line 146 of file rtl_malloc.c.

Referenced by init_memory_pool(), rtl_free_ex(), rtl_malloc_ex(), and structure_status().

 
#define INIT_THREAD_MUTEX  ) 
 

Definition at line 69 of file rtl_malloc.c.

Referenced by init_memory_pool().

#define IS_LAST_BLOCK  )     ((x -> size & LAST_BLOCK) == LAST_BLOCK)
 

Definition at line 145 of file rtl_malloc.c.

Referenced by rtl_free_ex(), rtl_malloc_ex(), and structure_status().

#define IS_USED_BLOCK  )     ((x -> size & USED_BLOCK) == USED_BLOCK)
 

Definition at line 144 of file rtl_malloc.c.

Referenced by rtl_free_ex().

#define LAST_BLOCK   0x40000000
 

Definition at line 141 of file rtl_malloc.c.

Referenced by print_block().

#define LOG2_TLSF_WORD_SIZE   2
 

Definition at line 100 of file rtl_malloc.c.

Referenced by init_memory_pool().

#define MAGIC_NUMBER   0x2A59FA59
 

Definition at line 152 of file rtl_malloc.c.

Referenced by free_blocks_status(), init_memory_pool(), rtl_free_ex(), rtl_malloc_ex(), and structure_status().

#define MIN_LOG2_SIZE   2
 

Definition at line 104 of file rtl_malloc.c.

Referenced by free_blocks_status(), init_memory_pool(), rtl_free_ex(), and rtl_malloc_ex().

#define MIN_SIZE   4
 

Definition at line 105 of file rtl_malloc.c.

Referenced by init_memory_pool(), mem_realloc(), and rtl_malloc_ex().

#define NOT_LAST_BLOCK   ~LAST_BLOCK
 

Definition at line 142 of file rtl_malloc.c.

#define SET_FREE_BLOCK  )     (x -> size &= FREE_BLOCK)
 

Definition at line 148 of file rtl_malloc.c.

Referenced by rtl_free_ex().

#define SET_LAST_BLOCK  )     (x -> size |= LAST_BLOCK)
 

Definition at line 149 of file rtl_malloc.c.

Referenced by init_memory_pool(), rtl_free_ex(), and rtl_malloc_ex().

#define SET_NOT_LAST_BLOCK  )     (x -> size &= NOT_LAST_BLOCK)
 

Definition at line 150 of file rtl_malloc.c.

#define SET_USED_BLOCK  )     (x -> size |= USED_BLOCK)
 

Definition at line 147 of file rtl_malloc.c.

Referenced by rtl_malloc_ex().

 
#define THREAD_LOCK  ) 
 

Definition at line 70 of file rtl_malloc.c.

Referenced by rtl_free_ex(), and rtl_malloc_ex().

 
#define THREAD_UNLOCK  ) 
 

Definition at line 71 of file rtl_malloc.c.

Referenced by rtl_free_ex(), and rtl_malloc_ex().

#define TLSF__clear_bit num,
mem   )     mem &= ~(1 << num)
 

Definition at line 215 of file rtl_malloc.c.

Referenced by rtl_free_ex(), and rtl_malloc_ex().

#define TLSF__set_bit num,
mem   )     mem |= (1 << num)
 

Definition at line 214 of file rtl_malloc.c.

Referenced by init_memory_pool(), rtl_free_ex(), and rtl_malloc_ex().

#define TLSF_WORD_SIZE   4
 

Definition at line 99 of file rtl_malloc.c.

#define TLSF_WORDS2BYTES  )     ((x) << LOG2_TLSF_WORD_SIZE)
 

Definition at line 107 of file rtl_malloc.c.

Referenced by free_blocks_status(), init_memory_pool(), print_block(), rtl_free_ex(), rtl_malloc_ex(), rtl_realloc_ex(), and structure_status().

#define USED_BLOCK   0x80000000
 

Definition at line 138 of file rtl_malloc.c.

Referenced by print_block().


Typedef Documentation

typedef struct block_header_struct block_header_t
 

Referenced by free_blocks_status(), init_memory_pool(), print_block(), rtl_free_ex(), rtl_malloc_ex(), rtl_realloc_ex(), and structure_status().

typedef struct fl_array_struct fl_array_t
 

Referenced by init_memory_pool().

typedef struct free_ptr_struct free_ptr_t
 

typedef struct TLSF_struct TLSF_t
 

Referenced by destroy_memory_pool(), free_blocks_status(), init_memory_pool(), mapping_function(), rtl_free_ex(), rtl_malloc_ex(), and structure_status().


Function Documentation

void destroy_memory_pool char *  block_ptr  ) 
 

Definition at line 385 of file rtl_malloc.c.

References TLSF_t.

Referenced by main().

00385                                            {
00386   TLSF_t *ptr_TLSF;
00387   ptr_TLSF = (TLSF_t *) block_ptr;
00388   ptr_TLSF -> magic_number = 0;
00389 } 

void dump_memory_region unsigned char *  mem_ptr,
unsigned int  size
 

Definition at line 907 of file rtl_malloc.c.

References PRINT_DBG_C, and PRINT_DBG_H.

00907                                                                     {
00908   
00909   unsigned int begin = (unsigned int) mem_ptr;
00910   unsigned int end = (unsigned int) mem_ptr + size;
00911   int column = 0;
00912 
00913   begin >>= 2;
00914   begin <<= 2;
00915   
00916   end >>= 2;
00917   end ++;
00918   end <<= 2;
00919   
00920   PRINT_DBG_C ("\nMemory region dumped: 0x");
00921   PRINT_DBG_H (begin);
00922   PRINT_DBG_C (" - ");
00923   PRINT_DBG_H (end);
00924   PRINT_DBG_C ("\n\n");
00925   
00926   column = 0;
00927   PRINT_DBG_C ("\t\t+0");
00928   PRINT_DBG_C ("\t+1");
00929   PRINT_DBG_C ("\t+2");
00930   PRINT_DBG_C ("\t+3");
00931   PRINT_DBG_C ("\t+4");
00932   PRINT_DBG_C ("\t+5");
00933   PRINT_DBG_C ("\n0x");
00934   PRINT_DBG_H (begin);
00935   PRINT_DBG_C ("\t");
00936 
00937   while (begin < end) {
00938     if (((unsigned char *) begin) [0] == 0)
00939       PRINT_DBG_C ("00");
00940     else
00941       PRINT_DBG_H (((unsigned char *) begin) [0]);
00942     if (((unsigned char *) begin) [1] == 0)
00943       PRINT_DBG_C ("00");
00944     else
00945       PRINT_DBG_H (((unsigned char *) begin) [1]);
00946     PRINT_DBG_C ("\t");
00947     begin += 2;
00948     column ++;
00949     if (column == 6) {
00950       PRINT_DBG_C ("\n0x");
00951       PRINT_DBG_H (begin);
00952       PRINT_DBG_C ("\t");
00953       column = 0;
00954     }
00955 
00956   }
00957   PRINT_DBG_C ("\n\n"); 
00958 }

void free_blocks_status char *  block_ptr  ) 
 

Definition at line 860 of file rtl_malloc.c.

References block_header_t, block_header_struct::free_ptr, MAGIC_NUMBER, MIN_LOG2_SIZE, free_ptr_struct::next, NULL, print_block(), PRINT_DBG_C, PRINT_DBG_D, PRINT_DBG_H, PRINT_MSG, TLSF_t, and TLSF_WORDS2BYTES.

00860                                          {
00861   int i, j;
00862   block_header_t *b;
00863 
00864   TLSF_t *ptr_TLSF;
00865   
00866   ptr_TLSF = (TLSF_t *) block_ptr; 
00867   if (ptr_TLSF == NULL || ptr_TLSF -> magic_number != MAGIC_NUMBER) {
00868     PRINT_MSG ("FATAL ERROR: TLSF structure not initialized\n");
00869     return;
00870   }
00871 
00872   PRINT_DBG_C ("\nTLSF structure address 0x");
00873   PRINT_DBG_H (ptr_TLSF);
00874   PRINT_DBG_C ("\nFREE BLOCKS\n\n");
00875   for (i = ptr_TLSF -> max_fl_index  - 1 - MIN_LOG2_SIZE; i >= 0; i--) {
00876     if (ptr_TLSF -> fl_array [i].bitmapSL > 0)
00877       for (j = ptr_TLSF -> max_sl_index - 1; j >= 0; j--) {
00878         if (ptr_TLSF -> fl_array [i].sl_array[j] != NULL) {
00879           b = ptr_TLSF -> fl_array [i].sl_array [j];
00880           PRINT_DBG_C ("[");
00881           PRINT_DBG_D (i + MIN_LOG2_SIZE);
00882           PRINT_DBG_C ("] ");
00883           PRINT_DBG_D (TLSF_WORDS2BYTES(1 << (i + MIN_LOG2_SIZE)));
00884           PRINT_DBG_C (" bytes -> Free blocks: 0x");
00885           PRINT_DBG_H (ptr_TLSF -> fl_array [i].bitmapSL);
00886           PRINT_DBG_C ("\n");
00887           
00888           while (b != NULL) {
00889             PRINT_DBG_C (">>>> First_Level [");
00890             PRINT_DBG_D (i + MIN_LOG2_SIZE);
00891             PRINT_DBG_C ("] Second Level [");
00892             PRINT_DBG_D (j);
00893             PRINT_DBG_C ("] -> ");
00894             PRINT_DBG_D (TLSF_WORDS2BYTES((1 << (i + MIN_LOG2_SIZE)) + 
00895                           ( ((1 << (i + MIN_LOG2_SIZE)) / 
00896                              ptr_TLSF -> max_sl_index) * j)));
00897 
00898             PRINT_DBG_C (" bytes\n");
00899             print_block (b);
00900             b = b -> ptr.free_ptr.next;
00901           }
00902         }
00903       }
00904   }
00905 }

Here is the call graph for this function:

int init_memory_pool int  max_size,
int  max_sl_log2_index,
char *  block_ptr
 

Definition at line 270 of file rtl_malloc.c.

References __s32, __u32, beg_header_overhead, block_header_t, BYTES2TLSF_WORDS, fl_array_t, GET_BLOCK_SIZE, INIT_THREAD_MUTEX, LOG2_TLSF_WORD_SIZE, MAGIC_NUMBER, mapping_function(), MAX_FL_INDEX, MIN_LOG2_SIZE, MIN_SIZE, NULL, PRINT_MSG, SET_LAST_BLOCK, TLSF__set_bit, TLSF_t, and TLSF_WORDS2BYTES.

Referenced by main().

00271                                                               {
00272   __s32 n, free_mem = 0, total_size;
00273   block_header_t *initial_block_ptr;
00274   __s32 size_fl_sl_array, i, fl, sl;
00275   TLSF_t *ptr_TLSF;
00276   
00277   if (!(max_size > 0)) {
00278     PRINT_MSG ("ERROR: size must be > 0\n");
00279     return -1;
00280   }
00281   
00282   if (max_sl_log2_index > 5 || max_sl_log2_index < 1) {
00283     PRINT_MSG ("ERROR max_sl_log2_index must be >=1 or <= 5\n");
00284     return -1;
00285   }
00286   
00287   if (max_sl_log2_index <= 0) {
00288     PRINT_MSG ("ERROR: max_sl_log2_index (%d) must be >= 0\n", 
00289                max_sl_log2_index);
00290     return -1;
00291   }
00292 
00293   if ((((__u32) block_ptr >> LOG2_TLSF_WORD_SIZE) << LOG2_TLSF_WORD_SIZE) 
00294       != (__u32) block_ptr) {
00295     PRINT_MSG ("ERROR block_ptr must be aligned\n");
00296     return -1;
00297   }
00298   
00299   memset ((char *) block_ptr, 0x00, max_size * 1024);
00300 
00301   INIT_THREAD_MUTEX();
00302   ptr_TLSF = (TLSF_t *) block_ptr;
00303   
00304   ptr_TLSF -> magic_number = MAGIC_NUMBER;
00305   
00306   /* Total size of the block, TLSF_struct + free_memory */
00307   
00308   total_size = BYTES2TLSF_WORDS(max_size * 1024);
00309 
00310   ptr_TLSF -> max_sl_log2_index = max_sl_log2_index;
00311   ptr_TLSF -> max_sl_index = (1 << ptr_TLSF -> max_sl_log2_index);
00312   
00313   size_fl_sl_array = BYTES2TLSF_WORDS((__s32) sizeof (fl_array_t) +
00314     ((__s32) sizeof (block_header_t *) * (__s32) ptr_TLSF -> max_sl_index));
00315 
00316   free_mem = total_size - BYTES2TLSF_WORDS(sizeof (TLSF_t)) - size_fl_sl_array;
00317     
00318   n = MIN_LOG2_SIZE + 1;
00319   
00320   while ((int) TLSF_WORDS2BYTES(free_mem) > 
00321          (1 << (n + LOG2_TLSF_WORD_SIZE)) && n < MAX_FL_INDEX) {
00322     n ++;
00323     free_mem -= size_fl_sl_array;
00324   }
00325   
00326   if (free_mem < 0) return -1;
00327 
00328   // max_fl_index never will be greater than 32 (4 Gbytes)
00329   
00330   ptr_TLSF -> max_fl_index = n;
00331   ptr_TLSF -> max_fl_pow2_index = (1 << ptr_TLSF -> max_fl_index);
00332   
00333   n -= MIN_LOG2_SIZE;
00334   
00335   /* max_fl_index will never be greater than MAX_FL_INDEX */
00336   if (ptr_TLSF -> max_fl_index < 0 || MAX_FL_INDEX < 0) return -1;
00337   
00338   ptr_TLSF -> fl_array = ( fl_array_t *) 
00339     ((__u32) &(ptr_TLSF -> fl_array) 
00340      + (__u32) sizeof (ptr_TLSF -> fl_array));
00341   
00342   for (i = 0 ; i < n; i ++)
00343     ptr_TLSF -> fl_array [i] .sl_array = (block_header_t **) 
00344       (((__s32) ptr_TLSF -> fl_array + ((__s32) sizeof (fl_array_t) * n)) +
00345        ((__s32) sizeof (block_header_t *) *
00346         (__s32) ptr_TLSF -> max_sl_index * i));
00347   
00348   initial_block_ptr = (block_header_t *) 
00349     ((__u32) ptr_TLSF -> fl_array + 
00350      (TLSF_WORDS2BYTES(size_fl_sl_array) * n));
00351   
00352   ptr_TLSF -> first_bh = initial_block_ptr;
00353   
00354   beg_header_overhead = BYTES2TLSF_WORDS((int) initial_block_ptr -> ptr.buffer
00355                                          - (int) initial_block_ptr);
00356 
00357   ptr_TLSF -> bitmapFL = 0;
00358  
00359   
00360   initial_block_ptr -> size =
00361     free_mem - beg_header_overhead;
00362 
00363   SET_LAST_BLOCK (initial_block_ptr);
00364 
00365   initial_block_ptr -> ptr.free_ptr.prev = NULL;
00366   initial_block_ptr -> ptr.free_ptr.next = NULL;
00367   initial_block_ptr -> prev_phys_block = NULL;
00368   
00369   if (TLSF_WORDS2BYTES(GET_BLOCK_SIZE(initial_block_ptr)) 
00370       <= MIN_SIZE) {
00371     return -1;
00372   } else {
00373     mapping_function (GET_BLOCK_SIZE(initial_block_ptr), &fl, &sl, 
00374                       ptr_TLSF);
00375     fl -= MIN_LOG2_SIZE;
00376   }
00377 
00378   ptr_TLSF -> fl_array [fl].sl_array [sl] = initial_block_ptr;
00379   TLSF__set_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00380   TLSF__set_bit (fl, ptr_TLSF -> bitmapFL);
00381   
00382   return TLSF_WORDS2BYTES(GET_BLOCK_SIZE(initial_block_ptr));
00383 }

Here is the call graph for this function:

__s32 log2size size_t  size,
size_t *  new_size
[inline, static]
 

Definition at line 226 of file rtl_malloc.c.

References __s32, and TLSF_fls().

Referenced by mapping_function().

00226                                                              {
00227   
00228   __s32 i;
00229 
00230   /* Other way quicker and also more machine dependent that the first one */
00231   /*------------------------------*/
00232   i = TLSF_fls(size);
00233   
00234     
00235   *new_size = (1 << i);
00236 
00237   return i;
00238 }

Here is the call graph for this function:

__s32 mapping_function size_t  size,
__s32 *  fl,
__s32 *  sl,
TLSF_t ptr_TLSF
[inline, static]
 

Definition at line 251 of file rtl_malloc.c.

References __s32, log2size(), and TLSF_t.

Referenced by init_memory_pool(), rtl_free_ex(), and rtl_malloc_ex().

00252                                                        {
00253   __s32 aux, new_len;
00254    
00255   /* This is a new way to calculate first level index 
00256      and second level index, it is quicker than older one */
00257   
00258   *fl = log2size (size, &new_len);
00259   aux = (*fl - ptr_TLSF -> max_sl_log2_index);
00260   *sl = ((size ^ new_len) >> aux);
00261   
00262   return 0;
00263 }

Here is the call graph for this function:

void print_block block_header_t b  )  [static]
 

Definition at line 786 of file rtl_malloc.c.

References block_header_t, FREE_BLOCK, block_header_struct::free_ptr, LAST_BLOCK, free_ptr_struct::next, NULL, free_ptr_struct::prev, PRINT_DBG_C, PRINT_DBG_D, PRINT_DBG_H, TLSF_WORDS2BYTES, and USED_BLOCK.

Referenced by free_blocks_status(), and structure_status().

00786                                            {
00787   if (b == NULL) return;
00788 
00789   PRINT_DBG_C (">>>> Address 0x");
00790   PRINT_DBG_H (b);
00791   
00792   if ((b -> size & USED_BLOCK) != USED_BLOCK)
00793     PRINT_DBG_C ("\n>>>> Status FREE");
00794   else
00795     PRINT_DBG_C ("\n>>>> Status USED");
00796   
00797   PRINT_DBG_C (" Block Size ");
00798   PRINT_DBG_D (TLSF_WORDS2BYTES(b -> size));
00799   PRINT_DBG_C (" bytes");
00800   
00801   if (b -> prev_phys_block == NULL)
00802     PRINT_DBG_C ("\n>>>> FIRST BLOCK");
00803   else {
00804     PRINT_DBG_C ("\n>>>> PREV. PHYS. BLOCK 0x");
00805     PRINT_DBG_H (b -> prev_phys_block);
00806   }
00807 
00808   if ((b -> size & LAST_BLOCK) == LAST_BLOCK)
00809     PRINT_DBG_C (" LAST BLOCK");
00810   else
00811     PRINT_DBG_C (" NOT LAST BLOCK");
00812   
00813   if ((b -> size & FREE_BLOCK) == FREE_BLOCK){
00814     PRINT_DBG_C ("\n---- Prev Free 0x");
00815     PRINT_DBG_H (b -> ptr.free_ptr.prev);
00816     PRINT_DBG_C (" Next Free 0x");
00817     PRINT_DBG_H (b -> ptr.free_ptr.next);
00818   }
00819   PRINT_DBG_C ("\n\n");
00820 }

void* rtl_calloc_ex size_t  nelem,
size_t  elem_size,
char *  block_ptr
 

Definition at line 764 of file rtl_malloc.c.

References __u8, NULL, and rtl_malloc_ex().

00764                                                                       {
00765 #else
00766 void *calloc_ex (size_t nelem, size_t elem_size, char *block_ptr) {
00767 #endif
00768 
00769   __u8 *p;
00770 
00771   if (nelem <= 0 || elem_size <= 0) return NULL;
00772 
00773 #ifdef WITH_RTL_PREFIX
00774   if ((p = (__u8 *) rtl_malloc_ex (nelem * elem_size, block_ptr)) == NULL)
00775     return NULL;
00776 #else
00777   if ((p = (__u8 *) malloc_ex (nelem * elem_size, block_ptr)) == NULL )
00778     return NULL;
00779 #endif
00780 
00781   memset (p, 0, nelem * elem_size);
00782   
00783   return ((void *) p);
00784 }

Here is the call graph for this function:

void rtl_free_ex void *  ptr,
char *  block_ptr
 

Definition at line 582 of file rtl_malloc.c.

References __u8, beg_header_overhead, block_header_t, block_header_struct::buffer, free_ptr_struct::first_index, block_header_struct::free_ptr, GET_BLOCK_SIZE, IS_LAST_BLOCK, IS_USED_BLOCK, MAGIC_NUMBER, mapping_function(), MIN_LOG2_SIZE, free_ptr_struct::next, NULL, free_ptr_struct::prev, PRINT_MSG, free_ptr_struct::second_index, SET_FREE_BLOCK, SET_LAST_BLOCK, THREAD_LOCK, THREAD_UNLOCK, TLSF__clear_bit, TLSF__set_bit, TLSF_t, and TLSF_WORDS2BYTES.

Referenced by rtl_realloc_ex().

00582                                               {
00583 #else
00584 void free_ex (void *ptr, char *block_ptr) {
00585 #endif
00586   int fl, sl;
00587   block_header_t *bh = NULL, *bh2 = NULL, *bh3;
00588 
00589   TLSF_t *ptr_TLSF;
00590 
00591   ptr_TLSF = (TLSF_t *) block_ptr;
00592 
00593   if (ptr_TLSF == NULL || ptr_TLSF -> magic_number != MAGIC_NUMBER) {
00594     PRINT_MSG ("FATAL ERROR: TLSF structure not initialized\n");
00595     return;
00596   }
00597 
00598   bh = (block_header_t *) ((__u8 *) ptr - 
00599                            TLSF_WORDS2BYTES(beg_header_overhead));
00600  
00601   THREAD_LOCK();
00602   /* now bh is a free block */
00603   
00604   SET_FREE_BLOCK (bh);
00605   bh -> ptr.free_ptr.prev = NULL;
00606   bh -> ptr.free_ptr.next = NULL;
00607 
00608   /*
00609    * first of all, we will try to merge bh with the
00610    * physically contiguos free block and
00611    * after we will inserte bh into TLSF structure
00612    */
00613 
00614   /* Now we will try if we can merge bh with the next phys. contiguos block */
00615   if (!IS_LAST_BLOCK (bh)) {
00616     /* is it the next block free? */
00617     /* The next block is easy to found */
00618     
00619     bh2 = (block_header_t *) (__u8 *) (bh -> ptr.buffer + 
00620                                        TLSF_WORDS2BYTES
00621                                        (GET_BLOCK_SIZE(bh)));
00622     if (!IS_USED_BLOCK (bh2)) {
00623       /* we are lucky, we can merge bh with the following one */  
00624       if (bh2 -> ptr.free_ptr.next != NULL)
00625         bh2 -> ptr.free_ptr.next -> ptr.free_ptr.prev =
00626           bh2  -> ptr.free_ptr.prev;
00627       
00628       if (bh2 -> ptr.free_ptr.prev != NULL)
00629         bh2 -> ptr.free_ptr.prev -> ptr.free_ptr.next =
00630           bh2 -> ptr.free_ptr.next;
00631       
00632       fl = bh2 -> ptr.free_ptr.first_index;
00633       sl = bh2 -> ptr.free_ptr.second_index;
00634       
00635       /* bh2 must be deleted from fl_array */
00636       if (ptr_TLSF -> fl_array [fl].sl_array [sl] == bh2)
00637         ptr_TLSF -> fl_array [fl].sl_array [sl] = bh2 -> ptr.free_ptr.next;
00638       
00639       if (ptr_TLSF -> fl_array [fl].sl_array [sl] == NULL){
00640         TLSF__clear_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00641         if (!ptr_TLSF -> fl_array[fl].bitmapSL) 
00642           TLSF__clear_bit (fl, ptr_TLSF -> bitmapFL);
00643         
00644       }
00645 
00646       bh -> size += bh2 -> size + beg_header_overhead;
00647       if (!IS_LAST_BLOCK (bh2)) {
00648         bh3 = (block_header_t *) (__u8 *) (bh2 -> ptr.buffer + 
00649                                            TLSF_WORDS2BYTES
00650                                            (GET_BLOCK_SIZE(bh2)));
00651         bh3 -> prev_phys_block = bh;
00652       }
00653       
00654       if (IS_LAST_BLOCK (bh2)) SET_LAST_BLOCK (bh);
00655     }
00656   }
00657 
00658   /* is it free the previous physical block? */
00659   if (bh -> prev_phys_block != NULL) { // This block is not the first block
00660    
00661     bh2 = bh -> prev_phys_block;
00662   
00663     if (!IS_USED_BLOCK (bh2)) {
00664 
00665       if (bh2 -> ptr.free_ptr.next != NULL)
00666         bh2 -> ptr.free_ptr.next -> ptr.free_ptr.prev =
00667           bh2  -> ptr.free_ptr.prev;
00668       
00669       if (bh2 -> ptr.free_ptr.prev != NULL)
00670         bh2 -> ptr.free_ptr.prev -> ptr.free_ptr.next =
00671           bh2 -> ptr.free_ptr.next;
00672       
00673       fl = bh2 -> ptr.free_ptr.first_index;
00674       sl = bh2 -> ptr.free_ptr.second_index;
00675         
00676       if (ptr_TLSF -> fl_array [fl].sl_array [sl] == bh2)
00677         ptr_TLSF -> fl_array [fl].sl_array [sl] = bh2 -> ptr.free_ptr.next;
00678       
00679       if (ptr_TLSF -> fl_array[fl].sl_array[sl] == NULL){
00680         
00681         TLSF__clear_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00682         if (!ptr_TLSF -> fl_array[fl].bitmapSL)
00683           TLSF__clear_bit (fl, ptr_TLSF -> bitmapFL);
00684         
00685       }     
00686       bh2 -> size += bh -> size + beg_header_overhead;
00687 
00688       bh = bh2;
00689       if (!IS_LAST_BLOCK (bh)) {
00690         bh3 = (block_header_t *) (__u8 *) (bh -> ptr.buffer + 
00691                                            TLSF_WORDS2BYTES
00692                                            (GET_BLOCK_SIZE(bh)));
00693         bh3 -> prev_phys_block = bh;
00694       }
00695     
00696     }
00697  
00698   }
00699 
00700   /*
00701    * and now we can merge the free block with the initial memory
00702    */
00703   mapping_function (GET_BLOCK_SIZE (bh), &fl, &sl, ptr_TLSF);
00704   fl -= MIN_LOG2_SIZE;
00705   bh -> ptr.free_ptr.first_index = fl;
00706   bh -> ptr.free_ptr.second_index = sl;
00707   bh -> ptr.free_ptr.next = ptr_TLSF -> fl_array [fl].sl_array [sl];
00708   bh -> ptr.free_ptr.prev = NULL;
00709  
00710   if (ptr_TLSF -> fl_array [fl].sl_array [sl] != NULL)
00711     ptr_TLSF -> fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = bh;
00712   ptr_TLSF -> fl_array [fl].sl_array [sl] = bh;
00713 
00714   TLSF__set_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00715   TLSF__set_bit (fl, ptr_TLSF -> bitmapFL);    
00716   THREAD_UNLOCK();
00717 }

Here is the call graph for this function:

void* rtl_malloc_ex size_t  size,
char *  block_ptr
 

Definition at line 406 of file rtl_malloc.c.

References __u8, beg_header_overhead, block_header_t, block_header_struct::buffer, BYTES2TLSF_WORDS, free_ptr_struct::first_index, TLSF_struct::fl_array, block_header_struct::free_ptr, GET_BLOCK_SIZE, IS_LAST_BLOCK, MAGIC_NUMBER, mapping_function(), MIN_LOG2_SIZE, MIN_SIZE, free_ptr_struct::next, NULL, free_ptr_struct::prev, PRINT_MSG, free_ptr_struct::second_index, SET_LAST_BLOCK, SET_USED_BLOCK, fl_array_struct::sl_array, THREAD_LOCK, THREAD_UNLOCK, TLSF__clear_bit, TLSF__set_bit, TLSF_fls(), TLSF_t, and TLSF_WORDS2BYTES.

Referenced by rtl_calloc_ex(), and rtl_realloc_ex().

00406                                                    {
00407 #else
00408 void *malloc_ex (size_t size, char *block_ptr) {
00409 #endif
00410   TLSF_t *ptr_TLSF;
00411   int fl, sl, n, found = 0, old_size = BYTES2TLSF_WORDS(size), last_block;
00412   block_header_t *bh = NULL, *bh2 = NULL, *bh3 = NULL;
00413   
00414   ptr_TLSF = (TLSF_t *) block_ptr;
00415 
00416   if (ptr_TLSF == NULL || ptr_TLSF -> magic_number != MAGIC_NUMBER) {
00417     PRINT_MSG ("FATAL ERROR: TLSF structure not initialized\n");
00418     return NULL;
00419   }
00420 
00421   if (!(size > 0)) {
00422     PRINT_MSG ("ERROR: Memory pool exhausted!!!\n");
00423     return NULL;
00424   }
00425 
00426   if (old_size < MIN_SIZE) {
00427     size = MIN_SIZE;
00428     fl = 0;
00429     sl = 0;
00430   } else {
00431     mapping_function (old_size, &fl, &sl, ptr_TLSF);
00432 
00433     if (++sl == ptr_TLSF -> max_sl_index) {
00434       fl ++;
00435       sl = 0;
00436     }
00437     
00438     /*
00439      * This is the reason of the internal fragmentation
00440      * The block given is greater that the size demanded
00441      */
00442     
00443     /* size can be smaller that maximum SLI, in this case the mapping function
00444        has problems calculating fl and sl values */
00445  
00446     if (old_size >= 
00447         BYTES2TLSF_WORDS(ptr_TLSF -> max_sl_index << 2)) {
00448       size = (1 << fl);
00449       size += (sl << (fl - ptr_TLSF -> max_sl_log2_index));
00450     } else {
00451       size = old_size + 1;
00452       sl = old_size - MIN_SIZE;
00453     }
00454     
00455     fl -= MIN_LOG2_SIZE;
00456   }
00457 
00458 
00459   /*----------------------------------------*/
00460   /* The search for a free block begins now */
00461   /*----------------------------------------*/
00462   
00463   /*
00464    * Our first try, we take the first free block 
00465    * from fl_array or its buddy
00466    */
00467   
00468   THREAD_LOCK();
00469   sl = ptr_TLSF -> fl_array[fl].bitmapSL & ((~0) << sl);
00470   if (sl != 0) {
00471     sl = TLSF_fls(sl);
00472     bh =  ptr_TLSF -> fl_array [fl].sl_array [sl];
00473     ptr_TLSF -> fl_array [fl].sl_array [sl] = bh -> ptr.free_ptr.next;
00474     if (ptr_TLSF -> fl_array [fl].sl_array [sl] != NULL)
00475       ptr_TLSF ->fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = NULL;
00476     else {
00477       TLSF__clear_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00478       if (!ptr_TLSF -> fl_array[fl].bitmapSL)
00479         TLSF__clear_bit (fl, ptr_TLSF -> bitmapFL);
00480     }
00481     found = 1;
00482     goto out;
00483   }
00484   
00485   /*
00486    * On the last case a free block is searched using a bitmap
00487    */
00488   
00489   fl = TLSF_fls(ptr_TLSF -> bitmapFL & ((~0) << (fl + 1)));
00490   
00491   if (fl > 0) {
00492     sl = TLSF_fls(ptr_TLSF -> fl_array[fl].bitmapSL);
00493     bh = ptr_TLSF -> fl_array [fl].sl_array [sl];
00494     ptr_TLSF -> fl_array [fl].sl_array [sl] = bh -> ptr.free_ptr.next;
00495     if (ptr_TLSF -> fl_array [fl].sl_array [sl] != NULL){
00496       ptr_TLSF -> fl_array [fl].sl_array [sl] 
00497         -> ptr.free_ptr.prev = NULL;
00498     } else {
00499       TLSF__clear_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00500       if (!ptr_TLSF -> fl_array[fl].bitmapSL)
00501         TLSF__clear_bit (fl, ptr_TLSF -> bitmapFL);
00502     }
00503     found = 1;
00504     goto out;
00505   }
00506   /* end of the search */
00507   /*------------------------------------------------------------*/
00508   
00509  out:
00510   
00511   /*
00512    * HUGGGG, NOT ENOUGHT MEMORY
00513    * I think that we have done all that we have been able, I'm sorry
00514    */
00515   
00516   if (!found) {
00517     THREAD_UNLOCK();
00518     PRINT_MSG ("ERROR: Memory pool exhausted!!!\n");
00519     return NULL;
00520   }
00521   
00522   /*
00523    * we can say: YESSSSSSSSSSS, we have enought memory!!!!
00524    */
00525   
00526   /* can bh be splitted? */ 
00527   
00528   n = (int)(GET_BLOCK_SIZE(bh) - size - beg_header_overhead);
00529   if (n >= (int) MIN_SIZE) {
00530     /*
00531      * Yes, bh will be splitted
00532      */
00533 
00534     /* The new block will begin at the end of the current block */
00535     last_block = IS_LAST_BLOCK(bh)?1:0;
00536     bh -> size = size;
00537     SET_USED_BLOCK(bh);
00538     
00539     bh2 = (block_header_t *) (__u8 *) (bh -> ptr.buffer + 
00540                                        TLSF_WORDS2BYTES
00541                                        (GET_BLOCK_SIZE(bh)));
00542     bh2 -> prev_phys_block = bh;
00543     bh2 -> size = n;
00544     if (last_block) SET_LAST_BLOCK (bh2);
00545     mapping_function (GET_BLOCK_SIZE(bh2), &fl, &sl, ptr_TLSF);
00546     fl -= MIN_LOG2_SIZE;
00547     bh2 -> ptr.free_ptr.first_index = fl;
00548     bh2 -> ptr.free_ptr.second_index = sl;
00549     bh2 -> ptr.free_ptr.prev = NULL;
00550     bh2 -> ptr.free_ptr.next = ptr_TLSF -> fl_array [fl].sl_array [sl];
00551     
00552     if (!IS_LAST_BLOCK (bh2)) {
00553       bh3 = (block_header_t *) (__u8 *) (bh2 -> ptr.buffer + 
00554                                          TLSF_WORDS2BYTES
00555                                          (GET_BLOCK_SIZE(bh2)));
00556       bh3 -> prev_phys_block = bh2;
00557     }
00558     
00559 
00560     if (ptr_TLSF -> fl_array [fl].sl_array [sl] != NULL)
00561       ptr_TLSF -> fl_array [fl].sl_array [sl] -> ptr.free_ptr.prev = bh2;
00562     ptr_TLSF -> fl_array [fl].sl_array [sl] = bh2;
00563     TLSF__set_bit (sl, ptr_TLSF -> fl_array[fl].bitmapSL);
00564     TLSF__set_bit (fl, ptr_TLSF -> bitmapFL); 
00565   }
00566   
00567   SET_USED_BLOCK(bh);
00568 
00569   THREAD_UNLOCK();
00570   
00571   return (void *)  bh -> ptr.buffer; 
00572 }

Here is the call graph for this function:

void* rtl_realloc_ex void *  p,
size_t  new_len,
char *  block_ptr
 

Definition at line 721 of file rtl_malloc.c.

References __u8, beg_header_overhead, block_header_t, NULL, rtl_free_ex(), rtl_malloc_ex(), and TLSF_WORDS2BYTES.

00721                                                                 {
00722 #else
00723 void *realloc_ex (void *p, size_t new_len, char *block_ptr) {
00724 #endif
00725   __u8 *ptr_aux;
00726   block_header_t *b;
00727 
00728   if (p == NULL)
00729 #ifdef WITH_RTL_PREFIX
00730     return (void *) rtl_malloc_ex (new_len, block_ptr);
00731 #else
00732     return (void *) malloc_ex (new_len, block_ptr);
00733 #endif
00734   else if (new_len == 0) {
00735 #ifdef WITH_RTL_PREFIX
00736     rtl_free_ex (p, block_ptr);
00737 #else
00738     free_ex (p, block_ptr);
00739 #endif
00740     return NULL;
00741   }
00742 
00743 #ifdef WITH_RTL_PREFIX  
00744   ptr_aux = (__u8 *) rtl_malloc_ex (new_len * sizeof (__u8), block_ptr);
00745 #else
00746   ptr_aux = (__u8 *) malloc_ex (new_len * sizeof (__u8), block_ptr);
00747 #endif
00748   
00749   b = (block_header_t *) (((__u8 *) p) - 
00750                           TLSF_WORDS2BYTES(beg_header_overhead));
00751 
00752   memcpy ((__u8 *) ptr_aux, (__u8 *) b, b -> size);
00753 #ifdef WITH_RTL_PREFIX
00754   rtl_free_ex (p, block_ptr);
00755 #else
00756   free_ex (p, block_ptr);
00757 #endif
00758 
00759   return ((void *) ptr_aux);
00760 }

Here is the call graph for this function:

void structure_status char *  block_ptr  ) 
 

Definition at line 825 of file rtl_malloc.c.

References __u8, block_header_t, block_header_struct::buffer, GET_BLOCK_SIZE, IS_LAST_BLOCK, MAGIC_NUMBER, NULL, print_block(), PRINT_DBG_C, PRINT_DBG_D, PRINT_DBG_H, PRINT_MSG, TLSF_t, and TLSF_WORDS2BYTES.

00825                                         {
00826   block_header_t *b;
00827   TLSF_t *ptr_TLSF;
00828   int end = 0;
00829   
00830   ptr_TLSF = (TLSF_t *) block_ptr; 
00831   if (ptr_TLSF == NULL || ptr_TLSF -> magic_number != MAGIC_NUMBER) {
00832     PRINT_MSG ("FATAL ERROR: TLSF structure not initialized\n");
00833     return;
00834   }
00835  
00836   b = ptr_TLSF -> first_bh;
00837   PRINT_DBG_C ("\nTLSF structure address 0x");
00838   PRINT_DBG_H (ptr_TLSF);
00839   PRINT_DBG_C ("\nMax. first level index: ");
00840   PRINT_DBG_D (ptr_TLSF -> max_fl_index);
00841   PRINT_DBG_C ("\nMax. second level index: ");
00842   PRINT_DBG_D (ptr_TLSF -> max_sl_log2_index);
00843   PRINT_DBG_C ("\n\nALL BLOCKS\n");
00844   while (!end) {
00845     print_block (b);
00846     if (IS_LAST_BLOCK(b))
00847       end = 1;
00848     else
00849       b = (block_header_t *) (__u8 *) (b -> ptr.buffer + 
00850                                        TLSF_WORDS2BYTES
00851                                        (GET_BLOCK_SIZE(b)));
00852   }
00853 
00854 }

Here is the call graph for this function:


Variable Documentation

__s32 beg_header_overhead = 0 [static]
 

Definition at line 212 of file rtl_malloc.c.

Referenced by init_memory_pool(), rtl_free_ex(), rtl_malloc_ex(), and rtl_realloc_ex().

char* main_buffer = NULL
 

Definition at line 217 of file rtl_malloc.c.


Generated on Wed Jan 14 12:59:10 2004 for RTL-lwIP-0.4 by doxygen 1.3.4