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

📄 gdk_heap.c

📁 这个是内存数据库中的一个管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
			block += size;		}	}}#endif /* TRACE */static voidHEAP_empty(Heap *heap, size_t nprivate, int alignment){	/*	   // Find position of header block.	 */	HEADER *hheader = HEAP_index(heap, 0, HEADER);	/*	   // Calculate position of first and only free block.	 */	size_t head = roundup_num(roundup_8(sizeof(HEADER)) + roundup_8(nprivate), alignment);	CHUNK *headp = HEAP_index(heap, head, CHUNK);	/*	   // Fill header block.	 */	hheader->head = head;	hheader->sizefcn = NULL;	hheader->alignment = alignment;	hheader->firstblock = head;	hheader->version = HEAPVERSION;	/*	   // Fill first free block.	 */	headp->size = heap->size - head;	headp->next = 0;#ifdef TRACE	THRprintf(GDKout, "#We created the following heap\n");	HEAP_printstatus(heap);#endif}voidHEAP_initialize(Heap *heap, size_t nbytes, size_t nprivate, int alignment){	/*	   // For now we know about two alignments.	 */	if (alignment != 8) {		alignment = 4;	}	if ((size_t) alignment < sizeof(size_t))		alignment = sizeof(size_t);	/*	   // Calculate number of bytes needed for heap + structures.	 */	{		size_t total = 100 + nbytes + nprivate + sizeof(HEADER) + sizeof(CHUNK);		total = roundup_8(total);		if (HEAPalloc(heap, total, 1) < 0)			return;		heap->free = heap->size;	}	/*	   // initialize heap as empty	 */	HEAP_empty(heap, nprivate, alignment);}var_tHEAP_malloc(Heap *heap, size_t nbytes){	size_t block, trail, ttrail;	CHUNK *blockp;	CHUNK *trailp;	HEADER *hheader = HEAP_index(heap, 0, HEADER);#ifdef TRACE	THRprintf(GDKout, "#Enter malloc with " SZFMT " bytes\n", nbytes);#endif	/* add space for size field */	nbytes += hheader->alignment;	if (hheader->alignment == 8) {		nbytes = roundup_8(nbytes);	} else if (hheader->alignment == 4) {		nbytes = roundup_4(nbytes);	} else {		GDKfatal("HEAP_malloc: Heap structure corrupt\n");	}	if (nbytes < sizeof(CHUNK))		nbytes = sizeof(CHUNK);	/*	   // block  -- points to block with acceptable size (if available).	   // trail  -- points to predecessor of block.	   // ttrail -- points to predecessor of trail.	 */	ttrail = 0;	trail = 0;	for (block = hheader->head; block != 0; block = HEAP_index(heap, block, CHUNK)->next) {		blockp = HEAP_index(heap, block, CHUNK);#ifdef TRACE		THRprintf(GDKout, "#block " SZFMT " is " SZFMT " bytes\n", block, blockp->size);#endif		if ((trail != 0) && (block <= trail))			GDKfatal("HEAP_malloc: Free list is not orderered\n");		if (blockp->size >= nbytes)			break;		ttrail = trail;		trail = block;	}	/*	   // If no block of acceptable size is found we try to enlarge the heap.	 */	if (block == 0) {		size_t newsize = roundup_8((size_t) (heap->free + MAX(heap->free, nbytes)));		block = heap->free;	/* current end-of-heap */#ifdef TRACE		THRprintf(GDKout, "#No block found\n");#endif		/*		   // Double the size of the heap.		   // TUNE: increase heap by diffent amount.		 */		if (HEAPextend(heap, newsize) < 0)			return 0;		heap->free = newsize;		hheader = HEAP_index(heap, 0, HEADER);		blockp = HEAP_index(heap, block, CHUNK);		trailp = HEAP_index(heap, trail, CHUNK);#ifdef TRACE		THRprintf(GDKout, "#New block made at pos " SZFMT " with size " SZFMT "\n", block, heap->size - block);#endif		blockp->next = 0;		blockp->size = heap->free - block;	/* determine size of allocated block */		/*		   // Try to join the last block in the freelist and the newly allocated		   // memory		 */		if ((trail != 0) && (trail + trailp->size == block)) {#ifdef TRACE			THRprintf(GDKout, "#Glue newly generated block to adjacent last\n");#endif			trailp->size += blockp->size;			trailp->next = blockp->next;			block = trail;			trail = ttrail;		}	}	/*	   // Now we have found a block which is big enough in block.	   // The predecessor of this block is in trail.	 */	trailp = HEAP_index(heap, trail, CHUNK);	blockp = HEAP_index(heap, block, CHUNK);	/*	   // If selected block is bigger than block needed split block in two.	   // TUNE: use different amount than 2*sizeof(CHUNK)	 */	if (blockp->size >= nbytes + 2 * sizeof(CHUNK)) {		size_t newblock = block + nbytes;		CHUNK *newblockp = HEAP_index(heap, newblock, CHUNK);		newblockp->size = blockp->size - nbytes;		newblockp->next = blockp->next;		blockp->next = newblock;		blockp->size = nbytes;	}	/*	   // Delete block from freelist	 */	if (trail == 0) {		hheader->head = blockp->next;	} else {		trailp = HEAP_index(heap, trail, CHUNK);		trailp->next = blockp->next;	}	block += hheader->alignment;	return block;}voidHEAP_free(Heap *heap, var_t block){	HEADER *hheader = HEAP_index(heap, 0, HEADER);	CHUNK *beforep;	CHUNK *blockp;	CHUNK *afterp;	size_t after, before;	if (hheader->alignment != 8 && hheader->alignment != 4) {		GDKfatal("HEAP_free: Heap structure corrupt\n");	}	block -= hheader->alignment;	blockp = HEAP_index(heap, block, CHUNK);	/*	   // block   -- block which we want to free	   // before  -- first free block before block	   // after   -- first free block after block	 */	before = 0;	for (after = hheader->head; after != 0; after = HEAP_index(heap, after, CHUNK)->next) {		if (after > block)			break;		before = after;	}	beforep = HEAP_index(heap, before, CHUNK);	afterp = HEAP_index(heap, after, CHUNK);	/*	   // If it is not the last free block.	 */	if (after != 0) {		/*		   // If this block and the block after are consecutive.		 */		if (block + blockp->size == after) {			/*			   // We unite them.			 */			blockp->size += afterp->size;			blockp->next = afterp->next;		} else			blockp->next = after;	} else {		/*		   // It is the last block in the freelist.		 */		blockp->next = 0;	}	/*	   //  If it is not the first block in the list.	 */	if (before != 0) {		/*		   // If the before block and this block are consecutive.		 */		if (before + beforep->size == block) {			/*			   // We unite them.			 */			beforep->size += blockp->size;			beforep->next = blockp->next;		} else			beforep->next = block;	} else {		/*		   //  Add block at head of free list.		 */		hheader->head = block;	}}intHEAP_check(Heap *heap, HeapRepair *hr){	HEADER *hheader = HEAP_index(heap, 0, HEADER);	size_t head = hheader->head, alignshift = 2;	size_t block, nwords = (heap->free - 1) >> 7;	size_t *freemask, prevblock = 0;	CHUNK *blockp;	hr->alignment = hheader->alignment;	hr->minpos = sizeof(HEADER);	hr->maxpos = heap->free;	hr->validmask = NULL;	if (hheader->alignment == 8) {		nwords >>= 1;		alignshift = 3;	} else if (hheader->alignment != 4) {		GDKerror("HEAP_check: Heap structure corrupt alignment = %d\n", hheader->alignment);		return FALSE;	}	if ((head != roundup_num(head, hheader->alignment))) {		GDKerror("HEAP_check: Heap structure corrupt: head = %d\n", head);		return FALSE;	}	/*	   // Create bitmasks that will hold all valid block positions	 */	hr->validmask = (size_t *) GDKmalloc(sizeof(size_t) * ++nwords);	freemask = (size_t *) GDKmalloc(sizeof(size_t) * nwords);	for (block = 0; block < nwords; block++)		freemask[block] = hr->validmask[block] = 0;	/*	   // Walk the freelist; register them in freemask	 */	for (block = hheader->head; block != 0; block = HEAP_index(heap, block, CHUNK)->next) {		size_t idx = block >> alignshift;		size_t pos = idx >> 5;		size_t mask = (size_t) 1 << (idx & 31);		if ((block <= prevblock) && (block != 0)) {			GDKerror("HEAP_check: Freelist is not ordered\n");		} else if (block <= 0 || block > heap->free) {			GDKerror("HEAP_check: Entry freelist corrupt: block %d not in heap\n", block);		} else {			freemask[pos] |= mask;			continue;		}		goto xit;	}	/*	   // Walk the blocklist; register in validmask/eliminate from freemask	 */	block = hheader->firstblock;	while (block < heap->free) {		size_t idx = block >> alignshift;		size_t pos = idx >> 5;		size_t mask = (size_t) 1 << (idx & 31);		hr->validmask[pos] |= mask;		blockp = HEAP_index(heap, block, CHUNK);		if (freemask[pos] & mask) {			freemask[pos] &= ~mask;			block += blockp->size;		} else {			block += blocksize(hheader, blockp);		}	}	if (block != heap->free) {		GDKerror("HEAP_check: Something wrong with heap\n");		goto xit;	}	/*	   // Check if there are left over free blocks	 */	for (block = hheader->head; block != 0; block = HEAP_index(heap, block, CHUNK)->next) {		size_t idx = block >> alignshift;		size_t pos = idx >> 5;		size_t mask = (size_t) 1 << (idx & 31);		if (freemask[pos] & mask) {			GDKerror("HEAP_check: Entry freelist corrupt: block %d not in blocklist\n", block);			goto xit;		}	}	GDKfree(freemask);	return TRUE;      xit:	GDKfree(freemask);	GDKfree(hr->validmask);	hr->validmask = NULL;	return FALSE;}voidHEAP_checkformat(Heap *heap){#if 0	HEADER_OTHER image = *HEAP_index(heap, 0, HEADER_OTHER);	if (image.alignment == 4 || image.alignment == 8) {		/* it is the other format => correct to the desired format */		HEADER *hheader = HEAP_index(heap, 0, HEADER);#if SIZEOF_SIZE_T==8		size_t hasfcn = *(size_t *) & image.sizefcn;#else		size_t hasfcn = (size_t) (image.sizefcn || image.dummy);		hheader->dummy = 0;#endif		hheader->head = image.head;		hheader->firstblock = image.firstblock;		hheader->alignment = image.alignment;		hheader->sizefcn = (int (*)(ptr)) hasfcn;	}#else	(void) heap;#endif}#line 985 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"#line 994 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"/* save space in the heap by registering a size function */voidHEAP_initialize_compact(Heap *heap, size_t nbytes, size_t nprivate, int alignment, int (*sizefcn) (ptr val)){	HEAP_initialize(heap, nbytes, nprivate, alignment);	if (heap->base) {		HEADER *hheader = HEAP_index(heap, 0, HEADER);		hheader->sizefcn = sizefcn;	}}/* reinitialize the size function after a load */voidHEAP_init(Heap *heap, int tpe){	HEADER *hheader = HEAP_index(heap, 0, HEADER);	if (hheader->sizefcn) {		hheader->sizefcn = BATatoms[tpe].atomLen;	}	/* make sure the freelist does not point after the end of the heap */	if (hheader->head > heap->free) {		hheader->head = 0;	/* cut off free block */	} else if (hheader->head) {		size_t idx = hheader->head;		while (idx) {			CHUNK *blk = HEAP_index(heap, idx, CHUNK);			if (idx + blk->size > heap->free) {				blk->size = heap->free - idx;	/* cut off illegal tail of block */			}			if (blk->next > heap->free || blk->next < (idx + blk->size) || (blk->next & (hheader->alignment - 1))) {				blk->next = 0;	/* cut off next block */				break;			}			idx = blk->next;		}	}}/* a heap is mmapabble (in append-only mode) if it only has a hole at the end */intHEAP_mmappable(Heap *heap){	HEADER *hheader = HEAP_index(heap, 0, HEADER);	if (hheader->head) {		CHUNK *blk = HEAP_index(heap, hheader->head, CHUNK);		if (hheader->head + blk->size >= heap->free) {			return TRUE;		}	}	return FALSE;}#line 1054 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_heap.mx"

⌨️ 快捷键说明

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