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

📄 emacsmalloc.c

📁 正则表达式库
💻 C
📖 第 1 页 / 共 2 页
字号:
  nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;  {    register unsigned int   shiftr = (nbytes - 1) >> 2;    while (shiftr >>= 1)      nunits++;  }  /* In case this is reentrant use of malloc from signal handler,     pick a block size that no other malloc level is currently     trying to allocate.  That's the easiest harmless way not to     interfere with the other level of execution.  */  while (busy[nunits]) nunits++;  busy[nunits] = 1;  /* If there are no blocks of the appropriate size, go get some */  /* COULD SPLIT UP A LARGER BLOCK HERE ... ACT */  if (nextf[nunits] == 0)    morecore (nunits);  /* Get one block off the list, and set the new list head */  if ((p = nextf[nunits]) == 0)    {      busy[nunits] = 0;      return 0;    }  nextf[nunits] = CHAIN (p);  busy[nunits] = 0;  /* Check for free block clobbered */  /* If not for this check, we would gobble a clobbered free chain ptr */  /* and bomb out on the NEXT allocate of this size block */  if (p -> mh_alloc != ISFREE || p -> mh_index != nunits)#ifdef rcheck    botch ("block on free list clobbered");#else /* not rcheck */    abort ();#endif /* not rcheck */  /* Fill in the info, and if range checking, set up the magic numbers */  p -> mh_alloc = ISALLOC;#ifdef rcheck  p -> mh_nbytes = n;  p -> mh_magic4 = MAGIC4;  {    /* Get the location n after the beginning of the user's space.  */    register char *m = (char *) p + ((sizeof *p + 7) & ~7) + n;    *m++ = MAGIC1, *m++ = MAGIC1, *m++ = MAGIC1, *m = MAGIC1;  }#else /* not rcheck */  p -> mh_size = n;#endif /* not rcheck */#ifdef MSTATS  nmalloc[nunits]++;  nmal++;#endif /* MSTATS */  return (char *) p + ((sizeof *p + 7) & ~7);}free (mem)     char *mem;{  register struct mhead *p;  {    register char *ap = mem;    if (ap == 0)      return;    p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));    if (p -> mh_alloc == ISMEMALIGN)      {	ap -= p->mh_size;	p = (struct mhead *) (ap - ((sizeof *p + 7) & ~7));      }#ifndef rcheck    if (p -> mh_alloc != ISALLOC)      abort ();#else rcheck    if (p -> mh_alloc != ISALLOC)      {	if (p -> mh_alloc == ISFREE)	  botch ("free: Called with already freed block argument\n");	else	  botch ("free: Called with bad argument\n");      }    ASSERT (p -> mh_magic4 == MAGIC4);    ap += p -> mh_nbytes;    ASSERT (*ap++ == MAGIC1); ASSERT (*ap++ == MAGIC1);    ASSERT (*ap++ == MAGIC1); ASSERT (*ap   == MAGIC1);#endif /* rcheck */  }  {    register int nunits = p -> mh_index;    ASSERT (nunits <= 29);    p -> mh_alloc = ISFREE;    /* Protect against signal handlers calling malloc.  */    busy[nunits] = 1;    /* Put this block on the free list.  */    CHAIN (p) = nextf[nunits];    nextf[nunits] = p;    busy[nunits] = 0;#ifdef MSTATS    nmalloc[nunits]--;    nfre++;#endif /* MSTATS */  }}char *realloc (mem, n)     char *mem;     register unsigned n;{  register struct mhead *p;  register unsigned int tocopy;  register unsigned int nbytes;  register int nunits;  if (mem == 0)    return malloc (n);  p = (struct mhead *) (mem - ((sizeof *p + 7) & ~7));  nunits = p -> mh_index;  ASSERT (p -> mh_alloc == ISALLOC);#ifdef rcheck  ASSERT (p -> mh_magic4 == MAGIC4);  {    register char *m = mem + (tocopy = p -> mh_nbytes);    ASSERT (*m++ == MAGIC1); ASSERT (*m++ == MAGIC1);    ASSERT (*m++ == MAGIC1); ASSERT (*m   == MAGIC1);  }#else /* not rcheck */  if (p -> mh_index >= 13)    tocopy = (1 << (p -> mh_index + 3)) - ((sizeof *p + 7) & ~7);  else    tocopy = p -> mh_size;#endif /* not rcheck */  /* See if desired size rounds to same power of 2 as actual size. */  nbytes = (n + ((sizeof *p + 7) & ~7) + EXTRA + 7) & ~7;  /* If ok, use the same block, just marking its size as changed.  */  if (nbytes > (4 << nunits) && nbytes <= (8 << nunits))    {#ifdef rcheck      register char *m = mem + tocopy;      *m++ = 0;  *m++ = 0;  *m++ = 0;  *m++ = 0;      p-> mh_nbytes = n;      m = mem + n;      *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;  *m++ = MAGIC1;#else /* not rcheck */      p -> mh_size = n;#endif /* not rcheck */      return mem;    }  if (n < tocopy)    tocopy = n;  {    register char *new;    if ((new = malloc (n)) == 0)      return 0;    bcopy (mem, new, tocopy);    free (mem);    return new;  }}/* This is in case something linked with Emacs calls calloc.  */char *calloc (num, size)     unsigned num, size;{  register char *mem;  num *= size;  mem = malloc (num);  if (mem != 0)    bzero (mem, num);  return mem;}#ifndef VMSchar *memalign (alignment, size)     unsigned alignment, size;{  register char *ptr = malloc (size + alignment);  register char *aligned;  register struct mhead *p;  if (ptr == 0)    return 0;  /* If entire block has the desired alignment, just accept it.  */  if (((int) ptr & (alignment - 1)) == 0)    return ptr;  /* Otherwise, get address of byte in the block that has that alignment.  */  aligned = (char *) (((int) ptr + alignment - 1) & -alignment);  /* Store a suitable indication of how to free the block,     so that free can find the true beginning of it.  */  p = (struct mhead *) (aligned - ((7 + sizeof (struct mhead)) & ~7));  p -> mh_size = aligned - ptr;  p -> mh_alloc = ISMEMALIGN;  return aligned;}#ifndef HPUX/* This runs into trouble with getpagesize on HPUX.   Patching out seems cleaner than the ugly fix needed.  */char *valloc (size){  return memalign (getpagesize (), size);}#endif /* not HPUX */#endif /* not VMS */#ifdef MSTATS/* Return statistics describing allocation of blocks of size 2**n. */struct mstats_value  {    int blocksize;    int nfree;    int nused;  };struct mstats_valuemalloc_stats (size)     int size;{  struct mstats_value v;  register int i;  register struct mhead *p;  v.nfree = 0;  if (size < 0 || size >= 30)    {      v.blocksize = 0;      v.nused = 0;      return v;    }  v.blocksize = 1 << (size + 3);  v.nused = nmalloc[size];  for (p = nextf[size]; p; p = CHAIN (p))    v.nfree++;  return v;}intmalloc_mem_used (){  int i;  int size_used;  size_used = 0;    for (i = 0; i < 30; i++)    {      int allocation_size = 1 << (i + 3);      struct mhead *p;            size_used += nmalloc[i] * allocation_size;    }  return size_used;}int malloc_mem_free (){  int i;  int size_unused;  size_unused = 0;    for (i = 0; i < 30; i++)    {      int allocation_size = 1 << (i + 3);      struct mhead *p;            for (p = nextf[i]; p ; p = CHAIN (p))	size_unused += allocation_size;    }  return size_unused;}#endif /* MSTATS *//* *	This function returns the total number of bytes that the process *	will be allowed to allocate via the sbrk(2) system call.  On *	BSD systems this is the total space allocatable to stack and *	data.  On USG systems this is the data space only. */#ifdef USGget_lim_data (){  extern long ulimit ();    #ifdef ULIMIT_BREAK_VALUE  lim_data = ULIMIT_BREAK_VALUE;#else  lim_data = ulimit (3, 0);#endif  lim_data -= (long) data_space_start;}#else /* not USG */#if defined (BSD4_1) || defined (VMS)get_lim_data (){  lim_data = vlimit (LIM_DATA, -1);}#else /* not BSD4_1 and not VMS */get_lim_data (){  struct rlimit XXrlimit;  getrlimit (RLIMIT_DATA, &XXrlimit);#ifdef RLIM_INFINITY  lim_data = XXrlimit.rlim_cur & RLIM_INFINITY; /* soft limit */#else  lim_data = XXrlimit.rlim_cur;	/* soft limit */#endif}#endif /* not BSD4_1 and not VMS */#endif /* not USG */#ifdef VMS/* There is a problem when dumping and restoring things on VMS. Calls * to SBRK don't necessarily result in contiguous allocation. Dumping * doesn't work when it isn't. Therefore, we make the initial * allocation contiguous by allocating a big chunk, and do SBRKs from * there. Once Emacs has dumped there is no reason to continue * contiguous allocation, malloc doesn't depend on it. * * There is a further problem of using brk and sbrk while using VMS C * run time library routines malloc, calloc, etc. The documentation * says that this is a no-no, although I'm not sure why this would be * a problem. In any case, we remove the necessity to call brk and * sbrk, by calling calloc (to assure zero filled data) rather than * sbrk. * * VMS_ALLOCATION_SIZE is the size of the allocation array. This * should be larger than the malloc size before dumping. Making this * too large will result in the startup procedure slowing down since * it will require more space and time to map it in. * * The value for VMS_ALLOCATION_SIZE in the following define was determined * by running emacs linked (and a large allocation) with the debugger and * looking to see how much storage was used. The allocation was 201 pages, * so I rounded it up to a power of two. */#ifndef VMS_ALLOCATION_SIZE#define VMS_ALLOCATION_SIZE	(512*256)#endif/* Use VMS RTL definitions */#undef sbrk#undef brk#undef mallocint vms_out_initial = 0;char vms_initial_buffer[VMS_ALLOCATION_SIZE];static char *vms_current_brk = &vms_initial_buffer;static char *vms_end_brk = &vms_initial_buffer[VMS_ALLOCATION_SIZE-1];#include <stdio.h>char *sys_sbrk (incr)     int incr;{  char *sbrk(), *temp, *ptr;  if (vms_out_initial)    {      /* out of initial allocation... */      if (!(temp = malloc (incr)))	temp = (char *) -1;    }  else    {      /* otherwise, go out of our area */      ptr = vms_current_brk + incr; /* new current_brk */      if (ptr <= vms_end_brk)	{	  temp = vms_current_brk;	  vms_current_brk = ptr;	}      else	{	  vms_out_initial = 1;	/* mark as out of initial allocation */	  if (!(temp = malloc (incr)))	    temp = (char *) -1;	}    }  return temp;}#endif /* VMS */

⌨️ 快捷键说明

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