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

📄 mem.c

📁 smallbasic for linux
💻 C
📖 第 1 页 / 共 2 页
字号:
/**	mem.h**	Simple and Virtual Memory Manager unix/palm**	Nicholas Christopoulos**	This program is distributed under the terms of the GPL v2.0 or later*	Download the GNU Public License (GPL) from www.gnu.org*/#include "sys.h"#include "pmem.h"#include "panic.h"#if defined(_PalmOS)#define	ID_SmBa	0x536D4261#define	ID_DATA	0x44415441#define ID_UFST  0x55465354#endif#if defined(_PalmOS)static FileHand	log_dev;		/* logfile file handle */#elsestatic int	log_dev;			/* logfile file handle */static char log_name[256];		/* LOGFILE filename */#endif#if defined(ENABLE_VMM)#if defined(_PalmOS)static LocalID	vm_lid;static FileHand	vm_dev;			/* VM swap file handle */static FileHand	vm_index;		/* VM index file handle */#elsestatic int	vm_dev;				/* VM swap file handle */static int	vm_index;			/* VM index file handle */static char vm_name[256];		/* VM swap filename */static char vm_idxname[256];	/* VM index filename */#endifstatic int	vm_init_count;		/* VM initialization check *//**	 VMM node*/struct	vm_node_s	{	void	*ptr;			/* pointer to local memory (only locked chunks had pointer!=NULL) */	dword	offset;			/* offset in file */	word	size;			/* block size */	word	status;			/* low byte = lock counter, high byte = [bit 7=deleted] */	};typedef struct vm_node_s	vm_node;static int vm_index_page_size;			/* VMM index page size (see vm_init(), index page size = 10% of free memory */static vm_node	*vm_table;				/* VMM index page */static int		vm_count;				/* VMM number of nodes */static word		vm_bank;				/* VMM current index-page number (this one is loaded into memory @'vm_table') */static dword	vm_fsize;				/* VMM data-file size; speed optimization */#endif // ENABLE_VMM/* ERROR MESSAGES */void	err_outofmem()					SEC(TRASH);void	err_outofmem()					{	panic("OUT OF MEMORY"); }void	err_tmpalloc(dword size)		SEC(TRASH);void	err_tmpalloc(dword size)		{	panic("tmp_alloc: size=%ld\n", size);	}void	err_tmpfree()					SEC(TRASH);void	err_tmpfree()					{	panic("tmp_free: Cannot recover handle");	}		  void	err_tmprealloc1()				SEC(TRASH);void	err_tmprealloc1()				{	panic("tmp_realloc: Cannot recover handle"); }void	err_tmprealloc2(dword size)		SEC(TRASH);void	err_tmprealloc2(dword size)		{	panic("tmp_realloc: Cannot resize memory to %ld", size); }void	err_memalloc1(dword size)		SEC(TRASH);void	err_memalloc1(dword size)		{	panic("mem_alloc: size=%ld\n", size);	}void	err_memrealloc1()				SEC(TRASH);void	err_memrealloc1()				{	panic("mem_realloc: Invalid handle"); }void	err_memrealloc2(dword size)		SEC(TRASH);void	err_memrealloc2(dword size)		{	panic("mem_realloc: Cannot resize memory to %ld", size); }void	err_lock()						SEC(TRASH);void	err_lock()						{	panic("mem_lock:MemLckErr");	}void	err_memunlock()					SEC(TRASH);void	err_memunlock()					{	panic("mem_unlock:MemHandleErr");	}void	err_memfree()					SEC(TRASH);void	err_memfree()					{	panic("mem_free:MemHandleErr");	}void	err_mlistadd()					SEC(TRASH);void	err_mlistadd()					{	panic("mlist_add: OUT OF MEMORY"); }void	err_tlistadd()					SEC(TRASH);void	err_tlistadd()					{	panic("tmplist_add: OUT OF MEMORY");	}/**	Allocate local memory*/#if defined(_PalmOS)void	*tmp_alloc(dword size){	void	*ptr;	MemHandle hdl;	if	( size < 0 )		err_tmpalloc(size);	hdl = MemHandleNew(size);	if	( hdl == 0 )		err_tmpalloc(size);	ptr = MemHandleLock(hdl);	return ptr;}#elsevoid	*tmp_allocX(dword size, const char *file, int line){	void	*ptr;	MemHandle hdl;	if	( size < 0 )		err_tmpalloc(size);	hdl = MemHandleNewX(size, file, line);	if	( hdl == 0 )		err_tmpalloc(size);	ptr = MemHandleLock(hdl);	return ptr;}#endif/**	Free local memory*/#if defined(_PalmOS)void	tmp_free(void *ptr){	MemHandle	hdl;	if	( ptr == NULL )		err_tmpfree();	MemPtrSize(ptr);	// check	hdl = MemPtrRecoverHandle(ptr);	if	( hdl == 0 )		err_tmpfree();	MemHandleUnlock(hdl);	MemHandleFree(hdl);}#elsevoid	tmp_freeX(void *ptr, const char *file, int line){	MemHandle	hdl;	if	( ptr == NULL )		err_tmpfree();	hdl = MemPtrRecoverHandleX(ptr, file, line);	if	( hdl == 0 )		err_tmpfree();	MemHandleUnlockX(hdl, file, line);	MemHandleFreeX(hdl, file, line);}#endif/**       Reallocate the size of a memory chunk*/void    *tmp_realloc(void *ptr, dword size){	MemHandle       hdl;	MemPtrSize(ptr);	// check	hdl = MemPtrRecoverHandle(ptr);	if  ( hdl == 0 )		err_tmprealloc1();	MemHandleUnlock(hdl);	#if defined(_PalmOS)	// memory defrag	MemHeapCompact(0);	#endif	if ( MemHandleResize(hdl, size) )		err_tmprealloc2(size);	return MemHandleLock(hdl);}/**	Allocate a memory handle (a memory block on "storage area")*/#if defined(_UnixOS)mem_t	mem_allocX(dword size, const char *file, int line)#elsemem_t	mem_alloc(dword size)#endif{	mem_t	h = 0;	if	( size < 0 )		err_memalloc1(size);		#if defined(_UnixOS)	h = MemHandleNewX(size, file, line);	#else	h = MemHandleNew(size);	#endif	if	( h == 0 )		err_outofmem();	return h;}/**	lock a memory handle (moves the memory block to dynamic RAM)*/void*	mem_lock(mem_t h){	void	*p;	if	( h <= 0 )		err_lock();	p = MemHandleLock(h);	if	( p == NULL )		err_lock();	return p;}/**	unlock a memory handle*/void	mem_unlock(mem_t h){	if	( h <= 0 )		err_memunlock();	MemHandleUnlock(h);}/**       Reallocate the size of a memory chunk*/mem_t	mem_realloc(mem_t hdl, dword new_size){	if  ( hdl == 0 )		err_memrealloc1();	if ( MemHandleResize(hdl, new_size) )		err_memrealloc2(new_size);	return hdl;}/**	free a memory block from storage RAM*/void	mem_free(mem_t h){	if	( h <= 0 )		err_memfree();	MemHandleFree(h);}/**	creates a memory block in storage RAM for string 'text'*/mem_t	mem_new_text(const char *text){	mem_t	h;	int		l;	char	*p;	l = strlen(text) + 1;	h = mem_alloc(l);	p = (char *) mem_lock(h);	strcpy(p, text);	mem_unlock(h);	return h;}#if defined(ENABLE_MEMLIST)/**	dynamic single-linked list in storage RAM**	list initialization*/void	mlist_init(mlist_t*lst){	lst->head = lst->tail = NULL;	lst->count = 0;}void	mlist_clear(mlist_t*lst){	mnode_t	*cur, *pre;	cur = lst->head;	while ( cur )	{		pre = cur;		cur = cur->next;		mem_free(pre->data);		MemPtrFree(pre);		}	mlist_init(lst);}mnode_t	*mlist_add(mlist_t* lst, mem_t h){	mnode_t		*np;	np = (mnode_t *) MemPtrNew(sizeof(mnode_t));	if	( !np )		err_mlistadd();	np->data = h;	np->next = NULL;	if	( lst->head )			( lst->tail->next = np, lst->tail = np );	else		lst->head = lst->tail = np;	lst->count ++;	return np;}#endif // ENABLE_MEMLIST#if defined(ENABLE_TMPLIST)/**	dynamic single-linked list in dynamic RAM*/void	tmplist_init(tmplist_t*lst){	lst->head = lst->tail = NULL;	lst->count = 0;}void	tmplist_clear(tmplist_t*lst){	tmpnode_t	*cur, *pre;	cur = lst->head;	while ( cur )	{		pre = cur;		cur = cur->next;		tmp_free(pre->data);		tmp_free(pre);		}	tmplist_init(lst);}tmpnode_t	*tmplist_add(tmplist_t* lst, void *data, int size){	tmpnode_t	*np;	np = (tmpnode_t *) MemPtrNew(sizeof(tmpnode_t));	if	( !np )		err_tlistadd();	np->data = tmp_alloc(size);	memcpy(np->data, data, size);	np->next = NULL;	if	( lst->head )			( lst->tail->next = np, lst->tail = np );	else		lst->head = lst->tail = np;	lst->count ++;	return np;}#endif // ENABLE_TMPLIST/* -----------------------------------------------------------------------------------------------------------------------**	LOGFILE**///void	lwrite(const char *buf){	#if defined(_PalmOS)	Err		ferr;	#endif	////////	// open	#if defined(_PalmOS)	log_dev = FileOpen(0, "SB.LOG", ID_UFST, ID_SmBa, fileModeAppend, &ferr);	if	( ferr != 0 )		panic("LOG: Error on creating log-file");	#else	#if defined(_Win32)		sprintf(log_name, "c:\sb.log");	#else	/* a real OS */		sprintf(log_name, "/tmp/sb.log");	#endif	log_dev = open(log_name, O_RDWR);	lseek(log_dev, 0, SEEK_END);	if	( log_dev == -1 )			log_dev = open(log_name, O_CREAT | O_RDWR);			if	( log_dev == -1 )		panic("LOG: Error on creating log file");	#endif	///////////	// write	#if defined(_PalmOS)	FileWrite(log_dev, (char *) buf, strlen(buf), 1, &ferr);	if	( ferr )	{		if	( ferr != fileErrEOF )			panic("LOG: write failed (ERR:%d)", ferr);		}	#else	if ( write(log_dev, buf, strlen(buf)) == -1 )		panic("LOG: write failed");	#endif	/// close	#if defined(_PalmOS)	FileClose(log_dev);	#else	close(log_dev);	#endif}//void	lprintf(const char *fmt, ...){	va_list ap;	char	*buf;	buf = tmp_alloc(256);	va_start(ap, fmt);	#if defined(_PalmOS)	StrVPrintF(buf, fmt, ap);	#else	vsprintf(buf, fmt, ap);	#endif	va_end(ap);	lwrite(buf);	tmp_free(buf);}//void	lg(const char *fmt, ...){	va_list ap;	char	*buf;//	#if defined(_PalmOS)//	ULong	dts;//	DateTimeType cur_date;//	#else//	struct tm 	tms;//	time_t	  	now;//	#endif	buf = tmp_alloc(256);	/////////////	// time/date//	#if defined(_PalmOS)//	dts = TimGetSeconds();//	TimSecondsToDateTime(dts, &cur_date);//	StrPrintF(buf, //		"%02d/%02d %02d:%02d:%02d: ", //		/* cur_date.year, */ cur_date.month, cur_date.day, //		cur_date.hour, cur_date.minute, cur_date.second);//	#else//	time(&now);//	tms = *localtime(&now);//	sprintf(buf, //		"%02d/%02d %02d:%02d:%02d: ", //		/* tms.tm_year+1900, */ tms.tm_mon+1, tms.tm_mday,//		tms.tm_hour, tms.tm_min, tms.tm_sec);//	#endif//	logwrite(buf);	lwrite("--- ");	va_start(ap, fmt);	#if defined(_PalmOS)	StrVPrintF(buf, fmt, ap);	#else	vsprintf(buf, fmt, ap);	#endif	va_end(ap);	strcat(buf, "\n");	lwrite(buf);	tmp_free(buf);}/* -----------------------------------------------------------------------------------------------------------------------**	VIRTUAL MEMORY**	VMM works like DBMS**	Its has a table of vm_node (vm_index file) witch keeps information about each allocated handle*	There is loaded (into the memory) only a part of this index of 'vmm_index_page_size' nodes witch located at vm_table*	Each block of vmm_index_page_size nodes is called bank.*/#if defined(ENABLE_VMM)/**	initialize*/void	vm_init(){	#if defined(_PalmOS)	dword	dwfre, dwmax;	Err		ferr;	#endif		if	( vm_init_count )			vm_init_count ++;	else	{		#if defined(_PalmOS)			vm_lid = DmFindDatabase(0, "SB.SWP");			if	( vm_lid )	{				FileDelete(0, "SB.SWP");				FileDelete(0, "SBIDX.SWP");				}			vm_dev   = FileOpen(0, "SB.SWP",    ID_DATA, ID_SmBa, fileModeReadWrite | fileModeTemporary, &ferr);			vm_index = FileOpen(0, "SBIDX.SWP", ID_DATA, ID_SmBa, fileModeReadWrite | fileModeTemporary, &ferr);			if	( ferr != 0 )				panic("VMM: Error on creating swap file");		#else			#if defined(_Win32)				sprintf(vm_name,    "c:\sb%d.swp",  1);				sprintf(vm_idxname, "c:\sb%di.swp", 1);			#else	/* a real OS */				sprintf(vm_name,    "/tmp/sb%d.swp",  getpid());				sprintf(vm_idxname, "/tmp/sb%di.swp", getpid());			#endif			remove(vm_name);			remove(vm_idxname);			vm_dev   = open(vm_name,    O_CREAT | O_RDWR | O_EXCL);			vm_index = open(vm_idxname, O_CREAT | O_RDWR | O_EXCL);			if	( vm_dev < 0 )				panic("VMM: Error on creating swap file");		#endif		//		#if defined(_PalmOS)		MemHeapFreeBytes(0, &dwfre, &dwmax);		vm_index_page_size = ((dwmax/10)/sizeof(vm_node));	// 10% of free memory		#else		vm_index_page_size = (65536/sizeof(vm_node));		// 64KB		#endif		vm_table = (vm_node *) tmp_alloc(sizeof(vm_node) * vm_index_page_size);		vm_bank  = 0;		vm_count = 0;		vm_fsize = 0;		vm_init_count ++;		}}/**	Switch bank */void	vm_swbank(int bank){

⌨️ 快捷键说明

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