32 #ifdef ENABLE_PERFORMANCE_METRICS
39 static const char *metric_names[] = {
40 "PERF_BIO_READ_PLAINTEXT",
41 "PERF_BIO_WRITE_PLAINTEXT",
42 "PERF_BIO_READ_CIPHERTEXT",
43 "PERF_BIO_WRITE_CIPHERTEXT",
44 "PERF_TLS_MULTI_PROCESS",
47 "PERF_MULTI_CREATE_INSTANCE",
48 "PERF_MULTI_CLOSE_INSTANCE",
49 "PERF_MULTI_SHOW_STATS",
59 "PERF_PROC_OUT_TUN_MTCP"
65 #define PS_METER_RUNNING 1
66 #define PS_METER_INTERRUPTED 2
83 static struct perf_set perf_set;
85 static void perf_print_state(
int lev);
88 get_stack_index(
int sdelta)
90 const int sindex = perf_set.stack_len + sdelta;
91 if (sindex >= 0 && sindex < STACK_N)
102 get_perf_index(
int sdelta)
104 const int sindex = get_stack_index(sdelta);
107 const int pindex = perf_set.stack[sindex];
108 if (pindex >= 0 && pindex <
PERF_N)
126 const int pindex = get_perf_index(sdelta);
129 return &perf_set.perf[pindex];
138 push_perf_index(
int pindex)
140 const int sindex = get_stack_index(0);
141 const int newlen = get_stack_index(1);
142 if (sindex >= 0 && newlen >= 0
143 && pindex >= 0 && pindex <
PERF_N)
146 for (i = 0; i < sindex; ++i)
148 if (perf_set.stack[i] == pindex)
151 msg(
M_FATAL,
"PERF: push_perf_index %s failed",
152 metric_names [pindex]);
156 perf_set.stack[sindex] = pindex;
157 perf_set.stack_len = newlen;
161 msg(
M_FATAL,
"PERF: push_perf_index: stack push error");
168 const int newlen = get_stack_index(-1);
171 perf_set.stack_len = newlen;
175 msg(
M_FATAL,
"PERF: pop_perf_index: stack pop error");
180 state_must_be(
const struct perf *p,
const int wanted)
182 if (p->state != wanted)
184 msg(
M_FATAL,
"PERF: bad state actual=%d wanted=%d",
191 update_sofar(
struct perf *p)
193 struct timeval current;
194 ASSERT(!gettimeofday(¤t, NULL));
195 p->sofar += (double)
tv_subtract(¤t, &p->start, 600) / 1000000.0;
200 perf_start(
struct perf *p)
202 state_must_be(p, PS_INITIAL);
203 ASSERT(!gettimeofday(&p->start, NULL));
205 p->state = PS_METER_RUNNING;
209 perf_stop(
struct perf *p)
211 state_must_be(p, PS_METER_RUNNING);
214 if (p->sofar > p->max)
220 p->state = PS_INITIAL;
224 perf_interrupt(
struct perf *p)
226 state_must_be(p, PS_METER_RUNNING);
228 p->state = PS_METER_INTERRUPTED;
232 perf_resume(
struct perf *p)
234 state_must_be(p, PS_METER_INTERRUPTED);
235 ASSERT(!gettimeofday(&p->start, NULL));
236 p->state = PS_METER_RUNNING;
246 push_perf_index(type);
255 perf_interrupt(prev);
284 msg(
M_INFO,
"LATENCY PROFILE (mean and max are in milliseconds)");
285 for (i = 0; i <
PERF_N; ++i)
287 struct perf *p = &perf_set.perf[i];
290 const double mean = p->sum / p->count;
291 msg(
M_INFO,
"%s n=%.0f mean=%.3f max=%.3f", metric_names[i], p->count, mean*1000.0, p->max*1000.0);
297 perf_print_state(
int lev)
301 msg(lev,
"PERF STATE");
303 for (i = 0; i < perf_set.stack_len; ++i)
305 const int j = perf_set.stack[i];
306 const struct perf *p = &perf_set.perf[j];
307 msg(lev,
"[%d] %s state=%d start=%s sofar=%f sum=%f max=%f count=%f",