From e0b225bad95d99af54e2eff591087ac27516ed2f Mon Sep 17 00:00:00 2001 From: "wagic.jeck" Date: Sun, 20 Sep 2009 03:10:34 +0000 Subject: [PATCH] Jeck - TEMPORARY enabling of exceptions. (~6hrs) Sorry, I've been an idiot lately and coded myself into a corner with stuff that "should only take a minute" to fine tune. I honestly shouldn't have committed r871+, but I'd sworn to high heaven that the damn thing was fixed. In reality getting the cache 100% needs a bit more time, so I'm committing this in the hopes that it'll prevent sloppy cache work from interrupting other people's coding. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exception handling in the cache means that Wagic runs slightly, but noticeably slower. However, it also means that the cache works the way it was intended to, and should prevent all sorts of awkward errors I introduced because things were half-allocated or worse. I've learned my lesson from tonight, and once I get this stuff put back together without exception handling I think I'll self-impose a manditory 24 hours debugging time before any commits. Sorry for the inconvenience. If for some reason you can't compile with exceptions, r862 should be completely without them. Again, wow, this was stupid-- I hadn't even realized exceptions were off for like 24 hours, as the compiler wasn't producing warnings. Apologies, —Jeck --- projects/mtg/Makefile | 186 ++++++++++++------------ projects/mtg/include/WResourceManager.h | 8 +- projects/mtg/src/WResourceManager.cpp | 131 +++++++++-------- 3 files changed, 171 insertions(+), 154 deletions(-) diff --git a/projects/mtg/Makefile b/projects/mtg/Makefile index 4e65960fd..a7e892cf6 100644 --- a/projects/mtg/Makefile +++ b/projects/mtg/Makefile @@ -1,93 +1,93 @@ -OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/SimplePad.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o -DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) - -RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) -ifeq ($(RESULT),) -DEFAULT_RULE = linux -TARGET_ARCHITECTURE = linux -TARGET = bin/wagic -else -DEFAULT_RULE = 3xx -TARGET_ARCHITECTURE = psp -PSPSDK = $(shell psp-config --pspsdk-path) -PSPDIR = $(shell psp-config --psp-prefix) -TARGET = wagic -endif -ifeq ($(MAKECMDGOALS),debug) -DEFAULT_RULE = debug -TARGET_ARCHITECTURE = linux -endif -ifeq ($(MAKECMDGOALS),linux) -DEFAULT_RULE = linux -TARGET_ARCHITECTURE = linux -endif - -ifeq ($(TARGET_ARCHITECTURE),psp) -DEFAULT_RULE = 3xx -TARGET_ARCHITECTURE = psp -PSP_FW_VERSION=371 -BUILD_PRX = 1 -LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu - -EXTRA_TARGETS = EBOOT.PBP -PSP_EBOOT_TITLE = Wagic, the Homebrew?! -PSP_EBOOT_ICON = icon.png -PSP_EBOOT_UNKPNG = NULL -#PSP_EBOOT_PIC1 = pic1.png -CXXFLAGS = -O2 -G0 -Wall -Werror -DDEVHOOK -DPSPFW3XX -fno-exceptions -INCDIR = ../../JGE/include ../../JGE/include/psp ../../JGE/include/psp/freetype2 ../../JGE/src -LIBDIR = ../../JGE/lib/psp -else -OBJS += objs/TestSuiteAI.o -INCDIR = -I ../../JGE/include -I ../../JGE/src -LIBDIR = -L ../../JGE/lib/linux -L ../../JGE -LIBS = -ljge -lfreetype -ljpeg -lgif -lpng -lz -lm -lstdc++ -lglut -lhgetools -lfmod-3.75 -CFLAGS = $(INCDIR) -O2 -Wall -W -Werror -Wno-unused -DDEVHOOK -DLINUX -CXXFLAGS += $(CFLAGS) -fno-exceptions -ASFLAGS = $(CXXFLAGS) - -all: $(DEFAULT_RULE) - -endif - -LDFLAGS = $(LIBS) - - - -debug: CXXFLAGS = -Wall -W -Werror -Wno-unused -DDEVHOOK -DPSPFW3XX -fno-exceptions -ggdb3 -D_DEBUG -DDEBUG -DLINUX $(INCDIR) - - - - -ifeq ($(TARGET_ARCHITECTURE),psp) -include $(PSPSDK)/lib/build.mak - -3xx: - @echo Rule 3xx is deprecated. Did you want to use just "make" ? - -else - - - -$(TARGET): $(OBJS) ../../JGE/lib/linux/libjge.a - g++ -o $(TARGET) $(OBJS) $(LIBS) $(LIBDIR) - -linux: $(TARGET) - -debug: linux - -clean: - $(RM) $(OBJS) - -endif - -$(OBJS): objs/%.o: src/%.cpp - $(CXX) -c -o $@ $(CXXFLAGS) $< - -$(DEPS): deps/%.d: src/%.cpp - @$(CXX) -MM $(CXXFLAGS) -MQ $(patsubst deps/%.d, objs/%.o, $(@)) -MQ $@ $< > $@ - -.DEFAULT: - @echo $@ has been deleted : updating deps. - --include $(DEPS) +OBJS = objs/ActionElement.o objs/ActionLayer.o objs/ActionStack.o objs/AIMomirPlayer.o objs/AIPlayer.o objs/AIStats.o objs/Blocker.o objs/CardGui.o objs/CardDescriptor.o objs/CardDisplay.o objs/CardEffect.o objs/CardSelector.o objs/ConstraintResolver.o objs/Counters.o objs/Credits.o objs/Damage.o objs/DamagerDamaged.o objs/DeckDataWrapper.o objs/DeckStats.o objs/DuelLayers.o objs/Effects.o objs/ExtraCost.o objs/GameApp.o objs/GameLauncher.o objs/GameObserver.o objs/GameOptions.o objs/GameState.o objs/GameStateDeckViewer.o objs/GameStateDuel.o objs/GameStateMenu.o objs/GameStateOptions.o objs/GameStateShop.o objs/GuiAvatars.o objs/GuiBackground.o objs/GuiCardsController.o objs/GuiCombat.o objs/GuiFrame.o objs/GuiHand.o objs/GuiLayers.o objs/GuiMana.o objs/GuiPhaseBar.o objs/GuiPlay.o objs/GuiStatic.o objs/Logger.o objs/ManaCost.o objs/ManaCostHybrid.o objs/MenuItem.o objs/MTGAbility.o objs/MTGCardInstance.o objs/MTGCard.o objs/MTGDeck.o objs/MTGDefinitions.o objs/MTGGamePhase.o objs/MTGGameZones.o objs/MTGRules.o objs/OptionItem.o objs/PhaseRing.o objs/Player.o objs/PlayerData.o objs/PlayGuiObjectController.o objs/PlayGuiObject.o objs/Pos.o objs/PriceList.o objs/ReplacementEffects.o objs/ShopItem.o objs/SimpleMenu.o objs/SimpleMenuItem.o objs/Subtypes.o objs/TargetChooser.o objs/TargetsList.o objs/TextScroller.o objs/SimplePad.o objs/Token.o objs/Translate.o objs/Trash.o objs/utils.o objs/WEvent.o objs/WResourceManager.o objs/WCachedResource.o +DEPS = $(patsubst objs/%.o, deps/%.d, $(OBJS)) + +RESULT = $(shell psp-config --psp-prefix 2> Makefile.cache) +ifeq ($(RESULT),) +DEFAULT_RULE = linux +TARGET_ARCHITECTURE = linux +TARGET = bin/wagic +else +DEFAULT_RULE = 3xx +TARGET_ARCHITECTURE = psp +PSPSDK = $(shell psp-config --pspsdk-path) +PSPDIR = $(shell psp-config --psp-prefix) +TARGET = wagic +endif +ifeq ($(MAKECMDGOALS),debug) +DEFAULT_RULE = debug +TARGET_ARCHITECTURE = linux +endif +ifeq ($(MAKECMDGOALS),linux) +DEFAULT_RULE = linux +TARGET_ARCHITECTURE = linux +endif + +ifeq ($(TARGET_ARCHITECTURE),psp) +DEFAULT_RULE = 3xx +TARGET_ARCHITECTURE = psp +PSP_FW_VERSION=371 +BUILD_PRX = 1 +LIBS = -ljge300 -lhgetools -lfreetype -ljpeg -lgif -lpng -lz -lm -lmikmod -lpsppower -lpspmpeg -lpspaudiocodec -lpspaudiolib -lpspaudio -lpspmp3 -lpspgum -lpspgu -lpsprtc -lstdc++ -lpspfpu + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = Wagic, the Homebrew?! +PSP_EBOOT_ICON = icon.png +PSP_EBOOT_UNKPNG = NULL +#PSP_EBOOT_PIC1 = pic1.png +CXXFLAGS = -O2 -G0 -Wall -Werror -DDEVHOOK -DPSPFW3XX +INCDIR = ../../JGE/include ../../JGE/include/psp ../../JGE/include/psp/freetype2 ../../JGE/src +LIBDIR = ../../JGE/lib/psp +else +OBJS += objs/TestSuiteAI.o +INCDIR = -I ../../JGE/include -I ../../JGE/src +LIBDIR = -L ../../JGE/lib/linux -L ../../JGE +LIBS = -ljge -lfreetype -ljpeg -lgif -lpng -lz -lm -lstdc++ -lglut -lhgetools -lfmod-3.75 +CFLAGS = $(INCDIR) -O2 -Wall -W -Werror -Wno-unused -DDEVHOOK -DLINUX +CXXFLAGS += $(CFLAGS) -fno-exceptions +ASFLAGS = $(CXXFLAGS) + +all: $(DEFAULT_RULE) + +endif + +LDFLAGS = $(LIBS) + + + +debug: CXXFLAGS = -Wall -W -Werror -Wno-unused -DDEVHOOK -DPSPFW3XX -ggdb3 -D_DEBUG -DDEBUG -DLINUX $(INCDIR) + + + + +ifeq ($(TARGET_ARCHITECTURE),psp) +include $(PSPSDK)/lib/build.mak + +3xx: + @echo Rule 3xx is deprecated. Did you want to use just "make" ? + +else + + + +$(TARGET): $(OBJS) ../../JGE/lib/linux/libjge.a + g++ -o $(TARGET) $(OBJS) $(LIBS) $(LIBDIR) + +linux: $(TARGET) + +debug: linux + +clean: + $(RM) $(OBJS) + +endif + +$(OBJS): objs/%.o: src/%.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $< + +$(DEPS): deps/%.d: src/%.cpp + @$(CXX) -MM $(CXXFLAGS) -MQ $(patsubst deps/%.d, objs/%.o, $(@)) -MQ $@ $< > $@ + +.DEFAULT: + @echo $@ has been deleted : updating deps. + +-include $(DEPS) diff --git a/projects/mtg/include/WResourceManager.h b/projects/mtg/include/WResourceManager.h index 99caba0e0..7d664fd42 100644 --- a/projects/mtg/include/WResourceManager.h +++ b/projects/mtg/include/WResourceManager.h @@ -8,11 +8,11 @@ #include "WCachedResource.h" //Soft limits. -#define HUGE_CACHE_LIMIT 6000000 -#define HUGE_CACHE_ITEMS 200 +#define HUGE_CACHE_LIMIT 10000000 +#define HUGE_CACHE_ITEMS 300 -#define LARGE_CACHE_LIMIT 4000000 -#define LARGE_CACHE_ITEMS 150 +#define LARGE_CACHE_LIMIT 5000000 +#define LARGE_CACHE_ITEMS 200 #define SMALL_CACHE_LIMIT 2000000 #define SMALL_CACHE_ITEMS 100 diff --git a/projects/mtg/src/WResourceManager.cpp b/projects/mtg/src/WResourceManager.cpp index 6d420b3c2..9315ebbf1 100644 --- a/projects/mtg/src/WResourceManager.cpp +++ b/projects/mtg/src/WResourceManager.cpp @@ -822,18 +822,18 @@ void WResourceManager::CacheForState(int state){ else textureWCache.Resize(SMALL_CACHE_LIMIT,SMALL_CACHE_ITEMS); sampleWCache.Resize(SMALL_CACHE_LIMIT,MAX_CACHED_SAMPLES); - ClearUnlocked(); + //ClearUnlocked(); break; //Deck editor and shop are entirely cache safe, so give it near infinite resources. case GAME_STATE_SHOP: case GAME_STATE_DECK_VIEWER: textureWCache.Resize(HUGE_CACHE_LIMIT,HUGE_CACHE_ITEMS); - ClearUnlocked(); + //ClearUnlocked(); break; //Anything unknown, use large cache. default: textureWCache.Resize(LARGE_CACHE_LIMIT,LARGE_CACHE_ITEMS); - Cleanup(); + //Cleanup(); break; } #endif @@ -1027,18 +1027,47 @@ cacheItem* WCache::AttemptNew(string filename, int submo item = Recycle(); + //There was nothing to recycle. Make absolutely certain we have an item. if(item == NULL){ - try{ - item = NEW cacheItem; + item = NEW cacheItem; + if(item) mError = CACHE_ERROR_NONE; - } - catch(std::bad_alloc){ - SAFE_DELETE(item); + else{ + //Try a few times to get an item. + for(int attempt=0;attemptAttempt(filename,submode,mError)){ - //No such file. Fail. + //Attempt to populate item. + mError = CACHE_ERROR_NONE; + for(int attempts = 0; attempts < MAX_CACHE_ATTEMPTS;attempts++) + { + //We use try/catch so any memory alloc'd in Attempt isn't lost. + try{ + //If we don't get a good item, remove oldest cache and continue trying. + if(!item->Attempt(filename,submode,mError) || !item->isGood()) + throw std::bad_alloc(); + } + catch(std::bad_alloc){ + RemoveOldest(); + } + + //No such file. Fail on first try. if(item && mError == CACHE_ERROR_404){ if(garbage.size() < MAX_CACHE_GARBAGE){ item->Trash(); @@ -1050,62 +1079,50 @@ cacheItem* WCache::AttemptNew(string filename, int submo return NULL; } - for(int attempt=0;attempt<10;attempt++){ - if(!RemoveOldest()) - break; - - if(!item){ - try{ - item = NEW cacheItem; - } - catch(std::bad_alloc){ - SAFE_DELETE(item); - continue; - } - } - - if(item && item->Attempt(filename,submode,mError)) - break; + //Succeeded, so enforce limits and return. + if(item->isGood()){ + mError = CACHE_ERROR_NONE; + item->lock(); + Cleanup(); + item->unlock(); + return item; } + } - - //Still no result, so clear cache entirely, then try again. - if(!item || !item->isGood()){ - ClearUnlocked(); - if(!item) item = NEW(cacheItem); - item->Attempt(filename,submode,mError); + //Still no result, so clear local cache, then try again. + if(!item->isGood()){ + ClearUnlocked(); + try{ + if(!item->Attempt(filename,submode,mError) || !item->isGood()) + throw std::bad_alloc(); } - - //Worst cache scenerio. Clear every cache we've got. - if(!item || !item->isGood()){ + catch(std::bad_alloc){ + //Failed, so clear every cache we've got in prep for the next try. resources.ClearUnlocked(); - if(!item){ - try{ - item = NEW(cacheItem); + } + + try{ + if(!item->Attempt(filename,submode,mError) || !item->isGood()) + throw std::bad_alloc(); + } + catch(std::bad_alloc){ + //Complete failure. Trash this object and return NULL. + if(item && !item->isGood()){ + if(garbage.size() < MAX_CACHE_GARBAGE){ + item->Trash(); + garbage.push_back(item); } - catch(std::bad_alloc){ - mError = CACHE_ERROR_BAD_ALLOC; + else SAFE_DELETE(item); - return NULL; - } + + mError = CACHE_ERROR_BAD; + return NULL; } - item->Attempt(filename,submode,mError); } } - - if(item && !item->isGood()){ - if(garbage.size() < MAX_CACHE_GARBAGE){ - item->Trash(); - garbage.push_back(item); - } - else - SAFE_DELETE(item); - mError = CACHE_ERROR_BAD; - return NULL; - } - else - mError = CACHE_ERROR_NONE; - + + //Success! Enforce cache limits, then return. + mError = CACHE_ERROR_NONE; item->lock(); Cleanup(); item->unlock();