]> git.proxmox.com Git - mirror_frr.git/blame - sharpd/sharp_logpump.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / sharpd / sharp_logpump.c
CommitLineData
acddc0ed 1// SPDX-License-Identifier: GPL-2.0-or-later
aef4a13f
DL
2/*
3 * testing log message generator
4 * Copyright (C) 2019-2020 David Lamparter for NetDEF, Inc.
aef4a13f
DL
5 */
6
7#include <zebra.h>
8
9#include "vty.h"
10#include "command.h"
11#include "prefix.h"
12#include "nexthop.h"
13#include "log.h"
24a58196 14#include "frrevent.h"
aef4a13f
DL
15#include "vrf.h"
16#include "zclient.h"
17#include "frr_pthread.h"
18
19#include "sharpd/sharp_vty.h"
20
21/* this is quite hacky, but then again it's a test tool and it does its job. */
22static struct frr_pthread *lpt;
23
24static unsigned long lp_duration;
25static unsigned lp_frequency;
26static unsigned lp_burst;
27static size_t lp_ctr, lp_expect;
28static struct rusage lp_rusage;
29static struct vty *lp_vty;
30
cd9d0537 31extern struct event_loop *master;
aef4a13f 32
e6685141 33static void logpump_done(struct event *thread)
aef4a13f
DL
34{
35 double x;
36
37 vty_out(lp_vty, "\nlogpump done\n");
38 vty_out(lp_vty, "%9zu messages written\n", lp_ctr);
39 x = (double)lp_ctr / (double)lp_expect * 100.;
40 vty_out(lp_vty, "%9zu messages targeted = %5.1lf%%\n", lp_expect, x);
41
42 x = lp_rusage.ru_utime.tv_sec * 1000000 + lp_rusage.ru_utime.tv_usec;
43 x /= (double)lp_ctr;
44 vty_out(lp_vty, "%6llu.%06u usr %9.1lfns/msg\n",
45 (unsigned long long)lp_rusage.ru_utime.tv_sec,
46 (unsigned)lp_rusage.ru_utime.tv_usec, x * 1000.);
47
48 x = lp_rusage.ru_stime.tv_sec * 1000000 + lp_rusage.ru_stime.tv_usec;
49 x /= (double)lp_ctr;
50 vty_out(lp_vty, "%6llu.%06u sys %9.1lfns/msg\n",
51 (unsigned long long)lp_rusage.ru_stime.tv_sec,
52 (unsigned)lp_rusage.ru_stime.tv_usec, x * 1000.);
53
54 frr_pthread_stop(lpt, NULL);
55 frr_pthread_destroy(lpt);
56 lpt = NULL;
aef4a13f
DL
57}
58
59static void *logpump_run(void *arg)
60{
61 struct timespec start, next, now;
62 unsigned long delta, period;
63
64 period = 1000000000L / lp_frequency;
65
0bdeb5e5
DL
66 zlog_tls_buffer_init();
67
aef4a13f
DL
68 clock_gettime(CLOCK_MONOTONIC, &start);
69 next = start;
70 do {
71 for (size_t inburst = 0; inburst < lp_burst; inburst++)
72 zlog_debug("log pump: %zu (burst %zu)",
73 lp_ctr++, inburst);
74
75 clock_gettime(CLOCK_MONOTONIC, &now);
76 delta = (now.tv_sec - start.tv_sec) * 1000000000L
77 + (now.tv_nsec - start.tv_nsec);
78
79 next.tv_nsec += period;
80 if (next.tv_nsec > 1000000000L) {
81 next.tv_sec++;
82 next.tv_nsec -= 1000000000L;
83 }
84#ifdef HAVE_CLOCK_NANOSLEEP
85 clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL);
86#else
87 struct timespec slpdur;
88
89 slpdur.tv_sec = next.tv_sec - now.tv_sec;
90 slpdur.tv_nsec = next.tv_nsec - now.tv_nsec;
91 if (slpdur.tv_nsec < 0) {
92 slpdur.tv_sec--;
93 slpdur.tv_nsec += 1000000000L;
94 }
95
96 nanosleep(&slpdur, NULL);
97#endif
98 } while (delta < lp_duration);
99
0bdeb5e5
DL
100 zlog_tls_buffer_fini();
101
aef4a13f
DL
102#ifdef RUSAGE_THREAD
103 getrusage(RUSAGE_THREAD, &lp_rusage);
104#else
105 getrusage(RUSAGE_SELF, &lp_rusage);
106#endif
107
907a2395 108 event_add_timer_msec(master, logpump_done, NULL, 0, NULL);
aef4a13f
DL
109 return NULL;
110}
111
112static int logpump_halt(struct frr_pthread *fpt, void **res)
113{
114 return 0;
115}
116
117/* default frr_pthread attributes */
118static const struct frr_pthread_attr attr = {
119 .start = logpump_run,
120 .stop = logpump_halt,
121};
122
123void sharp_logpump_run(struct vty *vty, unsigned duration, unsigned frequency,
124 unsigned burst)
125{
126 if (lpt != NULL) {
127 vty_out(vty, "logpump already running\n");
128 return;
129 }
130
131 vty_out(vty, "starting logpump...\n");
132 vty_out(vty, "keep this VTY open and press Enter to see results\n");
133
134 lp_vty = vty;
135 lp_duration = duration * 1000000000UL;
136 lp_frequency = frequency;
137 lp_burst = burst;
138 lp_expect = duration * frequency * burst;
139 lp_ctr = 0;
140
141 lpt = frr_pthread_new(&attr, "logpump", "logpump");
142 frr_pthread_run(lpt, NULL);
143}