From: Ben Pfaff Date: Wed, 12 May 2010 19:53:07 +0000 (-0700) Subject: poll-loop: New function poll_timer_wait_until(). X-Git-Tag: v1.0.1~28 X-Git-Url: http://git.onelab.eu/?a=commitdiff_plain;h=7cf8b2660f9813fe080a3f4fcc975099cb36417a;p=sliver-openvswitch.git poll-loop: New function poll_timer_wait_until(). Many of poll_timer_wait()'s callers actually want to wait until a specific time, so it's convenient for them to offer a function that does this. --- diff --git a/extras/ezio/ezio-term.c b/extras/ezio/ezio-term.c index cedc5c967..d96122bc8 100644 --- a/extras/ezio/ezio-term.c +++ b/extras/ezio/ezio-term.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2008, 2009 Nicira Networks, Inc. +/* Copyright (c) 2008, 2009, 2010 Nicira Networks, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -907,14 +907,7 @@ scanner_run(struct scanner *s, struct ezio *ezio) static void scanner_wait(struct scanner *s) { - long long int now = time_msec(); - long long int expires = s->last_move + 750; - if (now >= expires) { - poll_immediate_wake(); - } else { - poll_timer_wait(expires - now); - } - + poll_timer_wait_until(s->last_move + 750); } static void diff --git a/extras/ezio/ovs-switchui.c b/extras/ezio/ovs-switchui.c index 16a6903f5..6ebfecee5 100644 --- a/extras/ezio/ovs-switchui.c +++ b/extras/ezio/ovs-switchui.c @@ -242,7 +242,7 @@ main(int argc, char *argv[]) refresh(); poll_fd_wait(STDIN_FILENO, POLLIN); - poll_timer_wait(timeout - time_msec()); + poll_timer_wait_until(timeout); poll_block(); } while (time_msec() < timeout); age_messages(); @@ -868,7 +868,7 @@ fetch_status(struct rconn *rconn, struct dict *dict, long long timeout) rconn_run_wait(rconn); rconn_recv_wait(rconn); - poll_timer_wait(timeout - time_msec()); + poll_timer_wait_until(timeout); poll_block(); } } @@ -1714,7 +1714,7 @@ menu_show(const struct menu *menu, int start, bool select) refresh(); if (pos < min || pos > max) { - poll_timer_wait(adjust - time_msec()); + poll_timer_wait_until(adjust); } poll_fd_wait(STDIN_FILENO, POLLIN); poll_block(); @@ -1946,7 +1946,7 @@ static void block_until(long long timeout) { while (timeout > time_msec()) { - poll_timer_wait(timeout - time_msec()); + poll_timer_wait_until(timeout); poll_block(); } drain_keyboard_buffer(); diff --git a/lib/dhcp-client.c b/lib/dhcp-client.c index 0abf115b0..563a415c5 100644 --- a/lib/dhcp-client.c +++ b/lib/dhcp-client.c @@ -806,13 +806,8 @@ void dhclient_wait(struct dhclient *cli) { if (cli->min_timeout != UINT_MAX) { - time_t now = time_now(); - unsigned int wake = sat_add(cli->state_entered, cli->min_timeout); - if (wake <= now) { - poll_immediate_wake(); - } else { - poll_timer_wait(sat_mul(sat_sub(wake, now), 1000)); - } + long long int wake = sat_add(cli->state_entered, cli->min_timeout); + poll_timer_wait_until(wake * 1000); } /* Reset timeout to 1 second. This will have no effect ordinarily, because * dhclient_run() will typically set it back to a higher value. If, diff --git a/lib/learning-switch.c b/lib/learning-switch.c index 91f8f0527..64639f2c8 100644 --- a/lib/learning-switch.c +++ b/lib/learning-switch.c @@ -220,8 +220,7 @@ lswitch_run(struct lswitch *sw, struct rconn *rconn) static void wait_timeout(long long int started) { - long long int now = time_msec(); - poll_timer_wait(10000 - (now - started)); + poll_timer_wait_until(started + 10000); } void diff --git a/lib/mac-learning.c b/lib/mac-learning.c index a9d414d2f..f9859b6b0 100644 --- a/lib/mac-learning.c +++ b/lib/mac-learning.c @@ -293,6 +293,6 @@ mac_learning_wait(struct mac_learning *ml) { if (!list_is_empty(&ml->lrus)) { struct mac_entry *e = mac_entry_from_lru_node(ml->lrus.next); - poll_timer_wait((e->expires - time_now()) * 1000); + poll_timer_wait_until(e->expires * 1000LL); } } diff --git a/lib/poll-loop.c b/lib/poll-loop.c index 29931f785..91034b04e 100644 --- a/lib/poll-loop.c +++ b/lib/poll-loop.c @@ -100,6 +100,23 @@ poll_timer_wait(long long int msec) : msec); } +/* Causes the following call to poll_block() to wake up when the current time, + * as returned by time_msec(), reaches 'msec' or later. If 'msec' is earlier + * than the current time, the following call to poll_block() will not block at + * all. + * + * The timer registration is one-shot: only the following call to poll_block() + * is affected. The timer will need to be re-registered after poll_block() is + * called if it is to persist. */ +void +poll_timer_wait_until(long long int msec) +{ + long long int now = time_msec(); + poll_timer_wait__(msec <= now ? 0 + : msec < now + INT_MAX ? msec - now + : INT_MAX); +} + /* Causes the following call to poll_block() to wake up immediately, without * blocking. */ void diff --git a/lib/poll-loop.h b/lib/poll-loop.h index eaeca2be5..a9038ca58 100644 --- a/lib/poll-loop.h +++ b/lib/poll-loop.h @@ -43,6 +43,7 @@ struct poll_waiter; /* Schedule events to wake up the following poll_block(). */ struct poll_waiter *poll_fd_wait(int fd, short int events); void poll_timer_wait(long long int msec); +void poll_timer_wait_until(long long int msec); void poll_immediate_wake(void); /* Wait until an event occurs. */ diff --git a/lib/rconn.c b/lib/rconn.c index ea45134fe..71198ea76 100644 --- a/lib/rconn.c +++ b/lib/rconn.c @@ -500,9 +500,8 @@ rconn_run_wait(struct rconn *rc) timeo = timeout(rc); if (timeo != UINT_MAX) { - unsigned int expires = sat_add(rc->state_entered, timeo); - unsigned int remaining = sat_sub(expires, time_now()); - poll_timer_wait(sat_mul(remaining, 1000)); + long long int expires = sat_add(rc->state_entered, timeo); + poll_timer_wait_until(expires * 1000); } if ((rc->state & (S_ACTIVE | S_IDLE)) && rc->txq.n) { diff --git a/ofproto/fail-open.c b/ofproto/fail-open.c index a79c5b226..b028493d6 100644 --- a/ofproto/fail-open.c +++ b/ofproto/fail-open.c @@ -271,7 +271,7 @@ void fail_open_wait(struct fail_open *fo) { if (fo->next_bogus_packet_in != LLONG_MAX) { - poll_timer_wait(fo->next_bogus_packet_in - time_msec()); + poll_timer_wait_until(fo->next_bogus_packet_in); } } diff --git a/ofproto/in-band.c b/ofproto/in-band.c index bf90273e1..e52a0a056 100644 --- a/ofproto/in-band.c +++ b/ofproto/in-band.c @@ -745,14 +745,9 @@ in_band_run(struct in_band *ib) void in_band_wait(struct in_band *in_band) { - time_t now = time_now(); - time_t wakeup + long long int wakeup = MIN(in_band->next_remote_refresh, in_band->next_local_refresh); - if (wakeup > now) { - poll_timer_wait((wakeup - now) * 1000); - } else { - poll_immediate_wake(); - } + poll_timer_wait_until(wakeup * 1000); } /* ofproto has flushed all flows from the flow table and it is calling us back diff --git a/ofproto/ofproto-sflow.c b/ofproto/ofproto-sflow.c index 60baf0e9e..37c1bb7f4 100644 --- a/ofproto/ofproto-sflow.c +++ b/ofproto/ofproto-sflow.c @@ -607,6 +607,6 @@ void ofproto_sflow_wait(struct ofproto_sflow *os) { if (ofproto_sflow_is_enabled(os)) { - poll_timer_wait(os->next_tick * 1000 - time_msec()); + poll_timer_wait_until(os->next_tick * 1000LL); } } diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 41977874b..101094835 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -1155,7 +1155,7 @@ ofproto_wait(struct ofproto *p) ofconn_wait(ofconn); } if (p->in_band) { - poll_timer_wait(p->next_in_band_update - time_msec()); + poll_timer_wait_until(p->next_in_band_update); in_band_wait(p->in_band); } if (p->fail_open) { @@ -1172,7 +1172,7 @@ ofproto_wait(struct ofproto *p) VLOG_DBG_RL(&rl, "need revalidate in ofproto_wait_cb()"); poll_immediate_wake(); } else if (p->next_expiration != LLONG_MAX) { - poll_timer_wait(p->next_expiration - time_msec()); + poll_timer_wait_until(p->next_expiration); } for (i = 0; i < p->n_listeners; i++) { pvconn_wait(p->listeners[i]); diff --git a/ovsdb/trigger.c b/ovsdb/trigger.c index 8f18291f4..47719698c 100644 --- a/ovsdb/trigger.c +++ b/ovsdb/trigger.c @@ -102,7 +102,7 @@ ovsdb_trigger_wait(struct ovsdb *db, long long int now) } if (deadline < LLONG_MAX) { - poll_timer_wait(deadline - now); + poll_timer_wait_until(deadline); } } } diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 354d4d894..04898f88d 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -1986,11 +1986,11 @@ bond_wait(struct bridge *br) for (j = 0; j < port->n_ifaces; j++) { struct iface *iface = port->ifaces[j]; if (iface->delay_expires != LLONG_MAX) { - poll_timer_wait(iface->delay_expires - time_msec()); + poll_timer_wait_until(iface->delay_expires); } } if (port->bond_fake_iface) { - poll_timer_wait(port->bond_next_fake_iface_update - time_msec()); + poll_timer_wait_until(port->bond_next_fake_iface_update); } } } diff --git a/xenserver/ovs-xenserverd.c b/xenserver/ovs-xenserverd.c index a69ca8adb..1598b01bf 100644 --- a/xenserver/ovs-xenserverd.c +++ b/xenserver/ovs-xenserverd.c @@ -240,7 +240,7 @@ network_uuid_refresh_wait(void) poll_timer_wait(1000); } if (next_refresh != LLONG_MAX) { - poll_timer_wait(next_refresh - time_msec()); + poll_timer_wait_until(next_refresh); } } }