1 /* $NetBSD: test-changelist.c,v 1.1.1.1 2013/04/11 16:43:33 christos Exp $ */ 2 /* 3 * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson 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 * 3. 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 #include "event2/event-config.h" 29 #include <sys/cdefs.h> 30 __RCSID("$NetBSD: test-changelist.c,v 1.1.1.1 2013/04/11 16:43:33 christos Exp $"); 31 32 #ifdef WIN32 33 #include <winsock2.h> 34 #include <windows.h> 35 #else 36 #include <unistd.h> 37 #endif 38 #include <sys/types.h> 39 #include <sys/stat.h> 40 #ifdef _EVENT_HAVE_SYS_TIME_H 41 #include <sys/time.h> 42 #endif 43 44 #ifdef _EVENT_HAVE_SYS_SOCKET_H 45 #include <sys/socket.h> 46 #endif 47 #include <fcntl.h> 48 #include <stdlib.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <errno.h> 52 53 #include "event2/event.h" 54 #include "event2/util.h" 55 #include <time.h> 56 57 struct cpu_usage_timer { 58 #ifdef WIN32 59 HANDLE thread; 60 FILETIME usertimeBegin; 61 FILETIME kerneltimeBegin; 62 #else 63 clock_t ticksBegin; 64 #endif 65 struct timeval timeBegin; 66 }; 67 static void 68 start_cpu_usage_timer(struct cpu_usage_timer *timer) 69 { 70 #ifdef WIN32 71 int r; 72 FILETIME createtime, exittime; 73 timer->thread = GetCurrentThread(); 74 r = GetThreadTimes(timer->thread, &createtime, &exittime, 75 &timer->usertimeBegin, &timer->kerneltimeBegin); 76 if (r==0) printf("GetThreadTimes failed."); 77 #else 78 timer->ticksBegin = clock(); 79 #endif 80 81 evutil_gettimeofday(&timer->timeBegin, NULL); 82 } 83 #ifdef WIN32 84 static ev_int64_t 85 filetime_to_100nsec(const FILETIME *ft) 86 { 87 /* Number of 100-nanosecond units */ 88 ev_int64_t n = ft->dwHighDateTime; 89 n <<= 32; 90 n += ft->dwLowDateTime; 91 return n; 92 } 93 static double 94 filetime_diff(const FILETIME *ftStart, const FILETIME *ftEnd) 95 { 96 ev_int64_t s, e, diff; 97 double r; 98 s = filetime_to_100nsec(ftStart); 99 e = filetime_to_100nsec(ftEnd); 100 diff = e - s; 101 r = (double) diff; 102 return r / 1.0e7; 103 } 104 #endif 105 106 static void 107 get_cpu_usage(struct cpu_usage_timer *timer, double *secElapsedOut, 108 double *secUsedOut, double *usageOut) 109 { 110 #ifdef WIN32 111 double usertime_seconds, kerneltime_seconds; 112 FILETIME createtime, exittime, usertimeEnd, kerneltimeEnd; 113 int r; 114 #else 115 clock_t ticksEnd; 116 #endif 117 struct timeval timeEnd, timeDiff; 118 double secondsPassed, secondsUsed; 119 120 #ifdef WIN32 121 r = GetThreadTimes(timer->thread, &createtime, &exittime, 122 &usertimeEnd, &kerneltimeEnd); 123 if (r==0) printf("GetThreadTimes failed."); 124 usertime_seconds = filetime_diff(&timer->usertimeBegin, &usertimeEnd); 125 kerneltime_seconds = filetime_diff(&timer->kerneltimeBegin, &kerneltimeEnd); 126 secondsUsed = kerneltime_seconds + usertime_seconds; 127 #else 128 ticksEnd = clock(); 129 secondsUsed = (ticksEnd - timer->ticksBegin) / (double)CLOCKS_PER_SEC; 130 #endif 131 evutil_gettimeofday(&timeEnd, NULL); 132 evutil_timersub(&timeEnd, &timer->timeBegin, &timeDiff); 133 secondsPassed = timeDiff.tv_sec + (timeDiff.tv_usec / 1.0e6); 134 135 *secElapsedOut = secondsPassed; 136 *secUsedOut = secondsUsed; 137 *usageOut = secondsUsed / secondsPassed; 138 } 139 140 static void 141 write_cb(evutil_socket_t fd, short event, void *arg) 142 { 143 printf("write callback. should only see this once\n"); 144 145 /* got what we want remove the event */ 146 event_del(*(struct event**)arg); 147 148 /* opps changed my mind add it back again */ 149 event_add(*(struct event**)arg,NULL); 150 151 /* not a good day for decisiveness, I really didn't want it after all */ 152 event_del(*(struct event**)arg); 153 154 } 155 156 static void 157 timeout_cb(evutil_socket_t fd, short event, void *arg) 158 { 159 printf("timeout fired, time to end test\n"); 160 event_del(*(struct event**)arg); 161 return; 162 } 163 164 int 165 main(int argc, char **argv) 166 { 167 struct event* ev; 168 struct event* timeout; 169 struct event_base* base; 170 171 evutil_socket_t pair[2]; 172 struct timeval tv; 173 struct cpu_usage_timer timer; 174 175 double usage, secPassed, secUsed; 176 177 #ifdef WIN32 178 WORD wVersionRequested; 179 WSADATA wsaData; 180 181 wVersionRequested = MAKEWORD(2, 2); 182 183 (void) WSAStartup(wVersionRequested, &wsaData); 184 #endif 185 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 186 return (1); 187 188 /* Initalize the event library */ 189 base = event_base_new(); 190 191 /* Initalize a timeout to terminate the test */ 192 timeout = evtimer_new(base,timeout_cb,&timeout); 193 /* and watch for writability on one end of the pipe */ 194 ev = event_new(base,pair[1],EV_WRITE | EV_PERSIST, write_cb, &ev); 195 196 tv.tv_sec = 5; 197 tv.tv_usec = 0; 198 199 evtimer_add(timeout, &tv); 200 201 event_add(ev, NULL); 202 203 start_cpu_usage_timer(&timer); 204 205 event_base_dispatch(base); 206 207 event_free(ev); 208 event_free(timeout); 209 event_base_free(base); 210 211 get_cpu_usage(&timer, &secPassed, &secUsed, &usage); 212 213 /* attempt to calculate our cpu usage over the test should be 214 virtually nil */ 215 216 printf("usec used=%d, usec passed=%d, cpu usage=%.2f%%\n", 217 (int)(secUsed*1e6), 218 (int)(secPassed*1e6), 219 usage*100); 220 221 if (usage > 50.0) /* way too high */ 222 return 1; 223 224 return 0; 225 } 226 227