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

📄 gdk_posix.mx

📁 这个是内存数据库中的一个管理工具
💻 MX
📖 第 1 页 / 共 5 页
字号:
/* Cygwin implementation: struct flock is there, but lockf() is   missing. */static intlockf(int fd, int cmd, off_t len){	struct flock l;	if (cmd == F_LOCK || cmd == F_TLOCK)		l.l_type = F_WRLCK;	else if (cmd == F_ULOCK)		l.l_type = F_UNLCK;	l.l_whence = SEEK_CUR;	l.l_start = 0;	l.l_len = len;	return fcntl(fd, cmd == F_TLOCK ? F_SETLKW : F_SETLK, &l);}#endif/* returns -1 when locking failed, * returns -2 when the lock file could not be opened/created * returns the (open) file descriptor to the file otherwise */intMT_lockf(char *filename, int mode, off_t off, off_t len){	int ret = -1, fd = open(filename, O_CREAT | O_RDWR, 0662);	if (fd < 0)		return -2;	if (lseek(fd, off, SEEK_SET) == off) {		if (lockf(fd, mode, len) == 0) {			ret = fd;		} else {			close(fd);		}	} else {		close(fd);	}	/* do not close else we lose the lock we want */	return ret;}voidMT_sleep_ms(unsigned int ms){#ifdef HAVE_NANOSLEEP	struct timespec ts;	ts.tv_sec = (time_t) (ms / 1000);	ts.tv_nsec = 1000000 * (ms % 1000);	while (nanosleep(&ts, &ts) == -1 && errno == EINTR)		;#else	struct timeval tv;	tv.tv_sec = ms / 1000;	tv.tv_usec = ms % 1000;	(void) select(0, NULL, NULL, NULL, &tv);#endif}#else /* WIN32 */#define MT_PAGESIZE(s)		(((((s)-1) >> 12) + 1) << 12)#define MT_SEGSIZE(s)		((((((s)-1) >> 16) & 65535) + 1) << 16)#ifndef MEM_TOP_DOWN#define MEM_TOP_DOWN 0#endifvoid *MT_vmalloc(size_t size, size_t * maxsize){	void *p, *a = NULL;	int mode = 0;	size = MT_PAGESIZE(size);	if (*maxsize < size) {		*maxsize = size;	}	*maxsize = MT_SEGSIZE(*maxsize);	if (*maxsize < 1000000) {		mode = MEM_TOP_DOWN;	/* help NT in keeping memory defragmented */	}	(void) pthread_mutex_lock(&MT_mmap_lock);	if (*maxsize > size) {		a = (void *) VirtualAlloc(NULL, *maxsize, MEM_RESERVE | mode, PAGE_NOACCESS);		if (a == NULL) {			*maxsize = size;		}	}	p = (void *) VirtualAlloc(a, size, MEM_COMMIT | mode, PAGE_READWRITE);	(void) pthread_mutex_unlock(&MT_mmap_lock);	if (p == NULL) {		stream_printf(GDKerr, "VirtualAlloc(" PTRFMT "," SZFMT ",MEM_COMMIT,PAGE_READWRITE): failed\n", PTRFMTCAST a, size);	}	return p;}voidMT_vmfree(void *p, size_t size){	if (VirtualFree(p, size, MEM_DECOMMIT) == 0)		stream_printf(GDKerr, "VirtualFree(" PTRFMT "," SZFMT ",MEM_DECOMMIT): failed\n", PTRFMTCAST p, size);	if (VirtualFree(p, 0, MEM_RELEASE) == 0)		stream_printf(GDKerr, "VirtualFree(" PTRFMT ",0,MEM_RELEASE): failed\n", PTRFMTCAST p);}void *MT_vmrealloc(void *v, size_t oldsize, size_t newsize, size_t oldmaxsize, size_t * newmaxsize){	char *p = (char *) v, *a = p;	/* sanitize sizes */	oldsize = MT_PAGESIZE(oldsize);	newsize = MT_PAGESIZE(newsize);	oldmaxsize = MT_PAGESIZE(oldmaxsize);	*newmaxsize = MT_PAGESIZE(*newmaxsize);	if (*newmaxsize < newsize) {		*newmaxsize = newsize;	}	if (oldsize > newsize) {		size_t ret = VirtualFree(p + newsize, oldsize - newsize, MEM_DECOMMIT);		if (ret == 0)			stream_printf(GDKerr, "VirtualFree(" PTRFMT "," SSZFMT ",MEM_DECOMMIT): failed\n", PTRFMTCAST(p + newsize), (ssize_t) (oldsize - newsize));	} else if (oldsize < newsize) {		(void) pthread_mutex_lock(&MT_mmap_lock);		a = (char *) VirtualAlloc(p, newsize, MEM_COMMIT, PAGE_READWRITE);		(void) pthread_mutex_unlock(&MT_mmap_lock);		if (a != p) {			char *q = a;			if (a == NULL) {				q = MT_vmalloc(newsize, newmaxsize);			}			if (q != NULL) {				memcpy(q, p, oldsize);				MT_vmfree(p, oldmaxsize);			}			if (a == NULL)				return q;		}	}	*newmaxsize = MAX(oldmaxsize, newsize);	return a;}/* see contract of unix MT_lockf */intMT_lockf(char *filename, int mode, off_t off, off_t len){	int ret = 1, illegalmode = 0, fd = -1;	OVERLAPPED ov;	OSVERSIONINFO os;	HANDLE fh = CreateFile(filename,			       GENERIC_READ | GENERIC_WRITE, 0,			       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);	os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);	GetVersionEx(&os);	memset(&ov, 0, sizeof(ov));	ov.Offset = (unsigned int) off;#if 0	ov.OffsetHigh = off >> 32;#else	ov.OffsetHigh = 0;	/* sizeof(off) == 4, i.e. off >> 32 is not possible */#endif	if (fh == NULL) {		return -2;	}	if (mode == F_ULOCK) {		if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)			ret = UnlockFileEx(fh, 0, 0, len, &ov);	} else if (mode == F_TLOCK) {		if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)			ret = LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY | LOCKFILE_EXCLUSIVE_LOCK, 0, 0, len, &ov);	} else if (mode == F_LOCK) {		if (os.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS)			ret = LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, 0, len, &ov);	} else {		illegalmode = 1;	}	CloseHandle(fh);	if (illegalmode) {		SetLastError(ERROR_INVALID_DATA);	}	if (ret != 0) {		fd = open(filename, O_CREAT | O_RDWR, 0662);		if (fd < 0) {			/* this is nasty, but I "trust" windows that it in this case			 * also cannot open the file into a filehandle any more, so			 * unlocking is in vain. */			return -2;		} else {			return fd;		}	} else {		return -1;	}}voidMT_sleep_ms(unsigned int ms){	Sleep(ms);}@-cygnus1.1.X has a bug in the semaphore routines. we work around it by directly using the WIN32 primitives.@c#ifndef NATIVE_WIN32intsem_init(sem_t * sem, int pshared, unsigned int value){	(void) pshared;	*sem = (sem_t) CreateSemaphore(NULL, value, 128, NULL);	return (*sem) ? 0 : -1;}intsem_destroy(sem_t * sem){	return CloseHandle((HANDLE) * sem) ? 0 : -1;}intsem_wait(sem_t * sem){	return (WaitForSingleObject((HANDLE) * sem, (unsigned int) INFINITE) != WAIT_FAILED) ? 0 : -1;}intsem_post(sem_t * sem){	return (ReleaseSemaphore((HANDLE) * sem, 1, NULL) == 0) ? -1 : 0;}#endif#endif@}@+ Memory fragmentation monitoringOn 32-bits systems, Monet's aggressive use of virtual memory may bring it intotrouble as the limits of what is addressable in a 32-bits system are reached (an 32-bits OS only allows 2 to 4GB of memory to be used). In order to aid debuggingsituations where VM allocs fail (due to memory fragmentation), a monitoringsystem was established. To this purpose, a map is made for the VM addressesbetween 0 and 3GB, in tiles of MT_VMUNITSIZE (64KB). These tiles have a bytevalue from the following domain:@table @samp@item 0-9 thread stack space of thread <num>@item B in use for a large BAT heap.@item b free (last usage was B)@item S in use for a malloc block@item s free (last usage was S)@item P in use for the BBP array@item p free (last usage was P)@item M in use as memory mapped region@item m free (last usage was M)@item C in use as MIL context buffer@item c free (last usage was C)@end tableThe MT_alloc_printmap condenses the map by printing a char for each MB,hence combining info from 16 tiles. On NT, we can check in real-time which tiles are actually in use (in case our own tile administration is out-of-sync with reality, eg due to a memory leak). This real-life usage is printed in a second line with encoding .=free, *=inuse, X=unusable. On Unix systems,*=inuse is not testable (unless with complicated signal stuff). On 64-bitssystems, this administration is dysfunctional. @{@c#ifdef DEBUG_ALLOC#if SIZEOF_VOID_P == 4unsigned char MT_alloc_map[65536] = { 0 };#endifintMT_alloc_register(void *addr, size_t size, char mode){#if SIZEOF_VOID_P == 4	size_t p = (size_t) addr;	if (size > 0) {		size_t i, base = p >> 16;		size = (size - 1) >> 16;		assert(p && ((lng) p) + size < (LL_CONSTANT(1) << 32));		for (i = 0; i <= size; i++)			MT_alloc_map[base + i] = (MT_alloc_map[base + i] & 128) | mode;	}#else	(void) addr;	(void) size;	(void) mode;#endif	return 0;}#define INUSEMODE(x) ((x >= '0' && x <= ('9'+4)) || (x >= 'A' && x <= 'Z'))intMT_alloc_print(void){#if SIZEOF_VOID_P == 4#ifdef WIN32	char *p = NULL;#endif	int i, j, k;	if (MT_alloc_map[0] == 0)		return 0;	for (i = 0; i < 40; i++) {		stream_printf(GDKout, "%02d00MB ", i);		for (j = 0; j < 100; j++) {			int mode = '.';			for (k = 0; k < 16; k++) {				int m = MT_alloc_map[k + 16 * (j + 100 * i)] & 127;				if (mode == '.' || INUSEMODE(m))					mode = m;			}			stream_printf(GDKout, "%c", mode);		}#ifdef WIN32		stream_printf(GDKout, "\n       ");		for (j = 0; j < 100; j++) {			int mode = '.';			for (k = 0; k < 16; k++, p += 1 << 16)				if (!IsBadReadPtr(p, 1)) {					mode = '*';				} else if (MT_alloc_map[k + 16 * (j + 100 * i)] & 128) {					mode = 'X';				}			stream_printf(GDKout, "%c", mode);		}#endif		stream_printf(GDKout, "\n");	}#endif	return 0;}@-The memory table dump can also be produced in tuple formatto enable front-ends to analyze it more easily.@cstruct {	char tag;	char *color;	char *info;} Encoding[] = {	{	'.', "0x00FFFDFE", "free"}, {	'0', "0x000035FC", "thread stack space of thread 0"}, {	'1', "0x000067FE", "thread stack space of thread 1"}, {	'2', "0x000095FE", "thread stack space of thread 2"}, {	'3', "0x0000BDFC", "thread stack space of thread 3"}, {	'4', "0x0000DCF8", "thread stack space of thread 4"}, {	'5', "0x002735FC", "thread stack space of thread 5"}, {	'6', "0x002767FE", "thread stack space of thread 6"}, {	'7', "0x002795FE", "thread stack space of thread 7"}, {	'8', "0x0027BDFC", "thread stack space of thread 8"}, {	'9', "0x0027DCF8", "thread stack space of thread 9"}, {	'B', "0x0000672D", "in use for a large BAT heap."}, {	'b', "0x004EF2A7", "free (last usage was B)"}, {	'S', "0x00B4006E", "in use for a malloc block"}, {	's', "0x00F2BDE0", "free (last usage was S)"}, {	'P', "0x00F26716", "in use for the BBP array"}, {	'p', "0x00F2BD16", "free (last usage was P)"}, {	'M', "0x00959516", "in use as memory mapped region"}, {	'm', "0x00CEDC16", "free (last usage was M)"}, {	'C', "0x004EFDC7", "in use as MIL context buffer"}, {	'c', "0x00FFFD2D", "free (last usage was M)"}, {	0, "0x00FFFDFE", "free"}};intMT_alloc_table(void){#if SIZEOF_VOID_P == 4#ifdef WIN32	char *p = NULL;#endif	int i, j, k;	if (MT_alloc_map[0] == 0)		return 0;	stream_printf(GDKout, "# addr\tX\tY\tcolor\tmode\tcomment\t# name\n");	stream_printf(GDKout, "# str\tint\tint\tcolor\tstr\tstr\t# type\n");	for (i = 0; i < 40; i++) {		for (j = 0; j < 100; j++) {			int mode = '.';			for (k = 0; k < 16; k++) {				int m = MT_alloc_map[k + 16 * (j + 100 * i)] & 127;				if (mode == '.' || INUSEMODE(m))					mode = m;			}			for (k = 0; k >= 0; k++)				if (Encoding[k].tag == mode || Encoding[k].tag == 0) {					if (mode == 0)						mode = ' ';					stream_printf(GDKout, "[ \"%d\",\t%d,\t%d,\t", k + 16 * (j + 100 * i), j, i);					stream_printf(GDKout, "\"%s\",\t", Encoding[k].color);					stream_printf(GDKout, "\"%c\",\t\"%s\"\t]\n", mode, Encoding[k].info);					break;				}		}#ifdef WIN32		stream_printf(GDKout, "\n       ");		for (j = 0; j < 100; j++) {			int mode = '.';			for (k = 0; k < 16; k++, p += 1 << 16)				if (!IsBadReadPtr(p, 1)) {					mode = '*';				} else if (MT_alloc_map[k + 16 * (j + 100 * i)] & 128) {					mode = 'X';				}			stream_printf(GDKout, "%c", mode);		}		stream_printf(GDKout, "\n");#endif	}#endif	return 0;}static voidMT_alloc_init(void){#if SIZEOF_VOID_P == 4	char *p = NULL;	int i;	for (i = 0; i < 65536; i++, p += MT_VMUNITSIZE) {		int mode = '.';#ifdef WIN32		if (!VirtualAlloc(p, MT_VMUNITSIZE, MEM_RESERVE, PAGE_NOACCESS)) {			mode |= 128;		} else {			VirtualFree(p, 0, MEM_RELEASE);		}#else		MMAP_OPEN_DEV_ZERO;		void *q = (char *) mmap(p, MT_VMUNITSIZE, PROT_NONE, MMAP_FLAGS(MAP_NORESERVE), MMAP_FD, 0);		MMAP_CLOSE_DE

⌨️ 快捷键说明

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