blob: 1b4670e71a2ca5a9a1efe9bd295f4fb7023e1151 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
Benny Prijono844653c2008-12-23 17:27:53 +00003 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono5dcb38d2005-11-21 01:55:47 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "test.h"
21#include <pjlib.h>
22
23static pj_atomic_t *total_bytes;
24
25static int worker_thread(void *arg)
26{
27 pj_sock_t sock = (pj_sock_t)arg;
28 char buf[512];
29 pj_status_t last_recv_err = PJ_SUCCESS, last_write_err = PJ_SUCCESS;
30
31 for (;;) {
32 pj_ssize_t len;
33 pj_status_t rc;
34 pj_sockaddr_in addr;
35 int addrlen;
36
37 len = sizeof(buf);
38 addrlen = sizeof(addr);
39 rc = pj_sock_recvfrom(sock, buf, &len, 0, &addr, &addrlen);
40 if (rc != 0) {
41 if (rc != last_recv_err) {
42 app_perror("...recv error", rc);
43 last_recv_err = rc;
44 }
45 continue;
46 }
47
48 pj_atomic_add(total_bytes, len);
49
50 rc = pj_sock_sendto(sock, buf, &len, 0, &addr, addrlen);
51 if (rc != PJ_SUCCESS) {
52 if (rc != last_write_err) {
53 app_perror("...send error", rc);
54 last_write_err = rc;
55 }
56 continue;
57 }
58 }
Benny Prijono95b53402009-01-01 20:56:36 +000059 PJ_UNREACHED(return 0;)
Benny Prijono5dcb38d2005-11-21 01:55:47 +000060}
61
62
63int echo_srv_sync(void)
64{
65 pj_pool_t *pool;
66 pj_sock_t sock;
67 pj_thread_t *thread[ECHO_SERVER_MAX_THREADS];
68 pj_status_t rc;
69 int i;
70
71 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
72 if (!pool)
73 return -5;
74
75 rc = pj_atomic_create(pool, 0, &total_bytes);
76 if (rc != PJ_SUCCESS) {
77 app_perror("...unable to create atomic_var", rc);
78 return -6;
79 }
80
Benny Prijono8ab968f2007-07-20 08:08:30 +000081 rc = app_socket(pj_AF_INET(), pj_SOCK_DGRAM(),0, ECHO_SERVER_START_PORT, &sock);
Benny Prijono5dcb38d2005-11-21 01:55:47 +000082 if (rc != PJ_SUCCESS) {
83 app_perror("...socket error", rc);
84 return -10;
85 }
86
87 for (i=0; i<ECHO_SERVER_MAX_THREADS; ++i) {
88 rc = pj_thread_create(pool, NULL, &worker_thread, (void*)sock,
89 PJ_THREAD_DEFAULT_STACK_SIZE, 0,
90 &thread[i]);
91 if (rc != PJ_SUCCESS) {
92 app_perror("...unable to create thread", rc);
93 return -20;
94 }
95 }
96
97 PJ_LOG(3,("", "...UDP echo server running with %d threads at port %d",
98 ECHO_SERVER_MAX_THREADS, ECHO_SERVER_START_PORT));
99 PJ_LOG(3,("", "...Press Ctrl-C to abort"));
100
101 echo_srv_common_loop(total_bytes);
102 return 0;
103}
104
105
106int echo_srv_common_loop(pj_atomic_t *bytes_counter)
107{
108 pj_highprec_t last_received, avg_bw, highest_bw;
109 pj_time_val last_print;
110 unsigned count;
111 const char *ioqueue_name;
112
113 last_received = 0;
114 pj_gettimeofday(&last_print);
115 avg_bw = highest_bw = 0;
116 count = 0;
117
118 ioqueue_name = pj_ioqueue_name();
119
120 for (;;) {
121 pj_highprec_t received, cur_received, bw;
122 unsigned msec;
123 pj_time_val now, duration;
124
125 pj_thread_sleep(1000);
126
127 received = cur_received = pj_atomic_get(bytes_counter);
128 cur_received = cur_received - last_received;
129
130 pj_gettimeofday(&now);
131 duration = now;
132 PJ_TIME_VAL_SUB(duration, last_print);
133 msec = PJ_TIME_VAL_MSEC(duration);
134
135 bw = cur_received;
136 pj_highprec_mul(bw, 1000);
137 pj_highprec_div(bw, msec);
138
139 last_print = now;
140 last_received = received;
141
142 avg_bw = avg_bw + bw;
143 count++;
144
145 PJ_LOG(3,("", "%s UDP (%d threads): %u KB/s (avg=%u KB/s) %s",
146 ioqueue_name,
147 ECHO_SERVER_MAX_THREADS,
148 (unsigned)(bw / 1000),
149 (unsigned)(avg_bw / count / 1000),
150 (count==20 ? "<ses avg>" : "")));
151
152 if (count==20) {
153 if (avg_bw/count > highest_bw)
154 highest_bw = avg_bw/count;
155
156 count = 0;
157 avg_bw = 0;
158
159 PJ_LOG(3,("", "Highest average bandwidth=%u KB/s",
160 (unsigned)(highest_bw/1000)));
161 }
162 }
Benny Prijono95b53402009-01-01 20:56:36 +0000163 PJ_UNREACHED(return 0;)
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000164}
165
166