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.

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
This commit is contained in:
wagic.jeck
2009-09-20 03:10:34 +00:00
parent 00c5b8cd7d
commit e0b225bad9
3 changed files with 171 additions and 154 deletions

View File

@@ -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)

View File

@@ -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

View File

@@ -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<cacheItem, cacheActual>::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;attempt<MAX_CACHE_ATTEMPTS;attempt++){
if(!RemoveOldest() || item)
break;
item = NEW cacheItem;
}
//We /really/ shouldn't get this far.
if(!item){
resources.ClearUnlocked();
item = NEW cacheItem;
if(!item){
//Nothing let us make an item. Failure.
mError = CACHE_ERROR_BAD_ALLOC;
return NULL;
}
}
}
}
if(item == NULL || !item->Attempt(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<cacheItem, cacheActual>::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();