sf_malloc.h

00001 /* $Id$
00002  *
00003  * shared memory, multi-process safe, pool based version of f_malloc
00004  *
00005  * Copyright (C) 2007 iptelorg GmbH
00006  *
00007  * Permission to use, copy, modify, and distribute this software for any
00008  * purpose with or without fee is hereby granted, provided that the above
00009  * copyright notice and this permission notice appear in all copies.
00010  *
00011  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
00012  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00013  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
00014  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00015  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00016  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00017  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00018  */
00019 /*
00020  * History:
00021  * --------
00022  *  2003-05-21  on sparc64 roundto 8 even in debugging mode (so malloc'ed
00023  *               long longs will be 64 bit aligned) (andrei)
00024  *  2004-07-19  support for 64 bit (2^64 mem. block) and more info
00025  *               for the future de-fragmentation support (andrei)
00026  *  2004-11-10  support for > 4Gb mem., switched to long (andrei)
00027  *  2007-06-09  forked from the f_malloc code (andrei)
00028  */
00029 
00030 
00031 #if !defined(sf_malloc_h)  
00032 #define sf_malloc_h
00033 
00034 
00035 #include "meminfo.h"
00036 
00037 #include "../lock_ops.h"
00038 #include "../atomic_ops.h"
00039 #include "../compiler_opt.h"
00040 /* defs*/
00041 
00042 
00043 #ifdef GEN_LOCK_T_UNLIMITED
00044 #define SFM_LOCK_PER_BUCKET
00045 #else
00046 #define SFM_ONE_LOCK
00047 #endif
00048 
00049 #ifdef DBG_SF_MALLOC
00050 #if defined(__CPU_sparc64) || defined(__CPU_sparc)
00051 /* tricky, on sun in 32 bits mode long long must be 64 bits aligned
00052  * but long can be 32 bits aligned => malloc should return long long
00053  * aligned memory */
00054         #define SF_ROUNDTO      sizeof(long long)
00055 #else
00056         #define SF_ROUNDTO      sizeof(void*) /* size we round to, must be = 2^n, and
00057                       sizeof(sfm_frag) must be multiple of SF_ROUNDTO !*/
00058 #endif
00059 #else /* DBG_SF_MALLOC */
00060         #define SF_ROUNDTO 8UL
00061 #endif
00062 #define SF_MIN_FRAG_SIZE        SF_ROUNDTO
00063 
00064 #define SFM_POOLS_NO 4U /* the more the better, but higher initial
00065                             mem. consumption */
00066 
00067 #define SF_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */
00068 #define SF_MALLOC_OPTIMIZE  (1UL<<SF_MALLOC_OPTIMIZE_FACTOR)
00069                                                                 /* size to optimize for,
00070                                                                         (most allocs <= this size),
00071                                                                         must be 2^k */
00072 
00073 #define SF_HASH_POOL_SIZE       (SF_MALLOC_OPTIMIZE/SF_ROUNDTO + 1)
00074 #define SF_POOL_MAX_SIZE        SF_MALLOC_OPTIMIZE
00075 
00076 #define SF_HASH_SIZE (SF_MALLOC_OPTIMIZE/SF_ROUNDTO + \
00077                 (sizeof(long)*8-SF_MALLOC_OPTIMIZE_FACTOR)+1)
00078 
00079 /* hash structure:
00080  * 0 .... SF_MALLOC_OPTIMIZE/SF_ROUNDTO  - small buckets, size increases with
00081  *                            SF_ROUNDTO from bucket to bucket
00082  * +1 .... end -  size = 2^k, big buckets */
00083 
00084 struct sfm_frag{
00085         union{
00086                 struct sfm_frag* nxt_free;
00087                 long reserved;
00088         }u;
00089         unsigned long size;
00090         unsigned long id; /* TODO better optimize the size */
00091         /* pad to SF_ROUNDTO multiple */
00092         char _pad[((3*sizeof(long)+SF_ROUNDTO-1)&~(SF_ROUNDTO-1))-3*sizeof(long)];
00093 #ifdef DBG_SF_MALLOC
00094         const char* file;
00095         const char* func;
00096         unsigned long line;
00097         unsigned long check;
00098 #endif
00099 };
00100 
00101 struct sfm_frag_lnk{
00102         struct sfm_frag* first;
00103 #ifdef SFM_LOCK_PER_BUCKET
00104         gen_lock_t lock;
00105 #endif
00106         unsigned long no;
00107 };
00108 
00109 struct sfm_pool_head{
00110         struct sfm_frag* first;
00111 #ifdef SFM_LOCK_PER_BUCKET
00112         gen_lock_t lock;
00113 #endif
00114         unsigned long no;
00115         unsigned long misses;
00116 };
00117 
00118 struct sfm_pool{
00119 #ifdef SFM_ONE_LOCK
00120         gen_lock_t lock;
00121 #endif
00122         unsigned long missed;
00123         unsigned long hits; /* debugging only TODO: remove */
00124         unsigned long bitmap;
00125         struct sfm_pool_head pool_hash[SF_HASH_POOL_SIZE];
00126 };
00127 
00128 struct sfm_block{
00129 #ifdef SFM_ONE_LOCK
00130         gen_lock_t lock;
00131 #endif
00132         atomic_t crt_id; /* current pool */
00133         unsigned long size; /* total size */
00134         /* stats are kept now per bucket */
00135         struct sfm_frag* first_frag;
00136         struct sfm_frag* last_frag;
00137         unsigned long bitmap; /* only up to SF_MALLOC_OPTIMIZE */
00138         struct sfm_frag_lnk free_hash[SF_HASH_SIZE];
00139         struct sfm_pool pool[SFM_POOLS_NO];
00140         int is_init;
00141         gen_lock_t get_and_split;
00142         char _pad[256];
00143 };
00144 
00145 
00146 
00147 struct sfm_block* sfm_malloc_init(char* address, unsigned long size);
00148 void sfm_malloc_destroy(struct sfm_block* qm);
00149 int sfm_pool_reset();
00150 
00151 #ifdef DBG_SF_MALLOC
00152 void* sfm_malloc(struct sfm_block*, unsigned long size,
00153                                         const char* file, const char* func, unsigned int line);
00154 #else
00155 void* sfm_malloc(struct sfm_block*, unsigned long size);
00156 #endif
00157 
00158 #ifdef DBG_SF_MALLOC
00159 void  sfm_free(struct sfm_block*, void* p, const char* file, const char* func, 
00160                                 unsigned int line);
00161 #else
00162 void  sfm_free(struct sfm_block*, void* p);
00163 #endif
00164 
00165 #ifdef DBG_SF_MALLOC
00166 void*  sfm_realloc(struct sfm_block*, void* p, unsigned long size, 
00167                                         const char* file, const char* func, unsigned int line);
00168 #else
00169 void*  sfm_realloc(struct sfm_block*, void* p, unsigned long size);
00170 #endif
00171 
00172 void  sfm_status(struct sfm_block*);
00173 void  sfm_info(struct sfm_block*, struct mem_info*);
00174 
00175 unsigned long sfm_available(struct sfm_block*);
00176 
00177 #endif