Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed bug under Asynch I/O where I/O completion did not delay the app…

…ropriate time before passing back device status to a simulator. Found by Sergey Oboguev.
  • Loading branch information...
commit 7ac35575245845537f3f00478fce653a31a18b3c 1 parent 6e6fdd0
@markpizz markpizz authored
View
10 0readmeAsynchIO.txt
@@ -89,7 +89,7 @@ example there now exists the routines:
t_stat sim_tape_rdrecf_a (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max, TAPE_PCALLBACK callback);
The Purpose of the callback function is to record the I/O completion status
-and then to schedule the activation of the unit.
+and then to schedule the activation of the unit.
Considerations:
Avoiding multiple concurrent users of the unit structure. While asynch
@@ -108,7 +108,13 @@ The callback routine must save the I/O completion status in a place
which the next invocation of the unit service routine will reference
and act on it. This allows device code to return error conditions
back to scp in a consistent way without regard to how the callback
-routine (and the actual I/O) may have been executed.
+routine (and the actual I/O) may have been executed. When the callback
+routine is called, it will already be on the simulator event queue with
+an event time which was specified when the unit was attached or via a
+call to sim_disk_set_async. If no value has been specified then it
+will have been scheduled with a delay time of 0. If a different event
+firing time is desired, then the callback completion routine should
+call sim_activate_abs to schedule the event at the appropriate time.
Required change in device coding.
Devices which wish to leverage the benefits of asynch I/O must rearrange
View
3  PDP11/pdp11_rp.c
@@ -782,7 +782,6 @@ void rp_io_complete (UNIT *uptr, t_stat status)
{
uptr->io_status = status;
uptr->io_complete = 1;
-sim_activate (uptr, 0);
}
/* Service unit timeout
@@ -1030,7 +1029,7 @@ t_stat r;
uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size;
r = sim_disk_attach (uptr, cptr, RP_NUMWD * sizeof (uint16),
sizeof (uint16), TRUE, 0,
- drv_tab[GET_DTYPE (uptr->flags)].name, drv_tab[GET_DTYPE (uptr->flags)].sect);
+ drv_tab[GET_DTYPE (uptr->flags)].name, drv_tab[GET_DTYPE (uptr->flags)].sect, 0);
if (r != SCPE_OK) /* error? */
return r;
drv = (int32) (uptr - rp_dev.units); /* get drv number */
View
9 PDP11/pdp11_rq.c
@@ -1800,10 +1800,9 @@ sim_debug (DBG_TRC, rq_devmap[cp->cnum], "rq_io_complete(status=%d)\n", status);
uptr->io_status = status;
uptr->io_complete = 1;
-if (elapsed > rq_xtime)
- sim_activate (uptr, 0);
-else
- sim_activate (uptr, rq_xtime-elapsed);
+/* Reschedule for the appropriate delay */
+if (elapsed <= rq_xtime)
+ sim_activate_abs (uptr, rq_xtime-elapsed);
}
/* Unit service for data transfer commands */
@@ -2487,7 +2486,7 @@ t_stat rq_attach (UNIT *uptr, char *cptr)
MSC *cp = rq_ctxmap[uptr->cnum];
t_stat r;
-r = sim_disk_attach (uptr, cptr, RQ_NUMBY, sizeof (uint16), (uptr->flags & UNIT_NOAUTO), DBG_DSK, drv_tab[GET_DTYPE (uptr->flags)].name, 0);
+r = sim_disk_attach (uptr, cptr, RQ_NUMBY, sizeof (uint16), (uptr->flags & UNIT_NOAUTO), DBG_DSK, drv_tab[GET_DTYPE (uptr->flags)].name, 0, 0);
if (r != SCPE_OK)
return r;
View
9 PDP11/pdp11_tq.c
@@ -1286,10 +1286,9 @@ sim_debug(DBG_TRC, &tq_dev, "tq_io_complete(status=%d)\n", status);
res->io_status = status;
res->io_complete = 1;
-if (elapsed > tq_xtime)
- sim_activate (uptr, 0);
-else
- sim_activate (uptr, tq_xtime-elapsed);
+/* Reschedule for the appropriate delay */
+if (elapsed <= tq_xtime)
+ sim_activate_abs (uptr, tq_xtime-elapsed);
}
@@ -2025,7 +2024,7 @@ t_stat tq_attach (UNIT *uptr, char *cptr)
{
t_stat r;
-r = sim_tape_attach_ex (uptr, cptr, DBG_TAP);
+r = sim_tape_attach_ex (uptr, cptr, DBG_TAP, 0);
if (r != SCPE_OK)
return r;
if (tq_csta == CST_UP)
View
13 sim_disk.c
@@ -733,9 +733,11 @@ static void _sim_disk_io_flush (UNIT *uptr)
uint32 f = DK_GET_FMT (uptr);
#if defined (SIM_ASYNCH_IO)
+struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx;
+
sim_disk_clr_async (uptr);
if (sim_asynch_enabled)
- sim_disk_set_async (uptr, 0);
+ sim_disk_set_async (uptr, ctx->asynch_io_latency);
#endif
switch (f) { /* case on format */
case DKUF_F_STD: /* Simh */
@@ -760,7 +762,8 @@ return stat;
}
-t_stat sim_disk_attach (UNIT *uptr, char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontautosize, uint32 dbit, const char *dtype, uint32 pdp11tracksize)
+t_stat sim_disk_attach (UNIT *uptr, char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontautosize,
+ uint32 dbit, const char *dtype, uint32 pdp11tracksize, int completion_delay)
{
struct disk_context *ctx;
DEVICE *dptr;
@@ -797,7 +800,7 @@ if (sim_switches & SWMASK ('D')) { /* create difference dis
vhd = sim_vhd_disk_create_diff (gbuf, cptr);
if (vhd) {
sim_vhd_disk_close (vhd);
- return sim_disk_attach (uptr, gbuf, sector_size, xfer_element_size, dontautosize, dbit, dtype, pdp11tracksize);
+ return sim_disk_attach (uptr, gbuf, sector_size, xfer_element_size, dontautosize, dbit, dtype, pdp11tracksize, completion_delay);
}
return SCPE_ARG;
}
@@ -816,7 +819,7 @@ if (sim_switches & SWMASK ('C')) { /* create vhd disk & cop
sim_switches |= SWMASK ('R') | SWMASK ('E');
sim_quiet = TRUE;
/* First open the source of the copy operation */
- r = sim_disk_attach (uptr, cptr, sector_size, xfer_element_size, dontautosize, dbit, dtype, pdp11tracksize);
+ r = sim_disk_attach (uptr, cptr, sector_size, xfer_element_size, dontautosize, dbit, dtype, pdp11tracksize, completion_delay);
sim_quiet = saved_sim_quiet;
if (r != SCPE_OK) {
sim_switches = saved_sim_switches;
@@ -1013,7 +1016,7 @@ if (capac && (capac != (t_addr)-1))
uptr->capac = capac/ctx->capac_factor;
#if defined (SIM_ASYNCH_IO)
-sim_disk_set_async (uptr, 0);
+sim_disk_set_async (uptr, completion_delay);
#endif
uptr->io_flush = _sim_disk_io_flush;
View
3  sim_disk.h
@@ -64,7 +64,8 @@ typedef void (*DISK_PCALLBACK)(UNIT *unit, t_stat status);
/* Prototypes */
-t_stat sim_disk_attach (UNIT *uptr, char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontautosize, uint32 debugbit, const char *drivetype, uint32 pdp11_tracksize);
+t_stat sim_disk_attach (UNIT *uptr, char *cptr, size_t sector_size, size_t xfer_element_size, t_bool dontautosize,
+ uint32 debugbit, const char *drivetype, uint32 pdp11_tracksize, int completion_delay);
t_stat sim_disk_detach (UNIT *uptr);
t_stat sim_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects);
t_stat sim_disk_rdsect_a (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects, DISK_PCALLBACK callback);
View
10 sim_tape.c
@@ -367,9 +367,11 @@ return SCPE_OK;
static void _sim_tape_io_flush (UNIT *uptr)
{
#if defined (SIM_ASYNCH_IO)
+struct tape_context *ctx = (struct tape_context *)uptr->tape_ctx;
+
sim_tape_clr_async (uptr);
if (sim_asynch_enabled)
- sim_tape_set_async (uptr, 0);
+ sim_tape_set_async (uptr, ctx->asynch_io_latency);
#endif
fflush (uptr->fileref);
}
@@ -378,10 +380,10 @@ fflush (uptr->fileref);
t_stat sim_tape_attach (UNIT *uptr, char *cptr)
{
-return sim_tape_attach_ex (uptr, cptr, 0);
+return sim_tape_attach_ex (uptr, cptr, 0, 0);
}
-t_stat sim_tape_attach_ex (UNIT *uptr, char *cptr, uint32 dbit)
+t_stat sim_tape_attach_ex (UNIT *uptr, char *cptr, uint32 dbit, int completion_delay)
{
struct tape_context *ctx;
uint32 objc;
@@ -429,7 +431,7 @@ ctx->dbit = dbit; /* save debug bit */
sim_tape_rewind (uptr);
#if defined (SIM_ASYNCH_IO)
-sim_tape_set_async (uptr, 0);
+sim_tape_set_async (uptr, completion_delay);
#endif
uptr->io_flush = _sim_tape_io_flush;
View
2  sim_tape.h
@@ -121,7 +121,7 @@ typedef void (*TAPE_PCALLBACK)(UNIT *unit, t_stat status);
/* Prototypes */
-t_stat sim_tape_attach_ex (UNIT *uptr, char *cptr, uint32 dbit);
+t_stat sim_tape_attach_ex (UNIT *uptr, char *cptr, uint32 dbit, int completion_delay);
t_stat sim_tape_attach (UNIT *uptr, char *cptr);
t_stat sim_tape_detach (UNIT *uptr);
t_stat sim_tape_rdrecf (UNIT *uptr, uint8 *buf, t_mtrlnt *bc, t_mtrlnt max);
Please sign in to comment.
Something went wrong with that request. Please try again.