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