[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH 2/2] pkl: remove global state from IOS
From: |
Jose E. Marchesi |
Subject: |
Re: [PATCH 2/2] pkl: remove global state from IOS |
Date: |
Sun, 30 Apr 2023 21:55:00 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
Hi Mohammad.
This is OK for master.
Thanks!
> 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);