root/opal/mca/event/libevent2022/libevent/test/bench_cascade.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. read_cb
  2. run_once
  3. main

   1 /*
   2  * Copyright 2007-2012 Niels Provos and Nick Mathewson
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  * 4. The name of the author may not be used to endorse or promote products
  13  *    derived from this software without specific prior written permission.
  14  *
  15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  25  *
  26  */
  27 
  28 #include "event2/event-config.h"
  29 
  30 #include <sys/types.h>
  31 #include <sys/stat.h>
  32 #ifdef _EVENT_HAVE_SYS_TIME_H
  33 #include <sys/time.h>
  34 #endif
  35 #ifdef WIN32
  36 #define WIN32_LEAN_AND_MEAN
  37 #include <windows.h>
  38 #else
  39 #include <sys/socket.h>
  40 #include <sys/resource.h>
  41 #endif
  42 #include <signal.h>
  43 #include <fcntl.h>
  44 #include <stdlib.h>
  45 #include <stdio.h>
  46 #include <string.h>
  47 #ifdef _EVENT_HAVE_UNISTD_H
  48 #include <unistd.h>
  49 #endif
  50 #include <errno.h>
  51 
  52 #include <event.h>
  53 #include <evutil.h>
  54 
  55 /*
  56  * This benchmark tests how quickly we can propagate a write down a chain
  57  * of socket pairs.  We start by writing to the first socket pair and all
  58  * events will fire subsequently until the last socket pair has been reached
  59  * and the benchmark terminates.
  60  */
  61 
  62 static int fired;
  63 static evutil_socket_t *pipes;
  64 static struct event *events;
  65 
  66 static void
  67 read_cb(evutil_socket_t fd, short which, void *arg)
  68 {
  69         char ch;
  70         evutil_socket_t sock = (evutil_socket_t)(ev_intptr_t)arg;
  71 
  72         recv(fd, &ch, sizeof(ch), 0);
  73         if (sock >= 0) {
  74                 if (send(sock, "e", 1, 0) < 0)
  75                         perror("send");
  76         }
  77         fired++;
  78 }
  79 
  80 static struct timeval *
  81 run_once(int num_pipes)
  82 {
  83         int i;
  84         evutil_socket_t *cp;
  85         static struct timeval ts, te, tv_timeout;
  86 
  87         events = calloc(num_pipes, sizeof(struct event));
  88         pipes = calloc(num_pipes * 2, sizeof(evutil_socket_t));
  89 
  90         if (events == NULL || pipes == NULL) {
  91                 perror("malloc");
  92                 exit(1);
  93         }
  94 
  95         for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
  96                 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, cp) == -1) {
  97                         perror("socketpair");
  98                         exit(1);
  99                 }
 100         }
 101 
 102         /* measurements includes event setup */
 103         evutil_gettimeofday(&ts, NULL);
 104 
 105         /* provide a default timeout for events */
 106         evutil_timerclear(&tv_timeout);
 107         tv_timeout.tv_sec = 60;
 108 
 109         for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
 110                 evutil_socket_t fd = i < num_pipes - 1 ? cp[3] : -1;
 111                 event_set(&events[i], cp[0], EV_READ, read_cb,
 112                     (void *)(ev_intptr_t)fd);
 113                 event_add(&events[i], &tv_timeout);
 114         }
 115 
 116         fired = 0;
 117 
 118         /* kick everything off with a single write */
 119         if (send(pipes[1], "e", 1, 0) < 0)
 120                 perror("send");
 121 
 122         event_dispatch();
 123 
 124         evutil_gettimeofday(&te, NULL);
 125         evutil_timersub(&te, &ts, &te);
 126 
 127         for (cp = pipes, i = 0; i < num_pipes; i++, cp += 2) {
 128                 event_del(&events[i]);
 129                 close(cp[0]);
 130                 close(cp[1]);
 131         }
 132 
 133         free(pipes);
 134         free(events);
 135 
 136         return (&te);
 137 }
 138 
 139 int
 140 main(int argc, char **argv)
 141 {
 142 #ifndef WIN32
 143         struct rlimit rl;
 144 #endif
 145         int i, c;
 146         struct timeval *tv;
 147 
 148         int num_pipes = 100;
 149         while ((c = getopt(argc, argv, "n:")) != -1) {
 150                 switch (c) {
 151                 case 'n':
 152                         num_pipes = atoi(optarg);
 153                         break;
 154                 default:
 155                         fprintf(stderr, "Illegal argument \"%c\"\n", c);
 156                         exit(1);
 157                 }
 158         }
 159 
 160 #ifndef WIN32
 161         rl.rlim_cur = rl.rlim_max = num_pipes * 2 + 50;
 162         if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
 163                 perror("setrlimit");
 164                 exit(1);
 165         }
 166 #endif
 167 
 168         event_init();
 169 
 170         for (i = 0; i < 25; i++) {
 171                 tv = run_once(num_pipes);
 172                 if (tv == NULL)
 173                         exit(1);
 174                 fprintf(stdout, "%ld\n",
 175                         tv->tv_sec * 1000000L + tv->tv_usec);
 176         }
 177 
 178         exit(0);
 179 }

/* [<][>][^][v][top][bottom][index][help] */