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

📄 mem.c

📁 smallbasic for linux
💻 C
📖 第 1 页 / 共 2 页
字号:
	int		bsize = vm_index_page_size * sizeof(vm_node);	int		bmax  = (vm_count-1) / vm_index_page_size;	#if defined(_PalmOS)	Err		ferr;	#endif//	printf("sw bank %d -> %d\n", vm_bank, bank);	if	( bank != vm_bank )	{		/*		*	Save current 'bank' to disk		*/		#if defined(_PalmOS)		FileSeek(vm_index, bsize * vm_bank, fileOriginBeginning);		FileClearerr(vm_index);		FileWrite(vm_index, vm_table, bsize, 1, &ferr);		if	( ferr )	{			if	( ferr != fileErrEOF )				panic("VMM: Swap page #1 (%d) failed", bank);			}		#else		lseek(vm_index, bsize * vm_bank, SEEK_SET);		if ( write(vm_index, vm_table, bsize) != bsize )			panic("VMM: Swap page #1 (%d) failed", bank);		#endif		}	#if defined(_PalmOS)	FileSeek(vm_index, bsize * bank, fileOriginBeginning);	#else	lseek(vm_index, bsize * bank, SEEK_SET);	#endif	if	( bank == (bmax+1) )	{			/*		*	We need a new bank. Create an empty bank and switch to the new bank		*/		memset(vm_table, 0, bsize);		#if defined(_PalmOS)		FileClearerr(vm_index);		FileWrite(vm_index, vm_table, bsize, 1, &ferr);		if	( ferr )	{			if	( ferr != fileErrEOF )				panic("VMM: Swap page #2 failed (%d)", bank);			}		#else		if ( write(vm_index, vm_table, bsize) != bsize )			panic("VMM: Swap page #2 failed (%d)", bank);		#endif		}	else if ( bank <= bmax )	{		/*		*	load bank		*/		#if defined(_PalmOS)		FileRead(vm_index, vm_table, bsize, 1, &ferr);		if	( ferr )	{			if	( ferr != fileErrEOF )				panic("VMM: load page failed (%d)", bank);			}		#else		if ( read(vm_index, vm_table, bsize) != bsize )			panic("VMM: load page failed (%d)", bank);		#endif		}	else		panic("VMM: Invalid page rq (%d)", bank);	vm_bank = bank;}/**	Returns the 'idx' VM index-node*/vm_node		*vm_getnode(int idx){	int		bank = idx / vm_index_page_size;	int		ridx = idx - (bank * vm_index_page_size);	if	( idx < 0 || idx >= vm_count )		panic("VMM: Invalid node rq (%d)", idx);			if	( bank != vm_bank )		vm_swbank(bank);	return &vm_table[ridx];}/**	Creates & returns a new VM index node*/vm_node		*vm_newnode(){	int		bank = vm_count / vm_index_page_size;	if	( bank != vm_bank )		vm_swbank(bank);	vm_count ++;	return vm_getnode(vm_count-1);}/**	Destroy	everything*/void	vm_close(){	int		i;	vm_node	*node = NULL;	if	( vm_init_count )	{			vm_init_count --;		if	( vm_init_count == 0 )	{						/*			*	cleanup - nodes			*/			for ( i = 0; i < vm_count; i ++ )	{				node = vm_getnode(i);				if	( node->status & 0xFF )							tmp_free(node->ptr);				}			tmp_free(vm_table);			/*			*	cleanup			*/			vm_table = NULL;			vm_bank  = 0;			vm_count = 0;			vm_fsize = 0;			#if defined(_PalmOS)				FileClose(vm_index);				FileClose(vm_dev);				FileDelete(0, "SBIDX.SWP");				FileDelete(0, "SB.SWP");			#else				remove(vm_idxname);				remove(vm_name);			#endif			}		}}/**	Returns the VM handle of ptr*/int		vm_findptr(void *ptr){	int		i;	vm_node	*node = NULL;	for ( i = 0; i < vm_count; i ++ )	{		node = vm_getnode(i);		if	( node->ptr == ptr )				return i;		}	return -1;}/**	Allocates a new memory block and returns the handle*/int		vm_halloc(word size){	#if defined(_PalmOS)	Err		ferr;	#endif	int		i, idx;	vm_node	*node = NULL;	idx = -1;	// search for deleted record	for ( i = 0; i < vm_count; i ++ )	{		node = vm_getnode(i);		if	( node->status & 0x8000 )	{			if	( node->size >= size )	{				idx = i;	// found				break;				}			// we can continue to looking for the best deleted block, but VM is already too slow on PalmOS			}		}	//	if	( idx == -1 )	{		// this is a new record		node = vm_newnode();		idx = vm_count - 1;		node->offset = vm_fsize;		vm_fsize = vm_fsize + (dword) size;		}	else	{		// this is replace/update		if	( (node->size - size) > 64 )	{	// the remain chunk is large enought to keep it 			node->offset += node->size;			node->size   -= size;			node = vm_newnode();			idx = vm_count - 1;			}		else		// the remain chunk is too small, so we'll replace it (actualy we going to append this to the new)			size = node->size;	// because the old size is eq or greater than the rq size		}		//	node->size = size;	node->status = 0;		// write an empty record	node->ptr = tmp_alloc(size);	node->size = size;	if	( node->ptr == NULL )		panic("VMM: Out of memory (new record), handle = %d, size = %d", idx, node->size);	memset(node->ptr, 0, node->size);		#if defined(_PalmOS)	FileSeek(vm_dev, node->offset, fileOriginBeginning);	FileClearerr(vm_dev);	FileWrite(vm_dev, node->ptr, node->size, 1, &ferr);	if	( ferr )	{		if	( ferr != fileErrEOF )			panic("VMM: Swap file corrupted #6 (%d)", idx);		}	#else	lseek(vm_dev, node->offset, SEEK_SET);	if ( write(vm_dev, node->ptr, node->size) != node->size )		panic("VMM: Swap file corrupted #6 (%d)", idx);	#endif	tmp_free(node->ptr);	node->ptr = NULL;	//	return idx;}/**	Release a memory block*/void	vm_hfree(int idx){	vm_node	*node = NULL;	node = vm_getnode(idx);	if	( node->status & 0xFF )		panic("VMM: vm_hfree: Handle %d is locked", idx);	node->status = 0x8000;}/**	lock handle**	(load data into memory)*/void*	vm_lock(int idx){	vm_node	*node = NULL;	#if defined(_PalmOS)	Err		ferr;	#endif	node = vm_getnode(idx);	if	( node->status & 0xFF )			node->status = (node->status & 0xFF) + 1;	else 	{			node->ptr = tmp_alloc(node->size);		if ( !node->ptr )				panic("VMM: Out of memory when I locking the %d handle", idx);		#if defined(_PalmOS)		if ( FileSeek(vm_dev, node->offset, fileOriginBeginning) )			panic("VMM: Swap file corrupted #1 (%d)", idx);		FileRead(vm_dev, node->ptr, node->size, 1, &ferr);		if	( ferr )	{			if	( ferr != fileErrEOF )				panic("VMM: Swap file corrupted #2 (%d)", idx);			}		#else		if	( lseek(vm_dev, node->offset, SEEK_SET) >= 0 || node->offset == 0 )	{			if	( read(vm_dev, node->ptr, node->size) != node->size )				panic("VMM: Swap file corrupted #2 (%d)", idx);			}		else			panic("VMM: Swap file corrupted #1 (%d)", idx);		#endif		node->status ++;		}	return node->ptr;}/**	unlock handle**	(write data to disk and free associeted memory)*/void	vm_unlock(int idx){	vm_node	*node = NULL;	#if defined(_PalmOS)	Err		ferr;	#endif	node = vm_getnode(idx);	if	( node->status & 0xFF )		{		node->status = (node->status & 0xFF) - 1;		if	( (node->status & 0xFF) == 0 )	{			#if defined(_PalmOS)			if ( FileSeek(vm_dev, node->offset, fileOriginBeginning) )				panic("VMM: Swap file corrupted #3 (%d)", idx);			FileWrite(vm_dev, node->ptr, node->size, 1, &ferr);			if	( ferr )	{				if	( ferr != fileErrEOF )					panic("VMM: Swap file corrupted #4 (%d)", idx);				}			#else			if	( lseek(vm_dev, node->offset, SEEK_SET) >= 0 )	{				if	( write(vm_dev, node->ptr, node->size) != node->size )					panic("VMM: Swap file corrupted #4 (%d)", idx);				}			else				panic("VMM: Swap file corrupted #3 (%d)", idx);			#endif			tmp_free(node->ptr);			node->ptr = NULL;			}		}	else		panic("VMM: Handle %d is unlocked", idx);}/**	Creates a new memory block and returns its pointer*/void*	vm_alloc(word size){	int		idx;	idx = vm_halloc(size);	return vm_lock(idx);}/**	Release a memory block using its pointer*/void	vm_free(void *ptr){	int		idx;	idx = vm_findptr(ptr);	if	( idx >= 0 )	{		vm_unlock(idx);		vm_hfree(idx);		}	else		panic("VMM: Invalid handle");}#endif // VMM/* -----------------------------------------------------------------------------------------------------------------------**	Tables (using PalmOS DataManager, or simple memory manager)**	For PalmOS, the DataManager is used.*	For the rest, we'll use simple memory allocation.*//**	Create a table*/dbt_t	dbt_create(const char *fileName){	dbt_t	fp;	#if defined(_PalmOS)	LocalID		lid;	lid = DmFindDatabase(0, (char *) fileName);	if	( !lid )	{		DmCreateDatabase(0, fileName, ID_SmBa, ID_DATA, 0);		lid = DmFindDatabase(0, (char *) fileName);		}	fp = DmOpenDatabase(0, lid, dmModeReadWrite);	#else	int		*table;	int		i, size = 32;	fp = mem_alloc(sizeof(int) * size);	table = (int *) mem_lock(fp);	for ( i = 0; i < size; i ++ )			table[i] = 0;	mem_unlock(fp);	#endif	return fp;}/**	Close table (warning: file does not deleted)*/void	dbt_close(dbt_t f){	#if defined(_PalmOS)	DmCloseDatabase(f);		#else	int		*table;	int		i, tsize;	table = (int *) mem_lock(f);	tsize = MemHandleSize(f) / sizeof(int);	for ( i = 0; i < tsize; i ++ )	{		if	( table[i] )			mem_free(table[i]);		}	mem_unlock(f);	mem_free(f);	#endif}/**	Allocate a standard size (use it at startup; good speed optimization)*/void	dbt_prealloc(dbt_t f, int num, int size){	#if defined(_PalmOS)	int		i;	word	recIndex, start;	mem_t	rec_h;	start = DmNumRecords(f);	if	( start < num )	{		// create a new records		for ( i = start; i < num; i ++ )	{			recIndex = dmMaxRecordIndex;			rec_h = DmNewRecord(f, &recIndex, size);			DmReleaseRecord(f, recIndex, 1);			}		}	else if ( start > num )	{		// delete extra records		for ( i = num; i < start; i ++ )				DmRemoveRecord(f, num);		}	#endif}/**	Store an element*/void	dbt_write(dbt_t f, int index, void *ptr, int size){	#if defined(_PalmOS)	word	recIndex, i;	mem_t	rec_h;	char	*prevrec;	if	( index >= DmNumRecords(f) )	{		// create a new record 		for ( i = index; i < index + 128; i ++ )	{			recIndex = dmMaxRecordIndex;			rec_h = DmNewRecord(f, &recIndex, size);			DmReleaseRecord(f, recIndex, 1);			}		recIndex = index;		rec_h = DmGetRecord(f, recIndex);		}	else	{		// update record		word	src_sz;		recIndex = index;		rec_h = DmGetRecord(f, recIndex);		src_sz = MemHandleSize(rec_h);		if	( src_sz != size )			MemHandleResize(rec_h, size);		}	prevrec = mem_lock(rec_h);	DmWrite(prevrec, 0, ptr, size);	mem_unlock(rec_h);	DmReleaseRecord(f, recIndex, 1);	#else	int		*table;	int		i, tsize;	char	*mp;	tsize = MemHandleSize(f) / sizeof(int);	if	( tsize <= index )	{		f = mem_realloc(f, sizeof(int) * (tsize + 32));		table = (int *) mem_lock(f);		for ( i = tsize; i < tsize+32; i ++ )				table[i] = 0;		mem_unlock(f);		tsize += 32;		}	table = (int *) mem_lock(f);	if	( table[index] == 0 )		table[index] = mem_alloc(size);	else if ( size != MemHandleSize(table[index]) )	{		mem_free(table[index]);		table[index] = mem_alloc(size);		}	mp = mem_lock(table[index]);	memcpy(mp, ptr, size);	mem_unlock(table[index]);	mem_unlock(f);	#endif}/**	Load an element*/void	dbt_read(dbt_t f, int index, void *ptr, int size){	#if defined(_PalmOS)	word	recIndex;	mem_t	rec_h;	char	*recptr;	if	( index >= DmNumRecords(f) )	{		// create a new record 		recIndex = dmMaxRecordIndex;		rec_h = DmNewRecord(f, &recIndex, size);		}	else	{		// update record		word	src_sz;		recIndex = index;		rec_h = DmGetRecord(f, recIndex);		src_sz = MemHandleSize(rec_h);		if	( src_sz != size )			MemHandleResize(rec_h, size);		}	recptr = mem_lock(rec_h);	memcpy(ptr, recptr, size);	mem_unlock(rec_h);	DmReleaseRecord(f, recIndex, 1);	#else	int		*table;	int		i, tsize;	char	*mp;	tsize = MemHandleSize(f) / sizeof(int);	if	( tsize <= index )	{		f = mem_realloc(f, sizeof(int) * (tsize + 32));		table = (int *) mem_lock(f);		for ( i = tsize; i < tsize+32; i ++ )				table[i] = 0;		mem_unlock(f);		tsize += 32;		}	table = (int *) mem_lock(f);	if	( table[index] == 0 )		table[index] = mem_alloc(size);	else if ( size > MemHandleSize(table[index]) )			table[index] = mem_realloc(table[index], size);	mp = mem_lock(table[index]);	memcpy(ptr, mp, size);	mem_unlock(table[index]);	mem_unlock(f);	#endif}

⌨️ 快捷键说明

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