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