1 /*
2  * ivykis, an event handling library
3  * Copyright (C) 2012 Lennert Buytenhek
4  * Dedicated to Marija Kulikova.
5  *
6  * This library is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License version
8  * 2.1 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License version 2.1 for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License version 2.1 along with this library; if not, write to the
17  * Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
18  * Boston, MA 02110-1301, USA.
19  */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <iv.h>
24 #include <iv_event.h>
25 #include <iv_thread.h>
26 #ifdef USE_SIGNAL
27 #include <signal.h>
28 #endif
29 
30 static int die;
31 static int ev_received;
32 static struct iv_event ev_parent;
33 static struct iv_event ev_child;
34 static struct timespec tim_start;
35 static struct timespec tim_end;
36 
37 #ifdef USE_SIGNAL
got_signal_timeout(int sigh)38 static void got_signal_timeout(int sigh)
39 {
40 	die = 1;
41 }
42 #else
43 static struct iv_timer timeout;
44 
got_timer_timeout(void * _dummy)45 static void got_timer_timeout(void *_dummy)
46 {
47 	die = 1;
48 }
49 #endif
50 
got_ev_parent(void * _dummy)51 static void got_ev_parent(void *_dummy)
52 {
53 	ev_received++;
54 
55 	if (die == 0) {
56 		iv_event_post(&ev_child);
57 	} else if (die == 1) {
58 		die = 2;
59 		iv_event_post(&ev_child);
60 	} else if (die == 2) {
61 		iv_fatal("iv_event_bench: entered invalid state");
62 	} else if (die == 3) {
63 		iv_validate_now();
64 		tim_end = iv_now;
65 		iv_event_unregister(&ev_parent);
66 	}
67 }
68 
got_ev_child(void * _dummy)69 static void got_ev_child(void *_dummy)
70 {
71 	if (die == 2) {
72 		die = 3;
73 		iv_event_post(&ev_parent);
74 		iv_event_unregister(&ev_child);
75 	} else {
76 		iv_event_post(&ev_parent);
77 	}
78 }
79 
thr_child(void * _dummy)80 static void thr_child(void *_dummy)
81 {
82 	iv_init();
83 
84 	IV_EVENT_INIT(&ev_child);
85 	ev_child.handler = got_ev_child;
86 	iv_event_register(&ev_child);
87 
88 	iv_validate_now();
89 	tim_start = iv_now;
90 
91 	iv_event_post(&ev_parent);
92 
93 	iv_main();
94 
95 	iv_deinit();
96 }
97 
main()98 int main()
99 {
100 	long long nsec;
101 
102 	iv_init();
103 
104 #ifdef USE_SIGNAL
105 	signal(SIGALRM, got_signal_timeout);
106 	alarm(5);
107 #else
108 	IV_TIMER_INIT(&timeout);
109 	iv_validate_now();
110 	timeout.expires = iv_now;
111 	timeout.expires.tv_sec += 5;
112 	timeout.handler = got_timer_timeout;
113 	iv_timer_register(&timeout);
114 #endif
115 
116 	IV_EVENT_INIT(&ev_parent);
117 	ev_parent.handler = got_ev_parent;
118 	iv_event_register(&ev_parent);
119 
120 	iv_thread_create("child", thr_child, NULL);
121 
122 	iv_main();
123 
124 	iv_deinit();
125 
126 	nsec = 1000000000ULL * (tim_end.tv_sec - tim_start.tv_sec) +
127 		(tim_end.tv_nsec - tim_start.tv_nsec);
128 
129 	printf("%s: %d in %ld nsec => %d/sec\n",
130 	       iv_poll_method_name(), ev_received, (long)nsec,
131 	       (int)(1000000000ULL * ev_received / nsec));
132 
133 	return 0;
134 }
135