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

📄 gmalloc.c

📁 内存分配的各种包装函数
💻 C
📖 第 1 页 / 共 3 页
字号:
  /* Account for the _heapinfo block itself in the statistics.  */  _bytes_used = heapsize * sizeof (malloc_info);  _chunks_used = 1;  __malloc_initialized = 1;  return 1;}/* Get neatly aligned memory, initializing or   growing the heap info table as necessary. */static __ptr_t morecore __P ((__malloc_size_t));static __ptr_tmorecore (size)     __malloc_size_t size;{  __ptr_t result;  malloc_info *newinfo, *oldinfo;  __malloc_size_t newsize;  result = align (size);  if (result == NULL)    return NULL;  /* Check if we need to grow the info table.  */  if ((__malloc_size_t) BLOCK ((char *) result + size) > heapsize)    {      newsize = heapsize;      while ((__malloc_size_t) BLOCK ((char *) result + size) > newsize)	newsize *= 2;      newinfo = (malloc_info *) align (newsize * sizeof (malloc_info));      if (newinfo == NULL)	{	  (*__morecore) (-size);	  return NULL;	}      memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info));      memset (&newinfo[heapsize], 0,	      (newsize - heapsize) * sizeof (malloc_info));      oldinfo = _heapinfo;      newinfo[BLOCK (oldinfo)].busy.type = 0;      newinfo[BLOCK (oldinfo)].busy.info.size	= BLOCKIFY (heapsize * sizeof (malloc_info));      _heapinfo = newinfo;      /* Account for the _heapinfo block itself in the statistics.  */      _bytes_used += newsize * sizeof (malloc_info);      ++_chunks_used;      _free_internal (oldinfo);      heapsize = newsize;    }  _heaplimit = BLOCK ((char *) result + size);  return result;}/* Allocate memory from the heap.  */__ptr_tmalloc (size)     __malloc_size_t size;{  __ptr_t result;  __malloc_size_t block, blocks, lastblocks, start;  register __malloc_size_t i;  struct list *next;  /* ANSI C allows `malloc (0)' to either return NULL, or to return a     valid address you can realloc and free (though not dereference).     It turns out that some extant code (sunrpc, at least Ultrix's version)     expects `malloc (0)' to return non-NULL and breaks otherwise.     Be compatible.  */#if	0  if (size == 0)    return NULL;#endif  if (__malloc_hook != NULL)    return (*__malloc_hook) (size);  if (!__malloc_initialized)    if (!initialize ())      return NULL;  if (size < sizeof (struct list))    size = sizeof (struct list);#ifdef SUNOS_LOCALTIME_BUG  if (size < 16)    size = 16;#endif  /* Determine the allocation policy based on the request size.  */  if (size <= BLOCKSIZE / 2)    {      /* Small allocation to receive a fragment of a block.	 Determine the logarithm to base two of the fragment size. */      register __malloc_size_t log = 1;      --size;      while ((size /= 2) != 0)	++log;      /* Look in the fragment lists for a	 free fragment of the desired size. */      next = _fraghead[log].next;      if (next != NULL)	{	  /* There are free fragments of this size.	     Pop a fragment out of the fragment list and return it.	     Update the block's nfree and first counters. */	  result = (__ptr_t) next;	  next->prev->next = next->next;	  if (next->next != NULL)	    next->next->prev = next->prev;	  block = BLOCK (result);	  if (--_heapinfo[block].busy.info.frag.nfree != 0)	    _heapinfo[block].busy.info.frag.first = (unsigned long int)	      ((unsigned long int) ((char *) next->next - (char *) NULL)	       % BLOCKSIZE) >> log;	  /* Update the statistics.  */	  ++_chunks_used;	  _bytes_used += 1 << log;	  --_chunks_free;	  _bytes_free -= 1 << log;	}      else	{	  /* No free fragments of the desired size, so get a new block	     and break it into fragments, returning the first.  */	  result = malloc (BLOCKSIZE);	  if (result == NULL)	    return NULL;	  /* Link all fragments but the first into the free list.  */	  for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> log); ++i)	    {	      next = (struct list *) ((char *) result + (i << log));	      next->next = _fraghead[log].next;	      next->prev = &_fraghead[log];	      next->prev->next = next;	      if (next->next != NULL)		next->next->prev = next;	    }	  /* Initialize the nfree and first counters for this block.  */	  block = BLOCK (result);	  _heapinfo[block].busy.type = log;	  _heapinfo[block].busy.info.frag.nfree = i - 1;	  _heapinfo[block].busy.info.frag.first = i - 1;	  _chunks_free += (BLOCKSIZE >> log) - 1;	  _bytes_free += BLOCKSIZE - (1 << log);	  _bytes_used -= BLOCKSIZE - (1 << log);	}    }  else    {      /* Large allocation to receive one or more blocks.	 Search the free list in a circle starting at the last place visited.	 If we loop completely around without finding a large enough	 space we will have to get more memory from the system.  */      blocks = BLOCKIFY (size);      start = block = _heapindex;      while (_heapinfo[block].free.size < blocks)	{	  block = _heapinfo[block].free.next;	  if (block == start)	    {	      /* Need to get more from the system.  Check to see if		 the new core will be contiguous with the final free		 block; if so we don't need to get as much.  */	      block = _heapinfo[0].free.prev;	      lastblocks = _heapinfo[block].free.size;	      if (_heaplimit != 0 && block + lastblocks == _heaplimit &&		  (*__morecore) (0) == ADDRESS (block + lastblocks) &&		  (morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL)		{ 		  /* Which block we are extending (the `final free 		     block' referred to above) might have changed, if 		     it got combined with a freed info table.  */ 		  block = _heapinfo[0].free.prev;  		  _heapinfo[block].free.size += (blocks - lastblocks);		  _bytes_free += (blocks - lastblocks) * BLOCKSIZE;		  continue;		}	      result = morecore (blocks * BLOCKSIZE);	      if (result == NULL)		return NULL;	      block = BLOCK (result);	      _heapinfo[block].busy.type = 0;	      _heapinfo[block].busy.info.size = blocks;	      ++_chunks_used;	      _bytes_used += blocks * BLOCKSIZE;	      return result;	    }	}      /* At this point we have found a suitable free list entry.	 Figure out how to remove what we need from the list. */      result = ADDRESS (block);      if (_heapinfo[block].free.size > blocks)	{	  /* The block we found has a bit left over,	     so relink the tail end back into the free list. */	  _heapinfo[block + blocks].free.size	    = _heapinfo[block].free.size - blocks;	  _heapinfo[block + blocks].free.next	    = _heapinfo[block].free.next;	  _heapinfo[block + blocks].free.prev	    = _heapinfo[block].free.prev;	  _heapinfo[_heapinfo[block].free.prev].free.next	    = _heapinfo[_heapinfo[block].free.next].free.prev	    = _heapindex = block + blocks;	}      else	{	  /* The block exactly matches our requirements,	     so just remove it from the list. */	  _heapinfo[_heapinfo[block].free.next].free.prev	    = _heapinfo[block].free.prev;	  _heapinfo[_heapinfo[block].free.prev].free.next	    = _heapindex = _heapinfo[block].free.next;	  --_chunks_free;	}      _heapinfo[block].busy.type = 0;      _heapinfo[block].busy.info.size = blocks;      ++_chunks_used;      _bytes_used += blocks * BLOCKSIZE;      _bytes_free -= blocks * BLOCKSIZE;      /* Mark all the blocks of the object just allocated except for the	 first with a negative number so you can find the first block by	 adding that adjustment.  */      while (--blocks > 0)	_heapinfo[block + blocks].busy.info.size = -blocks;    }  return result;}#ifndef _LIBC/* On some ANSI C systems, some libc functions call _malloc, _free   and _realloc.  Make them use the GNU functions.  */__ptr_t_malloc (size)     __malloc_size_t size;{  return malloc (size);}void_free (ptr)     __ptr_t ptr;{  free (ptr);}__ptr_t_realloc (ptr, size)     __ptr_t ptr;     __malloc_size_t size;{  return realloc (ptr, size);}#endif/* Free a block of memory allocated by `malloc'.   Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc.		  Written May 1989 by Mike Haertel.This library is free software; you can redistribute it and/ormodify it under the terms of the GNU Library General Public License aspublished by the Free Software Foundation; either version 2 of theLicense, or (at your option) any later version.This library is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNULibrary General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; see the file COPYING.LIB.  Ifnot, write to the Free Software Foundation, Inc., 675 Mass Ave,Cambridge, MA 02139, USA.   The author may be reached (Email) at the address mike@ai.mit.edu,   or (US mail) as Mike Haertel c/o Free Software Foundation.  */#ifndef	_MALLOC_INTERNAL#define _MALLOC_INTERNAL#include <malloc.h>#endif/* Debugging hook for free.  */void (*__free_hook) __P ((__ptr_t __ptr));/* List of blocks allocated by memalign.  */struct alignlist *_aligned_blocks = NULL;/* Return memory to the heap.   Like `free' but don't call a __free_hook if there is one.  */void_free_internal (ptr)     __ptr_t ptr;{  int type;  __malloc_size_t block, blocks;  register __malloc_size_t i;  struct list *prev, *next;  block = BLOCK (ptr);  type = _heapinfo[block].busy.type;  switch (type)    {    case 0:      /* Get as many statistics as early as we can.  */      --_chunks_used;      _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;      _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;      /* Find the free cluster previous to this one in the free list.	 Start searching at the last block referenced; this may benefit	 programs with locality of allocation.  */      i = _heapindex;      if (i > block)	while (i > block)	  i = _heapinfo[i].free.prev;      else	{	  do	    i = _heapinfo[i].free.next;	  while (i > 0 && i < block);	  i = _heapinfo[i].free.prev;	}      /* Determine how to link this block into the free list.  */      if (block == i + _heapinfo[i].free.size)	{	  /* Coalesce this block with its predecessor.  */	  _heapinfo[i].free.size += _heapinfo[block].busy.info.size;	  block = i;	}      else	{	  /* Really link this block back into the free list.  */	  _heapinfo[block].free.size = _heapinfo[block].busy.info.size;	  _heapinfo[block].free.next = _heapinfo[i].free.next;	  _heapinfo[block].free.prev = i;	  _heapinfo[i].free.next = block;	  _heapinfo[_heapinfo[block].free.next].free.prev = block;	  ++_chunks_free;	}      /* Now that the block is linked in, see if we can coalesce it	 with its successor (by deleting its successor from the list	 and adding in its size).  */      if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)	{	  _heapinfo[block].free.size	    += _heapinfo[_heapinfo[block].free.next].free.size;	  _heapinfo[block].free.next	    = _heapinfo[_heapinfo[block].free.next].free.next;	  _heapinfo[_heapinfo[block].free.next].free.prev = block;	  --_chunks_free;	}      /* Now see if we can return stuff to the system.  */      blocks = _heapinfo[block].free.size;      if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit	  && (*__morecore) (0) == ADDRESS (block + blocks))	{	  register __malloc_size_t bytes = blocks * BLOCKSIZE;	  _heaplimit -= blocks;	  (*__morecore) (-bytes);	  _heapinfo[_heapinfo[block].free.prev].free.next	    = _heapinfo[block].free.next;	  _heapinfo[_heapinfo[block].free.next].free.prev	    = _heapinfo[block].free.prev;	  block = _heapinfo[block].free.prev;	  --_chunks_free;	  _bytes_free -= bytes;	}      /* Set the next search to begin at this block.  */      _heapindex = block;      break;    default:      /* Do some of the statistics.  */      --_chunks_used;      _bytes_used -= 1 << type;      ++_chunks_free;      _bytes_free += 1 << type;      /* Get the address of the first free fragment in this block.  */      prev = (struct list *) ((char *) ADDRESS (block) +			   (_heapinfo[block].busy.info.frag.first << type));      if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)	{	  /* If all fragments of this block are free, remove them	     from the fragment list and free the whole block.  */	  next = prev;	  for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i)	    next = next->next;	  prev->prev->next = next;	  if (next != NULL)	    next->prev = prev->prev;	  _heapinfo[block].busy.type = 0;	  _heapinfo[block].busy.info.size = 1;	  /* Keep the statistics accurate.  */	  ++_chunks_used;	  _bytes_used += BLOCKSIZE;	  _chunks_free -= BLOCKSIZE >> type;	  _bytes_free -= BLOCKSIZE;	  free (ADDRESS (block));	}      else if (_heapinfo[block].busy.info.frag.nfree != 0)	{	  /* If some fragments of this block are free, link this	     fragment into the fragment list after the first free	     fragment of this block. */	  next = (struct list *) ptr;	  next->next = prev->next;	  next->prev = prev;	  prev->next = next;	  if (next->next != NULL)	    next->next->prev = next;	  ++_heapinfo[block].busy.info.frag.nfree;	}      else	{	  /* No fragments of this block are free, so link this	     fragment into the fragment list and announce that	     it is the first free fragment of this block. */	  prev = (struct list *) ptr;	  _heapinfo[block].busy.info.frag.nfree = 1;	  _heapinfo[block].busy.info.frag.first = (unsigned long int)	    ((unsigned long int) ((char *) ptr - (char *) NULL)	     % BLOCKSIZE >> type);	  prev->next = _fraghead[type].next;	  prev->prev = &_fraghead[type];	  prev->prev->next = prev;	  if (prev->next != NULL)

⌨️ 快捷键说明

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