From dda669080ce79eea40a9c8447e0fd4e4bbd84288 Mon Sep 17 00:00:00 2001 From: mcmartin Date: Thu, 12 Dec 2002 23:00:33 +0000 Subject: [PATCH] Some race conditions eliminated, from PhracturedBlue Also added debug information. git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@417 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/ChangeLog | 1 + sc2/src/sc2code/libs/threads/thrcommon.c | 73 ++++++++++++++++++++++-- sc2/src/sc2code/outfit.c | 5 +- sc2/src/sc2code/restart.c | 2 + sc2/src/sc2code/shipyard.c | 3 +- 5 files changed, 78 insertions(+), 6 deletions(-) diff --git a/sc2/ChangeLog b/sc2/ChangeLog index 08ed36311..c372e23fc 100644 --- a/sc2/ChangeLog +++ b/sc2/ChangeLog @@ -1,4 +1,5 @@ 0.2: +- Some race conditions eliminated, from PhracturedBlue - Earth / other slave shielded planet color issue fixed, from PhracturedBlue - Orbit/starmap related lockup fixed, from PhracturedBlue - 3D planet showing on starmap when in orbit fixed, from PhracturedBlue diff --git a/sc2/src/sc2code/libs/threads/thrcommon.c b/sc2/src/sc2code/libs/threads/thrcommon.c index b4710e072..4ea7a82e1 100644 --- a/sc2/src/sc2code/libs/threads/thrcommon.c +++ b/sc2/src/sc2code/libs/threads/thrcommon.c @@ -27,11 +27,22 @@ #include #endif +#define DEBUG_TRACK_SEM + +#ifdef DEBUG_TRACK_SEM +// Define all semaphores to be tracked in SemList. Make sure it is NULL terminated +// Make that semthread is the same length as SemList, and is initialized as all 0's +extern Semaphore GraphicsSem; +static Semaphore *SemList[] = {&GraphicsSem, NULL}; +Uint32 semthread[] = {0, 0}; +#endif + #ifdef THREAD_QUEUE static volatile Thread threadQueue = NULL; static Semaphore threadQueueSemaphore; #endif + struct ThreadStartInfo { ThreadFunction func; @@ -307,25 +318,79 @@ DestroySemaphore (Semaphore sem) int SetSemaphore (Semaphore sem) { - return NativeSetSemaphore ((NativeSemaphore) sem); + int i; + + i = NativeSetSemaphore ((NativeSemaphore) sem); +#ifdef DEBUG_TRACK_SEM + if (i != 0) + fprintf(stderr, "WARNING: SetSemaphore did not return 0, this could be bad!\n"); + for (i = 0; SemList[i] != NULL; i++) + if (*SemList[i] == sem) + { + semthread[i] = SDL_ThreadID (); + break; + } +#endif + return i; } int TrySetSemaphore (Semaphore sem) { - return NativeTrySetSemaphore ((NativeSemaphore) sem); + int i; + + i = NativeTrySetSemaphore ((NativeSemaphore) sem); +#ifdef DEBUG_TRACK_SEM + if (i == 0) + for (i = 0; SemList[i] != NULL; i++) + if (*SemList[i] == sem) + { + semthread[i] = SDL_ThreadID (); + break; + } +#endif + return (i); } int TimeoutSetSemaphore (Semaphore sem, TimePeriod timeout) { - return NativeTimeoutSetSemaphore ((NativeSemaphore) sem, - timeout); + int i; + + i = NativeTimeoutSetSemaphore ((NativeSemaphore) sem, timeout); +#ifdef DEBUG_TRACK_SEM + if (i == 0) + for (i = 0; SemList[i] != NULL; i++) + if (*SemList[i] == sem) + { + semthread[i] = SDL_ThreadID (); + break; + } +#endif + return (i); } void ClearSemaphore (Semaphore sem) { + int i; +#ifdef DEBUG_TRACK_SEM + Uint32 semval = SDL_SemValue (sem); + if (semval != 0) + { + fprintf (stderr, "WARNING: trying to clear a free semaphore (value=%d)\n", semval); + // Should we unset the Semaphore twice? Perhaps not. + return; + } + for (i = 0;SemList[i] != NULL; i++) + if (*SemList[i] == sem) + { + if (! semthread[i] && semthread[i] != SDL_ThreadID ()) + fprintf( stderr, "WARNING: tried to free a Semaphore held by another thread!\n"); + semthread[i] = 0; + break; + } +#endif NativeClearSemaphore ((NativeSemaphore) sem); } diff --git a/sc2/src/sc2code/outfit.c b/sc2/src/sc2code/outfit.c index 611dae0f8..87521a9f4 100644 --- a/sc2/src/sc2code/outfit.c +++ b/sc2/src/sc2code/outfit.c @@ -539,6 +539,7 @@ DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS) BatchGraphics (); DrawSISFrame (); + SetSemaphore(GraphicsSem); DrawSISMessage (GAME_STRING (STARBASE_STRING_BASE + 2)); DrawSISTitle (GAME_STRING (STARBASE_STRING_BASE)); @@ -572,7 +573,6 @@ DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS) GLOBAL_SIS (ModuleSlots[num_frames])) < EMPTY_SLOT) DrawShipPiece (pMS, which_piece, num_frames, FALSE); } - RedistributeFuel (); DisplayLanders (pMS); if (GET_GAME_STATE (CHMMR_BOMB_STATE) < 3) @@ -596,8 +596,11 @@ DoOutfit (INPUT_STATE InputState, PMENU_STATE pMS) DrawStamp ((PSTAMP)&s); } + ClearSemaphore(GraphicsSem); DrawMenuStateStrings (PM_FUEL, pMS->CurState); + SetSemaphore(GraphicsSem); DrawFlagshipName (FALSE); + ClearSemaphore(GraphicsSem); { RECT r; diff --git a/sc2/src/sc2code/restart.c b/sc2/src/sc2code/restart.c index c5df5f37e..de8aa7592 100644 --- a/sc2/src/sc2code/restart.c +++ b/sc2/src/sc2code/restart.c @@ -220,7 +220,9 @@ LastActivity = WON_LAST_BATTLE; BatchGraphics (); ClearDrawable (); FlushColorXForms (); + SetSemaphore (GraphicsSem); DrawStamp (&s); + ClearSemaphore (GraphicsSem); UnbatchGraphics (); FlushInput (); diff --git a/sc2/src/sc2code/shipyard.c b/sc2/src/sc2code/shipyard.c index 1f1acb015..5075da352 100644 --- a/sc2/src/sc2code/shipyard.c +++ b/sc2/src/sc2code/shipyard.c @@ -1070,9 +1070,10 @@ DoShipyard (INPUT_STATE InputState, PMENU_STATE pMS) BatchGraphics (); DrawSISFrame (); + SetSemaphore(GraphicsSem); DrawSISMessage (GAME_STRING (STARBASE_STRING_BASE + 3)); DrawSISTitle (GAME_STRING (STARBASE_STRING_BASE)); - + ClearSemaphore(GraphicsSem); DrawBluePrint (pMS); pMS->ModuleFrame = s.frame;