VirtualBox

Changeset 16572 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Feb 9, 2009 10:05:27 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
42528
Message:

NAT: select => poll (2x speed up on Unix)

Location:
trunk/src/VBox/Devices/Network
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r16566 r16572  
    4343# ifndef RT_OS_WINDOWS
    4444#  include <unistd.h>
     45#  include <poll.h>
    4546# endif
    4647# include <errno.h>
     
    148149    Log2(("drvNATSend: pvBuf=%p cb=%#x\n%.*Rhxd\n", pvBuf, cb, cb, pvBuf));
    149150
    150 #ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC 
     151#ifdef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    151152
    152153    PRTREQ pReq = NULL;
     
    164165
    165166    /* @todo: Here we should get mbuf instead temporal buffer */
    166     buf = RTMemAlloc(cb); 
     167    buf = RTMemAlloc(cb);
    167168    if (buf == NULL)
    168169    {
     
    348349    HANDLE  *phEvents;
    349350    unsigned int cBreak = 0;
     351# else
     352    struct pollfd *polls;
    350353# endif
    351354
     
    364367    while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    365368    {
    366         FD_ZERO(&ReadFDs);
    367         FD_ZERO(&WriteFDs);
    368         FD_ZERO(&XcptFDs);
    369369        nFDs = -1;
    370370
     
    372372         * To prevent concurent execution of sending/receving threads
    373373         */
    374         slirp_select_fill(pThis->pNATState, &nFDs, &ReadFDs, &WriteFDs, &XcptFDs);
     374# ifndef RT_OS_WINDOWS
     375        nFDs = slirp_get_nsock(pThis->pNATState);
     376        polls = (struct pollfd *)RTMemAllocZ((2 + nFDs) * sizeof(struct pollfd)); /* allocation for all sockets + ICMP and Management pipe*/
     377        if (polls == NULL)
     378        {
     379            LogRel(("Can't allocate memory for polling\n"));
     380            AssertRelease(polls);
     381        }
     382
     383        slirp_select_fill(pThis->pNATState, &nFDs, &polls[1]); /*don't bother Slirp with knowelege about managemant pipe*/
    375384        ms = slirp_get_timeout_ms(pThis->pNATState);
    376 # ifndef RT_OS_WINDOWS
    377         struct timeval tv = { 0, ms*1000 };
    378         FD_SET(pThis->PipeRead, &ReadFDs);
    379         nFDs = ((int)pThis->PipeRead < nFDs ? nFDs : pThis->PipeRead);
    380         int cChangedFDs = select(nFDs + 1, &ReadFDs, &WriteFDs, &XcptFDs, ms ? &tv : NULL);
     385
     386        polls[0].fd = pThis->PipeRead;
     387        polls[0].events = POLLRDNORM|POLLPRI|POLLRDBAND; /* POLLRDBAND usually doesn't used on Linux but seems used on Solaris */
     388        int cChangedFDs = poll(polls, nFDs + 2, ms ? ms : -1);
    381389        if (cChangedFDs >= 0)
    382390        {
    383             slirp_select_poll(pThis->pNATState, &ReadFDs, &WriteFDs, &XcptFDs);
    384             if (FD_ISSET(pThis->PipeRead, &ReadFDs))
     391            slirp_select_poll(pThis->pNATState, &polls[1], nFDs);
     392            if (polls[0].revents & (POLLRDNORM|POLLPRI|POLLRDBAND))
    385393            {
    386394                /* drain the pipe */
     
    392400            RTReqProcess(pThis->pReqQueue, 0);
    393401        }
     402        RTMemFree(polls);
    394403# else /* RT_OS_WINDOWS */
     404        slirp_select_fill(pThis->pNATState, &nFDs);
     405        ms = slirp_get_timeout_ms(pThis->pNATState);
     406        struct timeval tv = { 0, ms*1000 };
    395407        event = WSAWaitForMultipleEvents(nFDs, phEvents, FALSE, ms ? ms : WSA_INFINITE, FALSE);
    396408        if (   (event < WSA_WAIT_EVENT_0 || event > WSA_WAIT_EVENT_0 + nFDs - 1)
     
    452464
    453465#ifdef VBOX_WITH_SLIRP_MT
    454 static DECLCALLBACK(int) drvNATAsyncIoGuest(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 
     466static DECLCALLBACK(int) drvNATAsyncIoGuest(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
    455467{
    456468    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
  • trunk/src/VBox/Devices/Network/slirp/libslirp.h

    r16563 r16572  
    1616# endif
    1717# include <sys/select.h>
     18# include <poll.h>
    1819# include <arpa/inet.h>
    1920#endif
     
    3334void slirp_link_down(PNATState);
    3435
     36#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
     37# if defined(RT_OS_WINDOWS)
     38void slirp_select_fill(PNATState pData, int *pndfs);
     39
     40void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
     41# else /* RT_OS_WINDOWS */
     42void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls);
     43void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs);
     44# endif /* !RT_OS_WINDOWS */
     45#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    3546void slirp_select_fill(PNATState pData, int *pnfds,
    3647                       fd_set *readfds, fd_set *writefds, fd_set *xfds);
    3748
    38 #if defined(RT_OS_WINDOWS) && defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
    39 void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp);
    40 #else
    41 void slirp_select_poll(PNATState pData, fd_set *readfds, fd_set *writefds, fd_set *xfds);
    42 #endif
     49void slirp_select_poll(PNATState pData, int *pnfds,
     50                       fd_set *readfds, fd_set *writefds, fd_set *xfds);
     51#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    4352
    4453void slirp_input(PNATState pData, const uint8_t *pkt, int pkt_len);
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r16564 r16572  
    77#include <VBox/pdmdrv.h>
    88#include <iprt/assert.h>
     9#include <poll.h>
    910
    1011#if !defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) || !defined(RT_OS_WINDOWS)
    1112
    12 # define DO_ENGAGE_EVENT1(so, fdset, label)          \
     13# ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
     14#  define DO_ENGAGE_EVENT1(so, fdset, label)          \
    1315    do {                                             \
    1416        FD_SET((so)->s, (fdset));                    \
     
    1719
    1820
    19 # define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
     21#  define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
    2022    do {                                             \
    2123        FD_SET((so)->s, (fdset1));                   \
     
    2426    } while(0)
    2527
    26 # define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
    27 
    28 # define DO_CHECK_FD_SET(so, events, fdset) (FD_ISSET((so)->s, (fdset)))
    29 
    30 # define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
    31 
     28#  define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
     29
     30#  define DO_CHECK_FD_SET(so, events, fdset) (FD_ISSET((so)->s, fdset))
     31# else /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
     32#  define DO_ENGAGE_EVENT1(so, fdset, label)            \
     33    do {                                                \
     34        polls[poll_index].fd = (so)->s;                 \
     35        (so)->so_poll_index = poll_index;               \
     36        polls[poll_index].events = N_(fdset ## _poll);  \
     37        poll_index++;                                   \
     38    } while(0)
     39
     40
     41#  define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label)                           \
     42    do {                                                                        \
     43        polls[poll_index].fd = (so)->s;                                         \
     44        (so)->so_poll_index = poll_index;                                       \
     45        polls[poll_index].events = N_(fdset1 ## _poll) | N_(fdset1 ## _poll);   \
     46        poll_index++;                                                           \
     47    } while(0)
     48
     49#  define DO_POLL_EVENTS(rc, error, so, events, label) do {} while (0)
     50
     51#  define DO_CHECK_FD_SET(so, events, fdset) (  ((so)->so_poll_index != -1)                     \
     52                                                && ((so)->so_poll_index <= ndfs)                \
     53                                                && ((so)->s == polls[so->so_poll_index].fd)     \
     54                                                && (polls[(so)->so_poll_index].revents          \
     55                                                && N_(fdset ## _poll)))
     56# endif /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
     57
     58#  define DO_WIN_CHECK_FD_SET(so, events, fdset ) 0 /* specific for Windows Winsock API */
    3259# ifndef RT_OS_WINDOWS
     60
     61#  ifndef RT_OS_LINUX
     62#   define readfds_poll (POLLRDNORM)
     63#   define writefds_poll (POLLWRNORM)
     64#   define xfds_poll (POLLRDBAND|POLLWRBAND|POLLPRI)
     65#  else
     66#   define readfds_poll (POLLIN)
     67#   define writefds_poll (POLLOUT)
     68#   define xfds_poll (POLLPRI)
     69#  endif
     70
    3371#  define ICMP_ENGAGE_EVENT(so, fdset)               \
    3472    do {                                             \
    3573        if (pData->icmp_socket.s != -1)              \
    36             DO_ENGAGE_EVENT1((so), (fdset), ICMP);   \
     74            DO_ENGAGE_EVENT1((so), fdset, ICMP);   \
    3775    } while (0)
    3876# else /* !RT_OS_WINDOWS */
     
    93131
    94132#define TCP_ENGAGE_EVENT1(so, fdset) \
    95     DO_ENGAGE_EVENT1((so), (fdset), tcp)
     133    DO_ENGAGE_EVENT1((so), fdset, tcp)
    96134
    97135#define TCP_ENGAGE_EVENT2(so, fdset1, fdset2) \
    98     DO_ENGAGE_EVENT2((so), (fdset1), (fdset2), tcp)
     136    DO_ENGAGE_EVENT2((so), fdset1, fdset2, tcp)
    99137
    100138#define UDP_ENGAGE_EVENT(so, fdset) \
    101     DO_ENGAGE_EVENT1((so), (fdset), udp)
     139    DO_ENGAGE_EVENT1((so), fdset, udp)
    102140
    103141#define POLL_TCP_EVENTS(rc, error, so, events) \
     
    570608#endif
    571609
     610#ifndef VBOX_WITH_SIMPLIFIED_SLIRP_SYNC
    572611void slirp_select_fill(PNATState pData, int *pnfds,
    573612                       fd_set *readfds, fd_set *writefds, fd_set *xfds)
     613#else /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
     614# ifdef RT_OS_WINDOWS
     615void slirp_select_fill(PNATState pData, int *pnfds)
     616# else /* RT_OS_WINDOWS */
     617void slirp_select_fill(PNATState pData, int *pnfds, struct pollfd *polls)
     618# endif /* !RT_OS_WINDOWS */
     619#endif /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    574620{
    575621    struct socket *so, *so_next;
     
    578624    int rc;
    579625    int error;
     626#endif
     627#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
     628    int poll_index = 0;
    580629#endif
    581630    int i;
     
    725774    }
    726775
    727 #if !defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) || !defined(RT_OS_WINDOWS)
     776#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
     777# if defined(RT_OS_WINDOWS)
     778    *pnfds = VBOX_EVENT_COUNT;
     779# else /* RT_OS_WINDOWS */
     780    *pnfds = poll_index;
     781# endif /* !RT_OS_WINDOWS */
     782#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    728783    *pnfds = nfds;
    729 #else
    730     *pnfds = VBOX_EVENT_COUNT;
    731 #endif
     784#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    732785
    733786    STAM_PROFILE_STOP(&pData->StatFill, a);
    734787}
    735788
    736 #if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && defined(RT_OS_WINDOWS)
     789#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC)
     790# if defined(RT_OS_WINDOWS)
    737791void slirp_select_poll(PNATState pData, int fTimeout, int fIcmp)
    738 #else
     792# else /* RT_OS_WINDOWS */
     793void slirp_select_poll(PNATState pData, struct pollfd *polls, int ndfs)
     794# endif /* !RT_OS_WINDOWS */
     795#else /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    739796void slirp_select_poll(PNATState pData, fd_set *readfds, fd_set *writefds, fd_set *xfds)
    740 #endif
     797#endif /* !VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    741798{
    742799    struct socket *so, *so_next;
     
    746803    int rc;
    747804    int error;
     805#endif
     806#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
     807    int poll_index = 0;
    748808#endif
    749809
     
    791851            sorecvfrom(pData, &pData->icmp_socket);
    792852#else
    793         if (pData->icmp_socket.s != -1 && FD_ISSET(pData->icmp_socket.s, readfds))
     853        if (   (pData->icmp_socket.s != -1)
     854            && CHECK_FD_SET(&pData->icmp_socket, ignored, readfds))
    794855            sorecvfrom(pData, &pData->icmp_socket);
    795856#endif
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r16501 r16572  
    7070    RTCRITSECT      so_mutex;
    7171    int             so_deleted;
     72#endif
     73#if defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) && !defined(RT_OS_WINDOWS)
     74    int so_poll_index;
    7275#endif
    7376};
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette