If you'd like to unsubscribe from the list, please go to the following
website, and enter your email address in the bottom of the page where
it says "unsubscribe or edit options"

http://mail.openvswitch.org/mailman/listinfo/dev

On Thu, Dec 12, 2013 at 5:44 PM, Nackeeran <[email protected]> wrote:
>
>
> Sent from my iPhone
>
>> On Dec 12, 2013, at 4:28 PM, [email protected] wrote:
>>
>> Send dev mailing list submissions to
>>    [email protected]
>>
>> To subscribe or unsubscribe via the World Wide Web, visit
>>    http://openvswitch.org/mailman/listinfo/dev
>> or, via email, send a message with subject or body 'help' to
>>    [email protected]
>>
>> You can reach the person managing the list at
>>    [email protected]
>>
>> When replying, please edit your Subject line so it is more specific
>> than "Re: Contents of dev digest..."
>>
>>
>> Today's Topics:
>>
>>   1. Re: [PATCHv2] monitor: Replace monitor_seq with periodic
>>      wakeup (Alex Wang)
>>   2. [PATCH] pool-loop: windows poll_block implementation (Linda Sun)
>>
>>
>> ----------------------------------------------------------------------
>>
>> Message: 1
>> Date: Thu, 12 Dec 2013 16:17:50 -0800
>> From: Alex Wang <[email protected]>
>> Subject: Re: [ovs-dev] [PATCHv2] monitor: Replace monitor_seq with
>>    periodic    wakeup
>> To: Joe Stringer <[email protected]>, Ben Pfaff <[email protected]>,
>>    Ethan Jackson <[email protected]>
>> Cc: "[email protected]" <[email protected]>
>> Message-ID:
>>    <CAArS4XXw0Bk1rm8c1re_FN=jlvdp4jgwwj+_tmypk65_55v...@mail.gmail.com>
>> Content-Type: text/plain; charset="iso-8859-1"
>>
>> Hey Ben, Ethan,
>>
>> Could any of you apply this patch?
>>
>> Thanks,
>> Alex Wang,
>>
>>
>>> On Thu, Dec 12, 2013 at 4:15 PM, Alex Wang <[email protected]> wrote:
>>>
>>> This patch looks good to me, thx for doing this.
>>>
>>>
>>> On Thu, Dec 12, 2013 at 1:03 PM, Joe Stringer <[email protected]>wrote:
>>>
>>>> Currently, every time a monitoring port is added or reconfigured, the
>>>> main thread notifies the monitoring thread to wake up immediately using
>>>> monitor_seq. When adding a large number of ports at once, this causes
>>>> contention as the threads fight over access to the monitor heap---one
>>>> thread adding new ports, the other popping and processing the new ports.
>>>>
>>>> This patch removes this mechanism in favour of a simple periodic wakeup
>>>> in the monitor thread. When configuring batches of 500 tunnels at once,
>>>> up to a total of 5000 tunnels, this reduces configuration time by up to
>>>> 35%. New port monitor port configuration may not take effect for as long
>>>> as ~100ms, although it may be less if the timer has not recently timed
>>>> out, or if a monitoring port is due to send a packet.
>>>>
>>>> Signed-off-by: Joe Stringer <[email protected]>
>>>> ---
>>>> v2: Rebase
>>>> ---
>>>> ofproto/ofproto-dpif-monitor.c |   18 ++++++++++--------
>>>> tests/bfd.at                   |   16 +++++++---------
>>>> tests/cfm.at                   |    8 +++++---
>>>> 3 files changed, 22 insertions(+), 20 deletions(-)
>>>>
>>>> diff --git a/ofproto/ofproto-dpif-monitor.c
>>>> b/ofproto/ofproto-dpif-monitor.c
>>>> index d06b2e1..2a833bb 100644
>>>> --- a/ofproto/ofproto-dpif-monitor.c
>>>> +++ b/ofproto/ofproto-dpif-monitor.c
>>>> @@ -63,7 +63,6 @@ static pthread_t monitor_tid;
>>>> /* True if the monitor thread is running. */
>>>> static bool monitor_running;
>>>>
>>>> -static struct seq *monitor_seq;
>>>> static struct latch monitor_exit_latch;
>>>> static struct ovs_rwlock monitor_rwlock = OVS_RWLOCK_INITIALIZER;
>>>>
>>>> @@ -149,10 +148,9 @@ mport_update(struct mport *mport, struct bfd *bfd,
>>>> struct cfm *cfm,
>>>>         memcpy(mport->hw_addr, hw_addr, ETH_ADDR_LEN);
>>>>     }
>>>>     /* If bfd/cfm is added or reconfigured, move the mport on top of the
>>>> heap
>>>> -     * and wakes up the monitor thread. */
>>>> +     * so that the monitor thread can run the mport next time it wakes
>>>> up. */
>>>>     if (mport->bfd || mport->cfm) {
>>>>         heap_change(&monitor_heap, &mport->heap_node, LLONG_MAX);
>>>> -        seq_change(monitor_seq);
>>>>     }
>>>> }
>>>>
>>>> @@ -165,7 +163,6 @@ monitor_init(void)
>>>>
>>>>     if (ovsthread_once_start(&once)) {
>>>>         hmap_init(&monitor_hmap);
>>>> -        monitor_seq = seq_create();
>>>>         ovsthread_once_done(&once);
>>>>     }
>>>> }
>>>> @@ -177,17 +174,18 @@ monitor_main(void * args OVS_UNUSED)
>>>>     set_subprogram_name("monitor");
>>>>     VLOG_INFO("monitor thread created");
>>>>     while (!latch_is_set(&monitor_exit_latch)) {
>>>> -        uint64_t seq = seq_read(monitor_seq);
>>>> -
>>>>         monitor_run();
>>>>         latch_wait(&monitor_exit_latch);
>>>> -        seq_wait(monitor_seq, seq);
>>>>         poll_block();
>>>>     }
>>>>     VLOG_INFO("monitor thread terminated");
>>>>     return NULL;
>>>> }
>>>>
>>>> +/* The monitor thread should wake up this often to ensure that newly
>>>> added or
>>>> + * reconfigured monitoring ports are run in a timely manner. */
>>>> +#define MONITOR_INTERVAL_MSEC 100
>>>> +
>>>> /* Checks the sending of control packets on mports that have timed out.
>>>>  * Sends the control packets if needed.  Executes bfd and cfm periodic
>>>>  * functions (run, wait) on those mports. */
>>>> @@ -234,7 +232,11 @@ monitor_run(void)
>>>>
>>>>     /* Waits on the earliest next wakeup time. */
>>>>     if (!heap_is_empty(&monitor_heap)) {
>>>> -
>>>> poll_timer_wait_until(PRIO_TO_MSEC(heap_max(&monitor_heap)->priority));
>>>> +        long long int next_timeout, next_mport_wakeup;
>>>> +
>>>> +        next_timeout = time_msec() + MONITOR_INTERVAL_MSEC;
>>>> +        next_mport_wakeup =
>>>> PRIO_TO_MSEC(heap_max(&monitor_heap)->priority);
>>>> +        poll_timer_wait_until(MIN(next_timeout, next_mport_wakeup));
>>>>     }
>>>>     ovs_rwlock_unlock(&monitor_rwlock);
>>>>     ofpbuf_uninit(&packet);
>>>> diff --git a/tests/bfd.at b/tests/bfd.at
>>>> index ccb62b5..6583dd5 100644
>>>> --- a/tests/bfd.at
>>>> +++ b/tests/bfd.at
>>>> @@ -334,6 +334,7 @@ BFD_CHECK([p1], [true], [false], [none], [up], [No
>>>> Diagnostic], [none], [up], [N
>>>> # for decay_min_rx < 2000ms, the decay detection time is set to 2000ms.
>>>> # this should reset the min_rx.
>>>> AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=1000])
>>>> +ovs-appctl time/warp 100
>>>> BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
>>>>
>>>> @@ -360,8 +361,7 @@ for i in `seq 0 9`; do ovs-appctl time/warp 500; done
>>>> # Test-4 BFD decay: set min_rx to 800ms.
>>>> # this should firstly reset the min_rx and then re-decay to 1000ms.
>>>> AT_CHECK([ovs-vsctl set Interface p0 bfd:min_rx=800])
>>>> -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> -BFD_CHECK_RX([p0], [800ms], [800ms], [500ms])
>>>> +ovs-appctl time/warp 100
>>>>
>>>> # for the following 1600ms, there should be no decay,
>>>> # since the decay detection time is set to 2000ms.
>>>> @@ -385,8 +385,7 @@ for i in `seq 0 9`; do ovs-appctl time/warp 500; done
>>>>
>>>> # Test-5 BFD decay: set min_rx to 300ms and decay_min_rx to 5000ms
>>>> together.
>>>> AT_CHECK([ovs-vsctl set Interface p0 bfd:min_rx=300
>>>> bfd:decay_min_rx=5000])
>>>> -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
>>>> +ovs-appctl time/warp 100
>>>>
>>>> # for decay_min_rx > 2000ms, the decay detection time is set to
>>>> # decay_min_rx (5000ms).
>>>> @@ -412,9 +411,8 @@ for i in `seq 0 9`; do ovs-appctl time/warp 500; done
>>>>
>>>> # Test-6 BFD decay: set decay_min_rx to 0 to disable bfd decay.
>>>> AT_CHECK([ovs-vsctl set Interface p0 bfd:decay_min_rx=0])
>>>> -# min_rx is reset.
>>>> -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
>>>> +ovs-appctl time/warp 100
>>>> +
>>>> for i in `seq 0 20`
>>>> do
>>>>     ovs-appctl time/warp 500
>>>> @@ -444,6 +442,8 @@ do
>>>> done
>>>> # reset the p1's min_tx to 500ms.
>>>> AT_CHECK([ovs-vsctl set Interface p1 bfd:min_tx=500])
>>>> +ovs-appctl time/warp 100
>>>> +
>>>> # since p0 has been in decay, now the RX will show 3000ms.
>>>> BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> BFD_CHECK_RX([p0], [3000ms], [3000ms], [500ms])
>>>> @@ -629,8 +629,6 @@ done
>>>>
>>>> # reconfigure the decay_min_rx to 1000ms.
>>>> AT_CHECK([ovs-vsctl set interface p0 bfd:decay_min_rx=1000])
>>>> -BFD_CHECK_TX([p0], [500ms], [300ms], [500ms])
>>>> -BFD_CHECK_RX([p0], [500ms], [300ms], [500ms])
>>>>
>>>> # wait for 5000ms to decay.
>>>> for i in `seq 0 9`; do ovs-appctl time/warp 500; done
>>>> diff --git a/tests/cfm.at b/tests/cfm.at
>>>> index 9e351d0..620e3e0 100644
>>>> --- a/tests/cfm.at
>>>> +++ b/tests/cfm.at
>>>> @@ -83,17 +83,19 @@ for i in `seq 0 100`; do ovs-appctl time/warp 100;
>>>> done
>>>> CFM_CHECK_EXTENDED([p0], [1], [100], [up], [up], [100ms], [2], [up])
>>>> CFM_CHECK_EXTENDED([p1], [2], [100], [up], [up], [100ms], [1], [up])
>>>>
>>>> -# turn cfm on p1 off, should increment the cfm_flap_count on p1.
>>>> +# turn cfm on p1 off, should increment the cfm_flap_count on p0.
>>>> AT_CHECK([ovs-vsctl remove interface p1 cfm_mpid 2])
>>>> for i in `seq 0 10`; do ovs-appctl time/warp 100; done
>>>> CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count      : 1])
>>>> CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count      :
>>>> [[]]])
>>>>
>>>> -# turn cfm on p1 on again, should increment the cfm_flap_count on p1.
>>>> +# turn cfm on p1 on again, should increment the cfm_flap_count on p0.
>>>> +# After p1 is configured, but before it is first run, it will receive
>>>> +# a ccm with the rdi bit set, and detect a flap as well.
>>>> AT_CHECK([ovs-vsctl set interface p1 cfm_mpid=2])
>>>> for i in `seq 0 10`; do ovs-appctl time/warp 100; done
>>>> CFM_VSCTL_LIST_IFACE([p0], [cfm_flap_count], [cfm_flap_count      : 2])
>>>> -CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count      : 0])
>>>> +CFM_VSCTL_LIST_IFACE([p1], [cfm_flap_count], [cfm_flap_count      : 2])
>>>>
>>>> OVS_VSWITCHD_STOP
>>>> AT_CLEANUP
>>>> \ No newline at end of file
>>>> --
>>>> 1.7.9.5
>>>>
>>>> _______________________________________________
>>>> dev mailing list
>>>> [email protected]
>>>> http://openvswitch.org/mailman/listinfo/dev
>> -------------- next part --------------
>> An HTML attachment was scrubbed...
>> URL: 
>> <http://openvswitch.org/pipermail/dev/attachments/20131212/25762204/attachment-0001.htm>
>>
>> ------------------------------
>>
>> Message: 2
>> Date: Thu, 12 Dec 2013 16:28:12 -0800
>> From: Linda Sun <[email protected]>
>> Subject: [ovs-dev] [PATCH] pool-loop: windows poll_block
>>    implementation
>> To: [email protected]
>> Message-ID: <[email protected]>
>>
>> Use WaitForMultipleObjects for polling on windows.  This works on all kinds
>> of objects, e.g. sockets, files, especially ioctl calls to the kernel.
>> One additional paramater is passed down in poll_fd_wait() to help
>> WaitForMultipleObjects.
>> latch is signaled with event, to be waited/polled by WaitForMultipleObjects()
>> as well.
>> Changed array of fds to hmap to check for duplicate fds.
>>
>> Signed-off-by: Linda Sun <[email protected]>
>> ---
>> lib/dpif-linux.c     |    2 +-
>> lib/fatal-signal.c   |    2 +-
>> lib/latch.c          |   37 ++++++++++++++-
>> lib/latch.h          |    3 ++
>> lib/netdev-linux.c   |    2 +-
>> lib/netlink-socket.c |    2 +-
>> lib/poll-loop.c      |  121 
>> +++++++++++++++++++++++++++++++++++++++++---------
>> lib/poll-loop.h      |    4 +-
>> lib/process.c        |    2 +-
>> lib/signals.c        |    2 +-
>> lib/socket-util.c    |    2 +-
>> lib/stream-fd.c      |    6 +--
>> lib/timeval.c        |   15 +++++--
>> lib/timeval.h        |    4 +-
>> tests/test-netflow.c |    2 +-
>> tests/test-sflow.c   |    2 +-
>> 16 files changed, 167 insertions(+), 41 deletions(-)
>>
>> diff --git a/lib/dpif-linux.c b/lib/dpif-linux.c
>> index 25715f4..a8246f3 100644
>> --- a/lib/dpif-linux.c
>> +++ b/lib/dpif-linux.c
>> @@ -1482,7 +1482,7 @@ dpif_linux_recv_wait(struct dpif *dpif_)
>>
>>     ovs_mutex_lock(&dpif->upcall_lock);
>>     if (dpif->epoll_fd >= 0) {
>> -        poll_fd_wait(dpif->epoll_fd, POLLIN);
>> +        poll_fd_wait(dpif->epoll_fd, 0, POLLIN);
>>     }
>>     ovs_mutex_unlock(&dpif->upcall_lock);
>> }
>> diff --git a/lib/fatal-signal.c b/lib/fatal-signal.c
>> index e980f4b..052ca26 100644
>> --- a/lib/fatal-signal.c
>> +++ b/lib/fatal-signal.c
>> @@ -182,7 +182,7 @@ void
>> fatal_signal_wait(void)
>> {
>>     fatal_signal_init();
>> -    poll_fd_wait(signal_fds[0], POLLIN);
>> +    poll_fd_wait(signal_fds[0], 0, POLLIN);
>> }
>>
>> static void
>> diff --git a/lib/latch.c b/lib/latch.c
>> index bf518b9..5bc97b4 100644
>> --- a/lib/latch.c
>> +++ b/lib/latch.c
>> @@ -27,15 +27,28 @@
>> void
>> latch_init(struct latch *latch)
>> {
>> +#ifndef WIN32
>>     xpipe_nonblocking(latch->fds);
>> +    latch->wevent = 0;
>> +#else
>> +    latch->fds[0] = 0;
>> +    latch->is_set = FALSE;
>> +    latch->wevent = CreateEvent(NULL, TRUE, FALSE, NULL);
>> +#endif
>> }
>>
>> /* Destroys 'latch'. */
>> void
>> latch_destroy(struct latch *latch)
>> {
>> +#ifndef WIN32
>>     close(latch->fds[0]);
>>     close(latch->fds[1]);
>> +#else
>> +    latch->fds[0] = 0;
>> +    latch->is_set = FALSE;
>> +    CloseHandle(latch->wevent);
>> +#endif
>> }
>>
>> /* Resets 'latch' to the unset state.  Returns true if 'latch' was previously
>> @@ -43,9 +56,18 @@ latch_destroy(struct latch *latch)
>> bool
>> latch_poll(struct latch *latch)
>> {
>> +#ifndef WIN32
>>     char buffer[_POSIX_PIPE_BUF];
>>
>>     return read(latch->fds[0], buffer, sizeof buffer) > 0;
>> +#else
>> +    bool is_set;
>> +
>> +    is_set = latch->is_set;
>> +    latch->is_set = FALSE;
>> +    ResetEvent(latch->wevent);
>> +    return is_set;
>> +#endif
>> }
>>
>> /* Sets 'latch'.
>> @@ -55,7 +77,12 @@ latch_poll(struct latch *latch)
>> void
>> latch_set(struct latch *latch)
>> {
>> +#ifndef WIN32
>>     ignore(write(latch->fds[1], "", 1));
>> +#else
>> +    latch->is_set = TRUE;
>> +    SetEvent(latch->wevent);
>> +#endif
>> }
>>
>> /* Returns true if 'latch' is set, false otherwise.  Does not reset 'latch'
>> @@ -63,6 +90,7 @@ latch_set(struct latch *latch)
>> bool
>> latch_is_set(const struct latch *latch)
>> {
>> +#ifndef WIN32
>>     struct pollfd pfd;
>>     int retval;
>>
>> @@ -73,6 +101,9 @@ latch_is_set(const struct latch *latch)
>>     } while (retval < 0 && errno == EINTR);
>>
>>     return pfd.revents & POLLIN;
>> +#else
>> +    return latch->is_set;
>> +#endif
>> }
>>
>> /* Causes the next poll_block() to wake up when 'latch' is set.
>> @@ -83,5 +114,9 @@ latch_is_set(const struct latch *latch)
>> void
>> latch_wait_at(const struct latch *latch, const char *where)
>> {
>> -    poll_fd_wait_at(latch->fds[0], POLLIN, where);
>> +#ifndef WIN32
>> +    poll_fd_wait_at(latch->fds[0], latch->wevent, POLLIN, where);
>> +#else
>> +    poll_fd_wait_at(latch->fds[0], latch->wevent, POLLIN, where);
>> +#endif
>> }
>> diff --git a/lib/latch.h b/lib/latch.h
>> index 0b6e8a3..3c27f86 100644
>> --- a/lib/latch.h
>> +++ b/lib/latch.h
>> @@ -24,9 +24,12 @@
>>
>> #include <stdbool.h>
>> #include "util.h"
>> +#include "ovs-thread.h"
>>
>> struct latch {
>>     int fds[2];
>> +    uint32_t wevent;
>> +    bool is_set;
>> };
>>
>> void latch_init(struct latch *);
>> diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
>> index 3e0da48..755e9da 100644
>> --- a/lib/netdev-linux.c
>> +++ b/lib/netdev-linux.c
>> @@ -878,7 +878,7 @@ static void
>> netdev_linux_rx_wait(struct netdev_rx *rx_)
>> {
>>     struct netdev_rx_linux *rx = netdev_rx_linux_cast(rx_);
>> -    poll_fd_wait(rx->fd, POLLIN);
>> +    poll_fd_wait(rx->fd, 0, POLLIN);
>> }
>>
>> static int
>> diff --git a/lib/netlink-socket.c b/lib/netlink-socket.c
>> index 4bd6d36..c015d93 100644
>> --- a/lib/netlink-socket.c
>> +++ b/lib/netlink-socket.c
>> @@ -802,7 +802,7 @@ nl_dump_done(struct nl_dump *dump)
>> void
>> nl_sock_wait(const struct nl_sock *sock, short int events)
>> {
>> -    poll_fd_wait(sock->fd, events);
>> +    poll_fd_wait(sock->fd, 0, events);
>> }
>>
>> /* Returns the underlying fd for 'sock', for use in "poll()"-like operations
>> diff --git a/lib/poll-loop.c b/lib/poll-loop.c
>> index 5e3618b..ef5ee44 100644
>> --- a/lib/poll-loop.c
>> +++ b/lib/poll-loop.c
>> @@ -30,18 +30,29 @@
>> #include "socket-util.h"
>> #include "timeval.h"
>> #include "vlog.h"
>> +#include "hmap.h"
>> +#include "hash.h"
>>
>> VLOG_DEFINE_THIS_MODULE(poll_loop);
>>
>> COVERAGE_DEFINE(poll_fd_wait);
>> COVERAGE_DEFINE(poll_zero_timeout);
>>
>> +struct poll_node {
>> +    struct hmap_node    hmap_node;
>> +    struct pollfd       poll_fd;    /* Events to pass to time_poll() */
>> +#ifdef WIN32
>> +    HANDLE              wevent;     /* events for waitformultipleobjects */
>> +#else
>> +    uint32_t            wevent;
>> +#endif
>> +    const char          *where;     /* where each pollfd was created */
>> +};
>> +
>> struct poll_loop {
>>     /* All active poll waiters. */
>> -    struct pollfd *pollfds;     /* Events to pass to poll(). */
>> -    const char **where;         /* Where each pollfd was created. */
>> +    struct hmap poll_nodes;
>>     size_t n_waiters;           /* Number of elems in 'where' and 'pollfds'. 
>> */
>> -    size_t allocated_waiters;   /* Allocated elems in 'where' and 
>> 'pollfds'. */
>>
>>     /* Time at which to wake up the next call to poll_block(), LLONG_MIN to
>>      * wake up immediately, or LLONG_MAX to wait forever. */
>> @@ -51,6 +62,20 @@ struct poll_loop {
>>
>> static struct poll_loop *poll_loop(void);
>>
>> +/* Look up the node with same fd and wevent */
>> +static struct poll_node *
>> +poll_fd_node_find(struct poll_loop *loop, int fd, uint32_t wevent)
>> +{
>> +    struct poll_node *node;
>> +
>> +    HMAP_FOR_EACH_WITH_HASH(node, hmap_node, hash_2words(fd, wevent), 
>> &loop->poll_nodes) {
>> +        if (node->poll_fd.fd == fd && node->wevent == wevent) {
>> +            return node;
>> +        }
>> +    }
>> +    return NULL;
>> +}
>> +
>> /* Registers 'fd' as waiting for the specified 'events' (which should be 
>> POLLIN
>>  * or POLLOUT or POLLIN | POLLOUT).  The following call to poll_block() will
>>  * wake up when 'fd' becomes ready for one or more of the requested events.
>> @@ -63,23 +88,38 @@ static struct poll_loop *poll_loop(void);
>>  * automatically provide the caller's source file and line number for
>>  * 'where'.) */
>> void
>> -poll_fd_wait_at(int fd, short int events, const char *where)
>> +poll_fd_wait_at(int fd, uint32_t wevent, short int events, const char 
>> *where)
>> {
>>     struct poll_loop *loop = poll_loop();
>> +    struct poll_node *node;
>>
>>     COVERAGE_INC(poll_fd_wait);
>> -    if (loop->n_waiters >= loop->allocated_waiters) {
>> -        loop->where = x2nrealloc(loop->where, &loop->allocated_waiters,
>> -                                 sizeof *loop->where);
>> -        loop->pollfds = xrealloc(loop->pollfds,
>> -                                 (loop->allocated_waiters
>> -                                  * sizeof *loop->pollfds));
>> +
>> +#ifdef WIN32
>> +    /* null event cannot be polled */
>> +    if (wevent == NULL) {
>> +        VLOG_ERR("No event to wait fd %d\n", fd);
>> +        return;
>>     }
>> +#endif
>>
>> -    loop->where[loop->n_waiters] = where;
>> -    loop->pollfds[loop->n_waiters].fd = fd;
>> -    loop->pollfds[loop->n_waiters].events = events;
>> -    loop->n_waiters++;
>> +    /* check for duplicate.  If found, "or" the event */
>> +    node = poll_fd_node_find(loop, fd, wevent);
>> +    if (node) {
>> +        node->poll_fd.events |= events;
>> +    } else {
>> +        node = xzalloc(sizeof *node);
>> +        if (node == NULL) {
>> +            return;
>> +        }
>> +        node->where = where;
>> +        node->poll_fd.fd = fd;
>> +        node->wevent = wevent;
>> +        node->poll_fd.events = events;
>> +        hmap_insert(&loop->poll_nodes, &node->hmap_node,
>> +            hash_2words(fd, wevent));
>> +        loop->n_waiters++;
>> +    }
>> }
>>
>> /* Causes the following call to poll_block() to block for no more than 'msec'
>> @@ -215,8 +255,16 @@ void
>> poll_block(void)
>> {
>>     struct poll_loop *loop = poll_loop();
>> +    struct poll_node *node, *next;
>> +    struct pollfd *pollfds;
>> +#ifdef WIN32
>> +    HANDLE *wevents;
>> +#else
>> +    uint32_t *wevents;
>> +#endif
>>     int elapsed;
>>     int retval;
>> +    int i = 0;
>>
>>     /* Register fatal signal events before actually doing any real work for
>>      * poll_block. */
>> @@ -227,7 +275,25 @@ poll_block(void)
>>     }
>>
>>     timewarp_wait();
>> -    retval = time_poll(loop->pollfds, loop->n_waiters,
>> +    pollfds = xzalloc(loop->n_waiters * sizeof *pollfds);
>> +    if (pollfds == NULL) {
>> +        return;
>> +    }
>> +
>> +    wevents = xzalloc(loop->n_waiters * sizeof *wevents);
>> +    if (wevents == NULL) {
>> +        free(pollfds);
>> +        return;
>> +    }
>> +
>> +    /* populate with all the fds and events */
>> +    HMAP_FOR_EACH(node, hmap_node, &loop->poll_nodes) {
>> +        memcpy(&pollfds[i], &node->poll_fd, sizeof node->poll_fd);
>> +        wevents[i] = node->wevent;
>> +        i++;
>> +    }
>> +
>> +    retval = time_poll(pollfds, loop->n_waiters, wevents,
>>                        loop->timeout_when, &elapsed);
>>     if (retval < 0) {
>>         static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
>> @@ -237,16 +303,23 @@ poll_block(void)
>>     } else if (get_cpu_usage() > 50 || VLOG_IS_DBG_ENABLED()) {
>>         size_t i;
>>
>> -        for (i = 0; i < loop->n_waiters; i++) {
>> -            if (loop->pollfds[i].revents) {
>> -                log_wakeup(loop->where[i], &loop->pollfds[i], 0);
>> +        HMAP_FOR_EACH(node, hmap_node, &loop->poll_nodes) {
>> +            if (node->poll_fd.revents) {
>> +                log_wakeup(node->where, &node->poll_fd, 0);
>>             }
>>         }
>>     }
>>
>> -    loop->timeout_when = LLONG_MAX;
>> +    HMAP_FOR_EACH_SAFE(node, next, hmap_node, &loop->poll_nodes) {
>> +        hmap_remove(&loop->poll_nodes, &node->hmap_node);
>> +        free(node);
>> +    }
>> +
>> +    loop->timeout_when = LLONG_MIN;
>>     loop->timeout_where = NULL;
>>     loop->n_waiters = 0;
>> +    free(pollfds);
>> +    free(wevents);
>>
>>     /* Handle any pending signals before doing anything else. */
>>     fatal_signal_run();
>> @@ -258,9 +331,14 @@ static void
>> free_poll_loop(void *loop_)
>> {
>>     struct poll_loop *loop = loop_;
>> +    struct poll_node *node, *next;
>>
>> -    free(loop->pollfds);
>> -    free(loop->where);
>> +    HMAP_FOR_EACH_SAFE(node, next, hmap_node, &loop->poll_nodes) {
>> +        hmap_remove(&loop->poll_nodes, &node->hmap_node);
>> +        free(node);
>> +    }
>> +
>> +    hmap_destroy(&loop->poll_nodes);
>>     free(loop);
>> }
>>
>> @@ -279,6 +357,7 @@ poll_loop(void)
>>     loop = pthread_getspecific(key);
>>     if (!loop) {
>>         loop = xzalloc(sizeof *loop);
>> +        hmap_init(&loop->poll_nodes);
>>         xpthread_setspecific(key, loop);
>>     }
>>     return loop;
>> diff --git a/lib/poll-loop.h b/lib/poll-loop.h
>> index 0397853..f5c5665 100644
>> --- a/lib/poll-loop.h
>> +++ b/lib/poll-loop.h
>> @@ -50,8 +50,8 @@ extern "C" {
>>  * caller to supply a location explicitly, which is useful if the caller's 
>> own
>>  * caller would be more useful in log output.  See timer_wait_at() for an
>>  * example. */
>> -void poll_fd_wait_at(int fd, short int events, const char *where);
>> -#define poll_fd_wait(fd, events) poll_fd_wait_at(fd, events, SOURCE_LOCATOR)
>> +void poll_fd_wait_at(int fd, uint32_t wevent, short int events, const char 
>> *where);
>> +#define poll_fd_wait(fd, wevent, events) poll_fd_wait_at(fd, wevent, 
>> events, SOURCE_LOCATOR)
>>
>> void poll_timer_wait_at(long long int msec, const char *where);
>> #define poll_timer_wait(msec) poll_timer_wait_at(msec, SOURCE_LOCATOR)
>> diff --git a/lib/process.c b/lib/process.c
>> index 5dd34b3..e0a2166 100644
>> --- a/lib/process.c
>> +++ b/lib/process.c
>> @@ -333,7 +333,7 @@ process_wait(struct process *p)
>>     if (p->exited) {
>>         poll_immediate_wake();
>>     } else {
>> -        poll_fd_wait(fds[0], POLLIN);
>> +        poll_fd_wait(fds[0], 0, POLLIN);
>>     }
>> }
>>
>> diff --git a/lib/signals.c b/lib/signals.c
>> index 27da5d6..cc56375 100644
>> --- a/lib/signals.c
>> +++ b/lib/signals.c
>> @@ -88,7 +88,7 @@ signal_poll(struct signal *s)
>> void
>> signal_wait(struct signal *s)
>> {
>> -    poll_fd_wait(s->fds[0], POLLIN);
>> +    poll_fd_wait(s->fds[0], 0, POLLIN);
>> }
>>
>> static void
>> diff --git a/lib/socket-util.c b/lib/socket-util.c
>> index bb48ade..6c5d0ba 100644
>> --- a/lib/socket-util.c
>> +++ b/lib/socket-util.c
>> @@ -1354,7 +1354,7 @@ send_iovec_and_fds_fully_block(int sock,
>>         if (error != EAGAIN) {
>>             return error;
>>         }
>> -        poll_fd_wait(sock, POLLOUT);
>> +        poll_fd_wait(sock, 0, POLLOUT);
>>         poll_block();
>>     }
>> }
>> diff --git a/lib/stream-fd.c b/lib/stream-fd.c
>> index 1171f32..3520201 100644
>> --- a/lib/stream-fd.c
>> +++ b/lib/stream-fd.c
>> @@ -117,11 +117,11 @@ fd_wait(struct stream *stream, enum stream_wait_type 
>> wait)
>>     switch (wait) {
>>     case STREAM_CONNECT:
>>     case STREAM_SEND:
>> -        poll_fd_wait(s->fd, POLLOUT);
>> +        poll_fd_wait(s->fd, 0, POLLOUT);
>>         break;
>>
>>     case STREAM_RECV:
>> -        poll_fd_wait(s->fd, POLLIN);
>> +        poll_fd_wait(s->fd, 0, POLLIN);
>>         break;
>>
>>     default:
>> @@ -235,7 +235,7 @@ static void
>> pfd_wait(struct pstream *pstream)
>> {
>>     struct fd_pstream *ps = fd_pstream_cast(pstream);
>> -    poll_fd_wait(ps->fd, POLLIN);
>> +    poll_fd_wait(ps->fd, 0, POLLIN);
>> }
>>
>> static int
>> diff --git a/lib/timeval.c b/lib/timeval.c
>> index 2ce45fc..445232e 100644
>> --- a/lib/timeval.c
>> +++ b/lib/timeval.c
>> @@ -232,12 +232,12 @@ time_alarm(unsigned int secs)
>>  *
>>  * Stores the number of milliseconds elapsed during poll in '*elapsed'. */
>> int
>> -time_poll(struct pollfd *pollfds, int n_pollfds, long long int timeout_when,
>> -          int *elapsed)
>> +time_poll(struct pollfd *pollfds, int n_pollfds, void *handles,
>> +          long long int timeout_when, int *elapsed)
>> {
>>     long long int *last_wakeup = last_wakeup_get();
>>     long long int start;
>> -    int retval;
>> +    int retval = 0;
>>
>>     time_init();
>>     coverage_clear();
>> @@ -261,10 +261,19 @@ time_poll(struct pollfd *pollfds, int n_pollfds, long 
>> long int timeout_when,
>>             time_left = timeout_when - now;
>>         }
>>
>> +#ifndef WIN32
>>         retval = poll(pollfds, n_pollfds, time_left);
>>         if (retval < 0) {
>>             retval = -errno;
>>         }
>> +#else
>> +        if (n_pollfds != 0) {
>> +            retval = WaitForMultipleObjects(n_pollfds, handles, FALSE, 
>> time_left);
>> +        }
>> +        if (retval < 0) {
>> +            retval = -WSAGetLastError();
>> +        }
>> +#endif
>>
>>         if (deadline <= time_msec()) {
>>             fatal_signal_handler(SIGALRM);
>> diff --git a/lib/timeval.h b/lib/timeval.h
>> index 1bbfd5c..3c700c5 100644
>> --- a/lib/timeval.h
>> +++ b/lib/timeval.h
>> @@ -52,8 +52,8 @@ long long int time_wall_msec(void);
>> void time_timespec(struct timespec *);
>> void time_wall_timespec(struct timespec *);
>> void time_alarm(unsigned int secs);
>> -int time_poll(struct pollfd *, int n_pollfds, long long int timeout_when,
>> -              int *elapsed);
>> +int time_poll(struct pollfd *, int n_pollfds, void *handles,
>> +              long long int timeout_when, int *elapsed);
>>
>> long long int timespec_to_msec(const struct timespec *);
>> long long int timeval_to_msec(const struct timeval *);
>> diff --git a/tests/test-netflow.c b/tests/test-netflow.c
>> index b6c3109..38486ac 100644
>> --- a/tests/test-netflow.c
>> +++ b/tests/test-netflow.c
>> @@ -228,7 +228,7 @@ main(int argc, char *argv[])
>>             break;
>>         }
>>
>> -        poll_fd_wait(sock, POLLIN);
>> +        poll_fd_wait(sock, 0, POLLIN);
>>         unixctl_server_wait(server);
>>         poll_block();
>>     }
>> diff --git a/tests/test-sflow.c b/tests/test-sflow.c
>> index cba01b9..634ca4a 100644
>> --- a/tests/test-sflow.c
>> +++ b/tests/test-sflow.c
>> @@ -544,7 +544,7 @@ main(int argc, char *argv[])
>>             break;
>>         }
>>
>> -        poll_fd_wait(sock, POLLIN);
>> +        poll_fd_wait(sock, 0, POLLIN);
>>         unixctl_server_wait(server);
>>         poll_block();
>>     }
>> --
>> 1.7.9.5
>>
>>
>>
>> ------------------------------
>>
>> _______________________________________________
>> dev mailing list
>> [email protected]
>> http://openvswitch.org/mailman/listinfo/dev
>>
>>
>> End of dev Digest, Vol 53, Issue 139
>> ************************************
> _______________________________________________
> dev mailing list
> [email protected]
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev

Reply via email to