[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC 4/4] tcg/plugins: Add example pair of QPP plugins
From: |
Alex Bennée |
Subject: |
Re: [RFC 4/4] tcg/plugins: Add example pair of QPP plugins |
Date: |
Wed, 21 Sep 2022 16:22:34 +0100 |
User-agent: |
mu4e 1.9.0; emacs 28.2.50 |
Andrew Fasano <fasano@mit.edu> writes:
> The first plugin, qpp_srv exposes two functions and one callback that other
> plugins can leverage. These functions are described in the corresponding
> header file.
>
> The second plugin, qpp_client, imports this header file, registers its
> own function to run on a qpp_srv-provided callback, and directly calls
> into the two exposed functions in qpp_srv.
I'll just sketch out how I would change the API in this example plugin:
>
> Signed-off-by: Andrew Fasano <fasano@mit.edu>
> ---
> contrib/plugins/Makefile | 2 ++
> contrib/plugins/qpp_client.c | 42 ++++++++++++++++++++++++++++++++++++
> contrib/plugins/qpp_client.h | 1 +
> contrib/plugins/qpp_srv.c | 33 ++++++++++++++++++++++++++++
> contrib/plugins/qpp_srv.h | 17 +++++++++++++++
> 5 files changed, 95 insertions(+)
> create mode 100644 contrib/plugins/qpp_client.c
> create mode 100644 contrib/plugins/qpp_client.h
> create mode 100644 contrib/plugins/qpp_srv.c
> create mode 100644 contrib/plugins/qpp_srv.h
>
> diff --git a/contrib/plugins/Makefile b/contrib/plugins/Makefile
> index b7720fea0f..b7510de89c 100644
> --- a/contrib/plugins/Makefile
> +++ b/contrib/plugins/Makefile
> @@ -21,6 +21,8 @@ NAMES += lockstep
> NAMES += hwprofile
> NAMES += cache
> NAMES += drcov
> +NAMES += qpp_srv
> +NAMES += qpp_client
>
> SONAMES := $(addsuffix .so,$(addprefix lib,$(NAMES)))
>
> diff --git a/contrib/plugins/qpp_client.c b/contrib/plugins/qpp_client.c
> new file mode 100644
> index 0000000000..de3335e167
> --- /dev/null
> +++ b/contrib/plugins/qpp_client.c
> @@ -0,0 +1,42 @@
> +#include <stdio.h>
> +#include <qemu-plugin.h>
> +#include <plugin-qpp.h>
> +#include <glib.h>
> +#include "qpp_srv.h"
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
QEMU_PLUGIN_EXPORT const char *qemu_plugin_name = "qpp_client";
QEMU_PLUGIN_EXPORT const char *qemu_plugin_uses = "qpp_server";
> +
> +void my_on_exit(int x, bool b)
void my_on_exit(gpointer evdata, gpointer udata)
{
struct qpp_exit_event *info = (struct qpp_exit_event *) evdata;
x = info->x;
b = info->b;
> +{
> + g_autoptr(GString) report = g_string_new("Client: on_exit runs with args:
> ");
> + g_string_append_printf(report, "%d, %d\n", x, b);
> + qemu_plugin_outs(report->str);
> +
> + g_string_printf(report, "Client: calls qpp_srv's do_add(1): %d\n",
> + qpp_srv_do_add(1));
> + qemu_plugin_outs(report->str);
> +
> + g_string_printf(report, "Client: calls qpp_srv's do_sub(1): %d\n",
> + qpp_srv_do_sub(1));
> + qemu_plugin_outs(report->str);
> +}
> +
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
> + const qemu_info_t *info, int argc, char **argv) {
> +
> + /*
> + * Register our "my_on_exit" function to run on the on_exit QPP-callback
> + * exported by qpp_srv
> + */
> + QPP_REG_CB("qpp_srv", on_exit, my_on_exit);
qemu_plugin_register_event_listener("qpp_server", "exit", my_on_exit);
> +
> + g_autoptr(GString) report = g_string_new(CURRENT_PLUGIN ": Call "
> + "qpp_srv's do_add(0) => ");
> + g_string_append_printf(report, "%d\n", qpp_srv_do_add(0));
> + qemu_plugin_outs(report->str);
> +
> + g_string_printf(report, "Client: registered on_exit callback\n");
> + return 0;
> +}
> +
> diff --git a/contrib/plugins/qpp_client.h b/contrib/plugins/qpp_client.h
> new file mode 100644
> index 0000000000..573923f580
> --- /dev/null
> +++ b/contrib/plugins/qpp_client.h
> @@ -0,0 +1 @@
> +void my_on_exit(int, bool);
> diff --git a/contrib/plugins/qpp_srv.c b/contrib/plugins/qpp_srv.c
> new file mode 100644
> index 0000000000..61a6ab38ed
> --- /dev/null
> +++ b/contrib/plugins/qpp_srv.c
> @@ -0,0 +1,33 @@
> +#include <stdio.h>
> +#include <qemu-plugin.h>
> +#include <plugin-qpp.h>
> +#include <gmodule.h>
> +#include "qpp_srv.h"
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
QEMU_PLUGIN_EXPORT const char *qemu_plugin_name = "qpp_server";
> +
> +QPP_CREATE_CB(on_exit);
void *on_exit;
> +
> +static void plugin_exit(qemu_plugin_id_t id, void *p)
> +{
> + qemu_plugin_outs(CURRENT_PLUGIN "exit triggered, running all registered"
> + " QPP callbacks\n");
> + QPP_RUN_CB(on_exit, 0, true);
struct qpp_exit_event *info = g_new0(qpp_exit_event, 1);
info->x = 0;
info->b = true;
qemu_plugin_trigger_event(on_exit, info);
> +}
> +
> +QEMU_PLUGIN_EXPORT int do_add(int x)
QEMU_PLUGIN_EXPORT int qpp_srv_do_add(int x)
> +{
> + return x + 1;
> +}
> +
> +QEMU_PLUGIN_EXPORT int do_sub(int x)
QEMU_PLUGIN_EXPORT int qpp_srv_do_sub(int x)
> +{
> + return x - 1;
> +}
> +
> +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
> + const qemu_info_t *info, int argc, char **argv) {
> + qemu_plugin_outs("qpp_srv loaded\n");
> + qemu_plugin_register_atexit_cb(id, plugin_exit, NULL);
> + return 0;
> +}
> diff --git a/contrib/plugins/qpp_srv.h b/contrib/plugins/qpp_srv.h
> new file mode 100644
> index 0000000000..ceb26e3d2c
> --- /dev/null
> +++ b/contrib/plugins/qpp_srv.h
> @@ -0,0 +1,17 @@
> +#ifndef QPP_SRV_H
> +#define QPP_SRV_H
> +
> +/*
> + * Prototype for the on_exit callback: callback functions should be
> + * of type `void f(int, bool)`
> + */
> +QPP_CB_PROTOTYPE(void, on_exit, int, bool);
can be dropped.
> +
> +/*
> + * Prototypes for the do_add and do_sub functions. Both return an int and
> + * take an int as an argument.
> + */
> +QPP_FUN_PROTOTYPE(qpp_srv, int, do_add, int);
> +QPP_FUN_PROTOTYPE(qpp_srv, int, do_sub, int);
int qpp_srv_do_add(int);
int qpp_srv_do_sub(int);
the linking is dealt with by loader.
> +
> +#endif /* QPP_SRV_H */
--
Alex Bennée