blob: 002bc8127c9259ed994e6f31229cb7fd85e315c0 [file] [log] [blame]
Benny Prijonoe93e2872006-06-28 16:46:49 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include "test.h"
20#include <pjsip.h>
21#include <pjlib.h>
22
23#define THIS_FILE "tsx_uas_test.c"
24
25
26static pjsip_module mod_tsx_user;
27
28static int uac_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
29{
30 unsigned i;
31 pjsip_tx_data *request;
32 pjsip_transaction **tsx;
33 pj_timestamp t1, t2, elapsed;
Benny Prijono86b73d52006-07-22 12:47:40 +000034 pjsip_via_hdr *via;
Benny Prijonoe93e2872006-06-28 16:46:49 +000035 pj_status_t status;
36
37 /* Create the request first. */
38 pj_str_t str_target = pj_str("sip:someuser@someprovider.com");
39 pj_str_t str_from = pj_str("\"Local User\" <sip:localuser@serviceprovider.com>");
40 pj_str_t str_to = pj_str("\"Remote User\" <sip:remoteuser@serviceprovider.com>");
41 pj_str_t str_contact = str_from;
42
43 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
44 &str_target, &str_from, &str_to,
45 &str_contact, NULL, -1, NULL,
46 &request);
47 if (status != PJ_SUCCESS) {
48 app_perror(" error: unable to create request", status);
49 return status;
50 }
51
Benny Prijono86b73d52006-07-22 12:47:40 +000052 via = (pjsip_via_hdr*) pjsip_msg_find_hdr(request->msg, PJSIP_H_VIA,
53 NULL);
54
Benny Prijonoe93e2872006-06-28 16:46:49 +000055 /* Create transaction array */
56 tsx = pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*));
57
Benny Prijonoac623b32006-07-03 15:19:31 +000058 pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user));
Benny Prijonoe93e2872006-06-28 16:46:49 +000059 mod_tsx_user.id = -1;
60
61 /* Benchmark */
62 elapsed.u64 = 0;
63 pj_get_timestamp(&t1);
64 for (i=0; i<working_set; ++i) {
65 status = pjsip_tsx_create_uac(&mod_tsx_user, request, &tsx[i]);
66 if (status != PJ_SUCCESS)
67 goto on_error;
Benny Prijono86b73d52006-07-22 12:47:40 +000068 /* Reset branch param */
69 via->branch_param.slen = 0;
Benny Prijonoe93e2872006-06-28 16:46:49 +000070 }
71 pj_get_timestamp(&t2);
72 pj_sub_timestamp(&t2, &t1);
73 pj_add_timestamp(&elapsed, &t2);
74
75 p_elapsed->u64 = elapsed.u64;
76 status = PJ_SUCCESS;
77
78on_error:
79 for (i=0; i<working_set; ++i) {
80 if (tsx[i]) {
81 pjsip_tsx_terminate(tsx[i], 601);
82 tsx[i] = NULL;
83 }
84 }
85 pjsip_tx_data_dec_ref(request);
86 flush_events(2000);
87 return status;
88}
89
90
91
92static int uas_tsx_bench(unsigned working_set, pj_timestamp *p_elapsed)
93{
94 unsigned i;
95 pjsip_tx_data *request;
96 pjsip_via_hdr *via;
97 pjsip_rx_data rdata;
98 pj_sockaddr_in remote;
99 pjsip_transaction **tsx;
100 pj_timestamp t1, t2, elapsed;
101 char branch_buf[80] = PJSIP_RFC3261_BRANCH_ID "0000000000";
102 pj_status_t status;
103
104 /* Create the request first. */
105 pj_str_t str_target = pj_str("sip:someuser@someprovider.com");
106 pj_str_t str_from = pj_str("\"Local User\" <sip:localuser@serviceprovider.com>");
107 pj_str_t str_to = pj_str("\"Remote User\" <sip:remoteuser@serviceprovider.com>");
108 pj_str_t str_contact = str_from;
109
110 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
111 &str_target, &str_from, &str_to,
112 &str_contact, NULL, -1, NULL,
113 &request);
114 if (status != PJ_SUCCESS) {
115 app_perror(" error: unable to create request", status);
116 return status;
117 }
118
119 /* Create Via */
120 via = pjsip_via_hdr_create(request->pool);
121 via->sent_by.host = pj_str("192.168.0.7");
122 via->sent_by.port = 5061;
123 via->transport = pj_str("udp");
124 via->rport_param = 1;
125 via->recvd_param = pj_str("192.168.0.7");
126 pjsip_msg_insert_first_hdr(request->msg, (pjsip_hdr*)via);
127
128
129 /* Create "dummy" rdata from the tdata */
Benny Prijonoac623b32006-07-03 15:19:31 +0000130 pj_bzero(&rdata, sizeof(pjsip_rx_data));
Benny Prijonoe93e2872006-06-28 16:46:49 +0000131 rdata.tp_info.pool = request->pool;
132 rdata.msg_info.msg = request->msg;
133 rdata.msg_info.from = pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
134 rdata.msg_info.to = pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL);
135 rdata.msg_info.cseq = pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL);
136 rdata.msg_info.cid = pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
137 rdata.msg_info.via = via;
138
139 pj_sockaddr_in_init(&remote, 0, 0);
140 status = pjsip_endpt_acquire_transport(endpt, PJSIP_TRANSPORT_LOOP_DGRAM,
141 &remote, sizeof(pj_sockaddr_in),
Benny Prijonodf2b71e2007-01-20 19:17:47 +0000142 NULL, &rdata.tp_info.transport);
Benny Prijonoe93e2872006-06-28 16:46:49 +0000143 if (status != PJ_SUCCESS) {
144 app_perror(" error: unable to get loop transport", status);
145 return status;
146 }
147
148
149 /* Create transaction array */
150 tsx = pj_pool_zalloc(request->pool, working_set * sizeof(pj_pool_t*));
151
Benny Prijonoac623b32006-07-03 15:19:31 +0000152 pj_bzero(&mod_tsx_user, sizeof(mod_tsx_user));
Benny Prijonoe93e2872006-06-28 16:46:49 +0000153 mod_tsx_user.id = -1;
154
155
156 /* Benchmark */
157 elapsed.u64 = 0;
158 pj_get_timestamp(&t1);
159 for (i=0; i<working_set; ++i) {
160 via->branch_param.ptr = branch_buf;
161 via->branch_param.slen = PJSIP_RFC3261_BRANCH_LEN +
162 pj_ansi_sprintf(branch_buf+PJSIP_RFC3261_BRANCH_LEN,
163 "-%d", i);
164 status = pjsip_tsx_create_uas(&mod_tsx_user, &rdata, &tsx[i]);
165 if (status != PJ_SUCCESS)
166 goto on_error;
167
168 }
169 pj_get_timestamp(&t2);
170 pj_sub_timestamp(&t2, &t1);
171 pj_add_timestamp(&elapsed, &t2);
172
173 p_elapsed->u64 = elapsed.u64;
174 status = PJ_SUCCESS;
175
176on_error:
177 for (i=0; i<working_set; ++i) {
178 if (tsx[i]) {
179 pjsip_tsx_terminate(tsx[i], 601);
180 tsx[i] = NULL;
181 }
182 }
183 pjsip_tx_data_dec_ref(request);
184 flush_events(2000);
185 return status;
186}
187
188
189
190int tsx_bench(void)
191{
Benny Prijono86b73d52006-07-22 12:47:40 +0000192 enum { WORKING_SET=10000, REPEAT = 4 };
Benny Prijonoe93e2872006-06-28 16:46:49 +0000193 unsigned i, speed;
194 pj_timestamp usec[REPEAT], min, freq;
195 char desc[250];
196 int status;
197
198 status = pj_get_timestamp_freq(&freq);
199 if (status != PJ_SUCCESS)
200 return status;
201
202
203 /*
204 * Benchmark UAC
205 */
206 PJ_LOG(3,(THIS_FILE, " benchmarking UAC transaction creation:"));
207 for (i=0; i<REPEAT; ++i) {
208 PJ_LOG(3,(THIS_FILE, " test %d of %d..",
209 i+1, REPEAT));
210 status = uac_tsx_bench(WORKING_SET, &usec[i]);
211 if (status != PJ_SUCCESS)
212 return status;
213 }
214
215 min.u64 = PJ_UINT64(0xFFFFFFFFFFFFFFF);
216 for (i=0; i<REPEAT; ++i) {
217 if (usec[i].u64 < min.u64) min.u64 = usec[i].u64;
218 }
219
220
221 /* Report time */
222 pj_ansi_sprintf(desc, "Time to create %d UAC transactions, in miliseconds",
223 WORKING_SET);
224 report_ival("create-uac-time", (unsigned)(min.u64 * 1000 / freq.u64), "msec", desc);
225
226
227 /* Write speed */
228 speed = (unsigned)(freq.u64 * WORKING_SET / min.u64);
229 PJ_LOG(3,(THIS_FILE, " UAC created at %d tsx/sec", speed));
230
231 pj_ansi_sprintf(desc, "Number of UAC transactions that potentially can be created per second "
232 "with <tt>pjsip_tsx_create_uac()</tt>, based on the time "
233 "to create %d simultaneous transactions above.",
234 WORKING_SET);
235
236 report_ival("create-uac-tsx-per-sec",
237 speed, "tsx/sec", desc);
238
239
240
241 /*
242 * Benchmark UAS
243 */
244 PJ_LOG(3,(THIS_FILE, " benchmarking UAS transaction creation:"));
245 for (i=0; i<REPEAT; ++i) {
246 PJ_LOG(3,(THIS_FILE, " test %d of %d..",
247 i+1, REPEAT));
248 status = uas_tsx_bench(WORKING_SET, &usec[i]);
249 if (status != PJ_SUCCESS)
250 return status;
251 }
252
253 min.u64 = PJ_UINT64(0xFFFFFFFFFFFFFFF);
254 for (i=0; i<REPEAT; ++i) {
255 if (usec[i].u64 < min.u64) min.u64 = usec[i].u64;
256 }
257
258
259 /* Report time */
260 pj_ansi_sprintf(desc, "Time to create %d UAS transactions, in miliseconds",
261 WORKING_SET);
262 report_ival("create-uas-time", (unsigned)(min.u64 * 1000 / freq.u64), "msec", desc);
263
264
265 /* Write speed */
266 speed = (unsigned)(freq.u64 * WORKING_SET / min.u64);
267 PJ_LOG(3,(THIS_FILE, " UAS created at %d tsx/sec", speed));
268
269 pj_ansi_sprintf(desc, "Number of UAS transactions that potentially can be created per second "
270 "with <tt>pjsip_tsx_create_uas()</tt>, based on the time "
271 "to create %d simultaneous transactions above.",
272 WORKING_SET);
273
274 report_ival("create-uas-tsx-per-sec",
275 speed, "tsx/sec", desc);
276
277 return PJ_SUCCESS;
278}
279