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

📄 gdk_posix.c

📁 这个是内存数据库中的一个管理工具
💻 C
📖 第 1 页 / 共 4 页
字号:
}voidMT_mmap_unpin(void *base, size_t len){	int i;	(void) pthread_mutex_lock(&MT_mmap_lock);	i = MT_mmap_idx(base, len);	if (i >= 0) {		MT_mmap_tab[i].pincnt--;	}	(void) pthread_mutex_unlock(&MT_mmap_lock);}void *MT_mmap(char *path, int mode, off_t off, size_t len){	MT_mmap_hdl hdl;	void *ret = MT_mmap_open(&hdl, path, mode, off, len, 0);	MT_mmap_close(&hdl);	return ret;}#ifndef NATIVE_WIN32#ifdef HAVE_POSIX_FADVISE#ifdef HAVE_UNAME#include <sys/utsname.h>#endif#endif#if !defined(WIN32) && defined(PROFILE) #ifdef HAVE_PTHREAD_H#undef pthread_create/* for profiling purposes (btw configure with --enable-profile *and* --disable-shared --enable-static) * without setting the ITIMER_PROF per thread, all profiling info for everything except the main thread is lost. */#include <stdlib.h>/* Our data structure passed to the wrapper */typedef struct wrapper_s{    void * (*start_routine)(void *);    void * arg;    pthread_mutex_t lock;    pthread_cond_t  wait;    struct itimerval itimer;} wrapper_t;/* The wrapper function in charge for setting the itimer value */static void * wrapper_routine(void * data){    /* Put user data in thread-local variables */    void * (*start_routine)(void *) = ((wrapper_t*)data)->start_routine;    void * arg = ((wrapper_t*)data)->arg;    /* Set the profile timer value */    setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL);    /* Tell the calling thread that we don't need its data anymore */    pthread_mutex_lock(&((wrapper_t*)data)->lock);    pthread_cond_signal(&((wrapper_t*)data)->wait);    pthread_mutex_unlock(&((wrapper_t*)data)->lock);    /* Call the real function */    return start_routine(arg);}/* Our wrapper function for the real pthread_create() */int gprof_pthread_create(pthread_t *__restrict thread,                   __const pthread_attr_t *__restrict attr,                   void * (*start_routine)(void *),                   void *__restrict arg){    wrapper_t wrapper_data;    int i_return;    /* Initialize the wrapper structure */    wrapper_data.start_routine = start_routine;    wrapper_data.arg = arg;    getitimer(ITIMER_PROF, &wrapper_data.itimer);    pthread_cond_init(&wrapper_data.wait, NULL);    pthread_mutex_init(&wrapper_data.lock, NULL);    pthread_mutex_lock(&wrapper_data.lock);    /* The real pthread_create call */    i_return = pthread_create(thread, attr, &wrapper_routine, &wrapper_data);    /* If the thread was successfully spawned, wait for the data to be released */    if(i_return == 0) {        pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock);    }    pthread_mutex_unlock(&wrapper_data.lock);    pthread_mutex_destroy(&wrapper_data.lock);    pthread_cond_destroy(&wrapper_data.wait);    return i_return;}#endif#endifvoidMT_init_posix(int alloc_map){#ifdef HAVE_POSIX_FADVISE#ifdef HAVE_UNAME	struct utsname ubuf;	/* do not use posix_fadvise on Linux systems running a 2.4 or	   older kernel */	do_not_use_posix_fadvise = uname(&ubuf) == 0 &&		strcmp(ubuf.sysname, "Linux") == 0 &&		strncmp(ubuf.release, "2.4", 3) <= 0;#endif#endif	MT_heapbase = (char *) sbrk(0);#ifdef DEBUG_ALLOC	static void MT_alloc_init(void);	if (alloc_map)		MT_alloc_init();#else	(void)alloc_map;#endif	MT_mmap_init();}size_tMT_getrss(void){	/* get RSS  -- linux only for the moment */	static char MT_mmap_procfile[128] = { 0 };	int fd;	if (MT_mmap_procfile[0] == 0) {		/* getpid returns pid_t, cast to long to be sure */		sprintf(MT_mmap_procfile, "/proc/%ld/stat", (long) getpid());	}	fd = open(MT_mmap_procfile, O_RDONLY);	if (fd >= 0) {		char buf[1024], *r = buf;		size_t i, sz = read(fd, buf, 1024);		close(fd);		if (sz > 0) {			for (i = 0; i < 23; i++) {				while (*r && (*r == ' ' || *r == '\t'))					r++;				while (*r && (*r != ' ' && *r != '\t'))					r++;			}			while (*r && (*r == ' ' || *r == '\t'))				r++;			return ((size_t) atol(r)) * MT_pagesize();		}	}	return 0;}char *MT_heapcur(void){	return (char *) sbrk(0);}void*MT_mmap_open(MT_mmap_hdl *hdl, char *path, int mode, off_t off, size_t len, size_t nremaps){	int fd = open(path, O_CREAT | ((mode & MMAP_WRITE) ? O_RDWR : O_RDONLY));	void *ret = (void *) -1L;	(void) nremaps;	if (fd >= 0) {		hdl->mode = mode;		hdl->fixed = NULL; 		hdl->hdl = (void *) (ssize_t) fd;		ret = MT_mmap_remap(hdl, off, len);	}	if (ret != (void *) -1L) {		hdl->fixed = ret;		fd = MT_mmap_new(path, ret, len, fd, (mode & MMAP_WRITABLE));		if (fd <= 0) hdl->hdl = (void *) 0; /* MT_mmap_new keeps the fd */	}	return ret;}void *MT_mmap_remap(MT_mmap_hdl *hdl, off_t off, size_t len){	void *ret;	ret = mmap(hdl->fixed, len, 		((hdl->mode & MMAP_WRITABLE) ? PROT_WRITE : 0) | PROT_READ, 		((hdl->mode & MMAP_COPY) ? (MAP_PRIVATE|MAP_NORESERVE) : MAP_SHARED) | 		 (hdl->fixed ? MAP_FIXED : 0), 		(int) (ssize_t) hdl->hdl, 		off);	if (ret != (void *) -1L) {		if (hdl->mode & MMAP_ADVISE) {			(void) MT_madvise(ret, len, hdl->mode & MMAP_ADVISE);		}		hdl->fixed = (void *) ((char *) ret + len);	}	return ret;}voidMT_mmap_close(MT_mmap_hdl *hdl){	int fd = (int) (ssize_t) hdl->hdl;	if (fd) close(fd);	hdl->hdl = NULL;}intMT_munmap(void *p, size_t len){	int ret = munmap(p, len);#ifdef MMAP_DEBUG	stream_printf(GDKerr, "munmap(" LLFMT "," LLFMT ",%d) = %d\n", (long long) p, (long long) len, ret);#endif	MT_mmap_del(p, len);	return ret;}intMT_msync(void *p, size_t len, int mode){	int ret = msync(p, len, (mode & MMAP_SYNC) ? MS_SYNC : ((mode & MMAP_ASYNC) ? MS_ASYNC : MS_INVALIDATE));#ifdef MMAP_DEBUG	stream_printf(GDKerr, "msync(" LLFMT "," LLFMT ",%s) = %d\n", (long long) p, (long long) len, (mode & MMAP_SYNC) ? "MS_SYNC" : ((mode & MMAP_ASYNC) ? "MS_ASYNC" : "MS_INVALIDATE"), ret);#endif	if (ret < 0)		return errno;	return ret;}intMT_madvise(void *p, size_t len, int advise){	int ret = posix_madvise(p, len, advise);#ifdef MMAP_DEBUG	stream_printf(GDKerr, "posix_madvise(" LLFMT "," LLFMT ",%d) = %d\n", (long long) p, (long long) len, advise, ret);#endif	if (MT_fadvise(p, len, advise))		ret = -1;	return ret;}struct mallinfoMT_mallinfo(void){	struct mallinfo _ret;#ifdef HAVE_MALLINFO	_ret = mallinfo();#else	memset(&_ret, 0, sizeof(_ret));#endif	if (_ret.uordblks + _ret.fordblks > _ret.arena) {		MT_alloc_register(MT_heapbase, _ret.arena, 'H');	}	return _ret;}intMT_path_absolute(char *pathname){	return (*pathname == DIR_SEP);}#ifdef WIN32#include <windows.h>#endif#else /* WIN32 native */#ifndef BUFSIZ#define BUFSIZ 1024#endif#undef _errno#undef stat#undef rmdir#undef mkdir#undef NAME_MAX#include <windows.h>#ifdef _MSC_VER#include <io.h>#endif /* _MSC_VER */#define MT_SMALLBLOCK 256voidMT_init_posix(int alloc_map){	MT_heapbase = 0;/*	_set_sbh_threshold(MT_SMALLBLOCK);*/#ifdef DEBUG_ALLOC	static void MT_alloc_init(void);	if (alloc_map)		MT_alloc_init();#else	(void)alloc_map;#endif	MT_mmap_init();}size_tMT_getrss(){#if (_WIN32_WINNT >= 0x0500)	MEMORYSTATUSEX state;	state.dwLength = sizeof(state);	GlobalMemoryStatusEx (&state);	return (size_t) (state.ullTotalPhys - state.ullAvailPhys);#else	MEMORYSTATUS state;	GlobalMemoryStatus (&state);	return state.dwTotalPhys - state.dwAvailPhys;#endif}char *MT_heapcur(void){	return (char *) 0;}/* Windows mmap keeps a global list of base addresses for complex (remapped) memory maps  * the reason is that each remapped segment needs to be unmapped separately in the end. */typedef struct _remap_t {    struct _remap_t * next;    char* start;    char* end;    size_t cnt;    void *bases[1]; /* EXTENDS (cnt-1) BEYOND THE END OF THE STRUCT */} remap_t;remap_t *remaps = NULL;static remap_t *remap_find(char* base, int delete) {	remap_t *map, *prev=NULL;	(void) pthread_mutex_lock(&MT_mmap_lock);	for(map=remaps; map; map=map->next) {		if (base >= map->start && base < map->end) {			if (delete) {				if (prev) prev->next = map->next;				else remaps = map->next;				map->next = NULL;			} break;		}	}	(void) pthread_mutex_unlock(&MT_mmap_lock);	return map;}	void*MT_mmap_open(MT_mmap_hdl *hdl, char *path, int mode, off_t off, size_t len, size_t nremaps){	void *ret = NULL;	int mode0 = GENERIC_READ;	int mode1 = FILE_SHARE_READ;	int mode2 = mode & MMAP_ADVISE;	int mode3 = PAGE_READONLY;	int mode4 = FILE_MAP_READ;	SECURITY_ATTRIBUTES sa;	HANDLE h1, h2;	remap_t *map;	memset(hdl, 0, sizeof(MT_mmap_hdl));	if (mode & MMAP_WRITE) {		mode0 |= GENERIC_WRITE;		mode1 |= FILE_SHARE_WRITE;	}	if (mode2 == MMAP_RANDOM || mode2 == MMAP_DONTNEED) {		mode2 = FILE_FLAG_RANDOM_ACCESS;	} else if (mode2 == MMAP_SEQUENTIAL || mode2 == MMAP_WILLNEED) {		mode2 = FILE_FLAG_SEQUENTIAL_SCAN;	} else {		mode2 = FILE_FLAG_NO_BUFFERING;	}	if (mode & MMAP_SYNC) {		mode2 |= FILE_FLAG_WRITE_THROUGH;	}	if (mode & MMAP_COPY) {		mode3 = PAGE_WRITECOPY;		mode4 = FILE_MAP_COPY;	} else if (mode & MMAP_WRITE) {		mode3 = PAGE_READWRITE;		mode4 = FILE_MAP_WRITE;	}	sa.nLength = sizeof(SECURITY_ATTRIBUTES);	sa.bInheritHandle = TRUE;	sa.lpSecurityDescriptor = 0;	h1 = CreateFile(path, mode0, mode1, &sa, OPEN_ALWAYS, mode2, NULL);	if (h1 == INVALID_HANDLE_VALUE) {		GDKsyserror("MT_mmap: CreateFile('%s', %d, %d, &sa, %d, %d, NULL) failed\n", path, mode0, mode1, OPEN_ALWAYS, mode2);		return (void *) -1;	}	h2 = CreateFileMapping(h1, &sa, mode3, (DWORD) ((((gdk_int64) off + (gdk_int64) len) >> 32) & LL_CONSTANT(0xFFFFFFFF)), (DWORD) ((off + len) & LL_CONSTANT(0xFFFFFFFF)), NULL);	if (h2 == NULL) {		GDKsyserror("MT_mmap: CreateFileMapping(" PTRFMT ", &sa, %d, %d, %u, NULL) failed\n", PTRFMTCAST h1, mode3, (DWORD) ((((gdk_int64) off + (gdk_int64) len) >> 32) & LL_CONSTANT(0xFFFFFFFF)), (DWORD) ((off + len) & LL_CONSTANT(0xFFFFFFFF)));		CloseHandle(h1);		return (void *) -1;	}	hdl->hdl = (void *) h2;	hdl->mode = mode4;	CloseHandle(h1);	if (nremaps == 0) {		return MT_mmap_remap(hdl, off, len); /* normal mmap(). no further remaps */	}	/* for complex mmaps we now make it very likely that the MapViewOfFileEx-es to a predetermined VM address will all succeed */	ret = VirtualAlloc(NULL, len, MEM_RESERVE, PAGE_READWRITE);    	if (ret == NULL)		return (void*) -1;	hdl->fixed = ret; /* now we have a VM region that is large enough */	/* ensure exclusive VM access to MapViewOfFile and VirtualAlloc (almost.. malloc() may trigger it -- ignored) */	(void) pthread_mutex_lock(&MT_mmap_lock);	hdl->hasLock = 1;	/* release the range, so we can MapViewOfFileEx into it later */	VirtualFree(ret, 0, MEM_RELEASE);	/* allocate a map record to administer all your bases (they are belong to us!) */	map = malloc(sizeof(remap_t) + sizeof(void *) * nremaps);	if (map == NULL)		return (void *) -1;	hdl->map = (void *) map;	map->cnt = 0;	map->start = (char *) hdl->fixed;	map->end = map->start + len;	return ret;}void *MT_mmap_remap(MT_mmap_hdl *hdl, off_t off, size_t len){	remap_t *map = (remap_t*) hdl->map;	void *ret;	ret = MapViewOfFileEx((HANDLE) hdl->hdl, hdl->mode, (DWORD) ((gdk_int64) off >> 32), (DWORD) off, len, (void *) ((char *) hdl->fixed));	if (ret == NULL) {		GDKsyserror("MT_mmap: MapViewOfFileEx(" PTRFMT ", %d, %d, %u, %d, " PTRFMT ") failed\n", PTRFMTCAST hdl->hdl, hdl->mode, (DWORD) ((gdk_int64) off >> 32), (DWORD) off, len, PTRFMTCAST hdl->fixed);		return (void *) -1;	} 	if (map) map->bases[map->cnt++] = ret; /* administer new base */	hdl->fixed = (void *) ((char *) ret + len);	return ret;}voidMT_mmap_close(MT_mmap_hdl *hdl){	if (hdl->hasLock) {		(void) pthread_mutex_unlock(&MT_mmap_lock);	}	if (hdl->hdl) {		CloseHandle((HANDLE) hdl->hdl);		hdl->hdl = NULL;	}}intMT_munmap(void *p, size_t dummy){	remap_t *map = remap_find(p, TRUE);	int ret = 0;	(void)dummy;	if (map) {		/* remapped region; has multiple bases on which we must invoke the Windows API */		size_t i;		for(i=0; i<map->cnt; i++) 			if (UnmapViewOfFile(map->bases[i]) == 0) ret = -1;		free(map);	} else {		/*       Windows' UnmapViewOfFile returns success!=0, error== 0,	  	 * while Unix's   munmap          returns success==0, error==-1. */		if (UnmapViewOfFile(p) == 0) ret = -1;	}	return ret;}intMT_msync(void *p, size_t len, int mode){	remap_t *map = remap_find(p, FALSE);	int ret = 0;	(void)mode;

⌨️ 快捷键说明

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