1 /*
2 * Copyright (c) 2009 Red Hat, Inc.
3 *
4 * All rights reserved.
5 *
6 * Author: Steven Dake (sdake@redhat.com)
7 *
8 * libqb is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 2.1 of the License, or
11 * (at your option) any later version.
12 *
13 * libqb is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with libqb. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <qb/qbipcc.h>
25 #include <stdio.h>
26 #include <stdint.h>
27 #include <string.h>
28 #include <sys/time.h>
29 #include <time.h>
30 #include <unistd.h>
31 #include <signal.h>
32
33 #include <qb/qbrb.h>
34 #include <qb/qbdefs.h>
35 #include <qb/qbutil.h>
36 #include <qb/qblog.h>
37
38 static int alarm_notice = 0;
39 static qb_ringbuffer_t *rb = NULL;
40 static qb_util_stopwatch_t *sw;
41 #define ONE_MEG 1048576
42 static char buffer[ONE_MEG * 3];
43
44 static void sigalrm_handler (int num)
45 {
46 alarm_notice = 1;
47 }
48
49 static void sigterm_handler(int32_t num)
50 {
51 qb_log(LOG_INFO, "writer: %s(%d)\n", __func__, num);
52 qb_rb_close(rb);
53 exit(0);
54 }
55
56 static void
57 _benchmark(ssize_t write_size)
58 {
59 ssize_t res;
60 int write_count = 0;
61 float secs;
62
63 alarm_notice = 0;
64
65 alarm (10);
66
67 qb_util_stopwatch_start(sw);
68 do {
69 res = qb_rb_chunk_write(rb, buffer, write_size);
|
(1) Event cond_false: |
Condition "res == write_size", taking false branch. |
70 if (res == write_size) {
71 write_count++;
|
(2) Event if_end: |
End of if statement. |
72 }
|
(3) Event cond_true: |
Condition "alarm_notice == 0", taking true branch. |
|
(4) Event cond_false: |
Condition "res == write_size", taking false branch. |
|
(5) Event cond_false: |
Condition "res == -11", taking false branch. |
73 } while (alarm_notice == 0 && (res == write_size || res == -EAGAIN));
|
(6) Event cond_true: |
Condition "res < 0", taking true branch. |
74 if (res < 0) {
75 perror("qb_ipcc_sendv");
76 }
77 qb_util_stopwatch_stop(sw);
|
(7) Event zero_return: |
Function call "qb_util_stopwatch_sec_elapsed_get(sw)" returns 0.0. [details] |
|
(8) Event assign: |
Assigning: "secs" = "qb_util_stopwatch_sec_elapsed_get(sw)". |
| Also see events: |
[divide_by_zero] |
78 secs = qb_util_stopwatch_sec_elapsed_get(sw);
79
80 printf ("%5d messages sent ", write_count);
81 printf ("%5ld bytes per write ", (long int) write_size);
82 printf ("%7.3f Seconds runtime ", secs);
83 printf ("%9.3f TP/s ",
84 ((float)write_count) / secs);
|
(9) Event divide_by_zero: |
In expression "(float)write_count * (float)write_size / secs", division by expression "secs" which may be zero results in either +infinity, -infinity, or NaN. |
| Also see events: |
[zero_return][assign] |
85 printf ("%7.3f MB/s.\n",
86 ((float)write_count) * ((float)write_size) / secs);
87 }
88
89
90 static void
91 do_throughput_benchmark(void)
92 {
93 ssize_t size = 64;
94 int i;
95
96 signal (SIGALRM, sigalrm_handler);
97 sw = qb_util_stopwatch_create();
98
99 for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */
100 _benchmark(size);
101 signal (SIGALRM, sigalrm_handler);
102 size *= 5;
103 if (size >= ONE_MEG) {
104 break;
105 }
106 }
107 }
108
109 static void show_usage(const char *name)
110 {
111 printf("usage: \n");
112 printf("%s <options>\n", name);
113 printf("\n");
114 printf(" options:\n");
115 printf("\n");
116 printf(" -n non-blocking ipc (default blocking)\n");
117 printf(" -v verbose\n");
118 printf(" -h show this help text\n");
119 printf("\n");
120 }
121
122 int32_t main(int32_t argc, char *argv[])
123 {
124 const char *options = "vh";
125 int32_t opt;
126 int32_t verbose = 0;
127
128 while ((opt = getopt(argc, argv, options)) != -1) {
129 switch (opt) {
130 case 'v':
131 verbose++;
132 break;
133 case 'h':
134 default:
135 show_usage(argv[0]);
136 exit(0);
137 break;
138 }
139 }
140
141 signal(SIGINT, sigterm_handler);
142
143 qb_log_init("rbwriter", LOG_USER, LOG_EMERG);
144 qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE);
145 qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
146 QB_LOG_FILTER_FILE, "*", LOG_INFO + verbose);
147 qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
148
149 rb = qb_rb_open("tester", ONE_MEG * 3,
150 QB_RB_FLAG_SHARED_PROCESS, 0);
151 do_throughput_benchmark();
152 qb_rb_close(rb);
153 qb_log_fini();
154 return EXIT_SUCCESS;
155 }
156