1 /* $NetBSD: test-changelist.c,v 1.4 2016/01/08 21:35:41 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2010-2012 Niels Provos and Nick Mathewson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "event2/event-config.h" 30 31 #ifdef _WIN32 32 #include <winsock2.h> 33 #include <windows.h> 34 #else 35 #include <unistd.h> 36 #endif 37 #include <sys/types.h> 38 #include <sys/stat.h> 39 #ifdef EVENT__HAVE_SYS_TIME_H 40 #include <sys/time.h> 41 #endif 42 43 #ifdef EVENT__HAVE_SYS_SOCKET_H 44 #include <sys/socket.h> 45 #endif 46 #include <fcntl.h> 47 #include <stdlib.h> 48 #include <stdio.h> 49 #include <string.h> 50 #include <errno.h> 51 52 #include "event2/event.h" 53 #include "event2/util.h" 54 #include <time.h> 55 56 struct cpu_usage_timer { 57 #ifdef _WIN32 58 HANDLE thread; 59 FILETIME usertimeBegin; 60 FILETIME kerneltimeBegin; 61 #else 62 clock_t ticksBegin; 63 #endif 64 struct timeval timeBegin; 65 }; 66 static void 67 start_cpu_usage_timer(struct cpu_usage_timer *timer) 68 { 69 #ifdef _WIN32 70 int r; 71 FILETIME createtime, exittime; 72 timer->thread = GetCurrentThread(); 73 r = GetThreadTimes(timer->thread, &createtime, &exittime, 74 &timer->usertimeBegin, &timer->kerneltimeBegin); 75 if (r==0) printf("GetThreadTimes failed."); 76 #else 77 timer->ticksBegin = clock(); 78 #endif 79 80 evutil_gettimeofday(&timer->timeBegin, NULL); 81 } 82 #ifdef _WIN32 83 static ev_int64_t 84 filetime_to_100nsec(const FILETIME *ft) 85 { 86 /* Number of 100-nanosecond units */ 87 ev_int64_t n = ft->dwHighDateTime; 88 n <<= 32; 89 n += ft->dwLowDateTime; 90 return n; 91 } 92 static double 93 filetime_diff(const FILETIME *ftStart, const FILETIME *ftEnd) 94 { 95 ev_int64_t s, e, diff; 96 double r; 97 s = filetime_to_100nsec(ftStart); 98 e = filetime_to_100nsec(ftEnd); 99 diff = e - s; 100 r = (double) diff; 101 return r / 1.0e7; 102 } 103 #endif 104 105 static void 106 get_cpu_usage(struct cpu_usage_timer *timer, double *secElapsedOut, 107 double *secUsedOut, double *usageOut) 108 { 109 #ifdef _WIN32 110 double usertime_seconds, kerneltime_seconds; 111 FILETIME createtime, exittime, usertimeEnd, kerneltimeEnd; 112 int r; 113 #else 114 clock_t ticksEnd; 115 #endif 116 struct timeval timeEnd, timeDiff; 117 double secondsPassed, secondsUsed; 118 119 #ifdef _WIN32 120 r = GetThreadTimes(timer->thread, &createtime, &exittime, 121 &usertimeEnd, &kerneltimeEnd); 122 if (r==0) printf("GetThreadTimes failed."); 123 usertime_seconds = filetime_diff(&timer->usertimeBegin, &usertimeEnd); 124 kerneltime_seconds = filetime_diff(&timer->kerneltimeBegin, &kerneltimeEnd); 125 secondsUsed = kerneltime_seconds + usertime_seconds; 126 #else 127 ticksEnd = clock(); 128 secondsUsed = (ticksEnd - timer->ticksBegin) / (double)CLOCKS_PER_SEC; 129 #endif 130 evutil_gettimeofday(&timeEnd, NULL); 131 evutil_timersub(&timeEnd, &timer->timeBegin, &timeDiff); 132 secondsPassed = timeDiff.tv_sec + (timeDiff.tv_usec / 1.0e6); 133 134 *secElapsedOut = secondsPassed; 135 *secUsedOut = secondsUsed; 136 *usageOut = secondsUsed / secondsPassed; 137 } 138 139 static void 140 write_cb(evutil_socket_t fd, short event, void *arg) 141 { 142 printf("write callback. should only see this once\n"); 143 144 /* got what we want remove the event */ 145 event_del(*(struct event**)arg); 146 147 /* opps changed my mind add it back again */ 148 event_add(*(struct event**)arg,NULL); 149 150 /* not a good day for decisiveness, I really didn't want it after all */ 151 event_del(*(struct event**)arg); 152 153 } 154 155 static void 156 timeout_cb(evutil_socket_t fd, short event, void *arg) 157 { 158 printf("timeout fired, time to end test\n"); 159 event_del(*(struct event**)arg); 160 return; 161 } 162 163 int 164 main(int argc, char **argv) 165 { 166 struct event* ev; 167 struct event* timeout; 168 struct event_base* base; 169 170 evutil_socket_t pair[2]; 171 struct timeval tv; 172 struct cpu_usage_timer timer; 173 174 double usage, secPassed, secUsed; 175 176 #ifdef _WIN32 177 WORD wVersionRequested; 178 WSADATA wsaData; 179 180 wVersionRequested = MAKEWORD(2, 2); 181 182 (void) WSAStartup(wVersionRequested, &wsaData); 183 #endif 184 if (evutil_socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 185 return (1); 186 187 /* Initalize the event library */ 188 if (!(base = event_base_new())) 189 return (1); 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 = 1; 197 tv.tv_usec = 500*1000; 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