Implement file cache. needs some testing :)

Fix some bugs in memory management.

svn-id: r23870
This commit is contained in:
Won Star 2006-09-13 07:32:54 +00:00
parent c66ec787d2
commit 595a035bee
6 changed files with 133 additions and 67 deletions

View File

@ -28,7 +28,7 @@ CFLAGS = -marm -march=armv4t -mtune=arm920 -mapcs \
-mno-thumb-interwork \ -mno-thumb-interwork \
-I$(GPSDK)/include \ -I$(GPSDK)/include \
-g \ -g \
-O \ -O2 \
-fomit-frame-pointer -fomit-frame-pointer
# -ffast-math \ # -ffast-math \
# -fshort-double # -fshort-double
@ -92,9 +92,9 @@ DEFINES += -DDISABLE_FANCY_THEMES
#LIBS += -Lbackends/platform/gp32/gpmad -lgpmad #LIBS += -Lbackends/platform/gp32/gpmad -lgpmad
# Support libminilzo. # Support libminilzo.
#DEFINES += -DUSE_MINILZO DEFINES += -DUSE_MINILZO
#INCLUDES += -Ibackends/platform/gp32/minilzo INCLUDES += -Ibackends/platform/gp32/minilzo
#LIBS += -Lbackends/platform/gp32/minilzo -lminilzo LIBS += -Lbackends/platform/gp32/minilzo -lminilzo
# Support for 8:3 save files names (The GP32 uses FAT12/16 (no vFAT) for the file system). # Support for 8:3 save files names (The GP32 uses FAT12/16 (no vFAT) for the file system).
DEFINES += -DSHORT_SAVENAMES DEFINES += -DSHORT_SAVENAMES
@ -159,19 +159,15 @@ DISABLE_HQ_SCALERS = 1
DISABLE_SCUMM_7_8 = 1 DISABLE_SCUMM_7_8 = 1
DISABLE_HE = 1 DISABLE_HE = 1
# ??? #DISABLE_SIMON = 1
DISABLE_SIMON = 1 #DISABLE_SKY = 1
DISABLE_SKY = 1 #DISABLE_QUEEN = 1
DISABLE_QUEEN = 1 #DISABLE_GOB = 1
DISABLE_GOB = 1 #DISABLE_LURE = 1
DISABLE_LURE = 1 #DISABLE_CINE = 1
DISABLE_CINE = 1 #DISABLE_SAGA = 1
#DISABLE_KYRA = 1
# In-development engines below. #DISABLE_AGI = 1
# Disable for ALL release builds.
DISABLE_SAGA = 1
DISABLE_KYRA = 1
DISABLE_AGI = 1
# The engines below are not supported on the GP32 port so there is # The engines below are not supported on the GP32 port so there is
# no point compiling support into the binary. # no point compiling support into the binary.

View File

@ -67,6 +67,7 @@ void GpMain(void *arg) {
//doConfig //doConfig
gp_initGammaTable((float)g_vars.gammaRamp / 10000); gp_initGammaTable((float)g_vars.gammaRamp / 10000);
gp_setCpuSpeed(g_vars.cpuSpeed); gp_setCpuSpeed(g_vars.cpuSpeed);
GPDEBUG("Set CPU Speed: %d", g_vars.cpuSpeed);
// FOR DEBUG PURPOSE! // FOR DEBUG PURPOSE!
//int argc = 4; //int argc = 4;

View File

@ -286,7 +286,7 @@ void GPDEBUG(const char *fmt, ...) {
} }
void NP(const char *fmt, ...) { void NP(const char *fmt, ...) {
return; // return;
char s[256]; char s[256];
va_list marker; va_list marker;
@ -299,7 +299,7 @@ void NP(const char *fmt, ...) {
} }
void LP(const char *fmt, ...) { void LP(const char *fmt, ...) {
return; // return;
char s[256]; char s[256];
va_list marker; va_list marker;
@ -312,7 +312,7 @@ void LP(const char *fmt, ...) {
} }
void SP(const char *fmt, ...) { void SP(const char *fmt, ...) {
return; // return;
char s[256]; char s[256];
va_list marker; va_list marker;
@ -325,7 +325,7 @@ void SP(const char *fmt, ...) {
} }
void BP(const char *fmt, ...) { void BP(const char *fmt, ...) {
return; // return;
char s[256]; char s[256];
va_list marker; va_list marker;

View File

@ -38,11 +38,49 @@ FILE *gp_stdout = NULL;
FILE *gp_stdin = NULL; FILE *gp_stdin = NULL;
// Cache Idea / Code borrowed from the ps2 port // Cache Idea / Code borrowed from the ps2 port
//#define USE_CACHE #define USE_CACHE
////////////////// //////////////////
//File functions //File functions
// CACHE
inline bool gp_cacheInPos(GPFILE *stream)
{
return (stream->cachePos <= stream->filePos && stream->filePos < stream->cachePos + stream->bytesInCache);
}
int gp_cacheMiss(GPFILE *stream)
{
unsigned long readcount = 0;
int copyLen = stream->fileSize - stream->filePos;
if (copyLen > FCACHE_SIZE)
copyLen = FCACHE_SIZE;
stream->cachePos = stream->filePos;
stream->cacheBufOffs = 0;
stream->bytesInCache = copyLen;
ERR_CODE err = GpFileRead(stream->handle, stream->cacheData, copyLen, &readcount);
stream->physFilePos += copyLen;
return err;
}
int gp_flushWriteCache(GPFILE *stream) {
ERR_CODE err = GpFileWrite(stream->handle, stream->cacheData, stream->bytesInCache); // flush cache
stream->filePos += stream->bytesInCache;
stream->physFilePos += stream->bytesInCache;
stream->bytesInCache = 0;
return err;
}
///////////////////////////////////////////////////////////////
GPFILE *gp_fopen(const char *fileName, const char *openMode) { GPFILE *gp_fopen(const char *fileName, const char *openMode) {
//FIXME: allocation, mode //FIXME: allocation, mode
uint32 mode; uint32 mode;
@ -88,6 +126,9 @@ GPFILE *gp_fopen(const char *fileName, const char *openMode) {
file->mode = mode; file->mode = mode;
file->cachePos = 0; file->cachePos = 0;
file->filePos = 0;
file->cacheBufOffs = 0;
file->physFilePos = 0;
file->bytesInCache = 0; file->bytesInCache = 0;
return file; return file;
@ -106,9 +147,8 @@ int gp_fclose(GPFILE *stream) {
*/ */
#ifdef USE_CACHE #ifdef USE_CACHE
if (stream->cachePos && stream->mode == OPEN_W) { if (stream->bytesInCache && stream->mode == OPEN_W) {
GpFileWrite(stream->handle, (char *)stream->cacheData, stream->cachePos); // flush cache gp_flushWriteCache(stream);
stream->cachePos = 0;
} }
#endif #endif
@ -130,18 +170,38 @@ int gp_fseek(GPFILE *stream, long offset, int whence) {
whence = FROM_END; whence = FROM_END;
break; break;
} }
return GpFileSeek(stream->handle, whence, offset, (long *)&stream->filePos); //FIXME?
ERR_CODE err;
#ifdef USE_CACHE
// need to flush cache
if (stream->mode == OPEN_W) { // write
gp_flushWriteCache(stream);
err = GpFileSeek(stream->handle, whence, offset, (long *)&stream->filePos);
} else { // read
if (whence == SEEK_CUR)
offset += stream->physFilePos - stream->filePos;
err = GpFileSeek(stream->handle, whence, offset, (long *)&stream->physFilePos);
stream->filePos = stream->physFilePos;
if (gp_cacheInPos(stream)) {
} else { // cache miss
gp_cacheMiss(stream);
}
}
#endif
return 1;
//return 0; //FIXME?
} }
size_t gp_fread(void *ptr, size_t size, size_t n, GPFILE *stream) { size_t gp_fread(void *ptr, size_t size, size_t n, GPFILE *stream) {
ulong readcount = 0; unsigned int len = size * n;
int len = size * n;
#ifdef USE_CACHE
uint8 *dest = (uint8 *)ptr; uint8 *dest = (uint8 *)ptr;
while (len && (stream->filePos != stream->fileSize)) { #ifdef USE_CACHE
if (stream->cachePos <= filePos && filePos < stream->cachePos + stream->bytesInCache) { while (len && !gp_feof(stream)) {
if (gp_cacheInPos(stream)) {
uint32 startPos = (stream->cacheBufOffs + (stream->filePos - stream->cachePos)) % FCACHE_SIZE; uint32 startPos = (stream->cacheBufOffs + (stream->filePos - stream->cachePos)) % FCACHE_SIZE;
uint32 copyLen = stream->bytesInCache - (stream->filePos - stream->cachePos); uint32 copyLen = stream->bytesInCache - (stream->filePos - stream->cachePos);
if (copyLen > len) if (copyLen > len)
@ -149,26 +209,28 @@ size_t gp_fread(void *ptr, size_t size, size_t n, GPFILE *stream) {
if (startPos + copyLen > FCACHE_SIZE) if (startPos + copyLen > FCACHE_SIZE)
copyLen = FCACHE_SIZE - startPos; copyLen = FCACHE_SIZE - startPos;
memcpy(dest, cacheData + startPos, copyLen); memcpy(dest, stream->cacheData + startPos, copyLen);
filePos += copyLen; stream->filePos += copyLen;
dest += copyLen; dest += copyLen;
len -= copyLen; len -= copyLen;
} else { } else { // cache miss or cache empty
#endif gp_cacheMiss(stream);
ERR_CODE err = GpFileRead(stream->handle, ptr, len, &readcount);
#ifdef USE_CACHE
stream->filePos += len;
} }
} }
#else
ulong readcount = 0;
ERR_CODE err = GpFileRead(stream->handle, ptr, len, &readcount);
stream->physFilePos += len;
stream->filePos += len;
#endif #endif
return readcount / size; //FIXME? return 1; //readcount / size; //FIXME
} }
size_t gp_fwrite(const void *ptr, size_t size, size_t n, GPFILE *stream) { size_t gp_fwrite(const void *ptr, size_t size, size_t n, GPFILE *stream) {
int len = size * n; int len = size * n;
uint8 *srcBuf = (uint8 *)ptr;
if (!stream) { if (!stream) {
//warning("writing to null file"); //warning("writing to null file");
@ -176,31 +238,37 @@ size_t gp_fwrite(const void *ptr, size_t size, size_t n, GPFILE *stream) {
} }
#ifdef USE_CACHE #ifdef USE_CACHE
if (stream->cachePos + len < FCACHE_SIZE) { while (len) {
memcpy(stream->cacheData + stream->cachePos, ptr, len); uint32 copyLen;
stream->cachePos += len; if (stream->bytesInCache + len > FCACHE_SIZE)
} else { copyLen = FCACHE_SIZE - stream->bytesInCache;
if (stream->cachePos) {
GpFileWrite(stream->handle, stream->cacheData, stream->cachePos); // flush cache
stream->cachePos = 0;
}
#endif
ERR_CODE err = GpFileWrite(stream->handle, ptr, len);
if (!err)
return n;
else else
return -err; copyLen = len;
#ifdef USE_CACHE
srcBuf += copyLen;
len -= copyLen;
if (stream->bytesInCache == FCACHE_SIZE) {
ERR_CODE err = GpFileWrite(stream->handle, stream->cacheData, stream->bytesInCache); // flush cache
stream->filePos += stream->bytesInCache;
stream->physFilePos += stream->bytesInCache;
stream->bytesInCache = 0;
}
} }
#else
ERR_CODE err = GpFileWrite(stream->handle, ptr, len);
if (!err)
return n;
else
return -err;
#endif #endif
return 0; return 1;
} }
//FIXME? use standard func
long gp_ftell(GPFILE *stream) { long gp_ftell(GPFILE *stream) {
ulong pos = 0; ulong pos = 0;
ERR_CODE err = GpFileSeek(stream->handle, FROM_CURRENT, 0, (long*)&pos); pos = stream->filePos;
//ERR_CODE err = GpFileSeek(stream->handle, FROM_CURRENT, 0, (long*)&pos);
return pos; return pos;
} }
@ -209,7 +277,7 @@ void gp_clearerr(GPFILE *stream)
} }
int gp_feof(GPFILE *stream) { int gp_feof(GPFILE *stream) {
return gp_ftell(stream) >= stream->fileSize; return (unsigned long)gp_ftell(stream) >= stream->fileSize;
} }
char gp_fgetc(GPFILE *stream) { char gp_fgetc(GPFILE *stream) {

View File

@ -33,6 +33,7 @@ typedef struct {
unsigned long mode; unsigned long mode;
unsigned long fileSize; unsigned long fileSize;
unsigned long filePos; unsigned long filePos;
unsigned long physFilePos;
unsigned long cachePos; unsigned long cachePos;
unsigned long cacheBufOffs; unsigned long cacheBufOffs;
unsigned long bytesInCache; unsigned long bytesInCache;

View File

@ -122,8 +122,10 @@ void *MemBlock::addBlock(size_t size)
} }
blk++; blk++;
} }
if(i == prevBlock) if(i == prevBlock) {
return NULL; prevBlock = 0;
return gm_malloc(size);
}
} }
byte *ptr = userMem + (i * USER_BLOCK_SIZE); byte *ptr = userMem + (i * USER_BLOCK_SIZE);
@ -139,11 +141,13 @@ void *MemBlock::addBlock(size_t size)
void MemBlock::deleteBlock(void *dstBlock) void MemBlock::deleteBlock(void *dstBlock)
{ {
// Faster method
uint32 np = (uint32) dstBlock - (uint32) userMem; uint32 np = (uint32) dstBlock - (uint32) userMem;
if ((np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE != np) { if ((np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE != np) {
gm_free(dstBlock); gm_free(dstBlock);
// warning("wrong block! (%d / %d)", (np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE, np); // warning("wrong block! (%d / %d)", (np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE, np);
return;
} }
int i = np / USER_BLOCK_SIZE; int i = np / USER_BLOCK_SIZE;
if (i > NUM_BLOCK) { if (i > NUM_BLOCK) {
@ -201,10 +205,6 @@ void *gp_malloc(size_t size) {
int allocSize = ALIGNED_SIZE(size) + sizeof(uint32) + sizeof(uint32); int allocSize = ALIGNED_SIZE(size) + sizeof(uint32) + sizeof(uint32);
if (allocSize <= USER_BLOCK_SIZE) { if (allocSize <= USER_BLOCK_SIZE) {
np = (uint32) MemBlock::addBlock(allocSize); np = (uint32) MemBlock::addBlock(allocSize);
if (!np) {
// GPDEBUG("falling back to gm_malloc");
np = (uint32) gm_malloc(allocSize);
}
} else { } else {
np = (uint32) gm_malloc(allocSize); np = (uint32) gm_malloc(allocSize);
} }
@ -276,7 +276,7 @@ static char usedMemStr[16];
int gUsedMem = 1024 * 1024; int gUsedMem = 1024 * 1024;
//#define CLEAN_MEMORY_WITH_0xE7 //#define CLEAN_MEMORY_WITH_0xE7
#define CHECK_USED_MEMORY //#define CHECK_USED_MEMORY
//#define CHECK_NEW_TIME //#define CHECK_NEW_TIME
//#define CHECK_NEW_SIZE //#define CHECK_NEW_SIZE