📄 mem.c
字号:
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 + -