--- visbjp_orig/Vis.h 2009-07-29 11:40:40.000000000 +0200 +++ visbjp/Vis.h 2010-01-12 14:36:30.865639900 +0100 @@ -119,12 +119,17 @@ #ifndef __alpha -extern HANDLE my_mutex; -#define LOCK WaitForSingleObject( my_mutex, INFINITE ) -#define UNLOCK ReleaseMutex( my_mutex ) +extern HANDLE read_mutex; +extern HANDLE save_mutex; +#define READ_LOCK WaitForSingleObject( read_mutex, INFINITE ) +#define READ_UNLOCK ReleaseMutex( read_mutex ) +#define SAVE_LOCK WaitForSingleObject( save_mutex, INFINITE ) +#define SAVE_UNLOCK ReleaseMutex( save_mutex ) #else -#define LOCK -#define UNLOCK +#define READ_LOCK +#define READ_UNLOCK +#define SAVE_LOCK +#define SAVE_UNLOCK #endif --- visbjp_orig/Vis.c 2009-07-30 09:59:14.000000000 +0200 +++ visbjp/Vis.c 2010-01-12 14:37:20.364526800 +0100 @@ -19,7 +19,9 @@ int leafon; // the next leaf to be given to a thread to process #ifndef __alpha -HANDLE my_mutex; +HANDLE read_mutex; +HANDLE save_mutex; +HANDLE work_mutexes[MAX_THREADS]; #endif byte *vismap, *vismap_p, *vismap_end; // past visfile @@ -467,6 +469,16 @@ return; } +#ifndef __alpha + // We wait for all threads to finish processing their current portal. + // This way we should guarantee that no portals are marked + // as being processed. + if( work_mutexes[0] != NULL ) + { + WaitForMultipleObjects( numthreads, work_mutexes, TRUE, INFINITE ); + } +#endif + PrevTime = Time; State.PercRate = PercRate; @@ -536,6 +548,16 @@ SavingTime = I_FloatTime () - Time; State.StateTime += SavingTime; //logprintf ("State save: %.2lf\n", SavingTime); + +#ifndef __alpha + if( work_mutexes[0] != NULL ) + { + for( i = 0; i < numthreads; i++ ) + { + ReleaseMutex( work_mutexes[i] ); + } + } +#endif } /* @@ -676,7 +698,7 @@ portal_t *p, *tp; int min; - LOCK; + READ_LOCK; min = 99999; p = NULL; @@ -694,7 +716,7 @@ if (p) p->status = stat_working; - UNLOCK; + READ_UNLOCK; return p; } @@ -711,6 +733,7 @@ void *LeafThread (int thread) #endif { + HANDLE work_mutex = (HANDLE)lpParam; portal_t *p; TimeOffset = State.CalcTime; @@ -719,9 +742,14 @@ { do { + WaitForSingleObject( work_mutex, INFINITE ); + p = GetNextPortal (); if (!p) + { + ReleaseMutex( work_mutex ); break; + } ShowPercent (NULL, State.CurrPortal + 1, numportals * 2 ); @@ -733,7 +761,14 @@ if (verbose) logprintf (" can see:%5i\n", p->numcansee); + ReleaseMutex( work_mutex ); + + SAVE_LOCK; + SaveState (NULL, State.CurrPortal, false); + + SAVE_UNLOCK; + } while (1); } @@ -914,20 +949,29 @@ HANDLE work_threads[MAX_THREADS]; int i; - my_mutex = CreateMutex( NULL, FALSE, NULL ); + read_mutex = CreateMutex( NULL, FALSE, NULL ); + save_mutex = CreateMutex( NULL, FALSE, NULL ); ShowPercent ("Full", 0, 0); for( i = 0 ; i < numthreads ; i++ ) { - work_threads[i] = CreateThread( NULL, 0, LeafThread, NULL, 0, (LPDWORD)&work_threads[i] ); + work_mutexes[i] = CreateMutex( NULL, FALSE, NULL ); + work_threads[i] = CreateThread( NULL, 0, LeafThread, work_mutexes[i], 0, (LPDWORD)&work_threads[i] ); } WaitForMultipleObjects( numthreads, work_threads, TRUE, INFINITE ); ShowPercent (NULL, 100, 100); - ReleaseMutex( my_mutex ); + CloseHandle( read_mutex ); + CloseHandle( save_mutex ); + + for( i = 0; i < numthreads; i++ ) + { + CloseHandle( work_mutexes[i] ); + CloseHandle( work_threads[i] ); + } } #else LeafThread (0); @@ -1306,6 +1350,10 @@ if (i != argc - 1) PrintOptions (); +#ifndef __alpha + memset( work_mutexes, 0, sizeof( work_mutexes ) ); +#endif + start = I_FloatTime (); strcpy (source, argv[i]);