blob: 10e5f1b4c143a5ffbe2605d84ee697521930af14 [file] [log] [blame]
/* SPDX-License-Identifier: LGPL-2.1 */
/*
* Copyright (C) 2016 Red Hat Inc, Steven Rostedt <srostedt@redhat.com>
*/
/**
* @file libkshark-plugin.h
* @brief KernelShark plugins.
*/
#ifndef _KSHARK_PLUGIN_H
#define _KSHARK_PLUGIN_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
// C
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
/* Quiet warnings over documenting simple structures */
//! @cond Doxygen_Suppress
#define __hidden __attribute__((visibility ("hidden")))
#define _MAKE_STR(x) #x
#define MAKE_STR(x) _MAKE_STR(x)
#define KSHARK_PLOT_PLUGIN_INITIALIZER kshark_data_plugin_initializer
#define KSHARK_PLOT_PLUGIN_DEINITIALIZER kshark_data_plugin_deinitializer
#define KSHARK_PLOT_PLUGIN_INITIALIZER_NAME MAKE_STR(KSHARK_PLOT_PLUGIN_INITIALIZER)
#define KSHARK_PLOT_PLUGIN_DEINITIALIZER_NAME MAKE_STR(KSHARK_PLOT_PLUGIN_DEINITIALIZER)
#define KSHARK_MENU_PLUGIN_INITIALIZER kshark_plugin_menu_initializer
#define KSHARK_MENU_PLUGIN_INITIALIZER_NAME MAKE_STR(KSHARK_MENU_PLUGIN_INITIALIZER)
#define KSHARK_INPUT_INITIALIZER kshark_input_initializer
#define KSHARK_INPUT_DEINITIALIZER kshark_input_deinitializer
#define KSHARK_INPUT_CHECK kshark_input_check
#define KSHARK_INPUT_FORMAT kshark_input_format
#define KSHARK_INPUT_INITIALIZER_NAME MAKE_STR(KSHARK_INPUT_INITIALIZER)
#define KSHARK_INPUT_DEINITIALIZER_NAME MAKE_STR(KSHARK_INPUT_DEINITIALIZER)
#define KSHARK_INPUT_CHECK_NAME MAKE_STR(KSHARK_INPUT_CHECK)
#define KSHARK_INPUT_FORMAT_NAME MAKE_STR(KSHARK_INPUT_FORMAT)
struct kshark_data_stream;
struct kshark_context;
struct kshark_entry;
//! @endcond
struct kshark_trace_histo;
/**
* Structure representing the C arguments of the drawing function of
* a plugin.
*/
struct kshark_cpp_argv {
/** Pointer to the model descriptor object. */
struct kshark_trace_histo *histo;
};
/** A function type to be used when defining plugin functions for drawing. */
typedef void (*kshark_plugin_draw_handler_func)(struct kshark_cpp_argv *argv,
int sd,
int val,
int draw_action);
/**
* A function type to be used when defining plugin functions for data
* manipulation.
*/
typedef void (*kshark_plugin_event_handler_func)(struct kshark_data_stream *stream,
void *rec, struct kshark_entry *e);
/** Plugin action identifier. */
enum kshark_plugin_actions {
/**
* Load plugins action. This action identifier is used when handling
* plugins.
*/
KSHARK_PLUGIN_INIT,
/**
* Reload plugins action. This action identifier is used when handling
* plugins.
*/
KSHARK_PLUGIN_UPDATE,
/**
* Unload plugins action. This action identifier is used when handling
* plugins.
*/
KSHARK_PLUGIN_CLOSE,
};
/** Plotting action identifier. */
enum kshark_plotting_actions {
/**
* Task draw action. This action identifier is used by the plugin draw
* function.
*/
KSHARK_TASK_DRAW = 1 << 0,
/**
* CPU draw action. This action identifier is used by the plugin draw
* function.
*/
KSHARK_CPU_DRAW = 1 << 1,
/**
* Draw action for the Host graph in Virtual Combos. This action
* identifier is used by the plugin draw function.
*/
KSHARK_HOST_DRAW = 1 << 2,
/**
* Draw action for the Guest graph in Virtual Combos. This action
* identifier is used by the plugin draw function.
*/
KSHARK_GUEST_DRAW = 1 << 3,
};
/** Plugin's Trace event processing handler structure. */
struct kshark_event_proc_handler {
/** Pointer to the next Plugin Event handler. */
struct kshark_event_proc_handler *next;
/**
* Event action function. This action can be used to modify the content
* of all kshark_entries having Event Ids equal to "id".
*/
kshark_plugin_event_handler_func event_func;
/** Unique Id ot the trace event type. */
int id;
};
struct kshark_event_proc_handler *
kshark_find_event_handler(struct kshark_event_proc_handler *handlers, int event_id);
int kshark_register_event_handler(struct kshark_data_stream *stream,
int event_id,
kshark_plugin_event_handler_func evt_func);
int kshark_unregister_event_handler(struct kshark_data_stream *stream,
int event_id,
kshark_plugin_event_handler_func evt_func);
void kshark_free_event_handler_list(struct kshark_event_proc_handler *handlers);
/** Plugin's drawing handler structure. */
struct kshark_draw_handler {
/** Pointer to the next Plugin Event handler. */
struct kshark_draw_handler *next;
/**
* Draw action function. This action can be used to draw additional
* graphical elements (shapes) for all kshark_entries having Event Ids
* equal to "id".
*/
kshark_plugin_draw_handler_func draw_func;
};
int kshark_register_draw_handler(struct kshark_data_stream *stream,
kshark_plugin_draw_handler_func draw_func);
void kshark_unregister_draw_handler(struct kshark_data_stream *stream,
kshark_plugin_draw_handler_func draw_func);
void kshark_free_draw_handler_list(struct kshark_draw_handler *handlers);
/**
* A function type to be used when defining load/reload/unload plugin
* functions.
*/
typedef int (*kshark_plugin_load_func)(struct kshark_data_stream *);
/**
* A function type to be used when defining data check function for the plugin.
*/
typedef bool (*kshark_check_data_func)(const char *file_name);
/**
* A function type to be used when defining data format function for the plugin.
*/
typedef const char *(*kshark_format_func) ();
/**
* A function type to be used when defining plugin's configuration/control
* function.
*/
typedef void *(*kshark_plugin_ctrl_func)(void *);
/** The limit in size of the data format identifier string. */
#define KS_DATA_FORMAT_SIZE 15
/** Plugable Data Readout Interface (dri). */
struct kshark_dri {
/** A short name for this data input. */
char *name;
/** Data format identifier. */
char data_format[KS_DATA_FORMAT_SIZE];
/** Callback function for initialization of the data input. */
kshark_plugin_load_func init;
/** Callback function for deinitialization of the data input. */
kshark_plugin_load_func close;
/**
* Callback function for checking if the data input is applicable for
* a given data file.
*/
kshark_check_data_func check_data;
};
/** Linked list of Data Readout Interfaces (dri). */
struct kshark_dri_list {
/** Pointer to the next input interface. */
struct kshark_dri_list *next;
/** Pointer to the interface of methods used by the input. */
struct kshark_dri *interface;
};
/** Plugable Data Processing Interface (dpi). */
struct kshark_dpi {
/** The plugin's short name. */
char *name;
/** Callback function for initialization of the plugin. */
kshark_plugin_load_func init;
/** Callback function for deinitialization of the plugin. */
kshark_plugin_load_func close;
};
/** Linked list of data processing interfaces (dpi). */
struct kshark_dpi_list {
/** Pointer to the next plugin interface. */
struct kshark_dpi_list *next;
/** Pointer to the interface of methods used by the plugin. */
struct kshark_dpi *interface;
/**
* The status of the interface.
*/
int status;
};
struct kshark_dri_list *
kshark_register_input(struct kshark_context *kshark_ctx,
struct kshark_dri *plugin);
void kshark_unregister_input(struct kshark_context *kshark_ctx,
const char *file);
void kshark_free_dri_list(struct kshark_dri_list *inputs);
/** Linked list of plugins. */
struct kshark_plugin_list {
/** Pointer to the next plugin. */
struct kshark_plugin_list *next;
/** The plugin's short name. */
char *name;
/** The plugin object file to load. */
char *file;
/** Plugin's object file handler. */
void *handle;
/**
* Control interface of the plugin. Can be used to configure
* the plugin.
*/
kshark_plugin_ctrl_func ctrl_interface;
/** The interface of methods used by a data processing plugin. */
struct kshark_dpi *process_interface;
/** The interface of methods used by a data readout plugin. */
struct kshark_dri *readout_interface;
};
/** Plugin status identifiers. */
enum kshark_plugin_status {
/** The plugin is enabled. */
KSHARK_PLUGIN_ENABLED = 1 << 0,
/** The plugin is successfully loaded. */
KSHARK_PLUGIN_LOADED = 1 << 1,
/** The plugin failed to initialization. */
KSHARK_PLUGIN_FAILED = 1 << 2,
};
struct kshark_plugin_list *
kshark_register_plugin(struct kshark_context *kshark_ctx,
const char *name,
const char *file);
void kshark_unregister_plugin(struct kshark_context *kshark_ctx,
const char *name,
const char *file);
void kshark_free_plugin_list(struct kshark_plugin_list *plugins);
void kshark_free_dpi_list(struct kshark_dpi_list *plugins);
struct kshark_plugin_list *
kshark_find_plugin(struct kshark_plugin_list *plugins, const char *file);
struct kshark_plugin_list *
kshark_find_plugin_by_name(struct kshark_plugin_list *plugins,
const char *name);
struct kshark_dpi_list *
kshark_register_plugin_to_stream(struct kshark_data_stream *stream,
struct kshark_dpi *plugin,
bool active);
void kshark_unregister_plugin_from_stream(struct kshark_data_stream *stream,
struct kshark_dpi *plugin);
int kshark_handle_dpi(struct kshark_data_stream *stream,
struct kshark_dpi_list *plugin,
enum kshark_plugin_actions task_id);
int kshark_handle_all_dpis(struct kshark_data_stream *stream,
enum kshark_plugin_actions task_id);
/** General purpose macro for resizing dynamic arrays. */
#define KS_DOUBLE_SIZE(array, size) \
({ \
ssize_t __n = size; \
bool __ok = false; \
__typeof__(array) __tmp = \
(__typeof__(array)) realloc(array, \
2 * __n * sizeof(*__tmp)); \
if (__tmp) { \
memset(__tmp + __n, 0, __n * sizeof(*__tmp)); \
size = 2 * __n; \
array = __tmp; \
__ok = true; \
} \
__ok; \
}) \
/** Identifier used to free the plugin context. */
#define KS_PLUGIN_CONTEXT_FREE -1
/**
* General purpose macro defining methods for adding plugin context.
* Do not use this macro in header files.
*/
#define KS_DEFINE_PLUGIN_CONTEXT(type, type_free) \
static type **__context_handler; \
static ssize_t __n_streams = -1; \
__hidden type *__init(int sd) \
{ \
type *obj; \
if (__n_streams < 0 && sd < KS_DEFAULT_NUM_STREAMS) { \
__context_handler = \
(type **) calloc(KS_DEFAULT_NUM_STREAMS, \
sizeof(*__context_handler)); \
if (!__context_handler) \
return NULL; \
__n_streams = KS_DEFAULT_NUM_STREAMS; \
} else if (sd >= __n_streams) { \
if (!KS_DOUBLE_SIZE(__context_handler, \
__n_streams)) \
return NULL; \
} \
assert(__context_handler[sd] == NULL); \
obj = (type *) calloc(1, sizeof(*obj)); \
__context_handler[sd] = obj; \
return obj; \
} \
__hidden type *__get_context(int sd) \
{ \
if (sd < 0 || sd >= __n_streams) \
return NULL; \
return __context_handler[sd]; \
} \
__hidden void __close(int sd) \
{ \
type *obj; \
if (sd == KS_PLUGIN_CONTEXT_FREE) { \
free(__context_handler); \
__n_streams = -1; \
return; \
} \
obj = __get_context(sd); \
if (obj) { \
type_free(__context_handler[sd]); \
__context_handler[sd] = NULL; \
} \
} \
/**
* General purpose macro declaring the methods for adding plugin context.
* To be used in header files.
*/
#define KS_DECLARE_PLUGIN_CONTEXT_METHODS(type) \
type *__init(int sd); \
void __close(int sd); \
type *__get_context(int sd); \
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // _KSHARK_PLUGIN_H