- ensure mutexes are properly protecting shared data in pathfinder

This commit is contained in:
Mark Vejvoda
2013-11-10 05:23:59 +00:00
parent c6368b221e
commit ebaa8ced1a
2 changed files with 28 additions and 57 deletions

View File

@@ -51,8 +51,6 @@ PathFinder::PathFinder() {
} }
int PathFinder::getPathFindExtendRefreshNodeCount(FactionState &faction, bool mutexLock) { int PathFinder::getPathFindExtendRefreshNodeCount(FactionState &faction, bool mutexLock) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex((mutexLock == true ? faction.getMutex() : NULL),mutexOwnerId);
int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax); int refreshNodeCount = faction.random.randRange(PathFinder::pathFindExtendRefreshNodeCountMin,PathFinder::pathFindExtendRefreshNodeCountMax);
return refreshNodeCount; return refreshNodeCount;
} }
@@ -66,9 +64,7 @@ PathFinder::PathFinder(const Map *map) {
void PathFinder::init(const Map *map) { void PathFinder::init(const Map *map) {
for(int factionIndex = 0; factionIndex < GameConstants::maxPlayers; ++factionIndex) { for(int factionIndex = 0; factionIndex < GameConstants::maxPlayers; ++factionIndex) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(factionIndex); FactionState &faction = factions.getFactionState(factionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
faction.nodePool.resize(pathFindNodesAbsoluteMax); faction.nodePool.resize(pathFindNodesAbsoluteMax);
faction.useMaxNodeCount = PathFinder::pathFindNodesMax; faction.useMaxNodeCount = PathFinder::pathFindNodesMax;
@@ -83,9 +79,7 @@ void PathFinder::init() {
PathFinder::~PathFinder() { PathFinder::~PathFinder() {
for(int factionIndex = 0; factionIndex < GameConstants::maxPlayers; ++factionIndex) { for(int factionIndex = 0; factionIndex < GameConstants::maxPlayers; ++factionIndex) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(factionIndex); FactionState &faction = factions.getFactionState(factionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
faction.nodePool.clear(); faction.nodePool.clear();
} }
@@ -346,14 +340,10 @@ TravelState PathFinder::findPath(Unit *unit, const Vec2i &finalPos, bool *wasStu
codeLocation = "25"; codeLocation = "25";
int factionIndex = unit->getFactionIndex(); int factionIndex = unit->getFactionIndex();
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(factionIndex); FactionState &faction = factions.getFactionState(factionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
int tryRadius = faction.random.randRange(0,1); int tryRadius = faction.random.randRange(0,1);
safeMutex.ReleaseLock(true);
// Try to bail out up to PathFinder::pathFindBailoutRadius cells away // Try to bail out up to PathFinder::pathFindBailoutRadius cells away
if(tryRadius > 0) { if(tryRadius > 0) {
for(int bailoutX = -PathFinder::pathFindBailoutRadius; bailoutX <= PathFinder::pathFindBailoutRadius && ts == tsBlocked; ++bailoutX) { for(int bailoutX = -PathFinder::pathFindBailoutRadius; bailoutX <= PathFinder::pathFindBailoutRadius && ts == tsBlocked; ++bailoutX) {
@@ -567,9 +557,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
codeLocation = "3"; codeLocation = "3";
int factionIndex = unit->getFactionIndex(); int factionIndex = unit->getFactionIndex();
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(factionIndex); FactionState &faction = factions.getFactionState(factionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
maxNodeCount = faction.useMaxNodeCount; maxNodeCount = faction.useMaxNodeCount;
} }
@@ -583,25 +571,19 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
int unitFactionIndex = unit->getFactionIndex(); int unitFactionIndex = unit->getFactionIndex();
int factionIndex = unit->getFactionIndex(); int factionIndex = unit->getFactionIndex();
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(factionIndex); FactionState &faction = factions.getFactionState(factionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
faction.nodePoolCount= 0; faction.nodePoolCount= 0;
faction.openNodesList.clear(); faction.openNodesList.clear();
faction.openPosList.clear(); faction.openPosList.clear();
faction.closedNodesList.clear(); faction.closedNodesList.clear();
safeMutex.ReleaseLock(true);
codeLocation = "5"; codeLocation = "5";
// check the pre-cache to see if we can re-use a cached path // check the pre-cache to see if we can re-use a cached path
if(frameIndex < 0) { if(frameIndex < 0) {
codeLocation = "6"; codeLocation = "6";
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutex2(faction.getMutex(),mutexOwnerId);
MutexSafeWrapper safeMutexPrecache(faction.getMutexPreCache(),mutexOwnerId); MutexSafeWrapper safeMutexPrecache(faction.getMutexPreCache(),mutexOwnerId);
bool foundPrecacheTravelState = (faction.precachedTravelState.find(unit->getId()) != faction.precachedTravelState.end()); bool foundPrecacheTravelState = (faction.precachedTravelState.find(unit->getId()) != faction.precachedTravelState.end());
safeMutexPrecache.ReleaseLock(true); safeMutexPrecache.ReleaseLock(true);
@@ -625,19 +607,26 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
Vec2i lastPos = unit->getPos(); Vec2i lastPos = unit->getPos();
for(int i=0; i < faction.precachedPath[unit->getId()].size(); i++) { safeMutexPrecache.Lock();
int unitPrecachePathSize = faction.precachedPath[unit->getId()].size();
safeMutexPrecache.ReleaseLock(true);
for(int i=0; i < unitPrecachePathSize; i++) {
codeLocation = "9"; codeLocation = "9";
safeMutexPrecache.Lock();
Vec2i nodePos = faction.precachedPath[unit->getId()][i]; Vec2i nodePos = faction.precachedPath[unit->getId()][i];
safeMutexPrecache.ReleaseLock(true);
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) { if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
throw megaglest_runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i)); throw megaglest_runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
} }
//if(i < pathFindRefresh ||
if(i < unit->getPathFindRefreshCellCount() || if(i < unit->getPathFindRefreshCellCount() ||
(faction.precachedPath[unit->getId()].size() >= pathFindExtendRefreshForNodeCount && (unitPrecachePathSize >= pathFindExtendRefreshForNodeCount &&
i < getPathFindExtendRefreshNodeCount(faction,false))) { i < getPathFindExtendRefreshNodeCount(faction,false))) {
codeLocation = "10"; codeLocation = "10";
//!!! Test MV
if(canUnitMoveSoon(unit, lastPos, nodePos) == false) { if(canUnitMoveSoon(unit, lastPos, nodePos) == false) {
canMoveToCells = false; canMoveToCells = false;
break; break;
@@ -655,16 +644,24 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
path->clear(); path->clear();
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path); UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
for(int i=0; i < faction.precachedPath[unit->getId()].size(); i++) { safeMutexPrecache.Lock();
int unitPrecachePathSize = faction.precachedPath[unit->getId()].size();
safeMutexPrecache.ReleaseLock(true);
for(int i=0; i < unitPrecachePathSize; i++) {
codeLocation = "13"; codeLocation = "13";
safeMutexPrecache.Lock();
Vec2i nodePos = faction.precachedPath[unit->getId()][i]; Vec2i nodePos = faction.precachedPath[unit->getId()][i];
safeMutexPrecache.ReleaseLock(true);
if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) { if(map->isInside(nodePos) == false || map->isInsideSurface(map->toSurfCoords(nodePos)) == false) {
throw megaglest_runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i)); throw megaglest_runtime_error("Pathfinder invalid node path position = " + nodePos.getString() + " i = " + intToStr(i));
} }
//if(i < pathFindRefresh || //if(i < pathFindRefresh ||
if(i < unit->getPathFindRefreshCellCount() || if(i < unit->getPathFindRefreshCellCount() ||
(faction.precachedPath[unit->getId()].size() >= pathFindExtendRefreshForNodeCount && (unitPrecachePathSize >= pathFindExtendRefreshForNodeCount &&
i < getPathFindExtendRefreshNodeCount(faction,false))) { i < getPathFindExtendRefreshNodeCount(faction,false))) {
codeLocation = "14"; codeLocation = "14";
path->add(nodePos); path->add(nodePos);
@@ -731,9 +728,7 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
codeLocation = "24"; codeLocation = "24";
float dist= unitPos.dist(finalPos); float dist= unitPos.dist(finalPos);
safeMutex.Lock();
faction.useMaxNodeCount = PathFinder::pathFindNodesMax; faction.useMaxNodeCount = PathFinder::pathFindNodesMax;
safeMutex.ReleaseLock(true);
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
@@ -741,7 +736,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
codeLocation = "26"; codeLocation = "26";
//a) push starting pos into openNodes //a) push starting pos into openNodes
safeMutex.Lock();
Node *firstNode= newNode(faction,maxNodeCount); Node *firstNode= newNode(faction,maxNodeCount);
if(firstNode == NULL) { if(firstNode == NULL) {
throw megaglest_runtime_error("firstNode == NULL"); throw megaglest_runtime_error("firstNode == NULL");
@@ -758,8 +752,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
faction.openNodesList[firstNode->heuristic].push_back(firstNode); faction.openNodesList[firstNode->heuristic].push_back(firstNode);
faction.openPosList[firstNode->pos] = true; faction.openPosList[firstNode->pos] = true;
safeMutex.ReleaseLock(true);
codeLocation = "27"; codeLocation = "27";
//b) loop //b) loop
bool pathFound = true; bool pathFound = true;
@@ -919,7 +911,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(nodeLimitReached == true) { if(nodeLimitReached == true) {
codeLocation = "41"; codeLocation = "41";
safeMutex.Lock();
if(faction.closedNodesList.empty() == false) { if(faction.closedNodesList.empty() == false) {
codeLocation = "42"; codeLocation = "42";
float bestHeuristic = faction.closedNodesList.begin()->first; float bestHeuristic = faction.closedNodesList.begin()->first;
@@ -928,7 +919,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
lastNode= faction.closedNodesList.begin()->second[0]; lastNode= faction.closedNodesList.begin()->second[0];
} }
} }
safeMutex.ReleaseLock(true);
} }
if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled == true && chrono.getMillis() > 4) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s Line: %d] took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis());
@@ -1006,6 +996,11 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path); UnitPathBasic *basicPathFinder = dynamic_cast<UnitPathBasic *>(path);
currNode= firstNode; currNode= firstNode;
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
MutexSafeWrapper safeMutexPreCache(faction.getMutexPreCache(),mutexOwnerId);
safeMutexPreCache.ReleaseLock(true);
for(int i=0; currNode->next != NULL; currNode= currNode->next, i++) { for(int i=0; currNode->next != NULL; currNode= currNode->next, i++) {
codeLocation = "55"; codeLocation = "55";
Vec2i nodePos = currNode->next->pos; Vec2i nodePos = currNode->next->pos;
@@ -1018,9 +1013,9 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
if(frameIndex >= 0) { if(frameIndex >= 0) {
codeLocation = "56"; codeLocation = "56";
safeMutex.Lock(); safeMutexPreCache.Lock();
faction.precachedPath[unit->getId()].push_back(nodePos); faction.precachedPath[unit->getId()].push_back(nodePos);
safeMutex.ReleaseLock(); safeMutexPreCache.ReleaseLock(true);
} }
else { else {
codeLocation = "57"; codeLocation = "57";
@@ -1067,7 +1062,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
codeLocation = "60"; codeLocation = "60";
safeMutex.Lock();
faction.openNodesList.clear(); faction.openNodesList.clear();
faction.openPosList.clear(); faction.openPosList.clear();
faction.closedNodesList.clear(); faction.closedNodesList.clear();
@@ -1086,7 +1080,6 @@ TravelState PathFinder::aStar(Unit *unit, const Vec2i &targetPos, bool inBailout
else { else {
if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) printf("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts); if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 5) printf("In [%s::%s Line: %d] astar took [%lld] msecs, ts = %d.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),ts);
} }
safeMutex.ReleaseLock();
if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) {
char szBuf[8096]=""; char szBuf[8096]="";

View File

@@ -88,12 +88,9 @@ public:
class FactionState { class FactionState {
protected: protected:
Mutex *factionMutex;
Mutex *factionMutexPrecache; Mutex *factionMutexPrecache;
public: public:
FactionState() : FactionState() :
//factionMutex(new Mutex()),
factionMutex(NULL),
factionMutexPrecache(new Mutex) { factionMutexPrecache(new Mutex) {
openPosList.clear(); openPosList.clear();
@@ -107,15 +104,10 @@ public:
precachedPath.clear(); precachedPath.clear();
} }
~FactionState() { ~FactionState() {
delete factionMutex;
factionMutex = NULL;
delete factionMutexPrecache; delete factionMutexPrecache;
factionMutexPrecache = NULL; factionMutexPrecache = NULL;
} }
Mutex * getMutex() {
return factionMutex;
}
Mutex * getMutexPreCache() { Mutex * getMutexPreCache() {
return factionMutexPrecache; return factionMutexPrecache;
} }
@@ -260,10 +252,7 @@ private:
Vec2i sucPos= node->pos + Vec2i(i, j); Vec2i sucPos= node->pos + Vec2i(i, j);
int unitFactionIndex = unit->getFactionIndex(); int unitFactionIndex = unit->getFactionIndex();
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(unitFactionIndex); FactionState &faction = factions.getFactionState(unitFactionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
if(openPos(sucPos, faction) == false && if(openPos(sucPos, faction) == false &&
canUnitMoveSoon(unit, node->pos, sucPos) == true) { canUnitMoveSoon(unit, node->pos, sucPos) == true) {
@@ -307,23 +296,16 @@ private:
std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> , std::map<Vec2i,Vec2i> cameFrom, std::map<std::pair<Vec2i,Vec2i> ,
bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) { bool> canAddNode, Unit *& unit, int & maxNodeCount, int curFrameIndex) {
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
FactionState &faction = factions.getFactionState(unitFactionIndex); FactionState &faction = factions.getFactionState(unitFactionIndex);
MutexSafeWrapper safeMutex(faction.getMutex(),mutexOwnerId);
safeMutex.ReleaseLock(true);
while(nodeLimitReached == false) { while(nodeLimitReached == false) {
whileLoopCount++; whileLoopCount++;
safeMutex.Lock();
if(faction.openNodesList.empty() == true) { if(faction.openNodesList.empty() == true) {
safeMutex.ReleaseLock(true);
pathFound = false; pathFound = false;
break; break;
} }
node = minHeuristicFastLookup(faction); node = minHeuristicFastLookup(faction);
if(node->pos == finalPos || node->exploredCell == false) { if(node->pos == finalPos || node->exploredCell == false) {
safeMutex.ReleaseLock(true);
pathFound = true; pathFound = true;
break; break;
} }
@@ -333,15 +315,11 @@ private:
} }
faction.closedNodesList[node->heuristic].push_back(node); faction.closedNodesList[node->heuristic].push_back(node);
faction.openPosList[node->pos] = true; faction.openPosList[node->pos] = true;
safeMutex.ReleaseLock(true);
int failureCount = 0; int failureCount = 0;
int cellCount = 0; int cellCount = 0;
safeMutex.Lock();
int tryDirection = faction.random.randRange(0, 3); int tryDirection = faction.random.randRange(0, 3);
safeMutex.ReleaseLock(true);
if(tryDirection == 3) { if(tryDirection == 3) {
for(int i = 1;i >= -1 && nodeLimitReached == false;--i) { for(int i = 1;i >= -1 && nodeLimitReached == false;--i) {
for(int j = -1;j <= 1 && nodeLimitReached == false;++j) { for(int j = -1;j <= 1 && nodeLimitReached == false;++j) {