📄 xalloc.c
字号:
/* * large block */ /* mmapped malloc */ /* round up amount */ amount += SIZE_HEADER + TAIL_SIZE; /* round up brutto amount to a multiple of the page size */ amount = (amount + pagesize-1) & ~(pagesize-1);#ifdef MMAP_DEV_ZERO ptr = (unsigned long *)mmap((caddr_t)0, (size_t)amount, PROT_READ | PROT_WRITE, MAP_PRIVATE, devzerofd, (off_t)0);#else ptr = (unsigned long *)mmap((caddr_t)0, (size_t)amount, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, (off_t)0);#endif if (-1!=(long)ptr) { ptr[0] = amount - SIZE_HEADER - TAIL_SIZE;#ifdef XALLOC_DEBUG ptr[1] = MAGIC;#endif /* XALLOC_DEBUG */#ifdef SIZE_TAIL# ifdef __hppa__ /* reserved space for 2 * sizeof(long), so use correct one */ /* see SIZE_TAIL macro */ ((unsigned long *)((char *)ptr + amount))[-2] = MAGIC2;# else ((unsigned long *)((char *)ptr + amount))[-1] = MAGIC2;# endif /* __hppa__ */#endif /* SIZE_TAIL */ ptr = (unsigned long *)((char *)ptr + SIZE_HEADER); LOG_ALLOC("Xalloc-L", amount, ptr); return ptr; } /* else fall through to 'Out of memory' */#endif /* HAS_MMAP_ANON || MMAP_DEV_ZERO */ } else { /* * medium sized block */ /* 'normal' malloc() */ ptr=(unsigned long *)calloc(1,amount+SIZE_HEADER+TAIL_SIZE); if (ptr != (unsigned long *)NULL) { ptr[0] = amount;#ifdef XALLOC_DEBUG ptr[1] = MAGIC;#endif /* XALLOC_DEBUG */#ifdef SIZE_TAIL *(unsigned long *)((char *)ptr + amount + SIZE_HEADER) = MAGIC2;#endif /* SIZE_TAIL */ ptr = (unsigned long *)((char *)ptr + SIZE_HEADER); LOG_ALLOC("Xalloc-M", amount, ptr); return ptr; } } if (Must_have_memory) FatalError("Out of memory"); LOG_ALLOC("Xalloc-oom", amount, 0); return (unsigned long *)NULL;}/***************** * XNFalloc * "no failure" realloc, alternate interface to Xalloc w/o Must_have_memory *****************/unsigned long *XNFalloc (amount) unsigned long amount;{ register unsigned long *ptr; /* zero size requested */ if (amount == 0) { LOG_ALLOC("XNFalloc=0", amount, 0); return (unsigned long *)NULL; } /* negative size (or size > 2GB) - what do we do? */ if ((long)amount < 0) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc: XNFalloc(<0)\n");#else ErrorF("Xalloc warning: XNFalloc(<0) ignored..\n");#endif LOG_ALLOC("XNFalloc<0", amount, 0); return (unsigned long *)NULL; } ptr = Xalloc(amount); if (!ptr) { FatalError("Out of memory"); } return ptr;}/***************** * Xcalloc *****************/unsigned long *Xcalloc (amount) unsigned long amount;{ unsigned long *ret; ret = Xalloc (amount); if (ret#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO) && (amount < MIN_LARGE) /* mmaped anonymous mem is already cleared */#endif ) bzero ((char *) ret, (int) amount); return ret;}/***************** * Xrealloc *****************/unsigned long *Xrealloc (ptr, amount) register pointer ptr; unsigned long amount;{ register unsigned long *new_ptr; /* zero size requested */ if (amount == 0) { if (ptr) Xfree(ptr); LOG_REALLOC("Xrealloc=0", ptr, amount, 0); return (unsigned long *)NULL; } /* negative size (or size > 2GB) - what do we do? */ if ((long)amount < 0) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc: Xrealloc(<0)\n");#else ErrorF("Xalloc warning: Xrealloc(<0) ignored..\n");#endif if (ptr) Xfree(ptr); /* ?? */ LOG_REALLOC("Xrealloc<0", ptr, amount, 0); return (unsigned long *)NULL; } new_ptr = Xalloc(amount); if ( (new_ptr) && (ptr) ) { unsigned long old_size; old_size = ((unsigned long *)ptr)[-2];#ifdef XALLOC_DEBUG if (MAGIC != ((unsigned long *)ptr)[-1]) {#ifdef FATALERRORS FatalError("Xalloc error: header corrupt in Xrealloc() :-(\n");#else ErrorF("Xalloc error: header corrupt in Xrealloc() :-(\n");#endif LOG_REALLOC("Xalloc error: header corrupt in Xrealloc() :-(", ptr, amount, 0); return (unsigned long *)NULL; }#endif /* XALLOC_DEBUG */ /* copy min(old size, new size) */ memcpy((char *)new_ptr, (char *)ptr, (amount < old_size ? amount : old_size)); } if (ptr) Xfree(ptr); if (new_ptr) { LOG_REALLOC("Xrealloc", ptr, amount, new_ptr); return new_ptr; } if (Must_have_memory) FatalError("Out of memory"); LOG_REALLOC("Xrealloc", ptr, amount, 0); return (unsigned long *)NULL;} /***************** * XNFrealloc * "no failure" realloc, alternate interface to Xrealloc w/o Must_have_memory *****************/unsigned long *XNFrealloc (ptr, amount) register pointer ptr; unsigned long amount;{ if (( ptr = (pointer)Xrealloc( ptr, amount ) ) == NULL) { FatalError( "Out of memory" ); } return ((unsigned long *)ptr);}/***************** * Xfree * calls free *****************/ voidXfree(ptr) register pointer ptr;{ unsigned long size; unsigned long *pheader; /* free(NULL) IS valid :-( - and widely used throughout the server.. */ if (!ptr) return; pheader = (unsigned long *)((char *)ptr - SIZE_HEADER);#ifdef XALLOC_DEBUG if (MAGIC != pheader[1]) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc error: Header corrupt in Xfree() :-(\n");#else ErrorF("Xalloc error: Header corrupt in Xfree() :-(\n");#endif LOG_FREE("Xalloc error: Header corrupt in Xfree() :-(", ptr); return; }#endif /* XALLOC_DEBUG */ size = pheader[0]; if (size <= MAX_SMALL) { int indx; /* * small block */#ifdef SIZE_TAIL if (MAGIC2 != *(unsigned long *)((char *)ptr + size)) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc error: Tail corrupt in Xfree() for small block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));#else ErrorF("Xalloc error: Tail corrupt in Xfree() for small block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));#endif LOG_FREE("Xalloc error: Tail corrupt in Xfree() for small block", ptr); return; }#endif /* SIZE_TAIL */#ifdef XFREE_ERASES memset(ptr,0xF0,size);#endif /* XFREE_ERASES */ /* put this small block at the head of the list */ indx = (size-1) / SIZE_STEPS; *(unsigned long **)(ptr) = free_lists[indx]; free_lists[indx] = (unsigned long *)ptr; LOG_FREE("Xfree", ptr); return;#if defined(HAS_MMAP_ANON) || defined(MMAP_DEV_ZERO) } else if (size >= MIN_LARGE) { /* * large block */#ifdef SIZE_TAIL if (MAGIC2 != ((unsigned long *)((char *)ptr + size))[0]) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc error: Tail corrupt in Xfree() for big block (adr=0x%x, val=0x%x)\n",(char *)ptr+size,((unsigned long *)((char *)ptr + size))[0]);#else ErrorF("Xalloc error: Tail corrupt in Xfree() for big block (adr=0x%x, val=0x%x)\n",(char *)ptr+size,((unsigned long *)((char *)ptr + size))[0]);#endif LOG_FREE("Xalloc error: Tail corrupt in Xfree() for big block", ptr); return; } size += SIZE_TAIL;#endif /* SIZE_TAIL */ LOG_FREE("Xfree", ptr); size += SIZE_HEADER; munmap((caddr_t)pheader, (size_t)size); /* no need to clear - mem is inaccessible after munmap.. */#endif /* HAS_MMAP_ANON */ } else { /* * medium sized block */#ifdef SIZE_TAIL if (MAGIC2 != *(unsigned long *)((char *)ptr + size)) { /* Diagnostic */#ifdef FATALERRORS FatalError("Xalloc error: Tail corrupt in Xfree() for medium block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));#else ErrorF("Xalloc error: Tail corrupt in Xfree() for medium block (adr=0x%x, val=0x%x)\n",(char *)ptr + size,*(unsigned long *)((char *)ptr + size));#endif LOG_FREE("Xalloc error: Tail corrupt in Xfree() for medium block", ptr); return; }#endif /* SIZE_TAIL */#ifdef XFREE_ERASES memset(pheader,0xF0,size+SIZE_HEADER);#endif /* XFREE_ERASES */ LOG_FREE("Xfree", ptr); free((char *)pheader); }}voidOsInitAllocator (){ static Bool beenhere = FALSE; if (beenhere) return; beenhere = TRUE;#if defined(HAS_MMAP_ANON) || defined (MMAP_DEV_ZERO)#if defined(_SC_PAGESIZE) /* || defined(linux) */ pagesize = sysconf(_SC_PAGESIZE);#else#ifdef HAS_GETPAGESIZE pagesize = getpagesize();#else pagesize = PAGE_SIZE;#endif#endif#endif /* set up linked lists of free blocks */ bzero ((char *) free_lists, MAX_SMALL/SIZE_STEPS*sizeof(unsigned long *));#ifdef MMAP_DEV_ZERO /* open /dev/zero on systems that have mmap, but not MAP_ANON */ if (devzerofd < 0) { if ((devzerofd = open("/dev/zero", O_RDWR, 0)) < 0) FatalError("OsInitAllocator: Cannot open /dev/zero (errno=%d)\n", errno); }#endif#ifdef XALLOC_LOG /* reset the log file to zero length */ { FILE *f; f = fopen(XALLOC_LOG_FILE, "w"); if (NULL!=f) fclose(f); }#endif}#else /* !INTERNAL_MALLOC *//* This is to avoid an empty .o */static int no_internal_xalloc;#endif /* INTERNAL_MALLOC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -