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

📄 efence.c

📁 网络时间协议NTP 源码 版本v4.2.0b 该源码用于linux平台下
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * can be used to hold information for any memory I create, and any	 * memory that I mark free.	 */	emptySlots[0] = 0;	emptySlots[1] = 0;	/*	 * The internal memory used by the allocator is currently	 * inaccessable, so that errant programs won't scrawl on the	 * allocator's arena. I'll un-protect it here so that I can make	 * a new allocation. I'll re-protect it before I return. 	 */	if ( !noAllocationListProtection )		Page_AllowAccess(allocationList, allocationListSize);	/*	 * If I'm running out of empty slots, create some more before	 * I don't have enough slots left to make an allocation.	 */	if ( !internalUse && unUsedSlots < 7 ) {		allocateMoreSlots();	}		/*	 * Iterate through all of the slot structures. Attempt to find a slot	 * containing free memory of the exact right size. Accept a slot with	 * more memory than we want, if the exact right size is not available.	 * Find two slot structures that are not in use. We will need one if	 * we split a buffer into free and allocated parts, and the second if	 * we have to create new memory and mark it as free.	 *	 */		for ( slot = allocationList, count = slotCount ; count > 0; count-- ) {		if ( slot->mode == FREE		 && slot->internalSize >= internalSize ) {			if ( !fullSlot			 ||slot->internalSize < fullSlot->internalSize){				fullSlot = slot;				if ( slot->internalSize == internalSize				 && emptySlots[0] )					break;	/* All done, */			}		}		else if ( slot->mode == NOT_IN_USE ) {			if ( !emptySlots[0] )				emptySlots[0] = slot;			else if ( !emptySlots[1] )				emptySlots[1] = slot;			else if ( fullSlot			 && fullSlot->internalSize == internalSize )				break;	/* All done. */		}		slot++;	}	if ( !emptySlots[0] )		internalError();	if ( !fullSlot ) {		/*		 * I get here if I haven't been able to find a free buffer		 * with all of the memory I need. I'll have to create more		 * memory. I'll mark it all as free, and then split it into		 * free and allocated portions later.		 */		size_t	chunkSize = MEMORY_CREATION_SIZE;		if ( !emptySlots[1] )			internalError();		if ( chunkSize < internalSize )			chunkSize = internalSize;		if ( (slack = chunkSize % bytesPerPage) != 0 )			chunkSize += bytesPerPage - slack;		/* Use up one of the empty slots to make the full slot. */		fullSlot = emptySlots[0];		emptySlots[0] = emptySlots[1];		fullSlot->internalAddress = Page_Create(chunkSize);		fullSlot->internalSize = chunkSize;		fullSlot->mode = FREE;		unUsedSlots--;	}	/*	 * If I'm allocating memory for the allocator's own data structures,	 * mark it INTERNAL_USE so that no errant software will be able to	 * free it.	 */	if ( internalUse )		fullSlot->mode = INTERNAL_USE;	else		fullSlot->mode = ALLOCATED;	/*	 * If the buffer I've found is larger than I need, split it into	 * an allocated buffer with the exact amount of memory I need, and	 * a free buffer containing the surplus memory.	 */	if ( fullSlot->internalSize > internalSize ) {		emptySlots[0]->internalSize		 = fullSlot->internalSize - internalSize;		emptySlots[0]->internalAddress		 = ((char *)fullSlot->internalAddress) + internalSize;		emptySlots[0]->mode = FREE;		fullSlot->internalSize = internalSize;		unUsedSlots--;	}	if ( !EF_PROTECT_BELOW ) {		/*		 * Arrange the buffer so that it is followed by an inaccessable		 * memory page. A buffer overrun that touches that page will		 * cause a segmentation fault.		 */		address = (char *)fullSlot->internalAddress;		/* Set up the "live" page. */		if ( internalSize - bytesPerPage > 0 )				Page_AllowAccess(				 fullSlot->internalAddress				,internalSize - bytesPerPage);					address += internalSize - bytesPerPage;		/* Set up the "dead" page. */		if ( EF_PROTECT_FREE )			Page_Delete(address, bytesPerPage);		else			Page_DenyAccess(address, bytesPerPage);		/* Figure out what address to give the user. */		address -= userSize;	}	else {	/* EF_PROTECT_BELOW != 0 */		/*		 * Arrange the buffer so that it is preceded by an inaccessable		 * memory page. A buffer underrun that touches that page will		 * cause a segmentation fault.		 */		address = (char *)fullSlot->internalAddress;		/* Set up the "dead" page. */		if ( EF_PROTECT_FREE )			Page_Delete(address, bytesPerPage);		else			Page_DenyAccess(address, bytesPerPage);					address += bytesPerPage;		/* Set up the "live" page. */		if ( internalSize - bytesPerPage > 0 )			Page_AllowAccess(address, internalSize - bytesPerPage);	}	fullSlot->userAddress = address;	fullSlot->userSize = userSize;	/*	 * Make the pool's internal memory inaccessable, so that the program	 * being debugged can't stomp on it.	 */	if ( !internalUse )		Page_DenyAccess(allocationList, allocationListSize);	return address;}/* * Find the slot structure for a user address. */static Slot *slotForUserAddress(void * address){	register Slot *	slot = allocationList;	register size_t	count = slotCount;		for ( ; count > 0; count-- ) {		if ( slot->userAddress == address )			return slot;		slot++;	}	return 0;}/* * Find the slot structure for an internal address. */static Slot *slotForInternalAddress(void * address){	register Slot *	slot = allocationList;	register size_t	count = slotCount;		for ( ; count > 0; count-- ) {		if ( slot->internalAddress == address )			return slot;		slot++;	}	return 0;}/* * Given the internal address of a buffer, find the buffer immediately * before that buffer in the address space. This is used by free() to * coalesce two free buffers into one. */static Slot *slotForInternalAddressPreviousTo(void * address){	register Slot *	slot = allocationList;	register size_t	count = slotCount;		for ( ; count > 0; count-- ) {		if ( ((char *)slot->internalAddress)		 + slot->internalSize == address )			return slot;		slot++;	}	return 0;}extern C_LINKAGE voidfree(void * address){	Slot *	slot;	Slot *	previousSlot = 0;	Slot *	nextSlot = 0;	if ( address == 0 )		return;	if ( allocationList == 0 )		EF_Abort("free() called before first malloc().");	if ( !noAllocationListProtection )		Page_AllowAccess(allocationList, allocationListSize);	slot = slotForUserAddress(address);	if ( !slot )		EF_Abort("free(%a): address not from malloc().", address);	if ( slot->mode != ALLOCATED ) {		if ( internalUse && slot->mode == INTERNAL_USE )			/* Do nothing. */;		else {			EF_Abort(			 "free(%a): freeing free memory."			,address);		}	}	if ( EF_PROTECT_FREE )		slot->mode = PROTECTED;	else		slot->mode = FREE;	previousSlot = slotForInternalAddressPreviousTo(slot->internalAddress);	nextSlot = slotForInternalAddress(	 ((char *)slot->internalAddress) + slot->internalSize);	if ( previousSlot	 && (previousSlot->mode == FREE || previousSlot->mode == PROTECTED) ) {		/* Coalesce previous slot with this one. */		previousSlot->internalSize += slot->internalSize;		if ( EF_PROTECT_FREE )			previousSlot->mode = PROTECTED;		slot->internalAddress = slot->userAddress = 0;		slot->internalSize = slot->userSize = 0;		slot->mode = NOT_IN_USE;		slot = previousSlot;		unUsedSlots++;	}	if ( nextSlot	 && (nextSlot->mode == FREE || nextSlot->mode == PROTECTED) ) {		/* Coalesce next slot with this one. */		slot->internalSize += nextSlot->internalSize;		nextSlot->internalAddress = nextSlot->userAddress = 0;		nextSlot->internalSize = nextSlot->userSize = 0;		nextSlot->mode = NOT_IN_USE;		unUsedSlots++;	}	slot->userAddress = slot->internalAddress;	slot->userSize = slot->internalSize;	/*	 * Free memory is _always_ set to deny access. When EF_PROTECT_FREE	 * is true, free memory is never reallocated, so it remains access	 * denied for the life of the process. When EF_PROTECT_FREE is false, 	 * the memory may be re-allocated, at which time access to it will be	 * allowed again.	 *	 * Some operating systems allow munmap() with single-page resolution,	 * and allow you to un-map portions of a region, rather than the	 * entire region that was mapped with mmap(). On those operating	 * systems, we can release protected free pages with Page_Delete(),	 * in the hope that the swap space attached to those pages will be	 * released as well.	 */	if ( EF_PROTECT_FREE )	    Page_Delete(slot->internalAddress, slot->internalSize);	else	    Page_DenyAccess(slot->internalAddress, slot->internalSize);	if ( !noAllocationListProtection )		Page_DenyAccess(allocationList, allocationListSize);}extern C_LINKAGE void *realloc(void * oldBuffer, size_t newSize){	void *	newBuffer = malloc(newSize);	if ( oldBuffer ) {		size_t	size;		Slot *	slot;		Page_AllowAccess(allocationList, allocationListSize);		noAllocationListProtection = 1;				slot = slotForUserAddress(oldBuffer);		if ( slot == 0 )			EF_Abort(			 "realloc(%a, %d): address not from malloc()."			,oldBuffer			,newSize);		if ( newSize < (size = slot->userSize) )			size = newSize;		if ( size > 0 )			memcpy(newBuffer, oldBuffer, size);		free(oldBuffer);		noAllocationListProtection = 0;		Page_DenyAccess(allocationList, allocationListSize);		if ( size < newSize )			memset(&(((char *)newBuffer)[size]), 0, newSize - size);				/* Internal memory was re-protected in free() */	}	return newBuffer;}extern C_LINKAGE void *malloc(size_t size){	if ( allocationList == 0 )		initialize();	/* This sets EF_ALIGNMENT */	return memalign(EF_ALIGNMENT, size);}extern C_LINKAGE void *calloc(size_t nelem, size_t elsize){	size_t	size = nelem * elsize;	void *	allocation = malloc(size);	memset(allocation, 0, size);	return allocation;}/* * This will catch more bugs if you remove the page alignment, but it * will break some software. */extern C_LINKAGE void *valloc (size_t size){	return memalign(bytesPerPage, size);}#ifdef __hpux/* * HP-UX 8/9.01 strcat reads a word past source when doing unaligned copies! * Work around it here. The bug report has been filed with HP. */char *strcat(char *d, const char *s){	strcpy(d+strlen(d), s);	return d;}#endif

⌨️ 快捷键说明

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