poke-devel
[Top][All Lists]
Advanced

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

[PATCH 2/2] pkl: remove global state from IOS


From: Mohammad-Reza Nabipoor
Subject: [PATCH 2/2] pkl: remove global state from IOS
Date: Sun, 30 Apr 2023 21:20:52 +0200

This patch introduces a new type `ios_context` to keep all
IOS-related data in one place for each instance of libpoke.
Also removes other IOS-related global states.

2023-04-30  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>

        * libpoke/ios.h (ios_context): New type.
        (ios_init): Returns `ios_context`.
        (ios_shutdown): Add new `ios_context` param.
        (ios_open): Likewise.
        (ios_close): Likewise.
        (ios_cur): Likewise.
        (ios_set_cur): Likewise.
        (ios_search): Likewise.
        (ios_search_by_id): Likewise.
        (ios_begin): Likewise.
        (ios_map): Likewise.
        (ios_register_foreign_iod): Likewise.
        (ios_foreign_iod): Likewise.
        * libpoke/ios-dev-sub.c (ios_dev_sub_open): Update.
        * libpoke/ios.c (struct ios): Mark `dev_if' as const.
        (struct ios_context): Add new field `foreign_dev_if'.
        (IOS_DEV_IF_DATA): Remove macro.
        (IOS_DEV_ZERO): New constant.
        (IOS_DEV_MEM): Likewise.
        (IOS_DEV_STREAM): Likewise.
        (IOS_DEV_NBD): Likewise.
        (IOS_DEV_PROC): Likewise.
        (IOS_DEV_SUB): Likewise.
        (IOS_DEV_FILE): Likewise.
        (ios_dev_ifs): Update.
        (ios_ctx): Remove.
        (ios_dev_ifs_count): New constant.
        (ios_context_data): New internal function.
        (ios_init): Returns `ios_context'.
        (ios_shutdown): Add new `ios_context' param.
        (ios_open): Likewise.
        (ios_close): Likewise.
        (ios_cur): Likewise.
        (ios_set_cur): Likewise.
        (ios_search): Likewise.
        (ios_search_by_id): Likewise.
        (ios_begin): Likewise.
        (ios_map): Likewise.
        (ios_foreign_iod): Likewise.
        (ios_register_foreign_iod): Likewise.
        * libpoke/pvm.h (pvm_ios_context): New function.
        * libpoke/pvm.c (pvm_ios_context): Likewise.
        (PVM_STATE_IOS_CONTEXT): New macro.
        (pvm_init): Add IOS initialization.
        (pvm_shutdown): Add IOS finalization.
        * libpoke/libpoke.c (struct _pk_compiler): Add `struct ios_dev_if`
        for foreign IOD.
        (pk_ios_completion_function): Update to use `ios_context'.
        (pk_ios_cur): Likewise.
        (pk_ios_set_cur): Likewise.
        (pk_ios_search): Likewise.
        (pk_ios_search_by_id): Likewise.
        (pk_ios_open): Likewise.
        (pk_ios_close): Likewise.
        (pk_ios_map): Likewise.
        (foreign_iod_if): Remove global variable.
        (pk_register_iod): Rely on `pk_compiler' fields instead of global
        variable. Use `ios_context'.
        * libpoke/pvm.jitter (state-struct-backing-c): Add new
        field `ios_context'.
        (state-initialization-c): Initialize new field.
        (PVM_PEEK): Update to use IOS context.
        (PVM_POKE): Likewise.
        (open): Likewise.
        (close): Likewise.
        (flush): Likewise.
        (pushios): Likewise.
        (popios): Likewise.
        (ioflags): Likewise.
        (iosize): Likewise.
        (ionum): Likewise.
        (ioref): Likewise.
        (iohandler): Likewise.
        (iogetb): Likewise.
        (iosetb): Likewise.
        (peeks): Likewise.
        (pokes): Likewise.
---
 ChangeLog             |  80 ++++++++++++++++++
 libpoke/ios-dev-sub.c |   3 +-
 libpoke/ios.c         | 184 +++++++++++++++++++++++++-----------------
 libpoke/ios.h         |  30 ++++---
 libpoke/libpoke.c     |  32 ++++----
 libpoke/pvm.c         |  27 ++++++-
 libpoke/pvm.h         |   4 +
 libpoke/pvm.jitter    |  58 ++++++++-----
 8 files changed, 291 insertions(+), 127 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 343a6e9f..71cc4ee3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,83 @@
+2023-04-30  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
+
+       * libpoke/ios.h (ios_context): New type.
+       (ios_init): Returns `ios_context`.
+       (ios_shutdown): Add new `ios_context` param.
+       (ios_open): Likewise.
+       (ios_close): Likewise.
+       (ios_cur): Likewise.
+       (ios_set_cur): Likewise.
+       (ios_search): Likewise.
+       (ios_search_by_id): Likewise.
+       (ios_begin): Likewise.
+       (ios_map): Likewise.
+       (ios_register_foreign_iod): Likewise.
+       (ios_foreign_iod): Likewise.
+       * libpoke/ios-dev-sub.c (ios_dev_sub_open): Update.
+       * libpoke/ios.c (struct ios): Mark `dev_if' as const.
+       (struct ios_context): Add new field `foreign_dev_if'.
+       (IOS_DEV_IF_DATA): Remove macro.
+       (IOS_DEV_ZERO): New constant.
+       (IOS_DEV_MEM): Likewise.
+       (IOS_DEV_STREAM): Likewise.
+       (IOS_DEV_NBD): Likewise.
+       (IOS_DEV_PROC): Likewise.
+       (IOS_DEV_SUB): Likewise.
+       (IOS_DEV_FILE): Likewise.
+       (ios_dev_ifs): Update.
+       (ios_ctx): Remove.
+       (ios_dev_ifs_count): New constant.
+       (ios_context_data): New internal function.
+       (ios_init): Returns `ios_context'.
+       (ios_shutdown): Add new `ios_context' param.
+       (ios_open): Likewise.
+       (ios_close): Likewise.
+       (ios_cur): Likewise.
+       (ios_set_cur): Likewise.
+       (ios_search): Likewise.
+       (ios_search_by_id): Likewise.
+       (ios_begin): Likewise.
+       (ios_map): Likewise.
+       (ios_foreign_iod): Likewise.
+       (ios_register_foreign_iod): Likewise.
+       * libpoke/pvm.h (pvm_ios_context): New function.
+       * libpoke/pvm.c (pvm_ios_context): Likewise.
+       (PVM_STATE_IOS_CONTEXT): New macro.
+       (pvm_init): Add IOS initialization.
+       (pvm_shutdown): Add IOS finalization.
+       * libpoke/libpoke.c (struct _pk_compiler): Add `struct ios_dev_if`
+       for foreign IOD.
+       (pk_ios_completion_function): Update to use `ios_context'.
+       (pk_ios_cur): Likewise.
+       (pk_ios_set_cur): Likewise.
+       (pk_ios_search): Likewise.
+       (pk_ios_search_by_id): Likewise.
+       (pk_ios_open): Likewise.
+       (pk_ios_close): Likewise.
+       (pk_ios_map): Likewise.
+       (foreign_iod_if): Remove global variable.
+       (pk_register_iod): Rely on `pk_compiler' fields instead of global
+       variable. Use `ios_context'.
+       * libpoke/pvm.jitter (state-struct-backing-c): Add new
+       field `ios_context'.
+       (state-initialization-c): Initialize new field.
+       (PVM_PEEK): Update to use IOS context.
+       (PVM_POKE): Likewise.
+       (open): Likewise.
+       (close): Likewise.
+       (flush): Likewise.
+       (pushios): Likewise.
+       (popios): Likewise.
+       (ioflags): Likewise.
+       (iosize): Likewise.
+       (ionum): Likewise.
+       (ioref): Likewise.
+       (iohandler): Likewise.
+       (iogetb): Likewise.
+       (iosetb): Likewise.
+       (peeks): Likewise.
+       (pokes): Likewise.
+
 2023-04-30  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * libpoke/ios.h (ios_get_dev_if): Add declaration.
diff --git a/libpoke/ios-dev-sub.c b/libpoke/ios-dev-sub.c
index 2a7f363e..6ca03aeb 100644
--- a/libpoke/ios-dev-sub.c
+++ b/libpoke/ios-dev-sub.c
@@ -73,6 +73,7 @@ ios_dev_sub_handler_normalize (const char *handler, uint64_t 
flags, int* error)
 static void *
 ios_dev_sub_open (const char *handler, uint64_t flags, int *error, void *data)
 {
+  ios_context ios_ctx = (ios_context)data;
   struct ios_dev_sub *sub = malloc (sizeof (struct ios_dev_sub));
   const char *p;
   char *end;
@@ -148,7 +149,7 @@ ios_dev_sub_open (const char *handler, uint64_t flags, int 
*error, void *data)
     uint64_t iflags;
 
     /* The referred IOS should exist.  */
-    base_ios = ios_search_by_id (base_ios_id);
+    base_ios = ios_search_by_id (ios_ctx, base_ios_id);
     if (base_ios == NULL)
       goto error;
 
diff --git a/libpoke/ios.c b/libpoke/ios.c
index fe7ace47..073d3e52 100644
--- a/libpoke/ios.c
+++ b/libpoke/ios.c
@@ -74,7 +74,7 @@ struct ios
   int num_sub_devs;
   char *handler;
   void *dev;
-  struct ios_dev_if *dev_if;
+  const struct ios_dev_if *dev_if;
   ios_off bias;
 
   struct ios *next;
@@ -85,13 +85,10 @@ struct ios_context
   int next_id;         /* Next available IOS id.  */
   struct ios *io_list; /* List of all IO spaces.  */
   struct ios *cur_io;  /* Pointer to the current IOS.  */
+  struct ios_dev_if *foreign_dev_if;
   void *foreign_dev_if_data; /* User-defined data for foreign device.  */
 };
 
-/* Only foreign device supports user-defined data.  */
-#define IOS_DEV_IF_DATA(dev_if)                                               \
-  ((dev_if) == ios_dev_ifs[0] ? ios_ctx.foreign_dev_if_data : NULL)
-
 /* The available backends are implemented in their own files, and
    provide the following interfaces.  */
 
@@ -107,45 +104,82 @@ extern struct ios_dev_if ios_dev_proc; /* ios-dev-proc.c 
*/
 #endif
 extern struct ios_dev_if ios_dev_sub; /* ios-dev-sub.c */
 
-static struct ios_dev_if *ios_dev_ifs[] =
+enum
+{
+  IOS_DEV_ZERO,
+  IOS_DEV_MEM,
+  IOS_DEV_STREAM,
+  IOS_DEV_NBD,
+  IOS_DEV_PROC,
+  IOS_DEV_SUB,
+  IOS_DEV_FILE, /* File must be last */
+};
+
+static const struct ios_dev_if *ios_dev_ifs[] =
   {
-   NULL, /* Optional foreign IOD.  */
-   &ios_dev_zero,
-   &ios_dev_mem,
-   &ios_dev_stream,
+    [IOS_DEV_ZERO] = &ios_dev_zero,
+    [IOS_DEV_MEM] = &ios_dev_mem,
+    [IOS_DEV_STREAM] = &ios_dev_stream,
 #ifdef HAVE_LIBNBD
-   &ios_dev_nbd,
+    [IOS_DEV_NBD] = &ios_dev_nbd,
+#else
+    [IOS_DEV_NBD] = NULL,
 #endif
 #ifdef HAVE_PROC
-   &ios_dev_proc,
+    [IOS_DEV_PROC] = &ios_dev_proc,
+#else
+    [IOS_DEV_PROC] = NULL,
 #endif
-   &ios_dev_sub,
-   /* File must be last */
-   &ios_dev_file,
-   NULL,
+    [IOS_DEV_SUB] = &ios_dev_sub,
+    [IOS_DEV_FILE] = &ios_dev_file, /* File must be last */
   };
 
-static struct ios_context ios_ctx;
+static const size_t ios_dev_ifs_count
+    = sizeof (ios_dev_ifs) / sizeof (ios_dev_ifs[0]);
 
-void
+static void *
+ios_context_data (ios_context ios_ctx, const struct ios_dev_if *dev_if)
+{
+  if (dev_if == ios_ctx->foreign_dev_if)
+    return ios_ctx->foreign_dev_if_data;
+  if (dev_if == ios_dev_ifs[IOS_DEV_SUB])
+    return ios_ctx;
+  return NULL;
+}
+
+ios_context
 ios_init (void)
 {
+  ios_context ios_ctx = calloc (1, sizeof (struct ios_context));
+
+  if (!ios_ctx)
+    return NULL;
   /* Nothing to do here... yet.  */
+  return ios_ctx;
 }
 
 void
-ios_shutdown (void)
+ios_shutdown (ios_context ios_ctx)
 {
+  ios inext;
+
+  if (!ios_ctx)
+    return;
   /* Close and free all open IO spaces.  */
-  while (ios_ctx.io_list)
-    ios_close (ios_ctx.io_list);
+  for (ios i = ios_ctx->io_list; i; i = inext)
+    {
+      inext = i->next;
+      ios_close (ios_ctx, i);
+    }
+  free (ios_ctx);
 }
 
 int
-ios_open (const char *handler, uint64_t flags, int set_cur)
+ios_open (ios_context ios_ctx, const char *handler, uint64_t flags,
+          int set_cur_p)
 {
   struct ios *io;
-  struct ios_dev_if **dev_if = NULL;
+  const struct ios_dev_if *dev_if = NULL;
   int iod_error = IOD_OK, error = IOS_ERROR;
 
   /* Allocate and initialize the new IO space.  */
@@ -161,33 +195,34 @@ ios_open (const char *handler, uint64_t flags, int 
set_cur)
 
   /* Look for a device interface suitable to operate on the given
      handler.  */
-  dev_if = ios_dev_ifs;
-  do
+  dev_if = ios_ctx->foreign_dev_if;
+  if (dev_if)
     {
-      if (*dev_if == NULL)
-        {
-          /* Skip the foreign IO device if it is not set.  */
-          ++dev_if;
-          continue;
-        }
-
-      io->handler = (*dev_if)->handler_normalize (handler, flags, &iod_error);
+      io->handler = dev_if->handler_normalize (handler, flags, &iod_error);
       if (iod_error != IOD_OK)
         goto error;
       if (io->handler)
-        break;
-
-      ++dev_if;
+        goto found;
+    }
+  for (size_t i = 0; i < ios_dev_ifs_count; ++i)
+    {
+      dev_if = ios_dev_ifs[i];
+      if (!dev_if)
+        continue; /* Skip unavailable devices.  */
+      io->handler = dev_if->handler_normalize (handler, flags, &iod_error);
+      if (iod_error != IOD_OK)
+        goto error;
+      if (io->handler)
+        goto found;
     }
-  while (*dev_if);
 
-  if (*dev_if == NULL)
-    goto error;
+  goto error;
 
-  io->dev_if = *dev_if;
+found:
+  io->dev_if = dev_if;
 
   /* Do not re-open an already-open IO space.  */
-  for (ios i = ios_ctx.io_list; i; i = i->next)
+  for (ios i = ios_ctx->io_list; i; i = i->next)
     if (STREQ (i->handler, io->handler))
       {
         error = IOS_EOPEN;
@@ -196,20 +231,20 @@ ios_open (const char *handler, uint64_t flags, int 
set_cur)
 
   /* Open the device using the interface found above.  */
   io->dev = io->dev_if->open (handler, flags, &iod_error,
-                              IOS_DEV_IF_DATA (io->dev_if));
+                              ios_context_data (ios_ctx, io->dev_if));
   if (iod_error || io->dev == NULL)
     goto error;
 
   /* Increment the id counter after all possible errors are avoided.  */
-  io->id = ios_ctx.next_id++;
+  io->id = ios_ctx->next_id++;
 
   /* Add the newly created space to the list, and update the current
      space.  */
-  io->next = ios_ctx.io_list;
-  ios_ctx.io_list = io;
+  io->next = ios_ctx->io_list;
+  ios_ctx->io_list = io;
 
-  if (!ios_ctx.cur_io || set_cur == 1)
-    ios_ctx.cur_io = io;
+  if (!ios_ctx->cur_io || set_cur_p == 1)
+    ios_ctx->cur_io = io;
 
   return io->id;
 
@@ -225,7 +260,7 @@ ios_open (const char *handler, uint64_t flags, int set_cur)
 }
 
 int
-ios_close (ios io)
+ios_close (ios_context ios_ctx, ios io)
 {
   struct ios *tmp;
   int ret;
@@ -238,23 +273,23 @@ ios_close (ios io)
 
   /* Unlink the IOS from the list.  */
   /* The list contains at least this IO space.  */
-  assert (ios_ctx.io_list != NULL);
-  if (ios_ctx.io_list == io)
-    ios_ctx.io_list = ios_ctx.io_list->next;
+  assert (ios_ctx->io_list != NULL);
+  if (ios_ctx->io_list == io)
+    ios_ctx->io_list = ios_ctx->io_list->next;
   else
     {
-      for (tmp = ios_ctx.io_list; tmp->next != io; tmp = tmp->next)
+      for (tmp = ios_ctx->io_list; tmp->next != io; tmp = tmp->next)
         ;
       tmp->next = io->next;
     }
 
   /* Set the new current IO.  */
-  if (io == ios_ctx.cur_io)
-    ios_ctx.cur_io = ios_ctx.io_list;
+  if (io == ios_ctx->cur_io)
+    ios_ctx->cur_io = ios_ctx->io_list;
 
   /* Re-use the ID if this IOS was the most-recently opened IOS.  */
-  if (ios_ctx.next_id == io->id + 1)
-    --ios_ctx.next_id;
+  if (ios_ctx->next_id == io->id + 1)
+    --ios_ctx->next_id;
 
   if (io->num_sub_devs == 0)
     free (io);
@@ -277,15 +312,15 @@ ios_handler (ios io)
 }
 
 ios
-ios_cur (void)
+ios_cur (ios_context ios_ctx)
 {
-  return ios_ctx.cur_io;
+  return ios_ctx->cur_io;
 }
 
 void
-ios_set_cur (ios io)
+ios_set_cur (ios_context ios_ctx, ios io)
 {
-  ios_ctx.cur_io = io;
+  ios_ctx->cur_io = io;
 }
 
 int
@@ -296,11 +331,11 @@ ios_zombie_p (ios io)
 }
 
 ios
-ios_search (const char *handler)
+ios_search (ios_context ios_ctx, const char *handler)
 {
   ios io;
 
-  for (io = ios_ctx.io_list; io; io = io->next)
+  for (io = ios_ctx->io_list; io; io = io->next)
     if (STREQ (io->handler, handler))
       break;
 
@@ -308,11 +343,11 @@ ios_search (const char *handler)
 }
 
 ios
-ios_search_by_id (int id)
+ios_search_by_id (ios_context ios_ctx, int id)
 {
   ios io;
 
-  for (io = ios_ctx.io_list; io; io = io->next)
+  for (io = ios_ctx->io_list; io; io = io->next)
     if (io->id == id)
       break;
 
@@ -344,9 +379,9 @@ ios_set_bias (ios io, ios_off bias)
 }
 
 ios
-ios_begin (void)
+ios_begin (ios_context ios_ctx)
 {
-  return ios_ctx.io_list;
+  return ios_ctx->io_list;
 }
 
 bool
@@ -362,12 +397,12 @@ ios_next (const ios io)
 }
 
 void
-ios_map (ios_map_fn cb, void *data)
+ios_map (ios_context ios_ctx, ios_map_fn cb, void *data)
 {
   ios io;
   ios io_next;
 
-  for (io = ios_ctx.io_list; io; io = io_next)
+  for (io = ios_ctx->io_list; io; io = io_next)
     {
       /* Note that the handler may close IO.  */
       io_next = io->next;
@@ -1657,19 +1692,20 @@ ios_get_dev_if (ios ios)
 }
 
 struct ios_dev_if *
-ios_foreign_iod (void)
+ios_foreign_iod (ios_context ios_ctx)
 {
-  return ios_dev_ifs[0];
+  return ios_ctx->foreign_dev_if;
 }
 
 int
-ios_register_foreign_iod (struct ios_dev_if *iod_if, void *data)
+ios_register_foreign_iod (ios_context ios_ctx, struct ios_dev_if *iod_if,
+                          void *data)
 {
-  if (ios_dev_ifs[0] != NULL)
+  if (ios_ctx->foreign_dev_if)
     return IOS_ERROR;
 
-  ios_dev_ifs[0] = iod_if;
-  ios_ctx.foreign_dev_if_data = data;
+  ios_ctx->foreign_dev_if = iod_if;
+  ios_ctx->foreign_dev_if_data = data;
   return IOS_OK;
 }
 
diff --git a/libpoke/ios.h b/libpoke/ios.h
index 0ef62693..3a487aa0 100644
--- a/libpoke/ios.h
+++ b/libpoke/ios.h
@@ -23,12 +23,14 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-/* The following two functions initialize and shutdown the IO poke
+typedef struct ios_context *ios_context;
+
+/* The following two functions intialize and shutdown the IO poke
    subsystem.  */
 
-void ios_init (void);
+ios_context ios_init (void);
 
-void ios_shutdown (void);
+void ios_shutdown (ios_context ios_ctx);
 
 /* "IO spaces" are the entities used in poke in order to abstract the
    heterogeneous devices that are suitable to be edited, such as
@@ -157,13 +159,14 @@ typedef int64_t ios_off;
    If no IOS_F_READ or IOS_F_WRITE flags are specified, then the IOS
    will be opened in whatever mode makes more sense.  */
 
-int ios_open (const char *handler, uint64_t flags, int set_cur);
+int ios_open (ios_context ios_ctx, const char *handler, uint64_t flags,
+              int set_cur);
 
 /* Close the given IO space, freing all used resources and flushing
    the space cache associated with the space.  Return IOS_OK on success
    and the error code on failure.  */
 
-int ios_close (ios io);
+int ios_close (ios_context ios_ctx, ios io);
 
 /* Return the flags which are active in a given IO.  Note that this
    doesn't necessarily correspond to the flags passed when opening the
@@ -179,21 +182,21 @@ const char *ios_handler (ios io);
 /* Return the current IO space, or NULL if there are no open
    spaces.  */
 
-ios ios_cur (void);
+ios ios_cur (ios_context ios_ctx);
 
 /* Set the current IO space to IO.  */
 
-void ios_set_cur (ios io);
+void ios_set_cur (ios_context ios_ctx, ios io);
 
 /* Return the IO space operating the given HANDLER.  Return NULL if no
    such space exists.  */
 
-ios ios_search (const char *handler);
+ios ios_search (ios_context ios_ctx, const char *handler);
 
 /* Return the IO space having the given ID.  Return NULL if no such
    space exists.  */
 
-ios ios_search_by_id (int id);
+ios ios_search_by_id (ios_context ios_ctx, int id);
 
 /* Return the ID of the given IO space.  */
 
@@ -217,7 +220,7 @@ void *ios_get_dev (ios ios);
 
 /* Return the first IO space.  */
 
-ios ios_begin (void);
+ios ios_begin (ios_context ios_ctx);
 
 /* Return the space following IO.  */
 
@@ -231,7 +234,7 @@ bool ios_end (const ios io);
 
 typedef void (*ios_map_fn) (ios io, void *data);
 
-void ios_map (ios_map_fn cb, void *data);
+void ios_map (ios_context ios_ctx, ios_map_fn cb, void *data);
 
 /* **************** IOS properties************************  */
 
@@ -368,7 +371,7 @@ int ios_flush (ios io, ios_off offset);
    If no forereign IO device is registered, return NULL.
    Otherwise return a pointer to the interface.  */
 
-struct ios_dev_if *ios_foreign_iod (void);
+struct ios_dev_if *ios_foreign_iod (ios_context ios_ctx);
 
 /* Register a foreign IO device.
 
@@ -378,7 +381,8 @@ struct ios_dev_if *ios_foreign_iod (void);
    Return IOS_OK otherwise.  */
 
 struct ios_dev_if;
-int ios_register_foreign_iod (struct ios_dev_if *iod_if, void *data);
+int ios_register_foreign_iod (ios_context ios_ctx,
+                              struct ios_dev_if *iod_if, void *data);
 
 /* **************** Sub IO space **************** */
 
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index b0d5501a..6ef4b155 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -38,6 +38,7 @@ struct _pk_compiler
   pvm vm;
 
   int status;  /* Status of last API function call. Initialized with PK_OK */
+  struct ios_dev_if foreign_iod_if;
   /* Data for completion machinery.  */
   pkl_ast_node complete_type;
   ios completion_ios;
@@ -462,7 +463,7 @@ pk_ios_completion_function (pk_compiler pkc, const char 
*text, int state)
 
   int len  = strlen (text);
 
-  IO = state == 0 ?  ios_begin () : ios_next (IO);
+  IO = state == 0 ?  ios_begin (pvm_ios_context (pkc->vm)) : ios_next (IO);
   while (1)
     {
       if (ios_end (IO))
@@ -571,14 +572,13 @@ pk_ios
 pk_ios_cur (pk_compiler pkc)
 {
   pkc->status = PK_OK;
-  return (pk_ios) ios_cur ();
+  return (pk_ios) ios_cur (pvm_ios_context (pkc->vm));
 }
 
 void
 pk_ios_set_cur (pk_compiler pkc, pk_ios io)
 {
-  /* XXX use pkc */
-  ios_set_cur ((ios) io);
+  ios_set_cur (pvm_ios_context (pkc->vm), (ios) io);
   pkc->status = PK_OK;
 }
 
@@ -598,16 +598,14 @@ pk_ios
 pk_ios_search (pk_compiler pkc, const char *handler)
 {
   pkc->status = PK_OK;
-  /* XXX use pkc */
-  return (pk_ios) ios_search (handler);
+  return (pk_ios) ios_search (pvm_ios_context (pkc->vm), handler);
 }
 
 pk_ios
 pk_ios_search_by_id (pk_compiler pkc, int id)
 {
   pkc->status = PK_OK;
-  /* XXX use pkc */
-  return (pk_ios) ios_search_by_id (id);
+  return (pk_ios) ios_search_by_id (pvm_ios_context (pkc->vm), id);
 }
 
 int
@@ -615,9 +613,9 @@ pk_ios_open (pk_compiler pkc,
              const char *handler, uint64_t flags, int set_cur_p)
 {
   int ret;
+  ios_context ios_ctx = pvm_ios_context (pkc->vm);
 
-  /* XXX use pkc */
-  if ((ret = ios_open (handler, flags, set_cur_p)) >= 0)
+  if ((ret = ios_open (ios_ctx, handler, flags, set_cur_p)) >= 0)
     return ret;
 
   switch (ret)
@@ -638,8 +636,7 @@ pk_ios_open (pk_compiler pkc,
 void
 pk_ios_close (pk_compiler pkc, pk_ios io)
 {
-  /* XXX use pkc */
-  ios_close ((ios) io);
+  ios_close (pvm_ios_context (pkc->vm), (ios) io);
   pkc->status = PK_OK;
 }
 
@@ -685,8 +682,7 @@ pk_ios_map (pk_compiler pkc,
             pk_ios_map_fn cb, void *data)
 {
   struct ios_map_fn_payload payload = { cb, data };
-  /* XXX use pkc */
-  ios_map (my_ios_map_fn, (void *) &payload);
+  ios_map (pvm_ios_context (pkc->vm), my_ios_map_fn, (void *) &payload);
   pkc->status = PK_OK;
 }
 
@@ -1094,14 +1090,14 @@ pk_print_val (pk_compiler pkc, pk_val val, pk_val 
*exit_exception)
     pkc->status = PK_OK;
 }
 
-static struct ios_dev_if foreign_iod_if;
-
 int
 pk_register_iod (pk_compiler pkc, struct pk_iod_if *iod_if)
 {
+  ios_context ios_ctx = pvm_ios_context (pkc->vm);
+
   pkc->status = PK_OK;
 
-#define CF(FN) foreign_iod_if.FN = iod_if->FN
+#define CF(FN) pkc->foreign_iod_if.FN = iod_if->FN
   CF (get_if_name);
   CF (handler_normalize);
   CF (open);
@@ -1113,7 +1109,7 @@ pk_register_iod (pk_compiler pkc, struct pk_iod_if 
*iod_if)
   CF (flush);
 #undef CF
 
-  (void) ios_register_foreign_iod (&foreign_iod_if, iod_if->data);
+  (void) ios_register_foreign_iod (ios_ctx, &pkc->foreign_iod_if, 
iod_if->data);
   return pkc->status;
 }
 
diff --git a/libpoke/pvm.c b/libpoke/pvm.c
index cdddf74f..0e212133 100644
--- a/libpoke/pvm.c
+++ b/libpoke/pvm.c
@@ -40,6 +40,8 @@
   (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, exit_code))
 #define PVM_STATE_VM(PVM)                               \
   (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, vm))
+#define PVM_STATE_IOS_CONTEXT(PVM)                      \
+  (PVM_STATE_BACKING_FIELD (& (PVM)->pvm_state, ios_ctx))
 #define PVM_STATE_ENV(PVM)                              \
   (PVM_STATE_RUNTIME_FIELD (& (PVM)->pvm_state, env))
 #define PVM_STATE_ENDIAN(PVM)                           \
@@ -111,10 +113,21 @@ pvm_initialize_state (pvm apvm, struct pvm_state *state)
 pvm
 pvm_init (void)
 {
-  pvm apvm = calloc (1, sizeof (struct pvm));
+  pvm apvm;
+  ios_context ios_ctx;
+
+  apvm = calloc (1, sizeof (struct pvm));
   if (!apvm)
     return NULL;
 
+  /* Initialize the IO space.  */
+  ios_ctx = ios_init ();
+  if (!ios_ctx)
+    {
+      free (apvm);
+      return NULL;
+    }
+
   /* Initialize the memory allocation subsystem.  */
   pvm_alloc_initialize ();
 
@@ -126,6 +139,7 @@ pvm_init (void)
 
   /* Initialize the VM state.  */
   pvm_initialize_state (apvm, &apvm->pvm_state);
+  PVM_STATE_IOS_CONTEXT (apvm) = ios_ctx;
 
   /* Initialize pvm-program.  */
   pvm_program_init ();
@@ -241,6 +255,9 @@ pvm_shutdown (pvm apvm)
   /* Finalize values.  */
   pvm_val_finalize ();
 
+  /* Shutdown the IO space.  */
+  ios_shutdown (PVM_STATE_IOS_CONTEXT (apvm));
+
   /* Finalize the VM state.  */
   pvm_state_finalize (&apvm->pvm_state);
 
@@ -253,6 +270,14 @@ pvm_shutdown (pvm apvm)
   pvm_alloc_finalize ();
 }
 
+ios_context
+pvm_ios_context (pvm apvm)
+{
+  assert (apvm);
+  assert (PVM_STATE_IOS_CONTEXT (apvm));
+  return PVM_STATE_IOS_CONTEXT (apvm);
+}
+
 enum ios_endian
 pvm_endian (pvm apvm)
 {
diff --git a/libpoke/pvm.h b/libpoke/pvm.h
index 1c000d3b..368782ca 100644
--- a/libpoke/pvm.h
+++ b/libpoke/pvm.h
@@ -596,6 +596,10 @@ pvm pvm_init (void);
 
 void pvm_shutdown (pvm pvm);
 
+/* Get the IO space context.  */
+
+ios_context pvm_ios_context (pvm apvm);
+
 /* Get the current run-time environment of PVM.  */
 
 pvm_env pvm_get_env (pvm pvm);
diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
index 61d4ee16..ff98aedd 100644
--- a/libpoke/pvm.jitter
+++ b/libpoke/pvm.jitter
@@ -374,12 +374,13 @@ late-header-c
      IOTYPE##64_t value;                                                     \
      ios io;                                                                 \
      ios_off offset;                                                         \
+     ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);                \
                                                                              \
      offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());                           \
      if (JITTER_UNDER_TOP_STACK () == PVM_NULL)                              \
-       io = ios_cur ();                                                      \
+       io = ios_cur (ios_ctx);                                               \
      else                                                                    \
-       io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));      \
+       io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_UNDER_TOP_STACK 
()));\
                                                                              \
      if (io == NULL)                                                         \
        PVM_RAISE_DFL (PVM_E_NO_IOS);                                         \
@@ -414,14 +415,15 @@ late-header-c
      pvm_val offset_val = JITTER_UNDER_TOP_STACK ();                         \
      ios io;                                                                 \
      ios_off offset;                                                         \
+     ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);                \
                                                                              \
      JITTER_DROP_STACK ();                                                   \
      JITTER_DROP_STACK ();                                                   \
                                                                              \
      if (JITTER_TOP_STACK () == PVM_NULL)                                    \
-       io = ios_cur ();                                                      \
+       io = ios_cur (ios_ctx);                                               \
      else                                                                    \
-       io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));            \
+       io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_TOP_STACK ()));   \
                                                                              \
      if (io == NULL)                                                         \
        PVM_RAISE_DFL (PVM_E_NO_IOS);                                         \
@@ -913,6 +915,7 @@ state-struct-backing-c
       jitter_stack_height canary_returnstack;
       jitter_stack_height canary_exceptionstack;
       pvm vm;
+      ios_context ios_ctx;
   end
 end
 
@@ -941,6 +944,7 @@ state-initialization-c
       jitter_state_backing->canary_exceptionstack = NULL;
       jitter_state_backing->exit_code = PVM_EXIT_OK;
       jitter_state_backing->result_value = PVM_NULL;
+      jitter_state_backing->ios_ctx = NULL;
       jitter_state_runtime->endian = IOS_ENDIAN_MSB;
       jitter_state_runtime->nenc = IOS_NENC_2;
       jitter_state_runtime->pretty_print = 0;
@@ -1484,8 +1488,9 @@ instruction open ()
   code
      char *filename = PVM_VAL_STR (JITTER_UNDER_TOP_STACK ());
      uint64_t flags = PVM_VAL_ULONG (JITTER_TOP_STACK ());
+     ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
 
-     int ret = ios_open (filename, flags, 0);
+     int ret = ios_open (ios_ctx, filename, flags, 0);
      JITTER_DROP_STACK ();
      JITTER_TOP_STACK () = PVM_MAKE_INT (ret, 32);
   end
@@ -1506,12 +1511,13 @@ instruction close ()
   branching # because of PVM_RAISE_DIRECT
   code
     int io_id = PVM_VAL_INT (JITTER_TOP_STACK ());
-    ios io = ios_search_by_id (io_id);
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+    ios io = ios_search_by_id (ios_ctx, io_id);
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
 
-    if (ios_close (io) != IOS_OK)
+    if (ios_close (ios_ctx, io) != IOS_OK)
       PVM_RAISE_DFL (PVM_E_IO);
 
     JITTER_DROP_STACK ();
@@ -1535,7 +1541,8 @@ instruction flush ()
   code
     ios_off offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());
     int io_id = PVM_VAL_INT (JITTER_UNDER_TOP_STACK ());
-    ios io = ios_search_by_id (io_id);
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+    ios io = ios_search_by_id (ios_ctx, io_id);
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_IO);
@@ -1558,7 +1565,8 @@ end
 
 instruction pushios ()
   code
-    ios cur_io = ios_cur ();
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+    ios cur_io = ios_cur (ios_ctx);
 
     if (cur_io == NULL)
        JITTER_PUSH_STACK (PVM_MAKE_INT (-1, 32));
@@ -1579,11 +1587,12 @@ end
 instruction popios ()
   branching # because of PVM_RAISE_DIRECT
   code
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    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);
-    ios_set_cur (io);
+    ios_set_cur (ios_ctx, io);
     JITTER_DROP_STACK ();
   end
 end
@@ -1601,7 +1610,8 @@ end
 instruction ioflags ()
   branching # because of PVM_RAISE_DIRECT
   code
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    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);
@@ -1622,7 +1632,8 @@ end
 instruction iosize ()
   branching # because of PVM_RAISE_DIRECT
   code
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    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);
@@ -1645,9 +1656,10 @@ end
 instruction ionum ()
   code
     struct ionum_ctx ctx;
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
 
     ctx.count = 0;
-    ios_map (ionum_callback, &ctx);
+    ios_map (ios_ctx, ionum_callback, &ctx);
     JITTER_PUSH_STACK (PVM_MAKE_ULONG (ctx.count, 64));
   end
 end
@@ -1666,11 +1678,12 @@ end
 instruction ioref ()
   branching # because of PVM_RAISE_DIRECT
   code
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
     struct ioref_ctx ctx;
 
     ctx.index = PVM_VAL_ULONG (JITTER_TOP_STACK ());
     ctx.ios_id = -1;
-    ios_map (ioref_callback, &ctx);
+    ios_map (ios_ctx, ioref_callback, &ctx);
     if (ctx.ios_id == -1)
       PVM_RAISE_DIRECT (PVM_E_OUT_OF_BOUNDS);
     JITTER_PUSH_STACK (PVM_MAKE_INT (ctx.ios_id, 32));
@@ -1689,7 +1702,8 @@ end
 instruction iohandler ()
   branching # because of PVM_RAISE_DIRECT
   code
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    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);
@@ -1716,7 +1730,8 @@ instruction iogetb ()
   branching # because of PVM_RAISE_DIRECT
   code
     pvm_val type, magnitude, unit;
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    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);
@@ -1756,7 +1771,8 @@ instruction iosetb ()
   code
     pvm_val bias = JITTER_UNDER_TOP_STACK();
     pvm_val bias_type = PVM_VAL_OFF_TYPE (bias);
-    ios io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+    ios io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_TOP_STACK ()));
 
     JITTER_DROP_STACK ();
 
@@ -6745,9 +6761,10 @@ instruction peeks ()
     ios_off offset;
     char *ios_str;
     int ret;
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
 
     offset = PVM_VAL_ULONG (JITTER_TOP_STACK ());
-    io = ios_search_by_id (PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));
+    io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_UNDER_TOP_STACK ()));
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
@@ -6783,13 +6800,14 @@ instruction pokes ()
     ios_off offset;
     char *str;
     int ret;
+    ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
 
     str = PVM_VAL_STR (JITTER_TOP_STACK ());
     offset = PVM_VAL_ULONG (JITTER_UNDER_TOP_STACK ());
     JITTER_DROP_STACK();
     JITTER_DROP_STACK();
 
-    io = ios_search_by_id (PVM_VAL_INT (JITTER_TOP_STACK ()));
+    io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_TOP_STACK ()));
 
     if (io == NULL)
       PVM_RAISE_DFL (PVM_E_NO_IOS);
-- 
2.40.1




reply via email to

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