Good point. Here's an incremental that switches to a pre-allocated array of 50
elements.
---
lib/timeval.c | 44 +++++++++++++++++++++++++-------------------
1 file changed, 25 insertions(+), 19 deletions(-)
diff --git a/lib/timeval.c b/lib/timeval.c
index 345c9ae..4763f47 100644
--- a/lib/timeval.c
+++ b/lib/timeval.c
@@ -32,7 +32,6 @@
#include "dummy.h"
#include "dynamic-string.h"
#include "fatal-signal.h"
-#include "list.h"
#include "signals.h"
#include "unixctl.h"
#include "util.h"
@@ -70,16 +69,16 @@ static bool time_stopped; /* Disables real-time
updates, if true. */
/* Time in milliseconds at which to die with SIGALRM (if not LLONG_MAX). */
static long long int deadline = LLONG_MAX;
-static struct unixctl_conn *backtrace_conn = NULL;
-static struct list traces = LIST_INITIALIZER(&traces);
-static size_t n_traces OVS_UNUSED = 0;
-
struct trace {
- struct list node; /* In 'traces' list. */
void *backtrace[32]; /* Populated by backtrace(). */
size_t n_frames; /* Number of frames in 'backtrace'. */
};
+#define MAX_TRACES 50
+static struct unixctl_conn *backtrace_conn = NULL;
+static struct trace *traces = NULL;
+static size_t n_traces = 0;
+
static void set_up_timer(void);
static void set_up_signal(int flags);
static void sigalrm_handler(int);
@@ -397,11 +396,8 @@ sigalrm_handler(int sig_nr OVS_UNUSED)
monotonic_tick = true;
#if HAVE_EXECINFO_H
- if (backtrace_conn) {
- struct trace *trace = xmalloc(sizeof *trace);
-
- n_traces++;
- list_push_back(&traces, &trace->node);
+ if (backtrace_conn && n_traces < MAX_TRACES) {
+ struct trace *trace = &traces[n_traces++];
trace->n_frames = backtrace(trace->backtrace,
ARRAY_SIZE(trace->backtrace));
}
@@ -612,30 +608,30 @@ static void
trace_run(void)
{
#if HAVE_EXECINFO_H
- if (backtrace_conn && n_traces >= 50) {
+ if (backtrace_conn && n_traces >= MAX_TRACES) {
struct ds ds = DS_EMPTY_INITIALIZER;
- struct trace *trace, *next;
size_t i;
- i = 1;
- LIST_FOR_EACH_SAFE (trace, next, node, &traces) {
+ for (i = 0; i < n_traces; i++) {
+ struct trace *trace = &traces[i];
char **frame_strs;
size_t j;
frame_strs = backtrace_symbols(trace->backtrace, trace->n_frames);
- ds_put_format(&ds, "Backtrace %zu\n", i);
+ ds_put_format(&ds, "Backtrace %zu\n", i + 1);
for (j = 0; j < trace->n_frames; j++) {
ds_put_format(&ds, "%s\n", frame_strs[j]);
}
ds_put_cstr(&ds, "\n");
free(frame_strs);
- list_remove(&trace->node);
- free(trace);
- i++;
}
+
+ free(traces);
+ traces = NULL;
n_traces = 0;
+
unixctl_command_reply(backtrace_conn, ds_cstr(&ds));
backtrace_conn = NULL;
}
@@ -686,6 +682,16 @@ backtrace_cb(struct unixctl_conn *conn,
void *aux OVS_UNUSED)
{
assert(HAVE_EXECINFO_H && CACHE_TIME);
+
+ if (backtrace_conn) {
+ unixctl_command_reply_error(conn, "In Use");
+ return;
+ }
+
+ assert(!traces);
+ traces = xmalloc(MAX_TRACES * sizeof *traces);
+ n_traces = 0;
+
backtrace_conn = conn;
}
--
1.7.12
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev