enhanced xma realloc()
This commit is contained in:
		| @ -491,37 +491,53 @@ static void* _realloc_merge (qse_xma_t* xma, void* b, qse_size_t size) | ||||
| 		if (rem >= MINBLKLEN)  | ||||
| 		{ | ||||
| 			qse_xma_blk_t* tmp; | ||||
| 			qse_xma_blk_t* n = blk->b.next; | ||||
|  | ||||
| 			/* the leftover is large enough to hold a block | ||||
| 			 * of minimum size. split the current block.  | ||||
| 			 * let 'tmp' point to the leftover. */ | ||||
| 			tmp = (qse_xma_blk_t*)(((qse_byte_t*)(blk + 1)) + size); | ||||
| 			tmp->avail = 1; | ||||
| 			tmp->size = rem - HDRSIZE; | ||||
|  | ||||
| 			/* link 'tmp' to the block list */ | ||||
| 			tmp->b.next = blk->b.next; | ||||
| 			tmp->b.prev = blk; | ||||
| 			if (blk->b.next) blk->b.next->b.prev = tmp; | ||||
| 			blk->b.next = tmp; | ||||
| 			blk->size = size; | ||||
| 			if (n && n->avail) | ||||
| 			{ | ||||
| 				/* merge with the next block */ | ||||
| 				detach_from_freelist (xma, n); | ||||
|  | ||||
| 				tmp->b.next = n->b.next; | ||||
| 				tmp->b.prev = blk; | ||||
| 				if (n->b.next) n->b.next->b.prev = tmp; | ||||
| 				blk->b.next = tmp; | ||||
| 				blk->size = size; | ||||
|  | ||||
| 				tmp->size = rem - HDRSIZE + HDRSIZE + n->size; | ||||
|  | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 				xma->stat.alloc -= rem; | ||||
| 				/* rem - HDRSIZE(tmp) + HDRSIZE(n) */ | ||||
| 				xma->stat.avail += rem; | ||||
| #endif | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* link 'tmp' to the block list */ | ||||
| 				tmp->b.next = n; | ||||
| 				tmp->b.prev = blk; | ||||
| 				if (n) n->b.prev = tmp; | ||||
| 				blk->b.next = tmp; | ||||
| 				blk->size = size; | ||||
|  | ||||
| 				tmp->size = rem - HDRSIZE; | ||||
|  | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 				xma->stat.nfree++; | ||||
| 				xma->stat.alloc -= rem; | ||||
| 				xma->stat.avail += tmp->size; | ||||
| #endif | ||||
| 			} | ||||
|  | ||||
| 			/* add 'tmp' to the free list */ | ||||
| 			attach_to_freelist (xma, tmp); | ||||
|  | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
| /* TODO: if the next block is free. need to merge tmp with that..... */ | ||||
|  | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 			xma->stat.nfree++; | ||||
| 			xma->stat.alloc -= rem; | ||||
| 			xma->stat.avail += tmp->size; | ||||
| #endif | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -711,7 +727,7 @@ void qse_xma_free (qse_xma_t* xma, void* b) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void qse_xma_dump (qse_xma_t* xma) | ||||
| void qse_xma_dump (qse_xma_t* xma, int (*printf)(const qse_char_t* fmt,...)) | ||||
| { | ||||
| 	qse_xma_blk_t* tmp; | ||||
| 	unsigned long long fsum, asum;  | ||||
| @ -719,19 +735,19 @@ void qse_xma_dump (qse_xma_t* xma) | ||||
| 	unsigned long long isum; | ||||
| #endif | ||||
|  | ||||
| 	qse_printf (QSE_T("<XMA DUMP>\n")); | ||||
| 	printf (QSE_T("<XMA DUMP>\n")); | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 	qse_printf (QSE_T("== statistics ==\n")); | ||||
| 	qse_printf (QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total); | ||||
| 	qse_printf (QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc); | ||||
| 	qse_printf (QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail); | ||||
| 	printf (QSE_T("== statistics ==\n")); | ||||
| 	printf (QSE_T("total = %llu\n"), (unsigned long long)xma->stat.total); | ||||
| 	printf (QSE_T("alloc = %llu\n"), (unsigned long long)xma->stat.alloc); | ||||
| 	printf (QSE_T("avail = %llu\n"), (unsigned long long)xma->stat.avail); | ||||
| #endif | ||||
|  | ||||
| 	qse_printf (QSE_T("== blocks ==\n")); | ||||
| 	qse_printf (QSE_T(" size               avail address\n")); | ||||
| 	printf (QSE_T("== blocks ==\n")); | ||||
| 	printf (QSE_T(" size               avail address\n")); | ||||
| 	for (tmp = xma->head, fsum = 0, asum = 0; tmp; tmp = tmp->b.next) | ||||
| 	{ | ||||
| 		qse_printf (QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp); | ||||
| 		printf (QSE_T(" %-18llu %-5d %p\n"), (unsigned long long)tmp->size, tmp->avail, tmp); | ||||
| 		if (tmp->avail) fsum += tmp->size; | ||||
| 		else asum += tmp->size; | ||||
| 	} | ||||
| @ -740,68 +756,19 @@ void qse_xma_dump (qse_xma_t* xma) | ||||
| 	isum = (xma->stat.nfree + xma->stat.nused) * HDRSIZE; | ||||
| #endif | ||||
|  | ||||
| 	qse_printf (QSE_T("---------------------------------------\n")); | ||||
| 	qse_printf (QSE_T("Allocated blocks: %18llu bytes\n"), asum); | ||||
| 	qse_printf (QSE_T("Available blocks: %18llu bytes\n"), fsum); | ||||
| 	printf (QSE_T("---------------------------------------\n")); | ||||
| 	printf (QSE_T("Allocated blocks: %18llu bytes\n"), asum); | ||||
| 	printf (QSE_T("Available blocks: %18llu bytes\n"), fsum); | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 	qse_printf (QSE_T("Internal use    : %18llu bytes\n"), isum); | ||||
| 	qse_printf (QSE_T("Total           : %18llu bytes\n"), asum + fsum + isum); | ||||
| 	printf (QSE_T("Internal use    : %18llu bytes\n"), isum); | ||||
| 	printf (QSE_T("Total           : %18llu bytes\n"), asum + fsum + isum); | ||||
| #endif | ||||
|  | ||||
| 	QSE_ASSERT (asum == xma->stat.alloc); | ||||
| 	QSE_ASSERT (fsum == xma->stat.avail); | ||||
| #ifdef QSE_XMA_ENABLE_STAT | ||||
| 	QSE_ASSERT (isum == xma->stat.total - (xma->stat.alloc + xma->stat.avail)); | ||||
| 	QSE_ASSERT (asum + fsum + isum == xma->stat.total); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| #if 0 | ||||
| int main () | ||||
| { | ||||
| 	int i; | ||||
| 	void* ptr[100]; | ||||
|  | ||||
| 	qse_xma_t* xma = qse_xma_open (100000L); | ||||
| 	if (xma == QSE_NULL)  | ||||
| 	{ | ||||
| 		printf ("cannot open xma\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	for (i = 0; i < 100; i++) | ||||
| 	{ | ||||
| 		int sz = (i + 1) * 10; | ||||
| 		/*int sz = 10240;*/ | ||||
| 		ptr[i] = qse_xma_alloc (xma, sz); | ||||
| 		if (ptr[i] == QSE_NULL)  | ||||
| 		{ | ||||
| 			printf ("failed to alloc %d\n", sz); | ||||
| 			break; | ||||
| 		} | ||||
| 		printf ("%d %p\n", sz, ptr[i]); | ||||
| 	} | ||||
|  | ||||
| 	for (--i; i > 0; i-= 3) | ||||
| 	{ | ||||
| 		if (i >= 0) qse_xma_free (xma, ptr[i]); | ||||
| 	} | ||||
|  | ||||
| /* | ||||
| 	qse_xma_free (xma, ptr[0]); | ||||
| 	qse_xma_free (xma, ptr[1]); | ||||
| 	qse_xma_free (xma, ptr[2]); | ||||
| */ | ||||
|  | ||||
| 	{ | ||||
| 		void* x, * y; | ||||
|  | ||||
| 		printf ("%p\n", qse_xma_alloc (xma, 5000)); | ||||
| 		printf ("%p\n", qse_xma_alloc (xma, 1000)); | ||||
| 		printf ("%p\n", (x = qse_xma_alloc (xma, 10))); | ||||
| 		printf ("%p\n", (y = qse_xma_alloc (xma, 40))); | ||||
|  | ||||
| 		if (x) qse_xma_free (xma, x); | ||||
| 		if (y) qse_xma_free (xma, y); | ||||
| 		printf ("%p\n", (x = qse_xma_alloc (xma, 10))); | ||||
| 		printf ("%p\n", (y = qse_xma_alloc (xma, 40))); | ||||
| 	} | ||||
| 	qse_xma_dump (xma); | ||||
|  | ||||
| 	qse_xma_close (xma); | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
		Reference in New Issue
	
	Block a user