VirtualBox

Changeset 16291 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jan 28, 2009 2:36:37 AM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
42115
Message:

NAT: multi threading.
Introduces set of macroces to use locking/unlocking/creating/destroing mutexes
Also every socket enqueueing is accomponement with lock creation
(it doen't work yet, compilable on Windows don't know about Linux)

Location:
trunk/src/VBox/Devices
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Makefile.kmk

    r16245 r16291  
    647647      $(if $(VBOX_WITH_SLIRP_MEMORY_CHECK),RTMEM_WRAP_TO_EF_APIS,) \
    648648      $(if $(VBOX_WITH_DEBUG_NAT_SOCKETS),VBOX_WITH_DEBUG_NAT_SOCKETS,) \
    649       $(if $(VBOX_WITH_MULTI_DNS),VBOX_WITH_MULTI_DNS,)
     649      $(if $(VBOX_WITH_MULTI_DNS),VBOX_WITH_MULTI_DNS,) \
     650      $(if $(VBOX_WITH_SLIRP_MT),VBOX_WITH_SLIRP_MT,)
    650651 ifeq ($(KBUILD_TARGET),win)
    651652  $(file)_CFLAGS = -wd4018
  • trunk/src/VBox/Devices/Network/DrvNAT.cpp

    r16201 r16291  
    9191    /* Send queue */
    9292    PPDMQUEUE               pSendQueue;
     93# ifdef VBOX_WITH_SLIRP_MT
     94    PPDMTHREAD              pGuestThread;
     95# endif
    9396# ifndef RT_OS_WINDOWS
    9497    /** The write end of the control pipe. */
     
    437440}
    438441
     442#ifdef VBOX_WITH_SLIRP_MT
     443static DECLCALLBACK(int) drvNATAsyncIoGuest(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     444{
     445    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     446        while (1)
     447        {
     448        }
     449}
     450
     451static DECLCALLBACK(int) drvNATAsyncIoGuestWakeup(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     452{
     453    PDRVNAT pThis = PDMINS_2_DATA(pDrvIns, PDRVNAT);
     454
     455    return VINF_SUCCESS;
     456}
     457#endif
     458
    439459#endif /* VBOX_WITH_SIMPLIFIED_SLIRP_SYNC */
    440460
     
    863883            rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvNATAsyncIoThread, drvNATAsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "NAT");
    864884            AssertReleaseRC(rc);
     885
     886#ifdef VBOX_WITH_SLIRP_MT
     887            rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pGuestThread, pThis, drvNATAsyncIoGuest, drvNATAsyncIoGuestWakeup, 128 * _1K, RTTHREADTYPE_EMULATION, "NAT");
     888            AssertReleaseRC(rc);
     889#endif
    865890#endif
    866891
  • trunk/src/VBox/Devices/Network/slirp/slirp.c

    r16254 r16291  
    88#include <iprt/assert.h>
    99
     10#ifdef VBOX_WITH_SLIRP_MT
     11# define CONTINUE(label) goto loop_end_ ## label ## _mt
     12/* @todo replace queue parameter with macrodinition */
     13# define LOOP_LABEL(label, so, sonext) loop_end_ ## label ## _mt:    \
     14    SOCKET_UNLOCK(so);                                               \
     15    QSOCKET_LOCK(_X(queue_ ## label ## _label));                     \
     16    (so) = (sonext)
     17#else
     18#define CONTINUE(label) continue;
     19# define LOOP_LABEL(label, so, sonext) /* empty*/
     20#endif
    1021#if !defined(VBOX_WITH_SIMPLIFIED_SLIRP_SYNC) || !defined(RT_OS_WINDOWS)
    1122
     
    4859# define ICMP_ENGAGE_EVENT(so, fdset)                do {} while(0)
    4960
    50 # define DO_ENGAGE_EVENT1(so, fdset1, label)         \
    51     do {                                             \
    52         rc = WSAEventSelect((so)->s, VBOX_SOCKET_EVENT, FD_ALL_EVENTS); \
    53         if (rc == SOCKET_ERROR)                      \
    54         {                                            \
    55             /* This should not happen */             \
    56             error = WSAGetLastError();               \
    57             LogRel(("WSAEventSelector (" #label ") error %d (so=%x, socket=%s, event=%x)\n", \
    58                         error, (so), (so)->s, VBOX_SOCKET_EVENT)); \
    59         }                                            \
    60     } while(0);                                      \
    61     continue
     61# define DO_ENGAGE_EVENT1(so, fdset1, label)                                                    \
     62    do {                                                                                        \
     63        rc = WSAEventSelect((so)->s, VBOX_SOCKET_EVENT, FD_ALL_EVENTS);                         \
     64        if (rc == SOCKET_ERROR)                                                                 \
     65        {                                                                                       \
     66            /* This should not happen */                                                        \
     67            error = WSAGetLastError();                                                          \
     68            LogRel(("WSAEventSelector (" #label ") error %d (so=%x, socket=%s, event=%x)\n",    \
     69                        error, (so), (so)->s, VBOX_SOCKET_EVENT));                              \
     70        }                                                                                       \
     71    } while(0);                                                                                                 \
     72    CONTINUE(label)
    6273
    6374# define DO_ENGAGE_EVENT2(so, fdset1, fdset2, label) \
     
    7081        (error) = WSAGetLastError();                                        \
    7182        LogRel(("WSAEnumNetworkEvents " #label " error %d\n", (error)));    \
    72         continue;                                                           \
     83        CONTINUE(label);                                                    \
    7384    }
    7485
     
    93104
    94105#define TCP_ENGAGE_EVENT1(so, fdset) \
    95     DO_ENGAGE_EVENT1((so), (fdset), TCP)
     106    DO_ENGAGE_EVENT1((so), (fdset), tcp)
    96107
    97108#define TCP_ENGAGE_EVENT2(so, fdset1, fdset2) \
    98     DO_ENGAGE_EVENT2((so), (fdset1), (fdset2), TCP)
     109    DO_ENGAGE_EVENT2((so), (fdset1), (fdset2), tcp)
    99110
    100111#define UDP_ENGAGE_EVENT(so, fdset) \
    101     DO_ENGAGE_EVENT1((so), (fdset), UDP)
     112    DO_ENGAGE_EVENT1((so), (fdset), udp)
    102113
    103114#define POLL_TCP_EVENTS(rc, error, so, events) \
    104     DO_POLL_EVENTS((rc), (error), (so), (events), TCP)
     115    DO_POLL_EVENTS((rc), (error), (so), (events), tcp)
    105116
    106117#define POLL_UDP_EVENTS(rc, error, so, events) \
    107     DO_POLL_EVENTS((rc), (error), (so), (events), UDP)
     118    DO_POLL_EVENTS((rc), (error), (so), (events), udp)
    108119
    109120#define CHECK_FD_SET(so, events, set)           \
     
    582593        STAM_COUNTER_RESET(&pData->StatTCPHot);
    583594
    584         for (so = tcb.so_next; so != &tcb; so = so_next)
    585         {
    586             so_next = so->so_next;
    587 
     595        QSOCKET_FOREACH(so, so_next, tcp)
     596        /* { */
    588597            STAM_COUNTER_INC(&pData->StatTCP);
    589598
     
    599608             */
    600609            if (so->so_state & SS_NOFDREF || so->s == -1)
    601                 continue;
     610                CONTINUE(tcp);
    602611
    603612            /*
     
    608617                STAM_COUNTER_INC(&pData->StatTCPHot);
    609618                TCP_ENGAGE_EVENT1(so, readfds);
    610                 continue;
     619                CONTINUE(tcp);
    611620            }
    612621
     
    640649                TCP_ENGAGE_EVENT2(so, readfds, xfds);
    641650            }
     651            LOOP_LABEL(tcp, so, so_next);
    642652        }
    643653
     
    648658        STAM_COUNTER_RESET(&pData->StatUDPHot);
    649659
    650         for (so = udb.so_next; so != &udb; so = so_next)
    651         {
     660        QSOCKET_FOREACH(so, so_next, udp)
     661        /* { */
    652662            so_next = so->so_next;
    653663
     
    662672                {
    663673                    udp_detach(pData, so);
    664                     continue;
     674                    CONTINUE(udp);
    665675                }
    666676                else
     
    683693                UDP_ENGAGE_EVENT(so, readfds);
    684694            }
     695            LOOP_LABEL(udp, so, so_next);
    685696        }
    686697
     
    768779             */
    769780            if (so->so_state & SS_NOFDREF || so->s == -1)
    770                 continue;
     781                CONTINUE(tcp);
    771782
    772783            POLL_TCP_EVENTS(rc, error, so, &NetworkEvents);
     
    801812                    if (!(NetworkEvents.lNetworkEvents & FD_CLOSE))
    802813#endif
    803                         continue;
     814                        CONTINUE(tcp);
    804815                }
    805816
     
    859870                            || errno == EINPROGRESS
    860871                            || errno == ENOTCONN)
    861                             continue;
     872                            CONTINUE(tcp);
    862873
    863874                        /* else failed */
     
    899910                        || errno == ENOTCONN)
    900911                    {
    901                         continue; /* Still connecting, continue */
     912                        CONTINUE(tcp); /* Still connecting, continue */
    902913                    }
    903914
     
    918929                            || errno == ENOTCONN)
    919930                        {
    920                             continue;
     931                            CONTINUE(tcp);
    921932                        }
    922933                        /* else failed */
     
    930941            } /* SS_ISFCONNECTING */
    931942#endif
     943            LOOP_LABEL(tcp, so, so_next);
    932944        }
    933945
     
    949961                sorecvfrom(pData, so);
    950962            }
    951         }
    952 
    953     }
    954 
     963            LOOP_LABEL(udp, so, so_next);
     964        }
     965
     966    }
     967
     968#ifndef VBOX_WITH_SLIRP_MT
    955969    /*
    956970     * See if we can start outputting
     
    958972    if (if_queued && link_up)
    959973        if_start(pData);
     974#endif
    960975
    961976    STAM_PROFILE_STOP(&pData->StatPoll, a);
  • trunk/src/VBox/Devices/Network/slirp/slirp_state.h

    r16249 r16291  
    115115    /* Stuff from tcp_input.c */
    116116    struct socket tcb;
     117#ifdef VBOX_WITH_SLIRP_MT
     118    RTSEMMUTEX      tcb_mutex;
     119#endif
    117120    struct socket *tcp_last_so;
    118121    tcp_seq tcp_iss;
     
    130133    struct udpstat_t udpstat;
    131134    struct socket udb;
     135#ifdef VBOX_WITH_SLIRP_MT
     136    RTSEMMUTEX      udb_mutex;
     137#endif
    132138    struct socket *udp_last_so;
    133139    struct socket icmp_socket;
     
    267273#endif
    268274
     275#define queue_tcp_label tcb
     276#define queue_udp_label udb
     277#define __X(x) x
     278#define _X(x) __X(x)
     279
     280#ifdef VBOX_WITH_SLIRP_MT
     281#define QSOCKET_LOCK(queue)                                                     \
     282do {                                                                            \
     283    int rc = RTSemMutexRequest(_X(queue) ## _mutex, RT_INDEFINITE_WAIT);     \
     284    AssertReleaseRC(rc);                                                        \
     285} while (0)
     286#define QSOCKET_UNLOCK(queue)                           \
     287do {                                                    \
     288    int rc = RTSemMutexRelease(_X(queue) ## _mutex);    \
     289    AssertReleaseRC(rc);                                \
     290} while (0)
     291#define QSOCKET_LOCK_CREATE(queue)                      \
     292do {                                                    \
     293    int rc = RTSemMutexCreate(&pData->queue ## _mutex); \
     294    AssertReleaseRC(rc);                                \
     295} while (0)
     296#define QSOCKET_LOCK_DESTROY(queue)                     \
     297do {                                                    \
     298    int rc = RTSemMutexDestroy(pData->queue ## _mutex); \
     299    AssertReleaseRC(rc);                                \
     300} while (0)
     301
     302# define QSOCKET_FOREACH(so, sonext, label)                        \
     303        QSOCKET_LOCK(__X(queue_## label ## _label));               \
     304        (so) = (_X(queue_ ## label ## _label)).so_next;             \
     305        SOCKET_LOCK((so));                      \
     306        for(;;)                                 \
     307        {                                       \
     308            if ((so) == &(_X(queue_## label ## _label)))               \
     309            {                                   \
     310                QSOCKET_UNLOCK(__X(queue_## label ##_label));                    \
     311                break;                          \
     312            }                                   \
     313            if ((so)->so_next != &(_X(queue_## label ## _label)))      \
     314            {                                   \
     315                SOCKET_LOCK((so)->so_next);     \
     316            }                                   \
     317            (sonext) = (so)->so_next;           \
     318            QSOCKET_UNLOCK(__X(queue_## label ##_label));
     319#else
     320#define QSOCKET_LOCK(queue) do {} while (0)
     321#define QSOCKET_UNLOCK(queue) do {} while (0)
     322#define QSOCKET_LOCK_CREATE(queue) do {} while (0)
     323#define QSOCKET_LOCK_DESTROY(queue) do {} while (0)
     324# define QSOCKET_FOREACH(so, sonext, label)                        \
     325   for ((so) = __X(queue_ ## label ## _label).so_next; so != &(__X(queue_ ## label ## _label)); (so) = (sonext))   \
     326   {                                                               \
     327            (sonext) = (so)->so_next;
     328#endif
     329
    269330#endif /* !_slirp_state_h_ */
  • trunk/src/VBox/Devices/Network/slirp/socket.c

    r16226 r16291  
    7272/*
    7373 * remque and free a socket, clobber cache
     74 * VBOX_WITH_SLIRP_MT: before sofree queue should be locked, because
     75 *      in sofree we don't know from which queue item beeing removed.
    7476 */
    7577void
     
    8789    if(so->so_next && so->so_prev)
    8890        remque(pData, so);  /* crashes if so is not in a queue */
     91
     92    SOCKET_UNLOCK(so);
     93    SOCKET_LOCK_DESTROY(so);
    8994
    9095    RTMemFree(so);
     
    644649        return NULL;
    645650    }
     651
     652    SOCKET_LOCK_CREATE(so);
     653    SOCKET_LOCK(so);
     654    QSOCKET_LOCK(tcb);
    646655    insque(pData, so,&tcb);
     656    QSOCKET_UNLOCK(tcb);
    647657
    648658    /*
     
    674684        int tmperrno = errno; /* Don't clobber the real reason we failed */
    675685        close(s);
     686        QSOCKET_LOCK(tcb);
    676687        sofree(pData, so);
     688        QSOCKET_UNLOCK(tcb);
    677689        /* Restore the real errno */
    678690        errno = tmperrno;
  • trunk/src/VBox/Devices/Network/slirp/socket.h

    r15636 r16291  
    1010#ifndef _SLIRP_SOCKET_H_
    1111#define _SLIRP_SOCKET_H_
     12#ifdef VBOX_WITH_SLIRP_MT
     13#include <iprt/semaphore.h>
     14#endif
    1215
    1316#define SO_EXPIRE 240000
     
    6467    struct sbuf     so_rcv;      /* Receive buffer */
    6568    struct sbuf     so_snd;      /* Send buffer */
     69#ifdef VBOX_WITH_SLIRP_MT
     70    RTSEMMUTEX      so_mutex;
     71#endif
    6672};
    6773
    68 
     74#ifdef VBOX_WITH_SLIRP_MT
     75# define SOCKET_LOCK(so)                                                \
     76    do {                                                                \
     77        int rc = RTSemMutexRequest((so)->so_mutex, RT_INDEFINITE_WAIT); \
     78        AssertReleaseRC(rc);                                            \
     79    } while (0)
     80# define SOCKET_UNLOCK(so)                                              \
     81    do {                                                                \
     82        int rc = RTSemMutexRelease((so)->so_mutex);                     \
     83        AssertReleaseRC(rc);                                            \
     84    } while (0)
     85# define SOCKET_LOCK_CREATE(so)                                         \
     86    do {                                                                \
     87        int rc = RTSemMutexCreate(&(so)->so_mutex);                     \
     88        AssertReleaseRC(rc);                                            \
     89    } while (0)
     90# define SOCKET_LOCK_DESTROY(so)                                        \
     91    do {                                                                \
     92        int rc = RTSemMutexDestroy((so)->so_mutex);                     \
     93        AssertReleaseRC(rc);                                            \
     94    } while (0)
     95#else
     96# define SOCKET_LOCK(so) do {} while (0)
     97# define SOCKET_UNLOCK(so) do {} while (0)
     98# define SOCKET_LOCK_CREATE(so) do {} while (0)
     99# define SOCKET_LOCK_DESTROY(so) do {} while (0)
     100#endif
    69101/*
    70102 * Socket state bits. (peer means the host on the Internet,
  • trunk/src/VBox/Devices/Network/slirp/tcp_input.c

    r16071 r16291  
    433433            goto dropwithreset;
    434434        }
    435 
     435       
     436        SOCKET_LOCK(so);
    436437        sbreserve(&so->so_snd, tcp_sndspace);
    437438        sbreserve(&so->so_rcv, tcp_rcvspace);
  • trunk/src/VBox/Devices/Network/slirp/tcp_subr.c

    r16226 r16291  
    539539        return -1;
    540540
     541    SOCKET_LOCK_CREATE(so);
     542    QSOCKET_LOCK(tcb);
    541543    insque(pData, so, &tcb);
     544    QSOCKET_UNLOCK(tcb);
    542545    return 0;
    543546}
  • trunk/src/VBox/Devices/Network/slirp/udp.c

    r16213 r16291  
    384384            /* enable broadcast for later use */
    385385            setsockopt(so->s, SOL_SOCKET, SO_BROADCAST, (const char *)&opt, sizeof(opt));
     386            SOCKET_LOCK_CREATE(so);
     387            QSOCKET_LOCK(udb);
    386388            insque(pData, so,&udb);
     389            QSOCKET_UNLOCK(udb);
    387390            status = getsockname(so->s, &sa_addr, &socklen);
    388391            Assert(status == 0 && sa_addr.sa_family == AF_INET);
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