Fixed asynch disk/tape I/O reset behaviors to reliably synchronize with the I/O thread's startup

This commit is contained in:
Mark Pizzolato 2012-04-29 05:55:46 -07:00
parent c4659a0903
commit 3775c17034
2 changed files with 15 additions and 2 deletions

View file

@ -108,6 +108,7 @@ struct disk_context {
pthread_t io_thread; /* I/O Thread Id */ pthread_t io_thread; /* I/O Thread Id */
pthread_mutex_t io_lock; pthread_mutex_t io_lock;
pthread_cond_t io_cond; pthread_cond_t io_cond;
pthread_cond_t startup_cond;
int io_dop; int io_dop;
uint8 *buf; uint8 *buf;
t_seccnt *rsects; t_seccnt *rsects;
@ -176,6 +177,7 @@ pthread_setschedparam (pthread_self(), sched_policy, &sched_priority);
sim_debug (ctx->dbit, ctx->dptr, "_disk_io(unit=%d) starting\n", uptr-ctx->dptr->units); sim_debug (ctx->dbit, ctx->dptr, "_disk_io(unit=%d) starting\n", uptr-ctx->dptr->units);
pthread_mutex_lock (&ctx->io_lock); pthread_mutex_lock (&ctx->io_lock);
pthread_cond_signal (&ctx->startup_cond); /* Signal we're ready to go */
while (ctx->asynch_io) { while (ctx->asynch_io) {
pthread_cond_wait (&ctx->io_cond, &ctx->io_lock); pthread_cond_wait (&ctx->io_cond, &ctx->io_lock);
if (ctx->io_dop == DOP_DONE) if (ctx->io_dop == DOP_DONE)
@ -423,12 +425,16 @@ ctx->asynch_io_latency = latency;
if (ctx->asynch_io) { if (ctx->asynch_io) {
pthread_mutex_init (&ctx->io_lock, NULL); pthread_mutex_init (&ctx->io_lock, NULL);
pthread_cond_init (&ctx->io_cond, NULL); pthread_cond_init (&ctx->io_cond, NULL);
pthread_cond_init (&ctx->startup_cond, NULL);
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_mutex_lock (&ctx->io_lock);
pthread_create (&ctx->io_thread, &attr, _disk_io, (void *)uptr); pthread_create (&ctx->io_thread, &attr, _disk_io, (void *)uptr);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
pthread_cond_wait (&ctx->startup_cond, &ctx->io_lock); /* Wait for thread to stabilize */
pthread_mutex_unlock (&ctx->io_lock);
pthread_cond_destroy (&ctx->startup_cond);
uptr->a_check_completion = _disk_completion_dispatch; uptr->a_check_completion = _disk_completion_dispatch;
sim_os_ms_sleep(50); /* Give the _disk_io thread a chance to stabilize */
} }
#endif #endif
return SCPE_OK; return SCPE_OK;

View file

@ -125,6 +125,7 @@ struct tape_context {
pthread_t io_thread; /* I/O Thread Id */ pthread_t io_thread; /* I/O Thread Id */
pthread_mutex_t io_lock; pthread_mutex_t io_lock;
pthread_cond_t io_cond; pthread_cond_t io_cond;
pthread_cond_t startup_cond;
int io_top; int io_top;
uint8 *buf; uint8 *buf;
uint32 *bc; uint32 *bc;
@ -211,6 +212,7 @@ struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_tape_io(unit=%d) starting\n", uptr-ctx->dptr->units); sim_debug (ctx->dbit, ctx->dptr, "_tape_io(unit=%d) starting\n", uptr-ctx->dptr->units);
pthread_mutex_lock (&ctx->io_lock); pthread_mutex_lock (&ctx->io_lock);
pthread_cond_signal (&ctx->startup_cond); /* Signal we're ready to go */
while (1) { while (1) {
pthread_cond_wait (&ctx->io_cond, &ctx->io_lock); pthread_cond_wait (&ctx->io_cond, &ctx->io_lock);
if (ctx->io_top == TOP_DONE) if (ctx->io_top == TOP_DONE)
@ -331,11 +333,15 @@ ctx->asynch_io_latency = latency;
if (ctx->asynch_io) { if (ctx->asynch_io) {
pthread_mutex_init (&ctx->io_lock, NULL); pthread_mutex_init (&ctx->io_lock, NULL);
pthread_cond_init (&ctx->io_cond, NULL); pthread_cond_init (&ctx->io_cond, NULL);
pthread_cond_init (&ctx->startup_cond, NULL);
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
pthread_mutex_lock (&ctx->io_lock);
pthread_create (&ctx->io_thread, &attr, _tape_io, (void *)uptr); pthread_create (&ctx->io_thread, &attr, _tape_io, (void *)uptr);
pthread_attr_destroy(&attr); pthread_attr_destroy(&attr);
sim_os_ms_sleep(50); /* Give the _tape_io thread a chance to stabilize */ pthread_cond_wait (&ctx->startup_cond, &ctx->io_lock); /* Wait for thread to stabilize */
pthread_mutex_unlock (&ctx->io_lock);
pthread_cond_destroy (&ctx->startup_cond);
} }
uptr->a_check_completion = _tape_completion_dispatch; uptr->a_check_completion = _tape_completion_dispatch;
#endif #endif
@ -362,6 +368,7 @@ if (ctx->asynch_io) {
pthread_join (ctx->io_thread, NULL); pthread_join (ctx->io_thread, NULL);
pthread_mutex_destroy (&ctx->io_lock); pthread_mutex_destroy (&ctx->io_lock);
pthread_cond_destroy (&ctx->io_cond); pthread_cond_destroy (&ctx->io_cond);
pthread_cond_destroy (&ctx->startup_cond);
} }
return SCPE_OK; return SCPE_OK;
#endif #endif