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

📄 gdk_utils.c

📁 这个是内存数据库中的一个管理工具
💻 C
📖 第 1 页 / 共 4 页
字号:
			if (stackBat == NULL)				return GDK_FAIL;			BBPrename(memBat->batCacheid, "mem_trace");			BBPrename(stackBat->batCacheid, "mem_stack");			memBat->hsorted = memBat->tsorted = 0;			BATkey(memBat, TRUE);			stackBat->hsorted = stackBat->tsorted = 0;			BATset(stackBat, TRUE);		}		mtrace++;	} else if (mtrace > 0)		mtrace--;	memBat->batDirty = TRUE;	stackBat->batDirty = TRUE;	if (*enable == bit_nil) {		printf("testing mtrace:\n");		mtrace_test();		--mtrace;	}	return GDK_SUCCEED;}BUNadd_dag(BAT *b, BUN p, mem_t current, mem_t parent){	const static int bunsize = sizeof(mem_t) + sizeof(mem_t);	BUN last = BUNlast(b);	while (p != last) {		if ((*(mem_t *) BUNhloc(b, p)) == current && (*(mem_t *) BUNtloc(b, p)) == parent)			return p;		p += bunsize;	}	if (b->batBuns->free + bunsize > b->batBuns->size) {		int tmp = mtrace;		mtrace = 0;		if (BATextend(b, BATgrows(b)) == NULL)			return BUNlast(b);		mtrace = tmp;		last = BUNlast(b);	}	bunfastins_nocheck(b, last, &current, &parent, bunsize);	return last;}#define MAX_STACK_ADDR 16#define STACK_LIST(STACK_ENTRY)						\	STACK_ENTRY(1) STACK_ENTRY(2) STACK_ENTRY(3)			\	STACK_ENTRY(4) STACK_ENTRY(5) STACK_ENTRY(6) STACK_ENTRY(7)	\	STACK_ENTRY(8) STACK_ENTRY(9) STACK_ENTRY(10) STACK_ENTRY(11)	\	STACK_ENTRY(12) STACK_ENTRY(13) STACK_ENTRY(14) STACK_ENTRY(15)#define STACK_READ(X)						\	if (continue_stack_trace &&				\	    ((mem_t)__builtin_frame_address((X)) != 0L) &&	\	    ((X) < MAX_STACK_ADDR)) {				\		parent = current;				\		current = (mem_t)__builtin_return_address((X)); \		if(parent)					\			p = add_dag(b, p, current, parent);	\	} else if (continue_stack_trace) {			\		continue_stack_trace = FALSE;			\	}intadd_stack(BAT *b){	mem_t current = 0, parent = 0;	bit continue_stack_trace = TRUE;	BUN p = BUNfirst(b);	STACK_LIST(STACK_READ);	return BUNindex(b, p);}#define __USE_GNU 1#include <dlfcn.h>voidprint_address(ptr address){	Dl_info dlip;	char *filename;	dladdr(address, &dlip);	filename = 0;		/* strrchr(dlip.dli_fname,'/'); */	printf(PTRFMT "\t%s\t%s\n", PTRFMTCAST address, dlip.dli_sname, filename ? filename + 1 : dlip.dli_fname);}static intGDKmprint(int *pidx){	int idx = *pidx;	BUN p = BUNptr(stackBat, idx), first = BUNfirst(stackBat);	const static int bunsize = sizeof(mem_t) + sizeof(mem_t);	mem_t *a;	if (p == NULL)		printf("No stack for index %d\n", idx);	a = (mem_t *) BUNhloc(stackBat, p);	print_address(*a);	a = (mem_t *) BUNtloc(stackBat, p);	print_address(*a);	while (p > first) {		p -= bunsize;		if (*(mem_t *) BUNhloc(stackBat, p) == *a) {			a = (mem_t *) BUNtloc(stackBat, p);			print_address(*a);		}	}	return GDK_SUCCEED;}voidadd_mem(BAT *b, mem_t mem, int idx){	REGISTER BUN last;	const static int bunsize = sizeof(mem_t) + sizeof(int);	if (b->batBuns->free + bunsize > b->batBuns->size) {		int tmp = mtrace;		mtrace = 0;		if (BATextend(b, BATgrows(b)))			return;		mtrace = tmp;	}	last = BUNlast(b);	bunfastins_nocheck(b, last, &mem, &idx, bunsize);}voiddel_mem(BAT *b, mem_t mem){	REGISTER BUN first = BUNfirst(b), p = BUNlast(b);	const static int bunsize = sizeof(mem_t) + sizeof(int);	for (p -= bunsize; p >= first; p -= bunsize) {		if (*(mem_t *) BUNhloc(b, p) == mem) {			int idx = -*(int *) BUNtloc(b, p);			if (idx > 0) {				printf("Double deletion of memory " PTRFMT ", " "size: " SSZFMT ", stack:%d\n", PTRFMTCAST(void *)mem, ((ssize_t *) mem)[-1], idx);				if (mtrace > 1)					GDKmprint(&idx);			} else {				BUNdelete(b, p);				/* BUNinplace(b,p,&mem,&idx,0); */			}			return;		}	}	printf("Free of unknown memory " PTRFMT ", size: " SSZFMT "\n", PTRFMTCAST(void *) mem, ((ssize_t *) mem)[-1]);}#endif#line 898 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"#line 950 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"static voidGDKmemfail(str s, size_t len, size_t memtarget, size_t vmtarget){	int bak = GDKdebug;	/* bumped your nose against the wall; try to prevent repetition by adjusting maxsizes */	if (memtarget < 0.3 * GDKmem_inuse()) {		size_t newmax = (size_t) (0.7 * (double) GDKmem_inuse());		if (newmax < GDK_mem_maxsize)			GDK_mem_maxsize = newmax;	}	if (vmtarget < 0.3 * GDKvm_cursize()) {		size_t newmax = (size_t) (0.7 * (double) GDKvm_cursize());		if (newmax < GDK_vm_maxsize)			GDK_vm_maxsize = newmax;	}	gdk_set_lock(GDKthreadLock, "GDKmemfail");	THRprintf(GDKout, "#%s(" SZFMT ") fail => BBPtrim(enter) usage[mem=" SZFMT ",vm=" SZFMT "]\n", s, len, GDKmem_inuse(), GDKvm_cursize());	GDKmemdump();	GDKdebug |= 4;	gdk_unset_lock(GDKthreadLock, "GDKmemfail");	BBPtrim(memtarget, vmtarget);	gdk_set_lock(GDKthreadLock, "GDKmemfail");	GDKdebug = MIN(GDKdebug, bak);	THRprintf(GDKout, "#%s(" SZFMT ") fail => BBPtrim(ready) usage[mem=" SZFMT ",vm=" SZFMT "]\n", s, len, GDKmem_inuse(), GDKvm_cursize());	GDKmemdump();	gdk_unset_lock(GDKthreadLock, "GDKmemfail");}/* the blocksize is stored in the ssize_t before it. Negative size <=> VM memory */#define GDK_MEM_BLKSIZE(p) ((ssize_t*) (p))[-1]#ifndef GDK_MEM_MISALIGN/* allocate 8 bytes extra (so it stays 8-bytes aligned) and put realsize in front */#define GDKmalloc_prefixsize(s,size) {					\	s = (ssize_t *) malloc(size + 8);				\	if (s != NULL) {						\		assert((((size_t) s)&7) == 0); /* no MISALIGN */	\		s = (ssize_t*) ((char*) s + 8);				\		s[-1] = (ssize_t) (size + 8);				\	}								\}#else/* work around old stupid libc mallocs that give 4-byte aligned pointers */#define GDKmalloc_prefixsize(s,size) {					\	s = (ssize_t *) malloc(size+8);					\	if (((size_t) s) & 4) { /* misaligned */			\		assert(sizeof(size_t) == 4); /* not on 64-bits */	\		s = (ssize_t*) ((char*) s + 4);				\		s[-1] = (ssize_t) (size + 9);  /* 1-bit is a marker */	\	} else if (s != NULL) {						\		s = (ssize_t*) ((char*) s + 8);				\		s[-1] = (ssize_t) (size + 8);				\	}								\}#endifvoid *GDKmallocmax(size_t size, size_t * maxsize, int emergency){	ssize_t *s = NULL;	if (size == 0) {#ifdef GDK_MEM_NULLALLOWED		return NULL;#else		GDKfatal("GDKmallocmax: called with size " SZFMT "", size);#endif	}	size = (size + 3) & ~3;	/* round up to a multiple of four */	if (size > GDK_mem_bigsize) {		size_t newsize = size + sizeof(size_t) + sizeof(size_t);		size_t newmax = MAX(*maxsize, newsize);		s = (ssize_t *) GDKvmalloc(newsize, &newmax, emergency);		if (s == 0 && emergency == 0)			return s;		MT_alloc_register(s, *maxsize, 'S');		s += 2;		s[-2] = (ssize_t) newmax;		s[-1] = -((ssize_t) newsize);		*maxsize = newmax - (sizeof(size_t) + sizeof(size_t));		return (void *) s;	}	CHKMEM(size, 0);	GDKmalloc_prefixsize(s, size);	if (s == NULL) {		GDKmemfail("GDKmalloc", size, BBPTRIM_ALL, 0);		GDKmalloc_prefixsize(s, size);		if (s == NULL) {			if (emergency)				return NULL;			MT_alloc_print();			GDKfatal("GDKmallocmax: failed for %u bytes", size);		} else {			THRprintf(GDKout, "#GDKmallocmax: recovery ok. Continuing..\n");		}	}	*maxsize = size;	#line 515 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	{		size_t _memdelta = (size_t) size+8;#ifdef GDK_MEM_TRACE		void*  _blk = (void*) s;		if (mtrace) {			int _idx = add_stack(stackBat);			add_mem(memBat,_blk,_idx);		}#endif		GDK_mallocedbytes_estimate += _memdelta;#ifdef GDK_MEM_KEEPHISTO		{			int _idx;			GDKmallidx(_idx, _memdelta);			GDK_nmallocs[_idx]++;		}#endif	}#line 1057 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	return (void *) s;}void *GDKmalloc(size_t size){	return GDKmallocmax(size, &size, 1);}void *GDKzalloc(size_t size){	size_t maxsize;	void *p = GDKmallocmax(size, &maxsize, 1);	if (p)		memset(p,0,size);	return p;}voidGDKfree(void *blk){	ssize_t size = 0, *s = (ssize_t *) blk;	if (s == NULL)		return;	size = GDK_MEM_BLKSIZE(s);	/* check against duplicate free */	assert((size & 2) == 0);	s[-1] |= 2;	if (size < 0) {		size_t maxsize = (size_t) s[-2];		size = -size;		MT_alloc_register((char *) (s - 2), maxsize, 's');		GDKvmfree((char *) (s - 2), (size_t) size, maxsize);	} else {#ifndef NDEBUG		/* The check above detects obvious duplicate free's,		 * but fails in case the "check-bit" is cleared between		 * two free's (e.g., as the respective memory has been 		 * re-allocated and initialized.		 * To simplify detection & debugging of duplicate free's,		 * we now overwrite the to be freed memory, which will		 * (1) trigger a segfault in case the memory had already		 * been freed and/or trigger some error in case the memory		 * is accessed after is has been freed.		 * To avoid performance penalty in the "production version",		 * we only do this in debugging/development mode (i.e.,		 * when configured with --enable-assert).		 * Disable at runtime via `Mserver --debug=33554432` or		 * `debugmask(or(debugmask(),33554432));` in MIL.		 */		DEADBEEFCHK memset(s,0xDB,size - (8 + (size & 1))); /* 0xDeadBeef */#endif#ifdef GDK_MEM_MISALIGN		if (size & 1)			free(((char *) s) - 4);		else#endif			free(((char *) s) - 8);		#line 537 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	{		size_t _memdelta = (size_t) size;#ifdef GDK_MEM_TRACE		void*  _blk = (void*) s;		if (mtrace) {			del_mem(memBat,_blk);		}#endif		if (_memdelta > GDK_mallocedbytes_estimate) {			/* clearly, the stats are off: it should never become less-than-zero */			GDKmem_heapcheck(GDKms());		} else {			GDK_mallocedbytes_estimate -= _memdelta;		}#ifdef GDK_MEM_KEEPHISTO		{			int _idx;			GDKmallidx(_idx, _memdelta);			GDK_nmallocs[_idx]--;		}#endif	}#line 1122 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	}}ptrGDKreallocmax(void *blk, size_t size, size_t * maxsize, int emergency){	ssize_t oldsize = 0, *s = (ssize_t *) blk;	if (s == NULL) {		return GDKmallocmax(size, maxsize, emergency);	}#ifdef GDK_MEM_NULLALLOWED	if (size == 0) {		GDKfree(blk);		*maxsize = 0;		return NULL;	}#endif	if (size <= 0) {		GDKfatal("GDKreallocmax: called with size %u", size);	}	/* round up to a multiple of four */	size = (size + 3) & ~3;	oldsize = GDK_MEM_BLKSIZE(s);	/* check against duplicate free */	assert((oldsize & 2) == 0);	if (oldsize < 0) {		size_t newsize = size + sizeof(size_t) + sizeof(size_t);		size_t oldmax = (size_t) s[-2];		size_t newmax = MAX(*maxsize, newsize);		s = (ssize_t *) GDKvmrealloc((ptr) (s - 2), (size_t) - oldsize, newsize, oldmax, &newmax, emergency);		if (s == NULL && !emergency)			return NULL;		s[0] = newmax;		s[1] = -((ssize_t) newsize);		*maxsize = newmax - (sizeof(size_t) + sizeof(size_t));		return (ptr) (s + 2);	}#ifndef GDK_MEM_MISALIGN	if (size <= GDK_mem_bigsize) {		size_t newsize = size + 8;		blk = realloc(((char *) blk) - 8, newsize);		if (blk != NULL) {			/* place 8 bytes before it */			assert((((size_t) blk) & 4) == 0);			blk = ((char *) blk) + 8;			((ssize_t *) blk)[-1] = (ssize_t) newsize;			/* adapt statistics */			#line 515 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	{		size_t _memdelta = (size_t) newsize;#ifdef GDK_MEM_TRACE		void*  _blk = (void*) blk;		if (mtrace) {			int _idx = add_stack(stackBat);			add_mem(memBat,_blk,_idx);		}#endif		GDK_mallocedbytes_estimate += _memdelta;#ifdef GDK_MEM_KEEPHISTO		{			int _idx;			GDKmallidx(_idx, _memdelta);			GDK_nmallocs[_idx]++;		}#endif	}#line 1176 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"			#line 537 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"	{		size_t _memdelta = (size_t) oldsize;#ifdef GDK_MEM_TRACE		void*  _blk = (void*) s;		if (mtrace) {			del_mem(memBat,_blk);		}#endif		if (_memdelta > GDK_mallocedbytes_estimate) {			/* clearly, the stats are off: it should never become less-than-zero */			GDKmem_heapcheck(GDKms());		} else {			GDK_mallocedbytes_estimate -= _memdelta;		}#ifdef GDK_MEM_KEEPHISTO		{			int _idx;			GDKmallidx(_idx, _memdelta);			GDK_nmallocs[_idx]--;		}#endif	}#line 1177 "/export/scratch0/monet/monet.GNU.64.64.d.14791/MonetDB/src/gdk/gdk_utils.mx"			*maxsize = size;			return blk;		}	}	/* alloc&copy due too failed realloc (may be very big heap that needs vm) */#else	/* alloc&copy because we cannot trust realloc due to misalignment */	if (oldsize & 1)		oldsize = MIN(size, (size_t) oldsize - 5);	else#endif		oldsize = MIN(size, (size_t) (oldsize - 8));	blk = (void *) GDKmallocmax(size, maxsize, emergency);	if (blk) {		memcpy(blk, s, oldsize);		GDKfree(s);	}	return (void *) blk;}ptrGDKrealloc(void *blk, size_t size){

⌨️ 快捷键说明

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