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

📄 elib_malloc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 4 页
字号:
    /* Set new endof heap marker and a new heap tail */    eheap_top[sz-1] = 0;    tail = (AllocatedBlock*) &eheap_top[sz-MIN_BLOCK_SIZE-1];    tail->hdr = FREE_ABOVE_BIT | MIN_WORD_SIZE;    tail->v[0] = 0;    tail->v[1] = 0;    tail->v[2] = 0;    /* Patch old tail with new appended size */    heap_tail->hdr = (heap_tail->hdr & FREE_ABOVE_BIT) |	(MIN_WORD_SIZE+1+(sz-MIN_BLOCK_SIZE-1));    deallocate(heap_tail, 0);    heap_tail = tail;    eheap_size += sz;    eheap_top += sz;    return 0;}#endif /* ELIB_HEAP_SBRK *//*** Scan heap and check for corrupted heap*/int elib_check_heap(void){    AllocatedBlock* p = heap_head;    EWord sz;    if (heap_locked) {	elib_printf(stderr, "heap is locked no info avaiable\n");	return 0;    }    while((sz = SIZEOF(p)) != 0) {	if (IS_FREE(p)) {	    if (p->v[sz-1] != sz) {		elib_printf(stderr, "panic: heap corrupted\r\n"); 		ELIB_FAILURE;		    }	    p = (AllocatedBlock*) (p->v + sz);	    if (!IS_FREE_ABOVE(p)) {		elib_printf(stderr, "panic: heap corrupted\r\n"); 		ELIB_FAILURE;		    }	}	else	    p = (AllocatedBlock*) (p->v + sz);    }    return 1;}/*** Load the byte vector pointed to by v of length vsz** with a heap image** The scale is defined by vsz and the current heap size** free = 0, full = 255** ** */int elib_heap_map(EByte* v, int vsz){    AllocatedBlock* p = heap_head;    EWord sz;    int gsz = eheap_size / vsz;  /* The granuality used */    int fsz = 0;    int usz = 0;    if (gsz == 0)	return -1;  /* too good reolution */    while((sz = SIZEOF(p)) != 0) {	if (IS_FREE(p)) {	    fsz += sz;	    if ((fsz + usz) > gsz) {		*v++ = (255*usz)/gsz;		fsz -= (gsz - usz);		usz = 0;		while(fsz >= gsz) {		    *v++ = 0;		    fsz -= gsz;		}	    }	}	else {	    usz += sz;	    if ((fsz + usz) > gsz) {		*v++ = 255 - (255*fsz)/gsz;		usz -= (gsz - fsz);		fsz = 0;		while(usz >= gsz) {		    *v++ = 255;		    usz -= gsz;		}	    }	}	p = (AllocatedBlock*) (p->v + sz);    }    return 0;}/*** Generate a histogram of free/allocated blocks** Count granuality of 10 gives** (0-10],(10-100],(100-1000],(1000-10000] ...** (0-2], (2-4], (4-8], (8-16], ....*/static int i_logb(EWord size, int base){    int lg = 0;    while(size >= base) {	size /= base;	lg++;    }    return lg;}int elib_histo(EWord* vf, EWord* va, int vsz, int base){    AllocatedBlock* p = heap_head;    EWord sz;    int i;    int linear;    if ((vsz <= 1) || (vf == 0 && va == 0))	return -1;    if (base < 0) {	linear = 1;	base = -base;    }    else	linear = 0;    if (base <= 1)	return -1;    if (vf != 0) {	for (i = 0; i < vsz; i++)	    vf[i] = 0;    }    if (va != 0) {	for (i = 0; i < vsz; i++)	    va[i] = 0;    }    while((sz = SIZEOF(p)) != 0) {	if (IS_FREE(p)) {	    if (vf != 0) {		int val;		if (linear)		    val = sz / base;		else		    val = i_logb(sz, base);		if (val >= vsz)		    vf[vsz-1]++;		else		    vf[val]++;	    }	}	else {	    if (va != 0) {		int val;		if (linear)		    val = sz / base;		else		    val = i_logb(sz, base);		if (val >= vsz)		    va[vsz-1]++;		else		    va[val]++;	    }	}	p = (AllocatedBlock*) (p->v + sz);    }    return 0;}/*** Fill the info structure with actual values** Total** Allocated** Free** maxMaxFree     */void elib_stat(struct elib_stat* info){    EWord blks = 0;    EWord sz_free = 0;    EWord sz_alloc = 0;    EWord sz_max_free = 0;    EWord sz_min_used = 0x7fffffff;    EWord sz;    EWord num_free = 0;    AllocatedBlock* p = heap_head;    info->mem_total = eheap_size;    p = (AllocatedBlock*) (p->v + SIZEOF(p));    while((sz = SIZEOF(p)) != 0) {	blks++;	if (IS_FREE(p)) {	    if (sz > sz_max_free)		sz_max_free = sz;	    sz_free += sz;	    ++num_free;	}	else {	    if (sz < sz_min_used)		sz_min_used = sz;	    sz_alloc += sz;	}	p = (AllocatedBlock*) (p->v + sz);    }    info->mem_blocks = blks;    info->free_blocks = num_free;    info->mem_alloc = sz_alloc;    info->mem_free = sz_free;    info->min_used = sz_min_used;    info->max_free = sz_max_free;    info->mem_max_alloc = max_allocated;    ASSERT(sz_alloc == tot_allocated);}/*** Dump the heap*/void elib_heap_dump(char* label){    AllocatedBlock* p = heap_head;    EWord sz;    elib_printf(stderr, "HEAP DUMP (%s)\n", label);    if (!elib_check_heap())	return;        while((sz = SIZEOF(p)) != 0) {	if (IS_FREE(p)) {	    elib_printf(stderr, "%p: FREE, size = %d\n", p, (int) sz);	}	else {	    elib_printf(stderr, "%p: USED, size = %d %s\n", p, (int) sz,		       IS_FREE_ABOVE(p)?"(FREE ABOVE)":"");	}	p = (AllocatedBlock*) (p->v + sz);    }}/***  Scan heaps and count:**  free_size, allocated_size, max_free_block*/void elib_statistics(void* to){    struct elib_stat info;    EWord frag;    if (!elib_check_heap())	return;    elib_stat(&info);    frag = 1000 - ((1000 * info.max_free) / info.mem_free);    elib_printf(to, "Heap Statistics: total(%d), blocks(%d), frag(%d.%d%%)\n", 	       info.mem_total, info.mem_blocks,	       (int) frag/10, (int) frag % 10);    elib_printf(to, "                 allocated(%d), free(%d), "		"free_blocks(%d)\n",	       info.mem_alloc, info.mem_free,info.free_blocks);    elib_printf(to, "                 max_free(%d),  min_used(%d)\n",	       info.max_free, info.min_used);}/*** Allocate a least nb bytes with alignment a** Algorithm:**    1) Try locate a block which match exacly among the by direct index.**    2) Try using a fix block of greater size**    3) Try locate a block by searching in lists where block sizes**       X may vary between 2^i < X <= 2^(i+1)**** Reset memory to zero if clear is true*/static AllocatedBlock* allocate(EWord nb, EWord a, int clear){    FreeBlock* p;    EWord nw;    if (a == ELIB_ALIGN) {	/*	 * Common case: Called by malloc(), realloc(), calloc().	 */	nw = nb < MIN_BYTE_SIZE ? MIN_ALIGN_SIZE : ALIGN_SIZE(nb);	if ((p = alloc_block(nw)) == 0)	    return NULL;    } else {	/*	 * Special case: Called by memalign().	 */	EWord asz, szp, szq, tmpsz;	FreeBlock *q;	if ((p = alloc_block((1+MIN_ALIGN_SIZE)*sizeof(EWord)+a-1+nb)) == 0)	    return NULL;	asz = a - ((EWord) ((AllocatedBlock *)p)->v) % a;	if (asz != a) {	    /* Enforce the alignment requirement by cutting of a free	       block at the beginning of the block. */	    if (asz < (1+MIN_ALIGN_SIZE)*sizeof(EWord) && !IS_FREE_ABOVE(p)) {		/* Not enough room to cut of a free block;		   increase align size */		asz += (((1+MIN_ALIGN_SIZE)*sizeof(EWord) + a - 1)/a)*a;	    }	    szq = ALIGN_SIZE(asz - sizeof(EWord));	    szp = SIZEOF(p) - szq - 1;	    q = p;	    p = (FreeBlock*) (((EWord*) q) + szq + 1);	    p->hdr = FREE_ABOVE_BIT | FREE_BIT | szp;	    if (IS_FREE_ABOVE(q)) { /* This should not be possible I think,				       but just in case... */		tmpsz = SIZEOF_ABOVE(q) + 1;		szq += tmpsz;		q = (FreeBlock*) (((EWord*) q) - tmpsz);		unlink_free_block((Block_t *) q);		q->hdr = (q->hdr & FREE_ABOVE_BIT) | FREE_BIT | szq;	    }	    mark_free(q, szq);	    link_free_block((Block_t *) q);	} /* else already had the correct alignment */ 	nw = nb < MIN_BYTE_SIZE ? MIN_ALIGN_SIZE : ALIGN_SIZE(nb);    }    split_block(p, nw, SIZEOF(p));    STAT_ALLOCED_BLOCK(SIZEOF(p));    if (clear) {	EWord* pp = ((AllocatedBlock*)p)->v;	while(nw--)	    *pp++ = 0;    }    return (AllocatedBlock*) p;}/*** Deallocate memory pointed to by p** 1. Merge with block above if this block is free** 2. Merge with block below if this block is free** Link the block to the correct free list**** p points to the block header!***/static void deallocate(AllocatedBlock* p, int stat_count){    FreeBlock* q;    EWord szq;    EWord szp;    szp = SIZEOF(p);    if (stat_count)	STAT_FREED_BLOCK(SIZEOF(p));    if (IS_FREE_ABOVE(p)) {	szq = SIZEOF_ABOVE(p);	q = (FreeBlock*) ( ((EWord*) p) - szq - 1);	unlink_free_block((Block_t *) q);	p = (AllocatedBlock*) q;	szp += (szq + 1);    }    q = (FreeBlock*) (p->v + szp);    if (IS_FREE(q)) {	szq = SIZEOF(q);	unlink_free_block((Block_t *) q);	szp += (szq + 1);    }    else	q->hdr |= FREE_ABOVE_BIT;    /* The block above p can NEVER be free !!! */    p->hdr = FREE_BIT | szp;    p->v[szp-1] = szp;    link_free_block((Block_t *) p);}/*** Reallocate memory** If preserve is true then data is moved if neccesary*/static AllocatedBlock* reallocate(AllocatedBlock* p, EWord nb, int preserve){    EWord szp;    EWord szq;    EWord sz;    EWord nw;    FreeBlock* q;    if (nb < MIN_BYTE_SIZE)	nw = MIN_ALIGN_SIZE;    else	nw = ALIGN_SIZE(nb);    sz = szp = SIZEOF(p);    STAT_FREED_BLOCK(szp);    /* Merge with block below */    q = (FreeBlock*) (p->v + szp);    if (IS_FREE(q)) {	szq = SIZEOF(q);	unlink_free_block((Block_t *) q);	szp += (szq + 1);    }    if (nw <= szp) {	split_block((FreeBlock *) p, nw, szp);	STAT_ALLOCED_BLOCK(SIZEOF(p));	return p;    }    else {	EWord* dp = p->v;	AllocatedBlock* npp;	if (IS_FREE_ABOVE(p)) {	    szq = SIZEOF_ABOVE(p);	    if (szq + szp + 1 >= nw) {		q = (FreeBlock*) (((EWord*) p) - szq - 1);		unlink_free_block((Block_t * )q);		szp += (szq + 1);		p = (AllocatedBlock*) q;		if (preserve) {		    EWord* pp = p->v;		    while(sz--)			*pp++ = *dp++;		}		split_block((FreeBlock *) p, nw, szp);		STAT_ALLOCED_BLOCK(SIZEOF(p));		return p;	    }	}	/*	 * Update p so that allocate() and deallocate() works.	 * (Note that allocate() may call expand_sbrk(), which in	 * in turn calls deallocate().)	 */	p->hdr = (p->hdr & FREE_ABOVE_BIT) | szp;	p->v[szp] &= ~FREE_ABOVE_BIT;	npp = allocate(nb, ELIB_ALIGN, 0);	if(npp == NULL)	    return NULL;	if (preserve) {	    EWord* pp = npp->v;	    while(sz--)		*pp++ = *dp++;	}	deallocate(p, 0);	return npp;    }}/*** What malloc() and friends should do (and return) when the heap is** exhausted.  [sverkerw]*/static void* heap_exhausted(void){    /* Choose behaviour */#if 0    /* Crash-and-burn --- leave a usable corpse (hopefully) */    abort();#endif        /* The usual ANSI-compliant behaviour */    return NULL;}/*** Allocate size bytes of memory*/void* ELIB_PREFIX(malloc, (size_t nb)){    void *res;    AllocatedBlock* p;    erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if (nb == 0)	res = NULL;    else if ((p = allocate(nb, ELIB_ALIGN, 0)) != 0) {	ELIB_ALIGN_CHECK(p->v);	res = p->v;    }    else	res = heap_exhausted();    erts_mtx_unlock(&malloc_mutex);    return res;}void* ELIB_PREFIX(calloc, (size_t nelem, size_t size)){    void *res;    int nb;    AllocatedBlock* p;        erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if ((nb = nelem * size) == 0)	res = NULL;    else if ((p = allocate(nb, ELIB_ALIGN, 1)) != 0) {	ELIB_ALIGN_CHECK(p->v);	res = p->v;    }    else	res = heap_exhausted();    erts_mtx_unlock(&malloc_mutex);    return res;}/*** Free memory allocated by malloc*/void ELIB_PREFIX(free, (EWord* p)){    erts_mtx_lock(&malloc_mutex);    if (elib_need_init)	locked_elib_init(NULL,(EWord)0);    if (p != 0)	deallocate((AllocatedBlock*)(p-1), 1);    erts_mtx_unlock(&malloc_mutex);}void ELIB_PREFIX(cfree, (EWord* p)){    ELIB_PREFIX(free, (p));}/*** Realloc the memory allocated in p to nb number of bytes***/void* ELIB_PREFIX(realloc, (EWord* p, size_t nb)){    void *res = NULL;    AllocatedBlock* pp;

⌨️ 快捷键说明

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