Running local plugins

Besides letting DQCsim spawn plugin processes for you, you can also let DQCsim run a plugin within a thread, or assume full control over spawning the process or thread. To do this, you need to use a plugin thread configuration object (tcfg) instead of a plugin process configuration.

Running a plugin within a thread

This method is similar to spawning a plugin in a process. However, because there's no process boundary, the plugin is defined within the host process, and can access memory of the host process. This can be useful particularly when you want to make a self-contained simulation, or want to insert a simple operator plugin somewhere in the pipeline that you don't want to make a separate executable for. The configuration object for this scenario is constructed using the following function.

dqcs_tcfg_new()

Creates a new plugin thread configuration object from a plugin definition.

dqcs_handle_t dqcs_tcfg_new(
    dqcs_handle_t pdef,
    const char *name
)

The plugin definition handle is consumed by this function.

Assuming full control over plugin spawning

This method gives you full control over spawning a plugin process or thread. This is useful for instance if you want to encapsulate the plugin process in a tool like gdb or valgrind. The configuration object for this method is constructed using the following function.

dqcs_tcfg_new_raw()

Creates a new plugin thread configuration object from a callback.

dqcs_handle_t dqcs_tcfg_new_raw(
    dqcs_plugin_type_t plugin_type,
    const char *name,
    void (*callback)(
        void *user_data,
        const char *simulator
    ),
    void (*user_free)(void *user_data),
    void *user_data
)

The callback is called by DQCsim from a dedicated thread when DQCsim wants to start the plugin. The callback must then in some way spawn a plugin process that connects to the provided simulator string. The callback should return only when the process terminates.

Querying plugin thread configuration objects

Similar to plugin process configuration objects, the name and type of the plugin are immutable after construction, but can be queried.

dqcs_tcfg_type()

Returns the type of the given plugin thread configuration.

dqcs_plugin_type_t dqcs_tcfg_type(dqcs_handle_t tcfg)
dqcs_tcfg_name()

Returns the configured name for the given plugin thread.

char *dqcs_tcfg_name(dqcs_handle_t tcfg)

On success, this returns a newly allocated string containing the name. Free it with free() when you're done with it to avoid memory leaks. On failure (i.e., the handle is invalid) this returns NULL.

Functional configuration

Like plugin process configuration objects, it's possible to send ArbCmds to the plugin's initialization callback. However, environment variables and the working directory of the plugin cannot be set, since they're tied to the host process.

dqcs_tcfg_init_cmd()

Appends an ArbCmd to the list of initialization commands of a plugin thread.

dqcs_return_t dqcs_tcfg_init_cmd(
    dqcs_handle_t tcfg,
    dqcs_handle_t cmd
)

The ArbCmd handle is consumed by this function, and is thus invalidated, if and only if it is successful.

Logging configuration

The logging behavior for a plugin thread can be configured with the following functions, just like plugin processes. However, file descriptors are shared between threads, so the plugin thread does not have a separate stdout/stderr stream that can be captured.

dqcs_tcfg_verbosity_set()

Configures the logging verbosity for the given plugin thread.

dqcs_return_t dqcs_tcfg_verbosity_set(
    dqcs_handle_t tcfg,
    dqcs_loglevel_t level
)
dqcs_tcfg_verbosity_get()

Returns the configured verbosity for the given plugin thread.

dqcs_loglevel_t dqcs_tcfg_verbosity_get(dqcs_handle_t tcfg)
dqcs_tcfg_tee()

Configures a plugin thread to also output its log messages to a file.

dqcs_return_t dqcs_tcfg_tee(
    dqcs_handle_t tcfg,
    dqcs_loglevel_t verbosity,
    const char *filename
)

verbosity configures the verbosity level for the file only.