TIMER: Changed sim_idle_ms_sleep() to use a mutex which is unique to idling

It seems that the prior use of sim_asynch_lock RECURSIVE mutex could
cause a pthread_cond_timedwait() failure with EINVAL returned.
As discussed in #595
This commit is contained in:
Mark Pizzolato 2018-07-11 11:59:05 -07:00
parent 29a4fb9802
commit 484889ea5a
3 changed files with 7 additions and 3 deletions

1
scp.c
View file

@ -326,6 +326,7 @@
#if defined (SIM_ASYNCH_IO) #if defined (SIM_ASYNCH_IO)
pthread_mutex_t sim_asynch_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t sim_asynch_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t sim_asynch_wake = PTHREAD_COND_INITIALIZER; pthread_cond_t sim_asynch_wake = PTHREAD_COND_INITIALIZER;
pthread_mutex_t sim_idle_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t sim_timer_lock = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t sim_timer_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t sim_timer_wake = PTHREAD_COND_INITIALIZER; pthread_cond_t sim_timer_wake = PTHREAD_COND_INITIALIZER;

View file

@ -1062,6 +1062,7 @@ struct MEMFILE {
extern pthread_mutex_t sim_asynch_lock; extern pthread_mutex_t sim_asynch_lock;
extern pthread_cond_t sim_asynch_wake; extern pthread_cond_t sim_asynch_wake;
extern pthread_mutex_t sim_idle_lock;
extern pthread_mutex_t sim_timer_lock; extern pthread_mutex_t sim_timer_lock;
extern pthread_cond_t sim_timer_wake; extern pthread_cond_t sim_timer_wake;
extern t_bool sim_timer_event_canceled; extern t_bool sim_timer_event_canceled;
@ -1174,6 +1175,7 @@ extern int32 sim_asynch_inst_latency;
do { \ do { \
pthread_mutex_destroy(&sim_asynch_lock); \ pthread_mutex_destroy(&sim_asynch_lock); \
pthread_cond_destroy(&sim_asynch_wake); \ pthread_cond_destroy(&sim_asynch_wake); \
pthread_mutex_destroy(&sim_idle_lock); \
pthread_mutex_destroy(&sim_timer_lock); \ pthread_mutex_destroy(&sim_timer_lock); \
pthread_cond_destroy(&sim_timer_wake); \ pthread_cond_destroy(&sim_timer_wake); \
pthread_mutex_destroy(&sim_tmxr_poll_lock); \ pthread_mutex_destroy(&sim_tmxr_poll_lock); \
@ -1223,6 +1225,7 @@ extern int32 sim_asynch_inst_latency;
do { \ do { \
pthread_mutex_destroy(&sim_asynch_lock); \ pthread_mutex_destroy(&sim_asynch_lock); \
pthread_cond_destroy(&sim_asynch_wake); \ pthread_cond_destroy(&sim_asynch_wake); \
pthread_mutex_destroy(&sim_idle_lock); \
pthread_mutex_destroy(&sim_timer_lock); \ pthread_mutex_destroy(&sim_timer_lock); \
pthread_cond_destroy(&sim_timer_wake); \ pthread_cond_destroy(&sim_timer_wake); \
pthread_mutex_destroy(&sim_tmxr_poll_lock); \ pthread_mutex_destroy(&sim_tmxr_poll_lock); \

View file

@ -248,9 +248,9 @@ if (done_time.tv_nsec > 1000000000) {
done_time.tv_sec += done_time.tv_nsec/1000000000; done_time.tv_sec += done_time.tv_nsec/1000000000;
done_time.tv_nsec = done_time.tv_nsec%1000000000; done_time.tv_nsec = done_time.tv_nsec%1000000000;
} }
pthread_mutex_lock (&sim_asynch_lock); pthread_mutex_lock (&sim_idle_lock);
sim_idle_wait = TRUE; sim_idle_wait = TRUE;
stat = pthread_cond_timedwait (&sim_asynch_wake, &sim_asynch_lock, &done_time); stat = pthread_cond_timedwait (&sim_asynch_wake, &sim_idle_lock, &done_time);
if (stat == 0) if (stat == 0)
sim_asynch_check = 0; /* force check of asynch queue now */ sim_asynch_check = 0; /* force check of asynch queue now */
else else
@ -264,7 +264,7 @@ else
abort (); abort ();
} }
sim_idle_wait = FALSE; sim_idle_wait = FALSE;
pthread_mutex_unlock (&sim_asynch_lock); pthread_mutex_unlock (&sim_idle_lock);
if (!timedout) { if (!timedout) {
AIO_UPDATE_QUEUE; AIO_UPDATE_QUEUE;
} }