poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED] libpoke, poke: support for volatile/non-volatile IO spaces


From: Jose E. Marchesi
Subject: [COMMITTED] libpoke, poke: support for volatile/non-volatile IO spaces
Date: Thu, 19 Sep 2024 11:38:38 +0200
User-agent: Gnus/5.13 (Gnus v5.13)

This patch introduces the notion of volatile vs. non-volatile IO
spaces in poke, which allows a smarter management of remaps.
Documentation and tests included.

2024-09-19  Jose E. Marchesi  <jemarch@gnu.org>

        * libpoke/ios-dev.h (struct ios_dev_if): New field
        volatile_by_default.
        * libpoke/libpoke.h (struct pk_iod_if): Likewise.
        * libpoke/ios.c (struct ios): New field volatile_p.
        (ios_open): Initialize volatile_p in newly opened IO space.
        (ios_volatile_p): Define.
        * libpoke/ios-dev-file.c (ios_dev_file_volatile_by_default):
        Define.
        (ios_dev_file): Set volatile_by_default.
        (ios_dev_file_convert_flags): Ignore IOS_F_VOLATILE.
        * libpoke/ios-dev-mem.c (ios_dev_mem_volatile_by_default): Define.
        (ios_dev_mem): Set volatile_by_default.
        * libpoke/ios-dev-mmap.c (ios_dev_mmap_volatile_by_default):
        Define.
        (ios_dev_mmap): set volatile_by_default.
        * libpoke/ios-dev-nbd.c (ios_dev_nbd_volatile_by_default): Define.
        (ios_dev_nbd): Set volatile_by_default.
        * libpoke/ios-dev-proc.c (ios_dev_proc_volatile_by_default):
        Define.
        (ios_dev_proc): Set volatile_by_default.
        * libpoke/ios-dev-stream.c (ios_dev_stream_volatile_by_default):
        Define.
        (ios_dev_stream): Set volatile_by_default.
        * libpoke/ios-dev-sub.c (ios_dev_sub_volatile_by_default): Define.
        (ios_dev_sub): Set volatile_by_default.
        * libpoke/ios-dev-zero.c (ios_dev_zero_volatile_by_default):
        Define.
        (ios_dev_zero): Define volatile_by_default.
        * libpoke/pvm.jitter (iogetv): New instruction.
        * libpoke/pkl-rt.pk (ioisvolatile): New function.
        (IOS_F_VOLATILE): Define.
        * poke/pk-cmd-info.pk (pk_info_ios): Add column "Volatile".
        * libpoke/ios.h (IOS_F_VOLATILE): Define.
        * testsuite/poke.libpoke/foreign-iod.c (iod_volatile_by_default):
        New function.
        (iod_if): Initialize volatile_by_default.
        * libpoke/libpoke.c (pk_register_iod): Update to handle
        volatile_by_default.
        * testsuite/poke.pkl/open-volatile-1.pk: New test.
        * testsuite/poke.pkl/open-volatile-2.pk: Likewise.
        * testsuite/poke.pkl/iovolatile-1.pk: Likewise.
        * testsuite/poke.cmd/file-bias-1.pk: Update test.
        * testsuite/poke.cmd/file-relative.pk: Likewise.
        * testsuite/poke.cmd/file-mode.pk: Likewise.
        * testsuite/poke.cmd/file-bias-2.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
        * doc/poke.texi (Files as IO Spaces): Update to reflect volatile
        attribute of IO spaces.
        (Buffers as IO Spaces): Likewise.
        (info command): Likewise.
        (iovolatile): New section.
        (Auto-Remapping): Update.
---
 ChangeLog                             |  55 +++++++++++++
 doc/poke.texi                         | 113 ++++++++++++++------------
 libpoke/ios-dev-file.c                |   9 +-
 libpoke/ios-dev-mem.c                 |   7 ++
 libpoke/ios-dev-mmap.c                |   9 +-
 libpoke/ios-dev-nbd.c                 |   7 ++
 libpoke/ios-dev-proc.c                |   9 +-
 libpoke/ios-dev-stream.c              |   9 +-
 libpoke/ios-dev-sub.c                 |  11 ++-
 libpoke/ios-dev-zero.c                |   8 ++
 libpoke/ios-dev.h                     |   1 +
 libpoke/ios.c                         |  16 ++++
 libpoke/ios.h                         |   6 ++
 libpoke/libpoke.c                     |   1 +
 libpoke/libpoke.h                     |   7 +-
 libpoke/pkl-rt.pk                     |   7 ++
 libpoke/pvm.jitter                    |  25 ++++++
 poke/pk-cmd-info.pk                   |   4 +-
 testsuite/Makefile.am                 |   3 +
 testsuite/poke.cmd/file-bias-1.pk     |   4 +-
 testsuite/poke.cmd/file-bias-2.pk     |   4 +-
 testsuite/poke.cmd/file-mode.pk       |   6 +-
 testsuite/poke.cmd/file-relative.pk   |   4 +-
 testsuite/poke.libpoke/foreign-iod.c  |   7 ++
 testsuite/poke.pkl/iovolatile-1.pk    |   8 ++
 testsuite/poke.pkl/open-volatile-1.pk |   8 ++
 testsuite/poke.pkl/open-volatile-2.pk |   8 ++
 27 files changed, 288 insertions(+), 68 deletions(-)
 create mode 100644 testsuite/poke.pkl/iovolatile-1.pk
 create mode 100644 testsuite/poke.pkl/open-volatile-1.pk
 create mode 100644 testsuite/poke.pkl/open-volatile-2.pk

diff --git a/ChangeLog b/ChangeLog
index 6b949026..11b45bf2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2024-09-19  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/ios-dev.h (struct ios_dev_if): New field
+       volatile_by_default.
+       * libpoke/libpoke.h (struct pk_iod_if): Likewise.
+       * libpoke/ios.c (struct ios): New field volatile_p.
+       (ios_open): Initialize volatile_p in newly opened IO space.
+       (ios_volatile_p): Define.
+       * libpoke/ios-dev-file.c (ios_dev_file_volatile_by_default):
+       Define.
+       (ios_dev_file): Set volatile_by_default.
+       (ios_dev_file_convert_flags): Ignore IOS_F_VOLATILE.
+       * libpoke/ios-dev-mem.c (ios_dev_mem_volatile_by_default): Define.
+       (ios_dev_mem): Set volatile_by_default.
+       * libpoke/ios-dev-mmap.c (ios_dev_mmap_volatile_by_default):
+       Define.
+       (ios_dev_mmap): set volatile_by_default.
+       * libpoke/ios-dev-nbd.c (ios_dev_nbd_volatile_by_default): Define.
+       (ios_dev_nbd): Set volatile_by_default.
+       * libpoke/ios-dev-proc.c (ios_dev_proc_volatile_by_default):
+       Define.
+       (ios_dev_proc): Set volatile_by_default.
+       * libpoke/ios-dev-stream.c (ios_dev_stream_volatile_by_default):
+       Define.
+       (ios_dev_stream): Set volatile_by_default.
+       * libpoke/ios-dev-sub.c (ios_dev_sub_volatile_by_default): Define.
+       (ios_dev_sub): Set volatile_by_default.
+       * libpoke/ios-dev-zero.c (ios_dev_zero_volatile_by_default):
+       Define.
+       (ios_dev_zero): Define volatile_by_default.
+       * libpoke/pvm.jitter (iogetv): New instruction.
+       * libpoke/pkl-rt.pk (ioisvolatile): New function.
+       (IOS_F_VOLATILE): Define.
+       * poke/pk-cmd-info.pk (pk_info_ios): Add column "Volatile".
+       * libpoke/ios.h (IOS_F_VOLATILE): Define.
+       * testsuite/poke.libpoke/foreign-iod.c (iod_volatile_by_default):
+       New function.
+       (iod_if): Initialize volatile_by_default.
+       * libpoke/libpoke.c (pk_register_iod): Update to handle
+       volatile_by_default.
+       * testsuite/poke.pkl/open-volatile-1.pk: New test.
+       * testsuite/poke.pkl/open-volatile-2.pk: Likewise.
+       * testsuite/poke.pkl/iovolatile-1.pk: Likewise.
+       * testsuite/poke.cmd/file-bias-1.pk: Update test.
+       * testsuite/poke.cmd/file-relative.pk: Likewise.
+       * testsuite/poke.cmd/file-mode.pk: Likewise.
+       * testsuite/poke.cmd/file-bias-2.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+       * doc/poke.texi (Files as IO Spaces): Update to reflect volatile
+       attribute of IO spaces.
+       (Buffers as IO Spaces): Likewise.
+       (info command): Likewise.
+       (iovolatile): New section.
+       (Auto-Remapping): Update.
+
 2024-09-16  Jose E. Marchesi  <jemarch@gnu.org>
 
        * poke/pk-cmd-ios.c (file_cmd): Add flags to command synopsis.
diff --git a/doc/poke.texi b/doc/poke.texi
index 8ad3941f..523076c9 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -1132,8 +1132,8 @@ about:
 
 @example
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 0    FILE    rw      0x00000000#B    0x00000398#B    ./foo.o
+  Id   Type   Volatile   Mode   Bias           Size           Name
+* 0    FILE   no         rw     0x00000000#B   0x00000398#B   ./foo.o
 @end example
 
 The command @command{.info ios} gives us information about all the IO
@@ -1141,10 +1141,13 @@ spaces that are currently open.  The first column tells 
us a positive
 integer that identifies the IOS.  This @dfn{IO space identifier} is
 unique at any given time.  In this example, the id corresponding to
 @file{foo.o} is @code{0}.  The second column tells us the type of IO
-space. The third column tells us that @file{foo.o} allows both reading
-and writing.  The fourth column tells us the size of the file, in
-hexadecimal.  The fifth column is the name of the IO space; in this
-case, it is the path to the file being edited.
+space. The third column tells us whether the IO space is
+@dfn{volatile} or not; the contents of a volatile IO space can change
+at any time out of our control.  The third column tells us that
+@file{foo.o} allows both reading and writing.  The fourth column tells
+us the size of the file, in hexadecimal.  The fifth column is the name
+of the IO space; in this case, it is the path to the file being
+edited.
 
 You may wonder what is that weird suffix @code{#B}.  It is a unit,
 and tells us that the size @code{0x398} is measured in bytes, @i{i.e.} the
@@ -1159,9 +1162,9 @@ clearly, let's open another file:
 (poke) .file bar.o
 The current IOS is now `./bar.o'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 1    FILE    rw      0x00000000#B    0x00000398#B    ./bar.o
-  0    FILE    rw      0x00000000#B    0x00000398#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 1     FILE    no         rw      0x00000000#B    0x00000398#B    ./bar.o
+  0     FILE    no         rw      0x00000000#B    0x00000398#B    ./foo.o
 @end example
 
 Ah, there we have both @file{foo.o} and @file{bar.o}.  Now the current
@@ -1175,9 +1178,9 @@ an IO space as an argument:
 (poke) .ios 0
 The current IOS is now `./foo.o'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-  1    FILE    rw      0x00000000#B    0x00000398#B    ./bar.o
-* 0    FILE    rw      0x00000000#B    0x00000398#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+  1     FILE    no         rw      0x00000000#B    0x00000398#B    ./bar.o
+* 0     FILE    no         rw      0x00000000#B    0x00000398#B    ./foo.o
 @end example
 
 @noindent
@@ -1187,8 +1190,8 @@ We are back to @file{foo.o}.  Since we are not really 
interested in
 @example
 (poke) .close 1
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 0    FILE    rw      0x00000000#B    0x00000398#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 0     FILE    no         rw      0x00000000#B    0x00000398#B    ./foo.o
 @end example
 
 Note how in the examples above we used the IO space identifiers (0 and
@@ -2737,8 +2740,8 @@ that opened a file as an IO space?
 (poke) .file foo.o
 The current IOS is now `./foo.o'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 0    FILE    rw      0x00000000#B    0x000004c8#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 0     FILE    no         rw      0x00000000#B    0x000004c8#B    ./foo.o
 @end example
 
 @noindent
@@ -2749,9 +2752,9 @@ Memory buffers can be created using a similar dot-command,
 (poke) .mem foo
 The current IOS is now `*foo*'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 1    MEMORY          0x00000000#B    0x00001000#B    *foo*
-  0    FILE    rw      0x00000000#B    0x000004c8#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 1     MEMORY  no                 0x00000000#B    0x00001000#B    *foo*
+  0     FILE    no         rw      0x00000000#B    0x000004c8#B    ./foo.o
 @end example
 
 Note how the name of the buffer is built by prepending and appending
@@ -2874,9 +2877,9 @@ we can continue our work tomorrow.  This is how we would 
do that:
 
 @example
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 1    MEMORY          0x00000000#B    0x00001000#B    *scratch*
-  0    FILE    rw      0x00000000#B    0x000f4241#B    ./foo.o
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 1     MEMORY  no                 0x00000000#B    0x00001000#B    *scratch*
+  0     FILE    no         rw      0x00000000#B    0x000f4241#B    ./foo.o
 (poke) save :from 0#B :size iosize (1) :file "scratch.dat"
 @end example
 
@@ -3918,9 +3921,9 @@ $ poke p.sbm
 (poke) .mem scratch
 The current IOS is now `*scratch*'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 1    MEMORY          0x00000000#B    0x00001000#B    *scratch*
-  0    FILE    rw      0x00000000#B    0x0000006e#B    ./p.sbm
+  Id    Type    Volatile Mode    Bias            Size            Name
+* 1     MEMORY  no               0x00000000#B    0x00001000#B    *scratch*
+  0     FILE    no       rw      0x00000000#B    0x0000006e#B    ./p.sbm
 (poke) copy :from_ios 0 :from 0#B :to 0#B :size iosize (0)
 (poke) dump
 76543210  0011 2233 4455 6677 8899 aabb ccdd eeff  0123456789ABCDEF
@@ -8721,9 +8724,9 @@ Display a list of open files.
 
 @example
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-  1    FILE    r       0x00000000#B    0x0000df78#B    foo.o
-* 0    FILE    rw      0x00000000#B    0x00000022#B    foo.bson
+  Id    Type    Volatile   Mode    Bias            Size            Name
+  1     FILE    no         r       0x00000000#B    0x0000df78#B    foo.o
+* 0     FILE    no         rw      0x00000000#B    0x00000022#B    foo.bson
 @end example
 
 @cindex IO space
@@ -8737,9 +8740,9 @@ switch to it as the new current IO space:
 (poke) .ios 1
 The current file is now `foo.o'.
 (poke) .info ios
-  Id   Type    Mode    Bias            Size            Name
-* 1    FILE    r       0x00000000#B    0x0000df78#B    foo.o
-  0    FILE    rw      0x00000000#B    0x00000022#B    foo.bson
+  Id    Type    Volatile   Mode    Bias            Size            Name
+* 1     FILE    no         r       0x00000000#B    0x0000df78#B    foo.o
+  0     FILE    no         rw      0x00000000#B    0x00000022#B    foo.bson
 @end example
 
 @item .info variables [@var{regexp}]
@@ -13608,6 +13611,7 @@ memory of some process.
 * iosearch::                    Search for an IO space by name.
 * iolist::                      Getting a list of open IO spaces.
 * openset::                     Opening and setting combined.
+* iovolatile::                  Getting whether a given IO space is volatile.
 * iosize::                     Getting the size of an IO space.
 * iotype::                      Getting the type of an IO space.
 * iohandler::                   Getting the handler string of an IO space.
@@ -13859,6 +13863,20 @@ fun openset = (string @var{handler}, uint<64> 
@var{flags} = 0) int<32>
 Where the meaning of @var{handler}, @var{flags} and the returned value
 are exactly like in @code{open}.
 
+@node iovolatile
+@subsubsection @code{iovolatile}
+@cindex @code{iovolatile}
+
+The @code{iovolatile} builtin returns a boolean indicating whether a
+given IO space is @dfn{volatile}.  It has the following prototype:
+
+@example
+fun iovolatile = (int<32> ios = get_ios) int<32>
+@end example
+
+If the IO space specified to @code{iovolatile} doesn't exist,
+@code{E_no_ios} will be raised.
+
 @node iosize
 @subsubsection @code{iosize}
 @cindex @code{iosize}
@@ -14395,11 +14413,12 @@ definition.
 @node Auto-Remapping
 @subsection Auto-Remapping
 @cindex remap
+@cindex volatile IO spaces
 
 By default poke always tries to handle mapped values in a transparent
 way, @i{i.e.} in the same way than if the values weren't mapped.  To
 guarantee that the contents of mapped values are always up to date, it
-issues @dfn{remaps} every time the value gets referenced.
+may need to issue @dfn{remaps} when the value gets referenced.
 
 @noindent
 For example, consider the following Poke program:
@@ -14425,26 +14444,16 @@ element in position 2.
 
 This re-mapping 100% guarantees that the mapped values are up to date.
 However, this can get very slow, depending on the data structures we
-are poking at.
-
-@noindent
-poke offers a way to turn this auto re-mapping off.  In Poke code:
-
-@example
-vm_set_autoremap (0)
-@end example
-
-@noindent
-Or using the poke application CLI:
-
-@example
-(poke) .set autoremap no
-@end example
-
-@noindent
-When auto-remap is switched off, mapped values are used as-is.  It is
-then the responsibility of the user to explicitly re-map values using
-the @code{remap} operator.  Like:
+are poking at. poke thus tries to be smart and do as less remapping as
+possible.  In non-volatile IO spaces, like files, only mapped values
+whose contents have been updated by poke itself will be re-mapped.
+This is in contrast to volatile IO spaces, in which the underlying
+contents may be updated any time out of the control of poke, and
+therefore remapping cannot be avoided.  In read-only non-volatile IO
+spaces poke doesn't remap values at all.
+
+The user can explicitly re-map values using the @code{remap} operator.
+Like:
 
 @example
 (poke) remap arr
diff --git a/libpoke/ios-dev-file.c b/libpoke/ios-dev-file.c
index 4f663c22..b291b245 100644
--- a/libpoke/ios-dev-file.c
+++ b/libpoke/ios-dev-file.c
@@ -298,6 +298,12 @@ ios_dev_file_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_file_volatile_by_default (void *iod, const char *handler)
+{
+  return 0;
+}
+
 struct ios_dev_if ios_dev_file =
   {
    .get_if_name = ios_dev_file_get_if_name,
@@ -308,5 +314,6 @@ struct ios_dev_if ios_dev_file =
    .pwrite = ios_dev_file_pwrite,
    .get_flags = ios_dev_file_get_flags,
    .size = ios_dev_file_size,
-   .flush = ios_dev_file_flush
+   .flush = ios_dev_file_flush,
+   .volatile_by_default = ios_dev_file_volatile_by_default
   };
diff --git a/libpoke/ios-dev-mem.c b/libpoke/ios-dev-mem.c
index e945c59b..5be54cd7 100644
--- a/libpoke/ios-dev-mem.c
+++ b/libpoke/ios-dev-mem.c
@@ -163,6 +163,12 @@ ios_dev_mem_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_mem_volatile_by_default (void *iod, const char *handler)
+{
+  return 0;
+}
+
 struct ios_dev_if ios_dev_mem =
   {
    .get_if_name = ios_dev_mem_get_if_name,
@@ -174,4 +180,5 @@ struct ios_dev_if ios_dev_mem =
    .get_flags = ios_dev_mem_get_flags,
    .size = ios_dev_mem_size,
    .flush = ios_dev_mem_flush,
+   .volatile_by_default = ios_dev_mem_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-mmap.c b/libpoke/ios-dev-mmap.c
index b619f269..9c1ee1c2 100644
--- a/libpoke/ios-dev-mmap.c
+++ b/libpoke/ios-dev-mmap.c
@@ -447,6 +447,12 @@ ios_dev_mmap_flush (void *iod, ios_dev_off offset)
   return IOD_OK;
 }
 
+static int
+ios_dev_mmap_volatile_by_default (void *iod, const char *handler)
+{
+  return 1;
+}
+
 struct ios_dev_if ios_dev_mmap =
   {
     .get_if_name = ios_dev_mmap_get_if_name,
@@ -457,5 +463,6 @@ struct ios_dev_if ios_dev_mmap =
     .pwrite = ios_dev_mmap_pwrite,
     .get_flags = ios_dev_mmap_get_flags,
     .size = ios_dev_mmap_size,
-    .flush = ios_dev_mmap_flush
+    .flush = ios_dev_mmap_flush,
+    .volatile_by_default = ios_dev_mmap_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-nbd.c b/libpoke/ios-dev-nbd.c
index a6bf2474..be1135f0 100644
--- a/libpoke/ios-dev-nbd.c
+++ b/libpoke/ios-dev-nbd.c
@@ -185,6 +185,12 @@ ios_dev_nbd_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_nbd_volatile_by_default (void *iod, const char *handler)
+{
+  return 1;
+}
+
 struct ios_dev_if ios_dev_nbd =
   {
    .get_if_name = ios_dev_nbd_get_if_name,
@@ -196,4 +202,5 @@ struct ios_dev_if ios_dev_nbd =
    .get_flags = ios_dev_nbd_get_flags,
    .size = ios_dev_nbd_size,
    .flush = ios_dev_nbd_flush,
+   .volatile_by_default = ios_dev_nbd_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-proc.c b/libpoke/ios-dev-proc.c
index 8a36b209..c89cc19e 100644
--- a/libpoke/ios-dev-proc.c
+++ b/libpoke/ios-dev-proc.c
@@ -172,6 +172,12 @@ ios_dev_proc_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_proc_volatile_by_default (void *iod, const char *handler)
+{
+  return 1;
+}
+
 struct ios_dev_if ios_dev_proc =
   {
    .get_if_name = ios_dev_proc_get_if_name,
@@ -182,5 +188,6 @@ struct ios_dev_if ios_dev_proc =
    .pwrite = ios_dev_proc_pwrite,
    .get_flags = ios_dev_proc_get_flags,
    .size = ios_dev_proc_size,
-   .flush = ios_dev_proc_flush
+   .flush = ios_dev_proc_flush,
+   .volatile_by_default = ios_dev_proc_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-stream.c b/libpoke/ios-dev-stream.c
index 1f3a7915..aca0686d 100644
--- a/libpoke/ios-dev-stream.c
+++ b/libpoke/ios-dev-stream.c
@@ -259,6 +259,12 @@ ios_dev_stream_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_stream_volatile_by_default (void *iod, const char *handler)
+{
+  return 1;
+}
+
 struct ios_dev_if ios_dev_stream =
   {
    .get_if_name = ios_dev_stream_get_dev_if_name,
@@ -269,5 +275,6 @@ struct ios_dev_if ios_dev_stream =
    .pwrite = ios_dev_stream_pwrite,
    .get_flags = ios_dev_stream_get_flags,
    .size = ios_dev_stream_size,
-   .flush = ios_dev_stream_flush
+   .flush = ios_dev_stream_flush,
+   .volatile_by_default = ios_dev_stream_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-sub.c b/libpoke/ios-dev-sub.c
index f0967101..bbb42ead 100644
--- a/libpoke/ios-dev-sub.c
+++ b/libpoke/ios-dev-sub.c
@@ -259,6 +259,14 @@ ios_dev_sub_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_sub_volatile_by_default (void *iod, const char *handler)
+{
+  struct ios_dev_sub *sub = iod;
+
+  return ios_volatile_p (sub->base_ios);
+}
+
 struct ios_dev_if ios_dev_sub =
   {
    .get_if_name = ios_dev_sub_get_if_name,
@@ -269,5 +277,6 @@ struct ios_dev_if ios_dev_sub =
    .pwrite = ios_dev_sub_pwrite,
    .get_flags = ios_dev_sub_get_flags,
    .size = ios_dev_sub_size,
-   .flush = ios_dev_sub_flush
+   .flush = ios_dev_sub_flush,
+   .volatile_by_default = ios_dev_sub_volatile_by_default,
   };
diff --git a/libpoke/ios-dev-zero.c b/libpoke/ios-dev-zero.c
index a563ad97..a304af41 100644
--- a/libpoke/ios-dev-zero.c
+++ b/libpoke/ios-dev-zero.c
@@ -105,6 +105,13 @@ ios_dev_zero_flush (void *iod, ios_dev_off offset)
   return IOS_OK;
 }
 
+static int
+ios_dev_zero_volatile_by_default (void *iod, const char *handler)
+{
+  return 0;
+}
+
+
 struct ios_dev_if ios_dev_zero =
   {
    .get_if_name = ios_dev_zero_get_if_name,
@@ -116,6 +123,7 @@ struct ios_dev_if ios_dev_zero =
    .get_flags = ios_dev_zero_get_flags,
    .size = ios_dev_zero_size,
    .flush = ios_dev_zero_flush,
+   .volatile_by_default = ios_dev_zero_volatile_by_default,
   };
 
 /* Handler: <zero> */
diff --git a/libpoke/ios-dev.h b/libpoke/ios-dev.h
index 1d437450..aa8126ac 100644
--- a/libpoke/ios-dev.h
+++ b/libpoke/ios-dev.h
@@ -65,6 +65,7 @@ struct ios_dev_if
   uint64_t (*get_flags) (void *dev);
   ios_dev_off (*size) (void *dev);
   int (*flush) (void *dev, ios_dev_off offset);
+  int (*volatile_by_default) (void *dev, const char *handler);
 };
 
 #define IOS_FILE_HANDLER_NORMALIZE(handler, new_handler)                \
diff --git a/libpoke/ios.c b/libpoke/ios.c
index 9c2452e0..c53ff13d 100644
--- a/libpoke/ios.c
+++ b/libpoke/ios.c
@@ -64,6 +64,10 @@
 
    NEXT is a pointer to the next open IO space, or NULL.
 
+   VOLATILE_P determines whether the IO space contents can vary
+   beetween calls to ios_write_*.  In other words, a volatile IOS
+   assume that its contents may change at any time.
+
    XXX: add status, saved or not saved.
  */
 
@@ -71,6 +75,7 @@ struct ios
 {
   int id;
   int zombie_p;
+  int volatile_p;
   int num_sub_devs;
   char *handler;
   void *dev;
@@ -244,6 +249,11 @@ found:
   if (iod_error || io->dev == NULL)
     goto error;
 
+  /* Set whether the IO space is volatile.  If it is not volatile by
+     default then it can be overriden by the IOS_F_VOLATILE flag.  */
+  io->volatile_p =
+    (flags & IOS_F_VOLATILE) || dev_if->volatile_by_default (io->dev, handler);
+
   /* Increment the id counter after all possible errors are avoided.  */
   io->id = ios_ctx->next_id++;
 
@@ -391,6 +401,12 @@ ios_get_id (ios io)
   return io->id;
 }
 
+int
+ios_volatile_p (ios io)
+{
+  return io->volatile_p;
+}
+
 const char *
 ios_get_handler (ios io)
 {
diff --git a/libpoke/ios.h b/libpoke/ios.h
index 2ad3947f..7a992fb1 100644
--- a/libpoke/ios.h
+++ b/libpoke/ios.h
@@ -125,6 +125,8 @@ typedef int64_t ios_off;
 #define IOS_F_WRITE  2
 #define IOS_F_CREATE 16
 
+#define IOS_F_VOLATILE (1 << 8)
+
 #define IOS_M_RDONLY (IOS_F_READ)
 #define IOS_M_WRONLY (IOS_F_WRITE)
 #define IOS_M_RDWR (IOS_F_READ | IOS_F_WRITE)
@@ -207,6 +209,10 @@ ios ios_search_by_id (ios_context ios_ctx, int id);
 
 int ios_get_id (ios io);
 
+/* Return whether the given IO space is volatile.  */
+
+int ios_volatile_p (ios io);
+
 /* Return the handler of the given IO space.  */
 
 const char *ios_get_handler (ios io);
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index f88c2128..9c258c83 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -1166,6 +1166,7 @@ pk_register_iod (pk_compiler pkc, struct pk_iod_if 
*iod_if)
   CF (close);
   CF (pread);
   CF (pwrite);
+  CF (volatile_by_default);
   CF (get_flags);
   CF (size);
   CF (flush);
diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
index 63f91d1f..2228b522 100644
--- a/libpoke/libpoke.h
+++ b/libpoke/libpoke.h
@@ -1328,7 +1328,6 @@ typedef uint64_t pk_iod_off;
 struct pk_iod_if
 {
   /* Return the name of this device interface. Cannot return NULL. */
-
   const char *(*get_if_name) ();
 
   /* Determine whether the provided HANDLER is recognized as a valid
@@ -1358,6 +1357,12 @@ struct pk_iod_if
      writes.  */
   int (*pwrite) (void *dev, const void *buf, size_t count, pk_iod_off offset);
 
+  /* Return whether IO spaces implemented by this interface are
+     "volatile" by default.  Volatile IO spaces assume that their
+     contents can change at any time, and not just as the result of
+     write operations in this interface.  */
+  int (*volatile_by_default) (void *dev, const char *handler);
+
   /* Return the flags of the device, as it was opened.  */
   uint64_t (*get_flags) (void *dev);
 
diff --git a/libpoke/pkl-rt.pk b/libpoke/pkl-rt.pk
index 4f28849d..8566c25f 100644
--- a/libpoke/pkl-rt.pk
+++ b/libpoke/pkl-rt.pk
@@ -367,6 +367,8 @@ immutable var IOS_F_READ   = 1;
 immutable var IOS_F_WRITE  = 2;
 immutable var IOS_F_CREATE = 16;
 
+immutable var IOS_F_VOLATILE = 1 <<. 8;
+
 immutable var IOS_M_RDONLY = IOS_F_READ;
 immutable var IOS_M_WRONLY = IOS_F_WRITE;
 immutable var IOS_M_RDWR = IOS_F_READ | IOS_F_WRITE;
@@ -975,6 +977,11 @@ immutable fun iosearch = (string handler) int<32>:
   raise E_no_ios;
 }
 
+immutable fun iovolatile = (int<32>ios = get_ios) int<32>:
+{
+  return asm int<32>: ("iogetv; nip" : ios);
+}
+
 immutable fun iosetbias = (offset<uint<64>,1> bias = 0#1, int<32> ios = 
get_ios) void:
 {
   asm ("iosetb; drop" :: bias, ios);
diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
index 8798a0c5..bf516efd 100644
--- a/libpoke/pvm.jitter
+++ b/libpoke/pvm.jitter
@@ -123,6 +123,7 @@ wrapped-functions
   ios_map
   ios_handler
   ios_size
+  ios_volatile_p
   ios_open
   ios_read_int
   ios_read_uint
@@ -1770,6 +1771,30 @@ instruction iohandler ()
   end
 end
 
+# Instruction: iogetv
+#
+# Push 1 on the stack if the IO space on the stack is volatile.
+# Push 0 otherwise.
+#
+# If the given IO space doesn't exist then the exception PVM_E_NO_IOS
+# is raised.
+#
+# Stack: ( INT - INT INT )
+# Exceptions: PVM_E_NO_IOS
+
+instruction iogetv ()
+  non-relocatable
+  branching # because of PVM_RAISE_DIRECT
+  code
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+    ios io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_TOP_STACK ()));
+
+    if (io == NULL)
+      PVM_RAISE_DFL (PVM_E_NO_IOS);
+    JITTER_PUSH_STACK (pvm_make_int (ios_volatile_p (io), 32));
+  end
+end
+
 # Instruction: iogetb
 #
 # Each IO space has a bias associated with it, which by default is 0
diff --git a/poke/pk-cmd-info.pk b/poke/pk-cmd-info.pk
index 7b38bfdf..e6c95cc2 100644
--- a/poke/pk-cmd-info.pk
+++ b/poke/pk-cmd-info.pk
@@ -21,12 +21,13 @@
 
 fun pk_info_ios = void:
 {
-  var table = Pk_Table { num_columns = pk_hserver_p ? 7 : 6,
+  var table = Pk_Table { num_columns = pk_hserver_p ? 8 : 7,
                          max_column_size = 80 };
 
   table.row ("table-header");
   table.column ("  Id");
   table.column ("Type");
+  table.column ("Volatile");
   table.column ("Mode");
   table.column ("Bias");
   table.column ("Size");
@@ -47,6 +48,7 @@ fun pk_info_ios = void:
       table.row;
       table.column ((ios == get_ios ? "* " : "  ") + format ("%i32d", ios));
       table.column (iotype);
+      table.column (iovolatile (ios) ? "yes" : "no");
       table.column (mode);
       if (bias > 0xffff_ffff)
         {
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 60794a6b..fda60303 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1807,6 +1807,7 @@ EXTRA_DIST = \
   poke.pkl/iosetbias-7.pk\
   poke.pkl/iotype-1.pk \
   poke.pkl/iotype-2.pk \
+  poke.pkl/iovolatile-1.pk \
   poke.pkl/ior-integers-1.pk \
   poke.pkl/ior-integers-2.pk \
   poke.pkl/ior-int-struct-1.pk \
@@ -2070,6 +2071,8 @@ EXTRA_DIST = \
   poke.pkl/open-sub-7.pk \
   poke.pkl/open-sub-8.pk \
   poke.pkl/open-sub-9.pk \
+  poke.pkl/open-volatile-1.pk \
+  poke.pkl/open-volatile-2.pk \
   poke.pkl/optcond-1.pk \
   poke.pkl/optcond-1-diag.pk \
   poke.pkl/optcond-2.pk \
diff --git a/testsuite/poke.cmd/file-bias-1.pk 
b/testsuite/poke.cmd/file-bias-1.pk
index 918c06fd..1bf77d26 100644
--- a/testsuite/poke.cmd/file-bias-1.pk
+++ b/testsuite/poke.cmd/file-bias-1.pk
@@ -4,5 +4,5 @@
 /* { dg-command { .file foo.data } } */
 /* { dg-command { iosetbias (0x13#b) } } */
 /* { dg-command { .info ios } } */
-/* { dg-output "  Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000013#b +0x00000008#B +./foo.data" } */
+/* { dg-output "  Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000013#b +0x00000008#B +./foo.data" 
} */
diff --git a/testsuite/poke.cmd/file-bias-2.pk 
b/testsuite/poke.cmd/file-bias-2.pk
index 921188a2..02fa8e71 100644
--- a/testsuite/poke.cmd/file-bias-2.pk
+++ b/testsuite/poke.cmd/file-bias-2.pk
@@ -4,5 +4,5 @@
 /* { dg-command { .file foo.data } } */
 /* { dg-command { iosetbias (0x13#B) } } */
 /* { dg-command { .info ios } } */
-/* { dg-output "  Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000013#B +0x00000008#B +./foo.data" } */
+/* { dg-output "  Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000013#B +0x00000008#B +./foo.data" 
} */
diff --git a/testsuite/poke.cmd/file-mode.pk b/testsuite/poke.cmd/file-mode.pk
index f2777c29..f803b2ad 100644
--- a/testsuite/poke.cmd/file-mode.pk
+++ b/testsuite/poke.cmd/file-mode.pk
@@ -5,6 +5,6 @@
 /* { dg-command { .file foo } } */
 /* { dg-command { .file /dev/null } } */
 /* { dg-command { .info ios } } */
-/* { dg-output "  Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output {\n. 1 +FILE +rw +0x00000000#B +0x00000000#B +/dev/null} } */
-/* { dg-output {\n  0 +FILE +r[w ] +0x00000000#B +0x[0-9a-f]*#B +foo} } */
+/* { dg-output "  Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output {\n. 1 +FILE +no +rw +0x00000000#B +0x00000000#B +/dev/null} } 
*/
+/* { dg-output {\n  0 +FILE +no +r[w ] +0x00000000#B +0x[0-9a-f]*#B +foo} } */
diff --git a/testsuite/poke.cmd/file-relative.pk 
b/testsuite/poke.cmd/file-relative.pk
index dbcb5cfc..fc702635 100644
--- a/testsuite/poke.cmd/file-relative.pk
+++ b/testsuite/poke.cmd/file-relative.pk
@@ -3,5 +3,5 @@
 
 /* { dg-command { .file a#b } } */
 /* { dg-command { .info ios } } */
-/* { dg-output "  Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000000#B +0x00000008#B +./a#b" } */
+/* { dg-output "  Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000000#B +0x00000008#B +./a#b" } */
diff --git a/testsuite/poke.libpoke/foreign-iod.c 
b/testsuite/poke.libpoke/foreign-iod.c
index 8eaf0055..f4ad5b15 100644
--- a/testsuite/poke.libpoke/foreign-iod.c
+++ b/testsuite/poke.libpoke/foreign-iod.c
@@ -137,6 +137,12 @@ iod_close (void *dev)
   return PK_OK;
 }
 
+int
+iod_volatile_by_default (void *dev, const char *handler)
+{
+  return 0;
+}
+
 static uint32_t USER_DATA = 0x706f6b65u; /* "poke" */
 
 struct pk_iod_if iod_if =
@@ -147,6 +153,7 @@ struct pk_iod_if iod_if =
     iod_close,
     iod_pread,
     iod_pwrite,
+    iod_volatile_by_default,
     iod_get_flags,
     iod_size,
     iod_flush,
diff --git a/testsuite/poke.pkl/iovolatile-1.pk 
b/testsuite/poke.pkl/iovolatile-1.pk
new file mode 100644
index 00000000..72a7025f
--- /dev/null
+++ b/testsuite/poke.pkl/iovolatile-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} foo } */
+
+/* { dg-command {var f = open ("foo")} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "0" } */
+/* { dg-command { iovolatile (f) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/open-volatile-1.pk 
b/testsuite/poke.pkl/open-volatile-1.pk
new file mode 100644
index 00000000..dd31c7fe
--- /dev/null
+++ b/testsuite/poke.pkl/open-volatile-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} foo } */
+
+/* File IO spaces are non-volatile by default.  */
+
+/* { dg-command {open ("foo")} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/open-volatile-2.pk 
b/testsuite/poke.pkl/open-volatile-2.pk
new file mode 100644
index 00000000..037c2556
--- /dev/null
+++ b/testsuite/poke.pkl/open-volatile-2.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} foo } */
+
+/* IOS_F_VOLATILE turns out volatile in file IO spaces.  */
+
+/* { dg-command {open ("foo", IOS_F_VOLATILE)} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "1" } */
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]