📄 rxvtmem.c
字号:
#endif /* adjust information in trunk_head */ tklist->first_trunk->fblock = block->u.next; tklist->first_trunk->fcount --; /* Set the address of trunk head so that we can find it in free. * Notice that u.trunk is the placehold for u.next when block is * free!!! */ block->u.trunk = tklist->first_trunk; /* if no free block left in the trunk */ if (0 == tklist->first_trunk->fcount) {#ifdef DEBUG /* print out statistics for the trunk */ rxvt_dbgmsg ((DBG_VERBOSE, DBG_MEMORY, "--Trunk of block size %d: %d bytes used (%d%%)\n", tklist->block_size, (int) tklist->first_trunk->tbyte, (int) (tklist->first_trunk->tbyte * 100 / (tklist->block_size * tklist->first_trunk->bmax))));#endif if (IS_NULL(tklist->first_trunk->next)) { /* no free trunk in this trunk list, allocate a new trunk */ struct trunk_head_t* new_trunk; new_trunk = get_trunk (tklist->u.tsize), new_trunk->list = tklist, tklist->trunk_count ++, /* increase trunk counter */ optimize_trunk_size (tklist); init_trunk (new_trunk, tklist->block_size); SET_NULL(new_trunk->next); SET_NULL(new_trunk->prev); /* clean up the old trunk */ SET_NULL(tklist->first_trunk->next); SET_NULL(tklist->first_trunk->prev); /* insert new trunk into trunk list */ tklist->first_trunk = new_trunk; } else { /* there is some free trunk in this trunk list, remove the * first trunk from the trunk list */ struct trunk_head_t* remove = tklist->first_trunk; tklist->first_trunk = remove->next;#ifdef DEBUG assert (TRUNK_MAGIC == tklist->first_trunk->magic_f); assert (TRUNK_MAGIC == tklist->first_trunk->magic_e);#endif SET_NULL(tklist->first_trunk->prev); /* clean up the old trunk */ SET_NULL(remove->next); SET_NULL(remove->prev); } } } /* now return the free block, BUT skip the block_head_t first */ block ++; return block;}/* EXTPROTO */void*rxvt_calloc(size_t number, size_t size){ void* ptr; size_t total = number * size;#ifdef DEBUG assert (memory_initialized);#endif /* possible overflow? */ assert (total >= 0 && size > 0); assert ((total / size) == number); ptr = rxvt_malloc (total); /* calloc requires us to zero out the memory, slow call */ MEMSET(ptr, 0, total); return (ptr);}/* EXTPROTO */void*rxvt_realloc(void* ptr, size_t size){ struct block_head_t* block; struct trunk_head_t* tk_head;#ifdef DEBUG assert (memory_initialized);#endif if (IS_NULL(ptr)) return (rxvt_malloc (size)); /* find the real block head structure */ block = (struct block_head_t*) ptr; block --;#ifdef DEBUG assert (BLOCK_MAGIC == block->magic_f); assert (BLOCK_MAGIC == block->magic_e);#endif /* find trunk_head_t structure for ptr */ tk_head = block->u.trunk; if ((struct trunk_head_t*) SYS_MALLOC_PTR == tk_head) { /* ptr was allocated useing system malloc here */ block = realloc (block, size + BHEAD_OFFSET); if (IS_NULL(block)) { rxvt_msg (DBG_FATAL, DBG_MEMORY, abort_msg); exit(EXIT_FAILURE); }#ifdef DEBUG block->magic_f = BLOCK_MAGIC; block->magic_e = BLOCK_MAGIC; #endif /* set special trunk address */ block->u.trunk = (struct trunk_head_t*) SYS_MALLOC_PTR; /* skip block structure */ block ++; } else { /* now do some serious business about reallocating this ptr */#ifdef DEBUG assert (TRUNK_MAGIC == tk_head->magic_f); assert (TRUNK_MAGIC == tk_head->magic_e);#endif /* nothing to do if this block is actually big enough */ if (size <= (size_t) tk_head->bsize) return ptr; block = rxvt_malloc (size); MEMCPY (block, ptr, tk_head->bsize); /* a bit waste, though */ rxvt_free (ptr); } return (block);}/* EXTPROTO */voidrxvt_free(void* ptr){ struct block_head_t* block; struct trunk_head_t* tk_head;#ifdef DEBUG assert (memory_initialized);#endif#if 0 assert (NOT_NULL(ptr)); /* generate core dump */#else /* * 2006-11-19 gi1242: glibc accepts free(NULL), and has been used in a few * places throughout the mrxvt code base. It's better to fail gracefully * here, as opposed to code bloat by first testing if a pointer is not null * before calling rxvt_free(). */ if( IS_NULL(ptr) ) return;#endif block = (struct block_head_t*) ptr; /* find the block_head_t structure */ block --;#ifdef DEBUG assert (BLOCK_MAGIC == block->magic_f); assert (BLOCK_MAGIC == block->magic_e);#endif /* find trunk_head_t structure for ptr */ tk_head = block->u.trunk; /* use system malloc */ if ((struct trunk_head_t*) SYS_MALLOC_PTR == tk_head) { free (block); } else {#ifdef DEBUG assert (TRUNK_MAGIC == tk_head->magic_f); assert (TRUNK_MAGIC == tk_head->magic_e); tk_head->tbyte -= block->bbyte;# ifdef DEBUG_MEMORY MEMSET (ptr, MEMORY_MAGIC, tk_head->list->block_size);# endif#endif /* Insert the block of ptr to the head of free block link list. * Notice that u.next is the placeholder for u.trunk when block * is in use!!! */ block->u.next = tk_head->fblock; tk_head->fblock = block; /* increase free block counter */ tk_head->fcount ++; if (1 == tk_head->fcount) { /* link the trunk back to the trunk list if all blocks were * allocated previously */ struct trunk_list_t* tklist; tklist = tk_head->list; assert (IS_NULL(tk_head->prev)); assert (IS_NULL(tk_head->next)); assert (NOT_NULL(tklist->first_trunk));#ifdef DEBUG assert (TRUNK_MAGIC == tklist->first_trunk->magic_f); assert (TRUNK_MAGIC == tklist->first_trunk->magic_e);#endif tk_head->next = tklist->first_trunk; tklist->first_trunk->prev = tk_head; /* insert this trunk into the beginnig of trunk list */ tklist->first_trunk = tk_head; } else if (tk_head->fcount == tk_head->bmax) { /* we can free this trunk now since all blocks in it are free. * but we do not free it if it is the only trunk in its trunk * list. */ struct trunk_list_t* tklist; tklist = tk_head->list; if (tklist->first_trunk == tk_head) { /* this trunk is the first in trunk list */ if (NOT_NULL(tk_head->next)) {#ifdef DEBUG assert (TRUNK_MAGIC == tk_head->next->magic_f); assert (TRUNK_MAGIC == tk_head->next->magic_e);#endif tklist->first_trunk = tk_head->next; tklist->first_trunk->prev = NULL; free_trunk (tk_head), tklist->trunk_count --, /* decrease trunk counter */ shrink_trunk_size (tklist); } } else { /* this trunk is not the first in trunk list */#ifdef DEBUG assert (TRUNK_MAGIC == tk_head->prev->magic_f); assert (TRUNK_MAGIC == tk_head->prev->magic_e);#endif tk_head->prev->next = tk_head->next; if (NOT_NULL(tk_head->next)) {#ifdef DEBUG assert (TRUNK_MAGIC == tk_head->next->magic_f); assert (TRUNK_MAGIC == tk_head->next->magic_e);#endif tk_head->next->prev = tk_head->prev; } free_trunk (tk_head), tklist->trunk_count --, /* decrease trunk counter */ shrink_trunk_size (tklist); } } }}#else /* !OUR_MALLOC *//* EXTPROTO */void*rxvt_malloc(size_t size){ void* p; /* see AC_FUNC_MALLOC macro in autoconf documentation */ if (0 == size) size = 1; p = malloc(size); if (p) return p; rxvt_msg (DBG_FATAL, DBG_MEMORY, abort_msg); exit(EXIT_FAILURE); /* NOTREACHED */}/* EXTPROTO */void*rxvt_calloc(size_t number, size_t size){ void* p; p = calloc(number, size); if (p) return p; rxvt_msg (DBG_FATAL, DBG_MEMORY, abort_msg); exit(EXIT_FAILURE); /* NOTREACHED */}/* EXTPROTO */void*rxvt_realloc(void *ptr, size_t size){ void* p; if (ptr) p = realloc(ptr, size); else p = malloc(size); if (p) return p; rxvt_msg (DBG_FATAL, DBG_MEMORY, abort_msg); exit(EXIT_FAILURE); /* NOT REACHED */}/* EXTPROTO */voidrxvt_free(void* ptr){#if 0 assert (NOT_NULL(ptr)); /* generate core dump */#endif free (ptr);}#endif /* OUR_MALLOC *//*----------------------- end-of-file (C source) -----------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -