summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-10-18 09:53:55 +0200
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-11-24 21:20:24 +0100
commite2052e8c5f9fa4dc50bdcf33ff96c6bcc71ca59e (patch)
treeeaef188a016195a3034e5ed84b74b4090383c554
parent0a25b9e2b934f07cfc820efc820187f77cb98875 (diff)
downloadlatrace-e2052e8c5f9fa4dc50bdcf33ff96c6bcc71ca59e.tar.gz
latrace-e2052e8c5f9fa4dc50bdcf33ff96c6bcc71ca59e.tar.xz
latrace-e2052e8c5f9fa4dc50bdcf33ff96c6bcc71ca59e.zip
fifo,run: Add support for multiple processing functions
Adding lt_process_register to register processing function callback in latrace tracer. The callback receives all the data from the tracee FIFOs.
-rw-r--r--src/config.c2
-rw-r--r--src/config.h14
-rw-r--r--src/run.c52
3 files changed, 60 insertions, 8 deletions
diff --git a/src/config.c b/src/config.c
index a7f588f..9fea08b 100644
--- a/src/config.c
+++ b/src/config.c
@@ -440,6 +440,8 @@ int lt_config(struct lt_config_app *cfg, int argc, char **argv)
cfg->fstat = stdout;
cfg->output_tty_fd = -1;
+ lt_init_list_head(&cfg->process_funcs);
+
/* read the default config file first */
if (read_config(cfg, LT_CONF_DIR "/latrace.conf")) {
printf("failed: read config file '" LT_CONF_DIR "/latrace.conf'\n");
diff --git a/src/config.h b/src/config.h
index e05e8c6..4ab0886 100644
--- a/src/config.h
+++ b/src/config.h
@@ -185,6 +185,8 @@ struct lt_config_app {
int notify_fd;
int notify_fd_watch;
+
+ struct lt_list_head process_funcs;
};
struct lt_config_ctl {
@@ -331,6 +333,15 @@ struct lt_symbol {
void *ptr;
};
+typedef int (*lt_process_cb)(struct lt_config_app *cfg,
+ struct lt_thread *t,
+ struct lt_fifo_mbase *mbase);
+
+struct lt_process_func {
+ lt_process_cb cb;
+ struct lt_list_head list;
+};
+
/* ctl */
int main_ctl(int argc, char **argv);
@@ -404,6 +415,9 @@ int tty_restore(struct lt_config_app *cfg);
int tty_process(struct lt_config_app *cfg, int master);
void tty_close(struct lt_config_app *cfg);
+/* process functions registration */
+int lt_process_register(struct lt_config_app *cfg, lt_process_cb cb);
+
#define PRINT(fmt, args...) \
do { \
char lpbuf[1024]; \
diff --git a/src/run.c b/src/run.c
index 41935d8..2c2318c 100644
--- a/src/run.c
+++ b/src/run.c
@@ -105,15 +105,12 @@ static int get_fifo(struct lt_config_app *cfg, int fd_notify,
return lt_fifo_open(cfg->sh, dir, event->name);
}
-static int process_fifo(struct lt_config_app *cfg, struct lt_thread *t)
+static int process_fifo_cb(struct lt_config_app *cfg,
+ struct lt_thread *t,
+ struct lt_fifo_mbase *mbase)
{
- static char buf[LT_FIFO_MSG_MAXLEN];
- struct lt_fifo_mbase *mbase = (struct lt_fifo_mbase*) buf;
- struct lt_fifo_msym *msym = (struct lt_fifo_msym*) buf;
- struct lt_fifo_mtext *mtext = (struct lt_fifo_mtext*) buf;
-
- if (-1 == lt_fifo_recv(cfg->sh, t, mbase, LT_FIFO_MSG_MAXLEN))
- return -1;
+ struct lt_fifo_msym *msym = (struct lt_fifo_msym*) mbase;
+ struct lt_fifo_mtext *mtext = (struct lt_fifo_mtext*) mbase;
if (lt_sh(cfg, counts)) {
/* should not happen, but anyway.. */
@@ -157,6 +154,28 @@ static int process_fifo(struct lt_config_app *cfg, struct lt_thread *t)
return 0;
}
+static int process_fifo(struct lt_config_app *cfg, struct lt_thread *t)
+{
+ struct lt_process_func *func;
+ static char buf[LT_FIFO_MSG_MAXLEN];
+ struct lt_fifo_mbase *mbase = (struct lt_fifo_mbase*) buf;
+
+ if (-1 == lt_fifo_recv(cfg->sh, t, mbase, LT_FIFO_MSG_MAXLEN))
+ return -1;
+
+ lt_list_for_each_entry(func, &cfg->process_funcs, list) {
+ int ret;
+
+ BUG_ON(!func->cb);
+
+ ret = func->cb(cfg, t, mbase);
+ if (ret)
+ return ret;
+ }
+
+ return 0;
+}
+
static void cleanup_threads(struct lt_config_app *cfg)
{
struct lt_thread *t = cfg->threads;
@@ -191,6 +210,10 @@ static int process(struct lt_config_app *cfg, struct lt_process_args *pa)
PRINT_VERBOSE(cfg, 1, "doing pipe\n");
FD_SET(fd_notify, &cfg_set);
max_fd = fd_notify;
+
+ /* default fifo processing callback */
+ if (lt_process_register(cfg, process_fifo_cb))
+ return -1;
}
if (cfg->output_tty) {
@@ -502,3 +525,16 @@ int lt_run(struct lt_config_app *cfg)
run_cleanup(cfg, &pa);
return ret;
}
+
+int lt_process_register(struct lt_config_app *cfg, lt_process_cb cb)
+{
+ struct lt_process_func *func;
+
+ func = malloc(sizeof(*func));
+ if (!func)
+ return -ENOMEM;
+
+ lt_list_add_tail(&func->list, &cfg->process_funcs);
+ func->cb = cb;
+ return 0;
+}