mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.9 KiB
179 lines
4.9 KiB
/* $Id$
|
|
*
|
|
* shared memory, multi-process safe, pool based, mostly lockless version of
|
|
* f_malloc
|
|
*
|
|
* Copyright (C) 2007 iptelorg GmbH
|
|
*
|
|
* Permission to use, copy, modify, and distribute this software for any
|
|
* purpose with or without fee is hereby granted, provided that the above
|
|
* copyright notice and this permission notice appear in all copies.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
*/
|
|
/*
|
|
* History:
|
|
* --------
|
|
* 2003-05-21 on sparc64 roundto 8 even in debugging mode (so malloc'ed
|
|
* long longs will be 64 bit aligned) (andrei)
|
|
* 2004-07-19 support for 64 bit (2^64 mem. block) and more info
|
|
* for the future de-fragmentation support (andrei)
|
|
* 2004-11-10 support for > 4Gb mem., switched to long (andrei)
|
|
* 2007-06-11 forked from the sf_malloc code (andrei)
|
|
*/
|
|
|
|
|
|
#if !defined(ll_malloc_h)
|
|
#define ll_malloc_h
|
|
|
|
|
|
#include "meminfo.h"
|
|
|
|
#include "../lock_ops.h"
|
|
#include "../atomic_ops.h"
|
|
#include "../compiler_opt.h"
|
|
/* defs*/
|
|
|
|
|
|
#ifdef GEN_LOCK_T_UNLIMITED
|
|
#define SFM_LOCK_PER_BUCKET
|
|
#else
|
|
#define SFM_ONE_LOCK
|
|
#endif
|
|
|
|
#ifdef DBG_SF_MALLOC
|
|
#if defined(__CPU_sparc64) || defined(__CPU_sparc)
|
|
/* tricky, on sun in 32 bits mode long long must be 64 bits aligned
|
|
* but long can be 32 bits aligned => malloc should return long long
|
|
* aligned memory */
|
|
#define SF_ROUNDTO sizeof(long long)
|
|
#else
|
|
#define SF_ROUNDTO sizeof(void*) /* size we round to, must be = 2^n, and
|
|
sizeof(sfm_frag) must be multiple of SF_ROUNDTO !*/
|
|
#endif
|
|
#else /* DBG_SF_MALLOC */
|
|
#define SF_ROUNDTO 8UL
|
|
#endif
|
|
#define SF_MIN_FRAG_SIZE SF_ROUNDTO
|
|
|
|
#define SFM_POOLS_NO 4U /* the more the better, but higher initial
|
|
mem. consumption */
|
|
|
|
#define SF_MALLOC_OPTIMIZE_FACTOR 14UL /*used below */
|
|
#define SF_MALLOC_OPTIMIZE (1UL<<SF_MALLOC_OPTIMIZE_FACTOR)
|
|
/* size to optimize for,
|
|
(most allocs <= this size),
|
|
must be 2^k */
|
|
|
|
#define SF_HASH_POOL_SIZE (SF_MALLOC_OPTIMIZE/SF_ROUNDTO + 1)
|
|
#define SF_POOL_MAX_SIZE SF_MALLOC_OPTIMIZE
|
|
|
|
#define SF_HASH_SIZE (SF_MALLOC_OPTIMIZE/SF_ROUNDTO + \
|
|
(sizeof(long)*8-SF_MALLOC_OPTIMIZE_FACTOR)+1)
|
|
|
|
/* hash structure:
|
|
* 0 .... SF_MALLOC_OPTIMIZE/SF_ROUNDTO - small buckets, size increases with
|
|
* SF_ROUNDTO from bucket to bucket
|
|
* +1 .... end - size = 2^k, big buckets */
|
|
|
|
struct sfm_frag{
|
|
union{
|
|
struct sfm_frag* nxt_free;
|
|
long reserved;
|
|
}u;
|
|
unsigned long size;
|
|
unsigned long id; /* TODO better optimize the size */
|
|
/* pad to SF_ROUNDTO multiple */
|
|
char _pad[((3*sizeof(long)+SF_ROUNDTO-1)&~(SF_ROUNDTO-1))-3*sizeof(long)];
|
|
#ifdef DBG_SF_MALLOC
|
|
const char* file;
|
|
const char* func;
|
|
unsigned long line;
|
|
unsigned long check;
|
|
#endif
|
|
};
|
|
|
|
struct sfm_frag_lnk{
|
|
struct sfm_frag* first;
|
|
#ifdef SFM_LOCK_PER_BUCKET
|
|
gen_lock_t lock;
|
|
#endif
|
|
unsigned long no;
|
|
};
|
|
|
|
struct sfm_pool_head{
|
|
struct sfm_frag* first;
|
|
#ifdef SFM_LOCK_PER_BUCKET
|
|
gen_lock_t lock;
|
|
#endif
|
|
unsigned long no;
|
|
unsigned long misses;
|
|
};
|
|
|
|
struct sfm_pool{
|
|
#ifdef SFM_ONE_LOCK
|
|
gen_lock_t lock;
|
|
#endif
|
|
unsigned long missed;
|
|
unsigned long hits; /* debugging only TODO: remove */
|
|
unsigned long bitmap;
|
|
struct sfm_pool_head pool_hash[SF_HASH_POOL_SIZE];
|
|
};
|
|
|
|
struct sfm_block{
|
|
#ifdef SFM_ONE_LOCK
|
|
gen_lock_t lock;
|
|
#endif
|
|
atomic_t crt_id; /* current pool */
|
|
unsigned long size; /* total size */
|
|
/* stats are kept now per bucket */
|
|
struct sfm_frag* first_frag;
|
|
struct sfm_frag* last_frag;
|
|
unsigned long bitmap; /* only up to SF_MALLOC_OPTIMIZE */
|
|
struct sfm_frag_lnk free_hash[SF_HASH_SIZE];
|
|
struct sfm_pool pool[SFM_POOLS_NO];
|
|
int is_init;
|
|
gen_lock_t get_and_split;
|
|
char _pad[256];
|
|
};
|
|
|
|
|
|
|
|
struct sfm_block* sfm_malloc_init(char* address, unsigned long size);
|
|
void sfm_malloc_destroy(struct sfm_block* qm);
|
|
int sfm_pool_reset();
|
|
|
|
#ifdef DBG_SF_MALLOC
|
|
void* sfm_malloc(struct sfm_block*, unsigned long size,
|
|
const char* file, const char* func, unsigned int line);
|
|
#else
|
|
void* sfm_malloc(struct sfm_block*, unsigned long size);
|
|
#endif
|
|
|
|
#ifdef DBG_SF_MALLOC
|
|
void sfm_free(struct sfm_block*, void* p, const char* file, const char* func,
|
|
unsigned int line);
|
|
#else
|
|
void sfm_free(struct sfm_block*, void* p);
|
|
#endif
|
|
|
|
#ifdef DBG_SF_MALLOC
|
|
void* sfm_realloc(struct sfm_block*, void* p, unsigned long size,
|
|
const char* file, const char* func, unsigned int line);
|
|
#else
|
|
void* sfm_realloc(struct sfm_block*, void* p, unsigned long size);
|
|
#endif
|
|
|
|
void sfm_status(struct sfm_block*);
|
|
void sfm_info(struct sfm_block*, struct mem_info*);
|
|
|
|
unsigned long sfm_available(struct sfm_block*);
|
|
|
|
#endif
|