poll-loop: Simplify and speed up polling.
[sliver-openvswitch.git] / lib / poll-loop.c
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Nicira, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <config.h>
18 #include "poll-loop.h"
19 #include <errno.h>
20 #include <inttypes.h>
21 #include <poll.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "coverage.h"
25 #include "dynamic-string.h"
26 #include "fatal-signal.h"
27 #include "list.h"
28 #include "socket-util.h"
29 #include "timeval.h"
30 #include "vlog.h"
31
32 #undef poll_fd_wait
33 #undef poll_timer_wait
34 #undef poll_timer_wait_until
35 #undef poll_immediate_wake
36
37 VLOG_DEFINE_THIS_MODULE(poll_loop);
38
39 COVERAGE_DEFINE(poll_fd_wait);
40 COVERAGE_DEFINE(poll_zero_timeout);
41
42 /* An event that will wake the following call to poll_block(). */
43 struct poll_waiter {
44     const char *where;          /* Where the waiter was created. */
45 };
46
47 /* All active poll waiters. */
48 static struct poll_waiter *waiters;
49 static struct pollfd *pollfds;
50 static size_t n_waiters, allocated_waiters;
51
52 /* Time at which to wake up the next call to poll_block(), in milliseconds as
53  * returned by time_msec(), LLONG_MIN to wake up immediately, or LLONG_MAX to
54  * wait forever. */
55 static long long int timeout_when = LLONG_MAX;
56
57 /* Location where waiter created. */
58 static const char *timeout_where;
59
60 static void new_waiter(int fd, short int events, const char *where);
61
62 /* Registers 'fd' as waiting for the specified 'events' (which should be POLLIN
63  * or POLLOUT or POLLIN | POLLOUT).  The following call to poll_block() will
64  * wake up when 'fd' becomes ready for one or more of the requested events.
65  *
66  * The event registration is one-shot: only the following call to poll_block()
67  * is affected.  The event will need to be re-registered after poll_block() is
68  * called if it is to persist.
69  *
70  * Ordinarily the 'where' argument is supplied automatically; see poll-loop.h
71  * for more information. */
72 void
73 poll_fd_wait(int fd, short int events, const char *where)
74 {
75     COVERAGE_INC(poll_fd_wait);
76     new_waiter(fd, events, where);
77 }
78
79 /* Causes the following call to poll_block() to block for no more than 'msec'
80  * milliseconds.  If 'msec' is nonpositive, the following call to poll_block()
81  * will not block at all.
82  *
83  * The timer registration is one-shot: only the following call to poll_block()
84  * is affected.  The timer will need to be re-registered after poll_block() is
85  * called if it is to persist.
86  *
87  * Ordinarily the 'where' argument is supplied automatically; see poll-loop.h
88  * for more information. */
89 void
90 poll_timer_wait(long long int msec, const char *where)
91 {
92     long long int now = time_msec();
93     long long int when;
94
95     if (msec <= 0) {
96         /* Wake up immediately. */
97         when = LLONG_MIN;
98     } else if ((unsigned long long int) now + msec <= LLONG_MAX) {
99         /* Normal case. */
100         when = now + msec;
101     } else {
102         /* now + msec would overflow. */
103         when = LLONG_MAX;
104     }
105
106     poll_timer_wait_until(when, where);
107 }
108
109 /* Causes the following call to poll_block() to wake up when the current time,
110  * as returned by time_msec(), reaches 'when' or later.  If 'when' is earlier
111  * than the current time, the following call to poll_block() will not block at
112  * all.
113  *
114  * The timer registration is one-shot: only the following call to poll_block()
115  * is affected.  The timer will need to be re-registered after poll_block() is
116  * called if it is to persist.
117  *
118  * Ordinarily the 'where' argument is supplied automatically; see poll-loop.h
119  * for more information. */
120 void
121 poll_timer_wait_until(long long int when, const char *where)
122 {
123     if (when < timeout_when) {
124         timeout_when = when;
125         timeout_where = where;
126     }
127 }
128
129 /* Causes the following call to poll_block() to wake up immediately, without
130  * blocking.
131  *
132  * Ordinarily the 'where' argument is supplied automatically; see poll-loop.h
133  * for more information. */
134 void
135 poll_immediate_wake(const char *where)
136 {
137     poll_timer_wait(0, where);
138 }
139
140 /* Logs, if appropriate, that the poll loop was awakened by an event
141  * registered at 'where' (typically a source file and line number).  The other
142  * arguments have two possible interpretations:
143  *
144  *   - If 'pollfd' is nonnull then it should be the "struct pollfd" that caused
145  *     the wakeup.  'timeout' is ignored.
146  *
147  *   - If 'pollfd' is NULL then 'timeout' is the number of milliseconds after
148  *     which the poll loop woke up.
149  */
150 static void
151 log_wakeup(const char *where, const struct pollfd *pollfd, int timeout)
152 {
153     static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(10, 10);
154     enum vlog_level level;
155     int cpu_usage;
156     struct ds s;
157
158     cpu_usage = get_cpu_usage();
159     if (VLOG_IS_DBG_ENABLED()) {
160         level = VLL_DBG;
161     } else if (cpu_usage > 50 && !VLOG_DROP_INFO(&rl)) {
162         level = VLL_INFO;
163     } else {
164         return;
165     }
166
167     ds_init(&s);
168     ds_put_cstr(&s, "wakeup due to ");
169     if (pollfd) {
170         char *description = describe_fd(pollfd->fd);
171         if (pollfd->revents & POLLIN) {
172             ds_put_cstr(&s, "[POLLIN]");
173         }
174         if (pollfd->revents & POLLOUT) {
175             ds_put_cstr(&s, "[POLLOUT]");
176         }
177         if (pollfd->revents & POLLERR) {
178             ds_put_cstr(&s, "[POLLERR]");
179         }
180         if (pollfd->revents & POLLHUP) {
181             ds_put_cstr(&s, "[POLLHUP]");
182         }
183         if (pollfd->revents & POLLNVAL) {
184             ds_put_cstr(&s, "[POLLNVAL]");
185         }
186         ds_put_format(&s, " on fd %d (%s)", pollfd->fd, description);
187         free(description);
188     } else {
189         ds_put_format(&s, "%d-ms timeout", timeout);
190     }
191     if (where) {
192         ds_put_format(&s, " at %s", where);
193     }
194     if (cpu_usage >= 0) {
195         ds_put_format(&s, " (%d%% CPU usage)", cpu_usage);
196     }
197     VLOG(level, "%s", ds_cstr(&s));
198     ds_destroy(&s);
199 }
200
201 /* Blocks until one or more of the events registered with poll_fd_wait()
202  * occurs, or until the minimum duration registered with poll_timer_wait()
203  * elapses, or not at all if poll_immediate_wake() has been called. */
204 void
205 poll_block(void)
206 {
207     int elapsed;
208     int retval;
209
210     /* Register fatal signal events before actually doing any real work for
211      * poll_block. */
212     fatal_signal_wait();
213
214     if (timeout_when == LLONG_MIN) {
215         COVERAGE_INC(poll_zero_timeout);
216     }
217     retval = time_poll(pollfds, n_waiters, timeout_when, &elapsed);
218     if (retval < 0) {
219         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
220         VLOG_ERR_RL(&rl, "poll: %s", ovs_strerror(-retval));
221     } else if (!retval) {
222         log_wakeup(timeout_where, NULL, elapsed);
223     } else if (get_cpu_usage() > 50 || VLOG_IS_DBG_ENABLED()) {
224         size_t i;
225
226         for (i = 0; i < n_waiters; i++) {
227             if (pollfds[i].revents) {
228                 log_wakeup(waiters[i].where, &pollfds[i], 0);
229             }
230         }
231     }
232
233     timeout_when = LLONG_MAX;
234     timeout_where = NULL;
235     n_waiters = 0;
236
237     /* Handle any pending signals before doing anything else. */
238     fatal_signal_run();
239 }
240 \f
241 /* Creates a new poll_waiter for 'fd' and 'events', recording 'where' as the
242  * location where the event was registered. */
243 static void
244 new_waiter(int fd, short int events, const char *where)
245 {
246     if (n_waiters >= allocated_waiters) {
247         waiters = x2nrealloc(waiters, &allocated_waiters, sizeof *waiters);
248         pollfds = xrealloc(pollfds, allocated_waiters * sizeof *pollfds);
249     }
250
251     waiters[n_waiters].where = where;
252     pollfds[n_waiters].fd = fd;
253     pollfds[n_waiters].events = events;
254     n_waiters++;
255 }