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:
29
sim_disk.c
29
sim_disk.c
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user