Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : */
3 : :
4 : : #include "spdk/stdinc.h"
5 : :
6 : : #include "spdk/env.h"
7 : : #include "spdk/event.h"
8 : : #include "spdk/string.h"
9 : : #include "spdk/thread.h"
10 : : #include "spdk/util.h"
11 : :
12 : : #define MAX_NUM_POLLERS 1000
13 : :
14 : : static int g_time_in_sec;
15 : : static int g_period_in_usec;
16 : : static int g_num_pollers;
17 : :
18 : : static struct spdk_poller *g_timer;
19 : : static struct spdk_poller *g_pollers[MAX_NUM_POLLERS];
20 : : static uint64_t g_run_count;
21 : :
22 : : static struct spdk_thread_stats g_start_stats;
23 : :
24 : : static int
25 : 164997000 : poller_run(void *arg)
26 : : {
27 : 164997000 : g_run_count++;
28 : :
29 : 164997000 : return SPDK_POLLER_BUSY;
30 : : }
31 : :
32 : : static void
33 : 42 : _poller_perf_end(void)
34 : : {
35 : 20 : struct spdk_thread_stats end_stats;
36 : : uint64_t tsc_hz, busy_cyc, poller_cost_cyc, poller_cost_nsec;
37 : : int i;
38 : :
39 : 42 : spdk_thread_get_stats(&end_stats);
40 : 42 : busy_cyc = end_stats.busy_tsc - g_start_stats.busy_tsc;
41 : :
42 : 42 : tsc_hz = spdk_get_ticks_hz();
43 : :
44 [ - + ]: 42 : printf("\r ======================================\n");
45 : :
46 [ - + ]: 42 : printf("\r busy:%" PRIu64 " (cyc)\n", busy_cyc);
47 [ - + ]: 42 : printf("\r total_run_count: %" PRIu64 "\n", g_run_count);
48 [ - + ]: 42 : printf("\r tsc_hz: %" PRIu64 " (cyc)\n", tsc_hz);
49 : :
50 [ - + ]: 42 : printf("\r ======================================\n");
51 : :
52 [ - + ]: 42 : poller_cost_cyc = busy_cyc / g_run_count;
53 [ - + ]: 42 : poller_cost_nsec = (poller_cost_cyc * SPDK_SEC_TO_NSEC) / tsc_hz;
54 : :
55 [ - + ]: 42 : printf("\r poller_cost: %" PRIu64 " (cyc), %" PRIu64 " (nsec)\n",
56 : : poller_cost_cyc, poller_cost_nsec);
57 : :
58 : 42 : spdk_poller_unregister(&g_timer);
59 : :
60 [ + + ]: 42042 : for (i = 0; i < g_num_pollers; i++) {
61 : 42000 : spdk_poller_unregister(&g_pollers[i]);
62 : : }
63 : :
64 : 42 : spdk_app_stop(0);
65 : 42 : }
66 : :
67 : : static int
68 : 42 : poller_perf_end(void *arg)
69 : : {
70 : 42 : _poller_perf_end();
71 : :
72 : 42 : return SPDK_POLLER_BUSY;
73 : : }
74 : :
75 : : static void
76 : 42 : poller_perf_start(void *arg1)
77 : : {
78 : : int i;
79 : :
80 [ - + ]: 42 : printf("Running %d pollers for %d seconds with %d microseconds period.\n",
81 : : g_num_pollers, g_time_in_sec, g_period_in_usec);
82 : 42 : fflush(stdout);
83 : :
84 [ + + ]: 42042 : for (i = 0; i < g_num_pollers; i++) {
85 : 42000 : g_pollers[i] = SPDK_POLLER_REGISTER(poller_run, NULL, g_period_in_usec);
86 : : }
87 : :
88 : 42 : spdk_thread_get_stats(&g_start_stats);
89 : :
90 : 42 : g_timer = SPDK_POLLER_REGISTER(poller_perf_end, NULL, g_time_in_sec * SPDK_SEC_TO_USEC);
91 : 42 : }
92 : :
93 : : static void
94 : 0 : poller_perf_shutdown_cb(void)
95 : : {
96 : 0 : _poller_perf_end();
97 : 0 : }
98 : :
99 : : static int
100 : 126 : poller_perf_parse_arg(int ch, char *arg)
101 : : {
102 : : int tmp;
103 : :
104 : 126 : tmp = spdk_strtol(optarg, 10);
105 [ - + ]: 126 : if (tmp < 0) {
106 [ # # # # ]: 0 : fprintf(stderr, "Parse failed for the option %c.\n", ch);
107 : 0 : return tmp;
108 : : }
109 : :
110 [ + + + - ]: 126 : switch (ch) {
111 : 42 : case 'b':
112 : 42 : g_num_pollers = tmp;
113 : 42 : break;
114 : 42 : case 'l':
115 : 42 : g_period_in_usec = tmp;
116 : 42 : break;
117 : 42 : case 't':
118 : 42 : g_time_in_sec = tmp;
119 : 42 : break;
120 : 0 : default:
121 : 0 : return -EINVAL;
122 : : }
123 : :
124 : 126 : return 0;
125 : : }
126 : :
127 : : static void
128 : 0 : poller_perf_usage(void)
129 : : {
130 [ # # ]: 0 : printf(" -b <number> number of pollers\n");
131 [ # # ]: 0 : printf(" -l <period> poller period in usec\n");
132 [ # # ]: 0 : printf(" -t <time> run time in seconds\n");
133 : 0 : }
134 : :
135 : : static int
136 : 42 : poller_perf_verify_params(void)
137 : : {
138 [ + - - + ]: 42 : if (g_num_pollers <= 0 || g_num_pollers > MAX_NUM_POLLERS) {
139 [ # # # # ]: 0 : fprintf(stderr, "number of pollers must not be more than %d\n", MAX_NUM_POLLERS);
140 : 0 : return -EINVAL;
141 : : }
142 : :
143 [ - + ]: 42 : if (g_period_in_usec < 0) {
144 [ # # # # ]: 0 : fprintf(stderr, "period of poller cannot be negative\n");
145 : 0 : return -EINVAL;
146 : : }
147 : :
148 [ - + ]: 42 : if (g_time_in_sec <= 0) {
149 [ # # # # ]: 0 : fprintf(stderr, "run time must be positive\n");
150 : 0 : return -EINVAL;
151 : : }
152 : :
153 : 42 : return 0;
154 : : }
155 : :
156 : : int
157 : 42 : main(int argc, char **argv)
158 : : {
159 : 20 : struct spdk_app_opts opts;
160 : : int rc;
161 : :
162 : 42 : spdk_app_opts_init(&opts, sizeof(opts));
163 : 42 : opts.name = "poller_perf";
164 : 42 : opts.shutdown_cb = poller_perf_shutdown_cb;
165 : 42 : opts.rpc_addr = NULL;
166 : :
167 : 42 : rc = spdk_app_parse_args(argc, argv, &opts, "b:l:t:", NULL,
168 : : poller_perf_parse_arg, poller_perf_usage);
169 [ - + ]: 42 : if (rc != SPDK_APP_PARSE_ARGS_SUCCESS) {
170 : 0 : return rc;
171 : : }
172 : :
173 : 42 : rc = poller_perf_verify_params();
174 [ - + ]: 42 : if (rc != 0) {
175 : 0 : return rc;
176 : : }
177 : :
178 : 42 : rc = spdk_app_start(&opts, poller_perf_start, NULL);
179 : :
180 : 42 : spdk_app_fini();
181 : :
182 : 42 : return rc;
183 : : }
|