⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elib_malloc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 4 页
字号:
    erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if (p != 0) {	pp = (AllocatedBlock*) (p-1);	if (nb > 0) {	    if ((pp = reallocate(pp, nb, 1)) != 0) {		ELIB_ALIGN_CHECK(pp->v);		res = pp->v;	    }	}	else	    deallocate(pp, 1);    }    else if (nb > 0) {	if ((pp = allocate(nb, ELIB_ALIGN, 0)) != 0) {	    ELIB_ALIGN_CHECK(pp->v);	    res = pp->v;	}	else	    res = heap_exhausted();    }    erts_mtx_unlock(&malloc_mutex);    return res;}/*** Resize the memory area pointed to by p with nb number of bytes*/void* ELIB_PREFIX(memresize, (EWord* p, int nb)){    void *res = NULL;    AllocatedBlock* pp;    erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if (p != 0) {	pp = (AllocatedBlock*) (p-1);	if (nb > 0) {	    if ((pp = reallocate(pp, nb, 0)) != 0) {		ELIB_ALIGN_CHECK(pp->v);		res = pp->v;	    }	}	else	    deallocate(pp, 1);    }    else if (nb > 0) {	if ((pp = allocate(nb, ELIB_ALIGN, 0)) != 0) {	    ELIB_ALIGN_CHECK(pp->v);	    res = pp->v;	}	else	    res = heap_exhausted();    }    erts_mtx_unlock(&malloc_mutex);    return res;}/* Create aligned memory a must be a power of 2 !!! */void* ELIB_PREFIX(memalign, (int a, int nb)){    void *res;    AllocatedBlock* p;    erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if (nb == 0 || a <= 0)	res = NULL;    else if ((p = allocate(nb, a, 0)) != 0) {	ALIGN_CHECK(a, p->v);	res = p->v;    }    else	res = heap_exhausted();    erts_mtx_unlock(&malloc_mutex);    return res;}void* ELIB_PREFIX(valloc, (int nb)){    return ELIB_PREFIX(memalign, (page_size, nb));}void* ELIB_PREFIX(pvalloc, (int nb)){    return ELIB_PREFIX(memalign, (page_size, PAGES(nb)*page_size));}/* Return memory size for pointer p in bytes */int ELIB_PREFIX(memsize, (p))EWord* p;{    return SIZEOF((AllocatedBlock*)(p-1))*4;}/*** --------------------------------------------------------------------------**   DEBUG LIBRARY** --------------------------------------------------------------------------*/#ifdef ELIB_DEBUG#define IN_HEAP(p)  (((p) >= (char*) eheap) && (p) < (char*) eheap_top)/*** ptr_to_block: return the pointer to heap block pointed into by ptr** Returns 0 if not pointing into a block*/static EWord* ptr_to_block(char* ptr){    AllocatedBlock* p = heap_head;    EWord sz;    while((sz = SIZEOF(p)) != 0) {	if ((ptr >= (char*) p->v) && (ptr < (char*)(p->v+sz)))	    return p->v;	p = (AllocatedBlock*) (p->v + sz);    }    return 0;}/*** Validate a pointer** returns:**      0  - if points to start of a block**      1  - if points outsize heap**     -1  - if points inside block***/static int check_pointer(char* ptr){    if (IN_HEAP(ptr)) {	if (ptr_to_block(ptr) == 0)	    return 1;	return 0;    }    return -1;}/*** Validate a memory area** returns:**      0 - if area is included in a block**     -1 - if area overlap a heap block**      1 - if area is outside heap*/static int check_area(char* ptr, int n){    if (IN_HEAP(ptr)) {	if (IN_HEAP(ptr+n-1)) {	    EWord* p1 = ptr_to_block(ptr);	    EWord* p2 = ptr_to_block(ptr+n-1);	    if (p1 == p2)		return (p1 == 0) ? -1 : 0;	    return -1;	}    }    else if (IN_HEAP(ptr+n-1))	return -1;    return 1;}/*** Check if a block write will overwrite heap block*/static void check_write(char* ptr, int n, char* file, int line, char* fun){    if (check_area(ptr, n) == -1) {	elib_printf(stderr, "RUNTIME ERROR: %s heap overwrite\n", fun);	elib_printf(stderr, "File: %s Line: %d\n", file, line);	ELIB_FAILURE;    }}/*** Check if a pointer is an allocated object*/static void check_allocated_block(char* ptr, char* file, int line, char* fun){    EWord* q;    if (!IN_HEAP(ptr) || ((q=ptr_to_block(ptr)) == 0) || (ptr != (char*) q)) {	elib_printf(stderr, "RUNTIME ERROR: %s non heap pointer\n", fun);	elib_printf(stderr, "File: %s Line: %d\n", file, line);	ELIB_FAILURE;    }    if (IS_FREE((AllocatedBlock*)(q-1))) {	elib_printf(stderr, "RUNTIME ERROR: %s free pointer\n", fun);	elib_printf(stderr, "File: %s Line: %d\n", file, line);	ELIB_FAILURE;    }}/*** --------------------------------------------------------------------------**  DEBUG VERSIONS (COMPILED WITH THE ELIB.H)** --------------------------------------------------------------------------*/void* elib_dbg_malloc(int n, char* file, int line){    return elib__malloc(n);}void* elib_dbg_calloc(int n, int s, char* file, int line){    return elib__calloc(n, s);}void* elib_dbg_realloc(EWord* p, int n, char* file, int line){    if (p == 0)	return elib__malloc(n);    check_allocated_block(p, file, line, "elib_realloc");    return elib__realloc(p, n);}void elib_dbg_free(EWord* p, char* file, int line){    if (p == 0)	return;    check_allocated_block(p, file, line, "elib_free");    elib__free(p);}void elib_dbg_cfree(EWord* p, char* file, int line){    if (p == 0)	return;    check_allocated_block(p, file, line, "elib_free");    elib__cfree(p);}void* elib_dbg_memalign(int a, int n, char* file, int line){    return elib__memalign(a, n);}void* elib_dbg_valloc(int n, char* file, int line){    return elib__valloc(n);}void* elib_dbg_pvalloc(int n, char* file, int line){    return elib__pvalloc(n);}void* elib_dbg_memresize(EWord* p, int n, char* file, int line){    if (p == 0)	return elib__malloc(n);    check_allocated_block(p, file, line, "elib_memresize");    return elib__memresize(p, n);}int elib_dbg_memsize(void* p, char* file, int line){    check_allocated_block(p, file, line, "elib_memsize");    return elib__memsize(p);}/*** --------------------------------------------------------------------------**  LINK TIME FUNCTIONS (NOT COMPILED CALLS)** --------------------------------------------------------------------------*/void* elib_malloc(int n){    return elib_dbg_malloc(n, "", -1);}void* elib_calloc(int n, int s){    return elib_dbg_calloc(n, s, "", -1);}void* elib_realloc(EWord* p, int n){    return elib_dbg_realloc(p, n, "", -1);}void elib_free(EWord* p){    elib_dbg_free(p, "", -1);}void elib_cfree(EWord* p){    elib_dbg_cfree(p, "", -1);}void* elib_memalign(int a, int n){    return elib_dbg_memalign(a, n, "", -1);}void* elib_valloc(int n){    return elib_dbg_valloc(n, "", -1);}void* elib_pvalloc(int n){    return elib_dbg_pvalloc(n, "", -1);}void* elib_memresize(EWord* p, int n){    return elib_dbg_memresize(p, n, "", -1);}int elib_memsize(EWord* p){    return elib_dbg_memsize(p, "", -1);}#endif /* ELIB_DEBUG *//*** --------------------------------------------------------------------------** Map c library functions to elib** --------------------------------------------------------------------------*/#if defined(ELIB_ALLOC_IS_CLIB)void* malloc(size_t nb){    return elib_malloc(nb);}void* calloc(size_t nelem, size_t size){    return elib_calloc(nelem, size);}void free(void *p){    elib_free(p);}void cfree(void *p){    elib_cfree(p);}void* realloc(void* p, size_t nb){    return elib_realloc(p, nb);}void* memalign(size_t a, size_t s){    return elib_memalign(a, s);}void* valloc(size_t nb){    return elib_valloc(nb);}void* pvalloc(size_t nb){    return elib_pvalloc(nb);}#if 0void* memresize(void* p, int nb){    return elib_memresize(p, nb);}int memsize(void* p){    return elib_memsize(p);}#endif#endif /* ELIB_ALLOC_IS_CLIB */#endif /* ENABLE_ELIB_MALLOC */void elib_ensure_initialized(void){#ifdef ENABLE_ELIB_MALLOC#ifndef ELIB_DONT_INITIALIZE    elib_init(NULL, 0);#endif#endif}#ifdef ENABLE_ELIB_MALLOC/** ** A Slightly modified version of the "address order best fit" algorithm ** used in erl_bestfit_alloc.c. Comments refer to that implementation. **//* * Description:	A combined "address order best fit"/"best fit" allocator *              based on a Red-Black (binary search) Tree. The search, *              insert, and delete operations are all O(log n) operations *              on a Red-Black Tree. In the "address order best fit" case *              n equals number of free blocks, and in the "best fit" case *              n equals number of distinct sizes of free blocks. Red-Black *              Trees are described in "Introduction to Algorithms", by *              Thomas H. Cormen, Charles E. Leiserson, and *              Ronald L. Riverest. * *              This module is a callback-module for erl_alloc_util.c * * Author: 	Rickard Green */#ifdef DEBUG#if 0#define HARD_DEBUG#endif#else#undef HARD_DEBUG#endif#define SZ_MASK			SIZE_MASK#define FLG_MASK		(~(SZ_MASK))#define BLK_SZ(B)  (*((Block_t *) (B)) & SZ_MASK)#define TREE_NODE_FLG		(((Uint) 1) << 0)#define RED_FLG			(((Uint) 1) << 1)#ifdef HARD_DEBUG#  define LEFT_VISITED_FLG	(((Uint) 1) << 2)#  define RIGHT_VISITED_FLG	(((Uint) 1) << 3)#endif#define IS_TREE_NODE(N)		(((RBTree_t *) (N))->flags & TREE_NODE_FLG)#define IS_LIST_ELEM(N)		(!IS_TREE_NODE(((RBTree_t *) (N))))#define SET_TREE_NODE(N)	(((RBTree_t *) (N))->flags |= TREE_NODE_FLG)#define SET_LIST_ELEM(N)	(((RBTree_t *) (N))->flags &= ~TREE_NODE_FLG)#define IS_RED(N)		(((RBTree_t *) (N)) \				 && ((RBTree_t *) (N))->flags & RED_FLG)#define IS_BLACK(N)		(!IS_RED(((RBTree_t *) (N))))#define SET_RED(N)		(((RBTree_t *) (N))->flags |= RED_FLG)#define SET_BLACK(N)		(((RBTree_t *) (N))->flags &= ~RED_FLG)#undef ASSERT#define ASSERT ASSERT_EXPR#if 1#define RBT_ASSERT	ASSERT#else#define RBT_ASSERT(x)#endif#ifdef HARD_DEBUGstatic RBTree_t * check_tree(Uint);#endif#ifdef ERTS_INLINE#  ifndef ERTS_CAN_INLINE#    define ERTS_CAN_INLINE 1#  endif#else#  if defined(__GNUC__)#    define ERTS_CAN_INLINE 1#    define ERTS_INLINE __inline__#  elif defined(__WIN32__)#    define ERTS_CAN_INLINE 1#    define ERTS_INLINE __inline#  else#    define ERTS_CAN_INLINE 0#    define ERTS_INLINE#  endif#endif/* Types... */#if 0typedef struct RBTree_t_ RBTree_t;struct RBTree_t_ {    Block_t hdr;    Uint flags;    RBTree_t *parent;    RBTree_t *left;    RBTree_t *right;};#endif#if 0typedef struct {    RBTree_t t;    RBTree_t *next;} RBTreeList_t;#define LIST_NEXT(N) (((RBTreeList_t *) (N))->next)#define LIST_PREV(N) (((RBTreeList_t *) (N))->t.parent)#endif#ifdef DEBUG/* Destroy all tree fields */#define DESTROY_TREE_NODE(N)						\  sys_memset((void *) (((Block_t *) (N)) + 1),				\	     0xff,							\	     (sizeof(RBTree_t) - sizeof(Block_t)))/* Destroy all tree and list fields */#define DESTROY_LIST_ELEM(N)						\  sys_memset((void *) (((Block_t *) (N)) + 1),				\	     0xff,							\	     (sizeof(RBTreeList_t) - sizeof(Block_t)))#else#define DESTROY_TREE_NODE(N)#define DESTROY_LIST_ELEM(N)#endif/* * Red-Black Tree operations needed */static ERTS_INLINE voidleft_rotate(RBTree_t **root, RBTree_t *x){    RBTree_t *y = x->right;    x->right = y->left;    if (y->left)	y->left->parent = x;    y->parent = x->parent;    if (!y->parent) {	RBT_ASSERT(*root == x);	*root = y;    }    else if (x == x->parent->left)	x->parent->left = y;    else {	RBT_ASSERT(x == x->parent->right);	x->parent->right = y;    }    y->left = x;    x->parent = y;}static ERTS_INLINE voidright_rotate(RBTree_t **root, RBTree_t *x){    RBTree_t *y = x->left;    x->left = y->right;    if (y->right)	y->right->parent = x;    y->parent = x->parent;    if (!y->parent) {	RBT_ASSERT(*root == x);	*root = y;    }    else if (x == x->parent->right)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -