From b8bd927b7be5fa19aa4990d5e6a0a1d3662eb3e2 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Wed, 6 Jul 2011 06:38:56 +0000 Subject: [PATCH] - finally fixed the unit sorting hang bug, try it tomryen --- source/glest_game/type_instances/faction.cpp | 8 +++-- source/glest_game/type_instances/faction.h | 6 ++-- source/glest_game/type_instances/unit.cpp | 35 ++++++++++++++------ source/glest_game/world/world.cpp | 31 ++++++++++++----- 4 files changed, 54 insertions(+), 26 deletions(-) diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index df4e629e..05d061f4 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -48,6 +48,7 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const { } Command *command= this->unit->getCurrrentCommandThreadSafe(); + //Command *command= this->unit->getCurrCommand(); if( command != NULL && (command->getCommandType()->getClass() == ccMove || command->getCommandType()->getClass() == ccAttack) && @@ -55,6 +56,7 @@ bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const { int curCommandGroupId = command->getUnitCommandGroupId(); Command *commandPeer = j.unit->getCurrrentCommandThreadSafe(); + //Command *commandPeer = j.unit->getCurrCommand(); if(commandPeer == NULL) { return true; } @@ -100,7 +102,7 @@ void FactionThread::setQuitStatus(bool value) { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } -void FactionThread::signalPathfinder(int frameIndex, std::vector *unitsInFactionsSorted) { +void FactionThread::signalPathfinder(int frameIndex, std::vector *unitsInFactionsSorted) { if(frameIndex >= 0) { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); @@ -188,7 +190,7 @@ void FactionThread::execute() { //std::vector *unitsInFactionsSorted int unitCount = unitsInFactionsSorted->size(); for(int j = 0; j < unitCount; ++j) { - Unit *unit = (*unitsInFactionsSorted)[j].unit; + Unit *unit = (*unitsInFactionsSorted)[j]->unit; if(unit == NULL) { throw runtime_error("unit == NULL"); } @@ -277,7 +279,7 @@ Faction::~Faction() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -void Faction::signalWorkerThread(int frameIndex, std::vector *unitsInFactionsSorted) { +void Faction::signalWorkerThread(int frameIndex, std::vector *unitsInFactionsSorted) { if(workerThread != NULL) { workerThread->signalPathfinder(frameIndex,unitsInFactionsSorted); } diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 241002a0..f5652480 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -65,7 +65,7 @@ protected: Semaphore semTaskSignalled; Mutex triggerIdMutex; std::pair frameIndex; - std::vector *unitsInFactionsSorted; + std::vector *unitsInFactionsSorted; virtual void setQuitStatus(bool value); virtual void setTaskCompleted(int frameIndex); @@ -74,7 +74,7 @@ protected: public: FactionThread(Faction *faction); virtual void execute(); - void signalPathfinder(int frameIndex,std::vector *unitsInFactionsSorted); + void signalPathfinder(int frameIndex,std::vector *unitsInFactionsSorted); bool isSignalPathfinderCompleted(int frameIndex); }; @@ -203,7 +203,7 @@ public: World * getWorld() { return world; } int getFrameCount(); - void signalWorkerThread(int frameIndex,std::vector *unitsInFactionsSorted); + void signalWorkerThread(int frameIndex,std::vector *unitsInFactionsSorted); bool isWorkerThreadSignalCompleted(int frameIndex); void limitResourcesToStore(); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index b067a3b1..efc6202e 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -908,6 +908,9 @@ Command *Unit::getCurrCommand() const { } void Unit::replaceCurrCommand(Command *cmd) { + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexCommands,mutexOwnerId); + assert(commands.empty() == false); commands.front() = cmd; this->setCurrentUnitTitle(""); @@ -967,22 +970,23 @@ CommandResult Unit::giveCommand(Command *command, bool tryQueue) { } else{ //Delete all lower-prioirty commands - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexCommands,mutexOwnerId); - for(list::iterator i= commands.begin(); i != commands.end();){ if((*i)->getPriority() < command_priority){ if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Deleting lower priority command [%s]\n",__FILE__,__FUNCTION__,__LINE__,(*i)->toString().c_str()); + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexCommands,mutexOwnerId); + deleteQueuedCommand(*i); i= commands.erase(i); + + safeMutex.ReleaseLock(); } else{ ++i; } } - safeMutex.ReleaseLock(); } if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -1055,19 +1059,23 @@ CommandResult Unit::finishCommand() { delete commands.front(); commands.erase(commands.begin()); + + safeMutex.ReleaseLock(true); + this->unitPath->clear(); while (commands.empty() == false) { if (commands.front()->getUnit() != NULL && livingUnitsp.find(commands.front()->getUnit()) == livingUnitsp.end()) { + safeMutex.Lock(); delete commands.front(); commands.erase(commands.begin()); - } else { + safeMutex.ReleaseLock(true); + } + else { break; } } - safeMutex.ReleaseLock(); - return crSuccess; } @@ -1093,10 +1101,12 @@ CommandResult Unit::cancelCommand() { delete commands.back(); commands.pop_back(); + safeMutex.ReleaseLock(); + //clear routes this->unitPath->clear(); - safeMutex.ReleaseLock(); + return crSuccess; } @@ -2113,17 +2123,20 @@ void Unit::updateTarget(){ } void Unit::clearCommands() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(&mutexCommands,mutexOwnerId); this->setCurrentUnitTitle(""); this->unitPath->clear(); while(commands.empty() == false) { undoCommand(commands.back()); + + static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); + MutexSafeWrapper safeMutex(&mutexCommands,mutexOwnerId); + delete commands.back(); commands.pop_back(); + + safeMutex.ReleaseLock(); } - safeMutex.ReleaseLock(); } void Unit::deleteQueuedCommand(Command *command) { diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 0060abaf..d75e5314 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -275,10 +275,10 @@ void World::updateAllFactionUnits() { // Prioritize grouped command units so closest units to target go first // units - const bool sortedUnitsAllowed = true; - int factionCount = getFactionCount(); + bool sortedUnitsAllowed = true; + std::map > unitsInFactionsSorted; - std::map > unitsInFactionsSorted; + int factionCount = getFactionCount(); if(sortedUnitsAllowed == true) { for(int i = 0; i < factionCount; ++i) { Faction *faction = getFaction(i); @@ -286,6 +286,9 @@ void World::updateAllFactionUnits() { throw runtime_error("faction == NULL"); } + std::vector &unitListToSort = unitsInFactionsSorted[faction->getIndex()]; + unitListToSort.clear(); + int unitCount = faction->getUnitCount(); for(int j = 0; j < unitCount; ++j) { Unit *unit = faction->getUnit(j); @@ -293,13 +296,16 @@ void World::updateAllFactionUnits() { throw runtime_error("unit == NULL"); } - unitsInFactionsSorted[faction->getIndex()].push_back(CommandGroupSorter(unit)); + unitListToSort.push_back(new CommandGroupSorter(unit)); + } + if(unitListToSort.size() > 0) { + std::sort(unitListToSort.begin(),unitListToSort.end()); } - std::vector &unitListToSort = unitsInFactionsSorted[faction->getIndex()]; - std::sort(unitListToSort.begin(),unitListToSort.end()); } } + //sortedUnitsAllowed = false; + // Signal the faction threads to do any pre-processing for(int i = 0; i < factionCount; ++i) { Faction *faction = getFaction(i); @@ -308,7 +314,7 @@ void World::updateAllFactionUnits() { } if(sortedUnitsAllowed == true) { - std::vector &unitListSorted = unitsInFactionsSorted[faction->getIndex()]; + std::vector &unitListSorted = unitsInFactionsSorted[faction->getIndex()]; faction->signalWorkerThread(frameCount,&unitListSorted); } else { @@ -350,7 +356,7 @@ void World::updateAllFactionUnits() { throw runtime_error("faction == NULL"); } - std::vector *unitListSorted = NULL; + std::vector *unitListSorted = NULL; int unitCount = faction->getUnitCount(); if(sortedUnitsAllowed == true) { unitListSorted = &unitsInFactionsSorted[faction->getIndex()]; @@ -360,7 +366,7 @@ void World::updateAllFactionUnits() { for(int j = 0; j < unitCount; ++j) { Unit *unit = NULL; if(sortedUnitsAllowed == true) { - unit = (*unitListSorted)[j].unit; + unit = (*unitListSorted)[j]->unit; } else { unit = faction->getUnit(j); @@ -370,6 +376,11 @@ void World::updateAllFactionUnits() { } unitUpdater.updateUnit(unit); + + if(sortedUnitsAllowed == true) { + delete (*unitListSorted)[j]; + (*unitListSorted)[j] = NULL; + } } // int unitCount = faction->getUnitCount(); @@ -383,6 +394,8 @@ void World::updateAllFactionUnits() { // } } + unitsInFactionsSorted.clear(); + if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); }