diff options
author | Won Star | 2006-06-29 05:15:45 +0000 |
---|---|---|
committer | Won Star | 2006-06-29 05:15:45 +0000 |
commit | 3a020e787617d9ae5004ffbd496b95a6d67e9ca2 (patch) | |
tree | 76b5f601adf34b73880307543481f264232570f4 /backends/gp32 | |
parent | fa4aa40b7b2bf0240b0c6e8116be4f87bdcb4cf0 (diff) | |
download | scummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.tar.gz scummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.tar.bz2 scummvm-rg350-3a020e787617d9ae5004ffbd496b95a6d67e9ca2.zip |
Add custom memory management code. malloc() for small allocs became much faster and startup time in the GP32 is now 10~30 secs depend on clock speed.
svn-id: r23338
Diffstat (limited to 'backends/gp32')
-rw-r--r-- | backends/gp32/Makefile | 1 | ||||
-rw-r--r-- | backends/gp32/gp32_main.cpp | 6 | ||||
-rw-r--r-- | backends/gp32/gp32_osys.h | 86 | ||||
-rw-r--r-- | backends/gp32/gp32std.cpp | 107 | ||||
-rw-r--r-- | backends/gp32/gp32std.h | 6 | ||||
-rw-r--r-- | backends/gp32/gp32std_memory.cpp | 304 | ||||
-rw-r--r-- | backends/gp32/gp32std_memory.h | 35 | ||||
-rw-r--r-- | backends/gp32/portdefs.h | 1 |
8 files changed, 391 insertions, 155 deletions
diff --git a/backends/gp32/Makefile b/backends/gp32/Makefile index 144ce36221..d61e8cb295 100644 --- a/backends/gp32/Makefile +++ b/backends/gp32/Makefile @@ -126,6 +126,7 @@ OBJS += backends/gp32/gp32std.o \ backends/gp32/gp32std_file.o \ backends/gp32/gp32std_grap.o \ backends/gp32/gp32std_input.o \ + backends/gp32/gp32std_memory.o \ backends/gp32/gp32std_sound.o \ #backends/gp32/dmaaudio_asm.o \ #backends/gp32/dmaaudio.o \ diff --git a/backends/gp32/gp32_main.cpp b/backends/gp32/gp32_main.cpp index b05117edc1..2175141f2e 100644 --- a/backends/gp32/gp32_main.cpp +++ b/backends/gp32/gp32_main.cpp @@ -38,6 +38,9 @@ GlobalVars g_vars; void init() { + extern void memChunkInit(); + memChunkInit(); + gp_setCpuSpeed(40); // Default CPU Speed GpGraphicModeSet(16, NULL); @@ -78,6 +81,9 @@ void GpMain(void *arg) { // Invoke the actual ScummVM main entry point: //int res = scummvm_main(argc, argv); int res = scummvm_main(1, NULL); + + extern void memChunkDeinit(); + memChunkDeinit(); g_system->quit(); // TODO: Consider removing / replacing this! //return res; diff --git a/backends/gp32/gp32_osys.h b/backends/gp32/gp32_osys.h index 0833577bc2..2986263424 100644 --- a/backends/gp32/gp32_osys.h +++ b/backends/gp32/gp32_osys.h @@ -85,62 +85,62 @@ protected: public: OSystem_GP32(); - virtual ~OSystem_GP32(); - - virtual bool hasFeature(Feature f); - virtual void setFeatureState(Feature f, bool enable); - virtual bool getFeatureState(Feature f); - virtual const GraphicsMode *getSupportedGraphicsModes() const; - virtual int getDefaultGraphicsMode() const; - virtual bool setGraphicsMode(int mode); + ~OSystem_GP32(); + + bool hasFeature(Feature f); + void setFeatureState(Feature f, bool enable); + bool getFeatureState(Feature f); + const GraphicsMode *getSupportedGraphicsModes() const; + int getDefaultGraphicsMode() const; + bool setGraphicsMode(int mode); bool setGraphicsMode(const char *name); - virtual int getGraphicsMode() const; - virtual void initSize(uint width, uint height); - virtual int16 getHeight(); - virtual int16 getWidth(); - virtual void setPalette(const byte *colors, uint start, uint num); - virtual void grabPalette(byte *colors, uint start, uint num); + int getGraphicsMode() const; + void initSize(uint width, uint height); + int16 getHeight(); + int16 getWidth(); + void setPalette(const byte *colors, uint start, uint num); + void grabPalette(byte *colors, uint start, uint num); - virtual void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); - virtual void updateScreen(); - virtual void setShakePos(int shakeOffset); + void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h); + void updateScreen(); + void setShakePos(int shakeOffset); - virtual void showOverlay(); - virtual void hideOverlay(); - virtual void clearOverlay(); - virtual void grabOverlay(OverlayColor *buf, int pitch); - virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); - virtual int16 getOverlayHeight(); - virtual int16 getOverlayWidth(); + void showOverlay(); + void hideOverlay(); + void clearOverlay(); + void grabOverlay(OverlayColor *buf, int pitch); + void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); + int16 getOverlayHeight(); + int16 getOverlayWidth(); - virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); - virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); + OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b); + void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b); - virtual bool showMouse(bool visible); + bool showMouse(bool visible); - virtual void warpMouse(int x, int y); - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1); + void warpMouse(int x, int y); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, byte keycolor = 255, int cursorTargetScale = 1); - virtual bool pollEvent(Event &event); - virtual uint32 getMillis(); - virtual void delayMillis(uint msecs); + bool pollEvent(Event &event); + uint32 getMillis(); + void delayMillis(uint msecs); - virtual void setTimerCallback(TimerProc callback, int interval); + void setTimerCallback(TimerProc callback, int interval); - virtual MutexRef createMutex(void); - virtual void lockMutex(MutexRef mutex); - virtual void unlockMutex(MutexRef mutex); - virtual void deleteMutex(MutexRef mutex); + MutexRef createMutex(void); + void lockMutex(MutexRef mutex); + void unlockMutex(MutexRef mutex); + void deleteMutex(MutexRef mutex); - virtual bool setSoundCallback(SoundProc proc, void *param); - virtual void clearSoundCallback(); - virtual int getOutputSampleRate() const; + bool setSoundCallback(SoundProc proc, void *param); + void clearSoundCallback(); + int getOutputSampleRate() const; - virtual void quit(); + void quit(); - virtual void setWindowCaption(const char *caption); + void setWindowCaption(const char *caption); - virtual void displayMessageOnOSD(const char *msg); + void displayMessageOnOSD(const char *msg); void fillMouseEvent(Event &event, int x, int y); void handleKbdMouse(); diff --git a/backends/gp32/gp32std.cpp b/backends/gp32/gp32std.cpp index 2e3cbea6cc..d6befb1367 100644 --- a/backends/gp32/gp32std.cpp +++ b/backends/gp32/gp32std.cpp @@ -33,6 +33,7 @@ #include "backends/gp32/gp32std.h" #include "backends/gp32/gp32std_grap.h" +#include "backends/gp32/gp32std_memory.h" #define DEBUG_MAX 5 char debline[DEBUG_MAX][256]; @@ -65,112 +66,6 @@ void _dprintf(const char *s, ...) { // gp_delay(100); } -///////////////////// -//Memory management -#undef memcpy -#undef memset -void *gp_memcpy(void *dst, const void *src, size_t count) { - return memcpy(dst, src, count); -} - -void *gp_memset(void *dst, int val, size_t count) { - return memset(dst, val, count); -} - -void *gp_malloc(size_t size) { - uint32 np; - uint32 *up; - - np = (uint32) gm_malloc(size + sizeof(uint32)); - - if (np) { - up = (uint32 *) np; - *up = 0x1234; - return (void *)(np + sizeof(uint32)); - } - - return NULL; -} - -void *gp_calloc(size_t nitems, size_t size) { - void *p = gp_malloc(nitems * size); //gpcalloc doesnt clear? - - gp_memset(p, 0, nitems * size); - -// if (*(uint8 *)p != 0) -// warning("%s: calloc doesn't clear", __FUNCTION__); //fixme: was error - - return p; -} - -void gp_free(void *block) { - uint32 np; - uint32 *up; - - if (!block) { - return; - } - - np = ((uint32) block) - sizeof(uint32); - up = (uint32 *) np; - if (*up == 0x4321) { - warning("%s: double deallocation", __FUNCTION__); - return; - } - - if (*up != 0x1234) { - warning("%s: corrupt block", __FUNCTION__); - return; - } - *up = 0x4321; - - gm_free(up); -} - -////////////////////////////////////////////////// -// GP32 stuff -////////////////////////////////////////////////// -static char usedMemStr[16]; -int gUsedMem = 1024 * 1024; - -//#define CLEAN_MEMORY_WITH_0xE7 -#define CHECK_USED_MEMORY -#define CHECK_NEW_TIME - -void *operator new(size_t size) { -#if defined(CHECK_NEW_TIME) - static int ftick; - ftick = GpTickCountGet(); -#endif -// printf("BP:operator new(%d)", size); - void *ptr = gp_malloc(size); - -#if defined(CLEAN_MEMORY_WITH_0xE7) - if(ptr != NULL) { - gp_memset(ptr, 0xE7, size); - } -#endif -#if defined(CHECK_USED_MEMORY) - // Check free memory. - gUsedMem = ((int)(ptr) + size) - 0xc000000; - - sprintf(usedMemStr, "%8d", gUsedMem); - gp_fillRect(frameBuffer1, 0, 0, 64, 12, 0); - gp_textOut(frameBuffer1, 0, 0, usedMemStr, 0xfffff); -#endif -#if defined(CHECK_NEW_TIME) - sprintf(usedMemStr, "%2d", GpTickCountGet() - ftick); - gp_fillRect(frameBuffer1, 72, 0, 24, 12, 0); - gp_textOut(frameBuffer1, 72, 0, usedMemStr, 0xfffff); -#endif - return ptr; -} - -void operator delete(void *ptr) { -// printf("operator delete(%x)", ptr); - gp_free(ptr); -} - //////////////////// //String functions char *gp_strcpy(char *dst, const char *src) { diff --git a/backends/gp32/gp32std.h b/backends/gp32/gp32std.h index 327860c489..0abe4f0b89 100644 --- a/backends/gp32/gp32std.h +++ b/backends/gp32/gp32std.h @@ -47,12 +47,6 @@ extern int gp_strcasecmp(const char *dst, const char *src); extern int gp_strncasecmp(const char *dst, const char *src, size_t count); extern void gp_sprintf(char *str, const char *fmt, ...); -extern void * gp_memcpy(void *dst, const void *src, size_t count); -extern void * gp_memset(void *dst, int val, size_t count); -extern void * gp_malloc(size_t size); -extern void * gp_calloc(size_t nitems, size_t size); -extern void gp_free(void *block); - extern void gp_setCpuSpeed(int freq); extern int gp_printf(const char *fmt, ...); extern void gp_delay(unsigned long msecs); diff --git a/backends/gp32/gp32std_memory.cpp b/backends/gp32/gp32std_memory.cpp new file mode 100644 index 0000000000..0fb54a5d9a --- /dev/null +++ b/backends/gp32/gp32std_memory.cpp @@ -0,0 +1,304 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2006 Won Star - GP32 Backend + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "stdafx.h" +#include "common/scummsys.h" +//#include "graphics/scaler.h" +#include "common/system.h" +#include "backends/intern.h" + +#include "base/engine.h" + +#include "backends/gp32/gp32std.h" +#include "backends/gp32/gp32std_grap.h" +#include "backends/gp32/gp32std_memory.h" + +///////////////////// +//Memory management + +#define USER_MEMORY_SIZE (256 * 1024) +#define USER_BLOCK_SIZE 24 +#define NUM_BLOCK (USER_MEMORY_SIZE / USER_BLOCK_SIZE) +// use fixed block size for small allocations +// consumes about 128k for block array +// consumes 256k for user memory + +class MemBlock { +protected: + static byte *userMem; +// static size_t allocSize; +// static MemBlock *head; + static int numBlock; + static int prevBlock; + + // Linked list is slow for this task. :) + static MemBlock block[NUM_BLOCK]; + + byte *block; + size_t size; + +// MemBlock *next; + + int used; + +public: + static void init(); + static void deinit(); + + static void *addBlock(size_t size); + static void deleteBlock(void *block); +}; + +byte *MemBlock::userMem = NULL; +//MemBlock *MemBlock::head = NULL; +//size_t MemBlock::allocSize = 0; +int MemBlock::numBlock = 0; +int MemBlock::prevBlock = 0; +MemBlock MemBlock::block[NUM_BLOCK]; + +void MemBlock::init() +{ + userMem = (byte *)gm_malloc(USER_MEMORY_SIZE + USER_BLOCK_SIZE); + if (!userMem) { + //error + } +} + +void MemBlock::deinit() +{ + if (!userMem) { + //error + } + gm_free(userMem); + userMem = NULL; +} + +void *MemBlock::addBlock(size_t size) +{ + int i; + + // some optimizaion with loop + for (i = prevBlock; i < NUM_BLOCK; i++) { + if (!block[i].used) { + break; + } + } + if(i == NUM_BLOCK) { + for (i = 0; i < prevBlock; i++) { + if (!block[i].used) { + break; + } + } + if(i == prevBlock) + return NULL; + } + + byte *ptr = userMem + (i * USER_BLOCK_SIZE); + + block[i].size = size; + block[i].block = ptr; + block[i].used = 1; + + prevBlock = i; + + return (void *) ptr; +} + +void MemBlock::deleteBlock(void *block) +{ + uint32 np = (uint32) block - (uint32) userMem; + + if ((np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE != np) { + gm_free(block); +// warning("wrong block! (%d / %d)", (np / USER_BLOCK_SIZE) * USER_BLOCK_SIZE, np); + } + int i = np / USER_BLOCK_SIZE; + if (i > NUM_BLOCK) { + gm_free(block); + return; + } + block[i].used = 0; + +/* + int i = 0; + for (i = 0; i < NUM_BLOCK; i++) { + if (block[i].block == block) + break; + } + if (i == NUM_BLOCK) { + gm_free(block); //fixme? + //warning("wrong block! %x", (uint32)block - (uint32)userMem); + } else { + GPDEBUG("deleteing block %d", i); + block[i].used = 0; + }*/ +} + +// HACK not to include struct MemBlock +void memBlockInit() +{ + MemBlock::init(); +} + +void memBlockDeinit() +{ + MemBlock::deinit(); +} + +#undef memcpy +#undef memset +void *gp_memcpy(void *dst, const void *src, size_t count) { + return memcpy(dst, src, count); +} + +void *gp_memset(void *dst, int val, size_t count) { + return memset(dst, val, count); +} + +#define MALLOC_MASK 0xAB800000 + +void *gp_malloc(size_t size) { + uint32 np; + uint32 *up; + + // size + 8 bytes : stores block size + int allocSize = size + sizeof(uint32) + sizeof(uint32); + if (allocSize <= USER_BLOCK_SIZE) { + np = (uint32) MemBlock::addBlock(allocSize); + if (!np) { +// GPDEBUG("falling back to gm_malloc"); + np = (uint32) gm_malloc(allocSize); + } + } else { + np = (uint32) gm_malloc(allocSize); + } + + if (np) { + up = (uint32 *)np; + *up = size | MALLOC_MASK; // mem size: up to 8mb + up = (uint32 *)(np + size + sizeof(uint32)); + *up = 0x1234; // catches oob acess + return (void *)(np + sizeof(uint32)); + } + + return NULL; +} + +void gp_free(void *block) { + uint32 np; + uint32 *up; + + if (!block) { + return; + } + + np = ((uint32) block) - sizeof(uint32); + up = (uint32 *) np; + if (*up == 0x43210900) { + warning("%s: double deallocation", __FUNCTION__); + return; + } + + if (*up & MALLOC_MASK != MALLOC_MASK) { + warning("%s: corrupt block", __FUNCTION__); + return; + } + + int blockSize = (*up & 0x7fffff); + up = (uint32 *)(np + blockSize + sizeof(uint32)); + if (*up != 0x1234) { + warning("gp_free: corrupt block - OOB access", __FUNCTION__); + return; + } + + *up = 0x43210900; + np = ((uint32) block) - sizeof(uint32); + up = (uint32 *) np; + + if (blockSize + 8 <= USER_BLOCK_SIZE) { + MemBlock::deleteBlock(up); + } else { + gm_free(up); + } +} + +void *gp_calloc(size_t nitems, size_t size) { + void *p = gp_malloc(nitems * size); //gpcalloc doesnt clear? + + gp_memset(p, 0, nitems * size); + +// if (*(uint8 *)p != 0) +// warning("%s: calloc doesn't clear", __FUNCTION__); //fixme: was error + + return p; +} + +////////////////////////////////////////////////// +// GP32 stuff +////////////////////////////////////////////////// +static char usedMemStr[16]; +int gUsedMem = 1024 * 1024; + +//#define CLEAN_MEMORY_WITH_0xE7 +#define CHECK_USED_MEMORY +//#define CHECK_NEW_TIME +//#define CHECK_NEW_SIZE + +void *operator new(size_t size) { +#if defined(CHECK_NEW_TIME) + static int ftick; + ftick = GpTickCountGet(); +#endif +// printf("BP:operator new(%d)", size); + void *ptr = gp_malloc(size); + +#if defined(CLEAN_MEMORY_WITH_0xE7) + if(ptr != NULL) { + gp_memset(ptr, 0xE7, size); + } +#endif +#if defined(CHECK_USED_MEMORY) + // Check free memory. + gUsedMem = ((int)(ptr) + size) - 0xc000000; + + sprintf(usedMemStr, "%8d", gUsedMem); + gp_fillRect(frameBuffer1, 0, 0, 64, 12, 0); + gp_textOut(frameBuffer1, 0, 0, usedMemStr, 0xfffff); +#endif +#if defined(CHECK_NEW_TIME) + sprintf(usedMemStr, "%2d", GpTickCountGet() - ftick); + gp_fillRect(frameBuffer1, 72, 0, 24, 12, 0); + gp_textOut(frameBuffer1, 72, 0, usedMemStr, 0xfffff); +#endif +#if defined(CHECK_NEW_SIZE) + sprintf(usedMemStr, "%8d", size); + gp_fillRect(frameBuffer1, 108, 0, 64, 12, 0); + gp_textOut(frameBuffer1, 108, 0, usedMemStr, 0xfffff); +#endif + return ptr; +} + +void operator delete(void *ptr) { +// printf("operator delete(%x)", ptr); + gp_free(ptr); +} diff --git a/backends/gp32/gp32std_memory.h b/backends/gp32/gp32std_memory.h new file mode 100644 index 0000000000..ea89b6ecb9 --- /dev/null +++ b/backends/gp32/gp32std_memory.h @@ -0,0 +1,35 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2001-2006 The ScummVM project + * Copyright (C) 2002 Ph0x - GP32 Backend + * Copyright (C) 2003/2004 DJWillis - GP32 Backend + * Copyright (C) 2005 Won Star - GP32 Backend + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef __GP32STD_MEMORY_H +#define __GP32STD_MEMORY_H + +extern void * gp_memcpy(void *dst, const void *src, size_t count); +extern void * gp_memset(void *dst, int val, size_t count); +extern void * gp_malloc(size_t size); +extern void * gp_calloc(size_t nitems, size_t size); +extern void gp_free(void *block); + +#endif diff --git a/backends/gp32/portdefs.h b/backends/gp32/portdefs.h index a56658ed76..7269f105e6 100644 --- a/backends/gp32/portdefs.h +++ b/backends/gp32/portdefs.h @@ -36,6 +36,7 @@ #include "gp32std.h" #include "gp32std_file.h" +#include "gp32std_memory.h" #undef byte |