SCP: Avoid writing out memory buffered devices on detach that haven't changed
As discussed in #1109
This commit is contained in:
parent
0116987fc7
commit
315a07cbc7
2 changed files with 18 additions and 5 deletions
22
scp.c
22
scp.c
|
@ -8143,13 +8143,22 @@ else {
|
||||||
}
|
}
|
||||||
if (uptr->flags & UNIT_BUFABLE) { /* buffer? */
|
if (uptr->flags & UNIT_BUFABLE) { /* buffer? */
|
||||||
uint32 cap = ((uint32) uptr->capac) / dptr->aincr; /* effective size */
|
uint32 cap = ((uint32) uptr->capac) / dptr->aincr; /* effective size */
|
||||||
if (uptr->flags & UNIT_MUSTBUF) /* dyn alloc? */
|
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
||||||
uptr->filebuf = calloc (cap, SZ_D (dptr)); /* allocate */
|
uptr->filebuf = calloc (cap, SZ_D (dptr)); /* allocate */
|
||||||
if (uptr->filebuf == NULL) /* no buffer? */
|
uptr->filebuf2 = calloc (cap, SZ_D (dptr)); /* allocate copy */
|
||||||
return attach_err (uptr, SCPE_MEM); /* error */
|
if ((uptr->filebuf == NULL) || /* no buffer? */
|
||||||
|
(uptr->filebuf2 == NULL)) {
|
||||||
|
free (uptr->filebuf);
|
||||||
|
uptr->filebuf = NULL;
|
||||||
|
free (uptr->filebuf2);
|
||||||
|
uptr->filebuf2 = NULL;
|
||||||
|
return attach_err (uptr, SCPE_MEM); /* error */
|
||||||
|
}
|
||||||
|
}
|
||||||
sim_messagef (SCPE_OK, "%s: buffering file in memory\n", sim_uname (uptr));
|
sim_messagef (SCPE_OK, "%s: buffering file in memory\n", sim_uname (uptr));
|
||||||
uptr->hwmark = (uint32)sim_fread (uptr->filebuf, /* read file */
|
uptr->hwmark = (uint32)sim_fread (uptr->filebuf, /* read file */
|
||||||
SZ_D (dptr), cap, uptr->fileref);
|
SZ_D (dptr), cap, uptr->fileref);
|
||||||
|
memcpy (uptr->filebuf2, uptr->filebuf, cap * SZ_D (dptr));/* save initial contents */
|
||||||
uptr->flags = uptr->flags | UNIT_BUF; /* set buffered */
|
uptr->flags = uptr->flags | UNIT_BUF; /* set buffered */
|
||||||
}
|
}
|
||||||
uptr->flags = uptr->flags | UNIT_ATT;
|
uptr->flags = uptr->flags | UNIT_ATT;
|
||||||
|
@ -8268,7 +8277,8 @@ if ((dptr = find_dev_from_unit (uptr)) == NULL)
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||||
uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr;
|
uint32 cap = (uptr->hwmark + dptr->aincr - 1) / dptr->aincr;
|
||||||
if (uptr->hwmark && ((uptr->flags & UNIT_RO) == 0)) {
|
if (((uptr->flags & UNIT_RO) == 0) &&
|
||||||
|
(memcmp (uptr->filebuf, uptr->filebuf2, (size_t)(SZ_D (dptr) * (uptr->capac / dptr->aincr))) != 0)) {
|
||||||
sim_messagef (SCPE_OK, "%s: writing buffer to file: %s\n", sim_uname (uptr), uptr->filename);
|
sim_messagef (SCPE_OK, "%s: writing buffer to file: %s\n", sim_uname (uptr), uptr->filename);
|
||||||
rewind (uptr->fileref);
|
rewind (uptr->fileref);
|
||||||
sim_fwrite (uptr->filebuf, SZ_D (dptr), cap, uptr->fileref);
|
sim_fwrite (uptr->filebuf, SZ_D (dptr), cap, uptr->fileref);
|
||||||
|
@ -8276,8 +8286,10 @@ if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) {
|
||||||
sim_printf ("%s: I/O error - %s", sim_uname (uptr), strerror (errno));
|
sim_printf ("%s: I/O error - %s", sim_uname (uptr), strerror (errno));
|
||||||
}
|
}
|
||||||
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
if (uptr->flags & UNIT_MUSTBUF) { /* dyn alloc? */
|
||||||
free (uptr->filebuf); /* free buf */
|
free (uptr->filebuf); /* free buffers */
|
||||||
uptr->filebuf = NULL;
|
uptr->filebuf = NULL;
|
||||||
|
free (uptr->filebuf2);
|
||||||
|
uptr->filebuf2 = NULL;
|
||||||
}
|
}
|
||||||
uptr->flags = uptr->flags & ~UNIT_BUF;
|
uptr->flags = uptr->flags & ~UNIT_BUF;
|
||||||
}
|
}
|
||||||
|
|
|
@ -585,6 +585,7 @@ struct UNIT {
|
||||||
uint32 dynflags; /* dynamic flags */
|
uint32 dynflags; /* dynamic flags */
|
||||||
t_addr capac; /* capacity */
|
t_addr capac; /* capacity */
|
||||||
t_addr pos; /* file position */
|
t_addr pos; /* file position */
|
||||||
|
void *filebuf2; /* copy of initial memory buffer */
|
||||||
void (*io_flush)(UNIT *up); /* io flush routine */
|
void (*io_flush)(UNIT *up); /* io flush routine */
|
||||||
uint32 iostarttime; /* I/O start time */
|
uint32 iostarttime; /* I/O start time */
|
||||||
int32 buf; /* buffer */
|
int32 buf; /* buffer */
|
||||||
|
|
Loading…
Add table
Reference in a new issue