blob: 5e9fdf6bd8e6bfebdc9d5589a1fe9f5b0aafd1b0 [file] [log] [blame]
Tristan Matthews0a329cc2013-07-17 13:20:14 -04001/* $Id$ */
2/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
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;
24static pj_bool_t thread_quit_flag = 0;
25
26static int worker_thread(void *arg)
27{
28 pj_sock_t sock = (pj_sock_t)arg;
29 char buf[512];
30 pj_status_t last_recv_err = PJ_SUCCESS, last_write_err = PJ_SUCCESS;
31
32 while (!thread_quit_flag) {
33 pj_ssize_t len;
34 pj_status_t rc;
35 pj_sockaddr_in addr;
36 int addrlen;
37
38 len = sizeof(buf);
39 addrlen = sizeof(addr);
40 rc = pj_sock_recvfrom(sock, buf, &len, 0, &addr, &addrlen);
41 if (rc != 0) {
42 if (rc != last_recv_err) {
43 app_perror("...recv error", rc);
44 last_recv_err = rc;
45 }
46 continue;
47 }
48
49 pj_atomic_add(total_bytes, (pj_atomic_value_t)len);
50
51 rc = pj_sock_sendto(sock, buf, &len, 0, &addr, addrlen);
52 if (rc != PJ_SUCCESS) {
53 if (rc != last_write_err) {
54 app_perror("...send error", rc);
55 last_write_err = rc;
56 }
57 continue;
58 }
59 }
60 return 0;
61}
62
63
64int echo_srv_sync(void)
65{
66 pj_pool_t *pool;
67 pj_sock_t sock;
68 pj_thread_t *thread[ECHO_SERVER_MAX_THREADS];
69 pj_status_t rc;
70 int i;
71
72 pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
73 if (!pool)
74 return -5;
75
76 rc = pj_atomic_create(pool, 0, &total_bytes);
77 if (rc != PJ_SUCCESS) {
78 app_perror("...unable to create atomic_var", rc);
79 return -6;
80 }
81
82 rc = app_socket(pj_AF_INET(), pj_SOCK_DGRAM(),0, ECHO_SERVER_START_PORT, &sock);
83 if (rc != PJ_SUCCESS) {
84 app_perror("...socket error", rc);
85 return -10;
86 }
87
88 for (i=0; i<ECHO_SERVER_MAX_THREADS; ++i) {
89 rc = pj_thread_create(pool, NULL, &worker_thread, (void*)sock,
90 PJ_THREAD_DEFAULT_STACK_SIZE, 0,
91 &thread[i]);
92 if (rc != PJ_SUCCESS) {
93 app_perror("...unable to create thread", rc);
94 return -20;
95 }
96 }
97
98 PJ_LOG(3,("", "...UDP echo server running with %d threads at port %d",
99 ECHO_SERVER_MAX_THREADS, ECHO_SERVER_START_PORT));
100 PJ_LOG(3,("", "...Press Ctrl-C to abort"));
101
102 echo_srv_common_loop(total_bytes);
103 return 0;
104}
105
106
107int echo_srv_common_loop(pj_atomic_t *bytes_counter)
108{
109 pj_highprec_t last_received, avg_bw, highest_bw;
110 pj_time_val last_print;
111 unsigned count;
112 const char *ioqueue_name;
113
114 last_received = 0;
115 pj_gettimeofday(&last_print);
116 avg_bw = highest_bw = 0;
117 count = 0;
118
119 ioqueue_name = pj_ioqueue_name();
120
121 for (;;) {
122 pj_highprec_t received, cur_received, bw;
123 unsigned msec;
124 pj_time_val now, duration;
125
126 pj_thread_sleep(1000);
127
128 received = cur_received = pj_atomic_get(bytes_counter);
129 cur_received = cur_received - last_received;
130
131 pj_gettimeofday(&now);
132 duration = now;
133 PJ_TIME_VAL_SUB(duration, last_print);
134 msec = PJ_TIME_VAL_MSEC(duration);
135
136 bw = cur_received;
137 pj_highprec_mul(bw, 1000);
138 pj_highprec_div(bw, msec);
139
140 last_print = now;
141 last_received = received;
142
143 avg_bw = avg_bw + bw;
144 count++;
145
146 PJ_LOG(3,("", "%s UDP (%d threads): %u KB/s (avg=%u KB/s) %s",
147 ioqueue_name,
148 ECHO_SERVER_MAX_THREADS,
149 (unsigned)(bw / 1000),
150 (unsigned)(avg_bw / count / 1000),
151 (count==20 ? "<ses avg>" : "")));
152
153 if (count==20) {
154 if (avg_bw/count > highest_bw)
155 highest_bw = avg_bw/count;
156
157 count = 0;
158 avg_bw = 0;
159
160 PJ_LOG(3,("", "Highest average bandwidth=%u KB/s",
161 (unsigned)(highest_bw/1000)));
162 }
163 }
164 PJ_UNREACHED(return 0;)
165}
166
167