1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 11:46:37 +00:00

Added missing sim_cancel support for device simulation code using the sim_disk and sim_tape libraries and doing asynchronous I/O if asynchronous I/O is active

This commit is contained in:
Mark Pizzolato
2012-12-12 10:58:19 -08:00
parent e541a3408f
commit 2b5ceae2be
5 changed files with 110 additions and 6 deletions

View File

@@ -108,6 +108,7 @@ struct disk_context {
pthread_t io_thread; /* I/O Thread Id */
pthread_mutex_t io_lock;
pthread_cond_t io_cond;
pthread_cond_t io_done;
pthread_cond_t startup_cond;
int io_dop;
uint8 *buf;
@@ -196,6 +197,7 @@ while (ctx->asynch_io) {
}
pthread_mutex_lock (&ctx->io_lock);
ctx->io_dop = DOP_DONE;
pthread_cond_signal (&ctx->io_done);
sim_activate (uptr, ctx->asynch_io_latency);
}
pthread_mutex_unlock (&ctx->io_lock);
@@ -209,7 +211,7 @@ return NULL;
processing events for any unit. It is only called when an asynchronous
thread has called sim_activate() to activate a unit. The job of this
routine is to put the unit in proper condition to digest what may have
occurred in the asynchrcondition thread.
occurred in the asynchrconous thread.
Since disk processing only handles a single I/O at a time to a
particular disk device (due to using stdio for the SimH Disk format
@@ -231,6 +233,25 @@ if (ctx->callback && ctx->io_dop == DOP_DONE) {
callback (uptr, ctx->io_status);
}
}
static t_bool _disk_is_active (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_disk_is_active(unit=%d, dop=%d)\n", uptr-ctx->dptr->units, ctx->io_dop);
return (ctx->io_dop != DOP_DONE);
}
static void _disk_cancel (UNIT *uptr)
{
struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
sim_debug (ctx->dbit, ctx->dptr, "_disk_cancel(unit=%d, dop=%d)\n", uptr-ctx->dptr->units, ctx->io_dop);
pthread_mutex_lock (&ctx->io_lock);
while (ctx->io_dop != DOP_DONE)
pthread_cond_wait (&ctx->io_done, &ctx->io_lock);
pthread_mutex_unlock (&ctx->io_lock);
}
#else
#define AIO_CALLSETUP
#define AIO_CALL(op, _lba, _buf, _rsects, _sects, _callback) \
@@ -425,6 +446,7 @@ ctx->asynch_io_latency = latency;
if (ctx->asynch_io) {
pthread_mutex_init (&ctx->io_lock, NULL);
pthread_cond_init (&ctx->io_cond, NULL);
pthread_cond_init (&ctx->io_done, NULL);
pthread_cond_init (&ctx->startup_cond, NULL);
pthread_attr_init(&attr);
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
@@ -434,8 +456,10 @@ if (ctx->asynch_io) {
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;
uptr->a_is_active = _disk_is_active;
uptr->a_cancel = _disk_cancel;
#endif
return SCPE_OK;
}
@@ -460,6 +484,7 @@ if (ctx->asynch_io) {
pthread_join (ctx->io_thread, NULL);
pthread_mutex_destroy (&ctx->io_lock);
pthread_cond_destroy (&ctx->io_cond);
pthread_cond_destroy (&ctx->io_done);
}
return SCPE_OK;
#endif