Fix race condition in Gravity.cpp

This commit is contained in:
iczero 2019-04-07 14:05:23 -07:00 committed by Tamás Bálint Misius
parent ff39c82e48
commit 2ba0f70efd
2 changed files with 48 additions and 46 deletions

1
.gitignore vendored
View File

@ -65,5 +65,6 @@ config.log
*.pyc *.pyc
site_scons/site_tools/mfprogram/*.pyc site_scons/site_tools/mfprogram/*.pyc
site_scons/site_tools/gch/*.pyc site_scons/site_tools/gch/*.pyc
.vscode/ipch
screenshot_* screenshot_*

View File

@ -83,47 +83,49 @@ void Gravity::gravity_cleanup()
void Gravity::gravity_update_async() void Gravity::gravity_update_async()
{ {
int result; int result;
if(ngrav_enable) if (ngrav_enable)
{ {
pthread_mutex_lock(&gravmutex); if (!pthread_mutex_trylock(&gravmutex))
result = grav_ready;
if(result) //Did the gravity thread finish?
{ {
//if (!sys_pause||framerender){ //Only update if not paused result = grav_ready;
//Switch the full size gravmaps, we don't really need the two above any more if (result) //Did the gravity thread finish?
float *tmpf; {
//if (!sys_pause||framerender){ //Only update if not paused
//Switch the full size gravmaps, we don't really need the two above any more
float *tmpf;
if (th_gravchanged && !ignoreNextResult) if (th_gravchanged && !ignoreNextResult)
{ {
#if !defined(GRAVFFT) && defined(GRAV_DIFF) #if !defined(GRAVFFT) && defined(GRAV_DIFF)
memcpy(gravy, th_gravy, (XRES/CELL)*(YRES/CELL)*sizeof(float)); memcpy(gravy, th_gravy, (XRES/CELL)*(YRES/CELL)*sizeof(float));
memcpy(gravx, th_gravx, (XRES/CELL)*(YRES/CELL)*sizeof(float)); memcpy(gravx, th_gravx, (XRES/CELL)*(YRES/CELL)*sizeof(float));
memcpy(gravp, th_gravp, (XRES/CELL)*(YRES/CELL)*sizeof(float)); memcpy(gravp, th_gravp, (XRES/CELL)*(YRES/CELL)*sizeof(float));
#else #else
tmpf = gravy; tmpf = gravy;
gravy = th_gravy; gravy = th_gravy;
th_gravy = tmpf; th_gravy = tmpf;
tmpf = gravx; tmpf = gravx;
gravx = th_gravx; gravx = th_gravx;
th_gravx = tmpf; th_gravx = tmpf;
tmpf = gravp; tmpf = gravp;
gravp = th_gravp; gravp = th_gravp;
th_gravp = tmpf; th_gravp = tmpf;
#endif #endif
} }
ignoreNextResult = false; ignoreNextResult = false;
tmpf = gravmap; tmpf = gravmap;
gravmap = th_gravmap; gravmap = th_gravmap;
th_gravmap = tmpf; th_gravmap = tmpf;
grav_ready = 0; //Tell the other thread that we're ready for it to continue grav_ready = 0; //Tell the other thread that we're ready for it to continue
pthread_cond_signal(&gravcv); pthread_cond_signal(&gravcv);
//} //}
}
pthread_mutex_unlock(&gravmutex);
} }
pthread_mutex_unlock(&gravmutex);
//Apply the gravity mask //Apply the gravity mask
membwand(gravy, gravmask, (XRES/CELL)*(YRES/CELL)*sizeof(float), (XRES/CELL)*(YRES/CELL)*sizeof(unsigned)); membwand(gravy, gravmask, (XRES/CELL)*(YRES/CELL)*sizeof(float), (XRES/CELL)*(YRES/CELL)*sizeof(unsigned));
membwand(gravx, gravmask, (XRES/CELL)*(YRES/CELL)*sizeof(float), (XRES/CELL)*(YRES/CELL)*sizeof(unsigned)); membwand(gravx, gravmask, (XRES/CELL)*(YRES/CELL)*sizeof(float), (XRES/CELL)*(YRES/CELL)*sizeof(unsigned));
@ -153,32 +155,30 @@ void Gravity::update_grav_async()
if (!grav_fft_status) if (!grav_fft_status)
grav_fft_init(); grav_fft_init();
#endif #endif
while(!thread_done){ pthread_mutex_lock(&gravmutex);
if(!done){ while (!thread_done)
{
if (!done)
{
// run gravity update
update_grav(); update_grav();
done = 1; done = 1;
pthread_mutex_lock(&gravmutex); grav_ready = 1;
grav_ready = done;
thread_done = gravthread_done; thread_done = gravthread_done;
pthread_mutex_unlock(&gravmutex);
} else { } else {
pthread_mutex_lock(&gravmutex); // wait for main thread
pthread_cond_wait(&gravcv, &gravmutex); pthread_cond_wait(&gravcv, &gravmutex);
done = grav_ready; done = grav_ready;
thread_done = gravthread_done; thread_done = gravthread_done;
pthread_mutex_unlock(&gravmutex);
} }
} }
pthread_mutex_unlock(&gravmutex);
pthread_exit(NULL); pthread_exit(NULL);
} }
void Gravity::start_grav_async() void Gravity::start_grav_async()
{ {
if(ngrav_enable) //If it's already enabled, restart it if (ngrav_enable) //If it's already enabled, restart it
stop_grav_async(); stop_grav_async();
gravthread_done = 0; gravthread_done = 0;
@ -196,7 +196,8 @@ void Gravity::start_grav_async()
void Gravity::stop_grav_async() void Gravity::stop_grav_async()
{ {
if(ngrav_enable){ if (ngrav_enable)
{
pthread_mutex_lock(&gravmutex); pthread_mutex_lock(&gravmutex);
gravthread_done = 1; gravthread_done = 1;
pthread_cond_signal(&gravcv); pthread_cond_signal(&gravcv);