root/lang/c/picoev/trunk/example/bench.c

Revision 35031, 7.2 kB (checked in by kazuho, 3 years ago)

comment out debug info

Line 
1/*
2 * Copyright 2003 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 4. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 *
28 * Mon 03/10/2003 - Modified by Davide Libenzi <davidel@xmailserver.org>
29 *
30 *     Added chain event propagation to improve the sensitivity of
31 *     the measure respect to the event loop efficency.
32 *
33 *
34 */
35
36#define timersub(tvp, uvp, vvp)                                         \
37        do {                                                            \
38                (vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec;          \
39                (vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec;       \
40                if ((vvp)->tv_usec < 0) {                               \
41                        (vvp)->tv_sec--;                                \
42                        (vvp)->tv_usec += 1000000;                      \
43                }                                                       \
44        } while (0)
45#ifdef HAVE_CONFIG_H
46#include "config.h"
47#endif
48
49#include <sys/types.h>
50#include <sys/stat.h>
51#include <sys/time.h>
52#include <sys/socket.h>
53#include <sys/signal.h>
54#include <sys/resource.h>
55#include <fcntl.h>
56#include <stdlib.h>
57#include <stdio.h>
58#include <string.h>
59#include <unistd.h>
60#include <errno.h>
61
62#if PICOEV
63# include "picoev.h"
64picoev_loop* pe_loop;
65#endif
66#if NATIVE
67# include "ev.h"
68#endif
69#include <event.h>
70
71
72static int count, writes, fired;
73static int *pipes;
74static int num_pipes, num_active, num_writes;
75static struct event *events;
76static int timers, native;
77static struct ev_io *evio;
78static struct ev_timer *evto;
79
80
81
82void
83read_cb(int fd, short which, void *arg)
84{
85        int idx = (int) arg, widx = idx + 1;
86        u_char ch;
87
88        if (timers)
89          {
90            if (native == 2) {
91#if PICOEV
92              picoev_set_timeout(pe_loop, fd, 10);
93              drand48();
94#else
95              abort();
96#endif
97            } else if (native)
98              {
99#if NATIVE
100                evto [idx].repeat = 10. + drand48 ();
101                ev_timer_again (&evto [idx]);
102#else
103                abort ();
104#endif
105              }
106            else
107              {
108                struct timeval tv;
109                event_del (&events [idx]);
110                tv.tv_sec  = 10;
111                tv.tv_usec = drand48() * 1e6;
112                event_add(&events[idx], &tv);
113              }
114          }
115
116        count += read(fd, &ch, sizeof(ch));
117        if (writes) {
118                if (widx >= num_pipes)
119                        widx -= num_pipes;
120                write(pipes[2 * widx + 1], "e", 1);
121                writes--;
122                fired++;
123        }
124}
125
126#if PICOEV
127void
128cb_picoev(picoev_loop* loop, int fd, int revents, void* cb_arg)
129{
130  read_cb(fd, revents, cb_arg);
131}
132#endif
133
134#if NATIVE
135void
136read_thunk(struct ev_io *w, int revents)
137{
138  read_cb (w->fd, revents, w->data);
139}
140
141void
142timer_cb (struct ev_timer *w, int revents)
143{
144  assert(0);
145}
146#endif
147
148struct timeval *
149run_once(void)
150{
151        int *cp, i, space;
152        static struct timeval ta, ts, te, tv;
153
154        gettimeofday(&ta, NULL);
155        for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
156          if (native == 2) {
157#if PICOEV
158            if (picoev_is_active(pe_loop, cp[0])) {
159              picoev_del(pe_loop, cp[0]);
160            }
161            picoev_add(pe_loop, cp[0], PICOEV_READ, 10, cb_picoev, (void*)i);
162            drand48();
163#else
164            abort();
165#endif
166          } else if (native)
167            {
168#if NATIVE
169              if (ev_is_active (&evio [i]))
170                ev_io_stop (&evio [i]);
171
172              ev_io_set (&evio [i], cp [0], EV_READ);
173              ev_io_start (&evio [i]);
174
175              evto [i].repeat = 10. + drand48 ();
176              ev_timer_again (&evto [i]);
177#else
178              abort ();
179#endif
180            }
181          else
182            {
183                event_del(&events[i]);
184                event_set(&events[i], cp[0], EV_READ | EV_PERSIST, read_cb, (void *) i);
185                tv.tv_sec  = 10.;
186                tv.tv_usec = drand48() * 1e6;
187                event_add(&events[i], timers ? &tv : 0);
188            }
189        }
190
191#if PICOEV
192        if (native == 2) {
193          picoev_loop_once(pe_loop, 0);
194        } else
195#endif
196        event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
197
198        fired = 0;
199        space = num_pipes / num_active;
200        space = space * 2;
201        for (i = 0; i < num_active; i++, fired++)
202                write(pipes[i * space + 1], "e", 1);
203
204        count = 0;
205        writes = num_writes;
206        { int xcount = 0;
207        gettimeofday(&ts, NULL);
208        do {
209#if PICOEV
210          if (native == 2) {
211            picoev_loop_once(pe_loop, 0);
212          } else
213#endif
214                event_loop(EVLOOP_ONCE | EVLOOP_NONBLOCK);
215                xcount++;
216        } while (count != fired);
217        gettimeofday(&te, NULL);
218
219        //if (xcount != count) fprintf(stderr, "Xcount: %d, Rcount: %d\n", xcount, count);
220        }
221
222        timersub(&te, &ta, &ta);
223        timersub(&te, &ts, &ts);
224                fprintf(stdout, "%8ld %8ld\n",
225                        ta.tv_sec * 1000000L + ta.tv_usec,
226                        ts.tv_sec * 1000000L + ts.tv_usec
227                        );
228
229        return (&te);
230}
231
232int
233main (int argc, char **argv)
234{
235        struct rlimit rl;
236        int i, c;
237        struct timeval *tv;
238        int *cp;
239        extern char *optarg;
240
241        num_pipes = 100;
242        num_active = 1;
243        num_writes = num_pipes;
244        while ((c = getopt(argc, argv, "n:a:w:te:")) != -1) {
245                switch (c) {
246                case 'n':
247                        num_pipes = atoi(optarg);
248                        break;
249                case 'a':
250                        num_active = atoi(optarg);
251                        break;
252                case 'w':
253                        num_writes = atoi(optarg);
254                        break;
255                case 'e':
256#if PICOEV
257                  if (strcmp(optarg, "picoev") == 0) {
258                    native = 2;
259                  } else
260#endif
261                        native = 1;
262                        break;
263                case 't':
264                        timers = 1;
265                        break;
266                default:
267                        fprintf(stderr, "Illegal argument \"%c\"\n", c);
268                        exit(1);
269                }
270        }
271
272#if 1
273        rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
274        if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
275                perror("setrlimit");
276        }
277#endif
278
279#if PICOEV
280        picoev_init(num_pipes * 2 + 10);
281        pe_loop = picoev_create_loop(60);
282#endif
283#if NATIVE
284        evio = calloc(num_pipes, sizeof(struct ev_io));
285        evto = calloc(num_pipes, sizeof(struct ev_timer));
286#endif
287        events = calloc(num_pipes, sizeof(struct event));
288        pipes = calloc(num_pipes * 2, sizeof(int));
289        if (events == NULL || pipes == NULL) {
290                perror("malloc");
291                exit(1);
292        }
293
294        event_init();
295
296        for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
297#if NATIVE
298          if (native) {
299            ev_init (&evto [i], timer_cb);
300            ev_init (&evio [i], read_thunk);
301            evio [i].data = (void *)i;
302          }
303#endif
304#ifdef USE_PIPES
305                if (pipe(cp) == -1) {
306#else
307                if (socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
308#endif
309                        perror("pipe");
310                        exit(1);
311                }
312        }
313
314        for (i = 0; i < 2; i++) {
315                tv = run_once();
316        }
317
318        exit(0);
319}
Note: See TracBrowser for help on using the browser.