VirtualBox

Changeset 35769 in vbox


Ignore:
Timestamp:
Jan 28, 2011 3:12:13 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
69733
Message:

DrvHostSerial: better fix for timing problems over host serial

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp

    r35353 r35769  
    7171#include "VBoxDD.h"
    7272
    73 
    74 /** Size of the send fifo queue (in bytes) */
    75 #ifdef RT_OS_DARWIN
    76   /** @todo This is really desperate, but it seriously looks like
    77    * the data is arriving way too fast for us to push over. 9600
    78    * baud and zoc reports sending at 12000+ chars/sec... */
    79 # define CHAR_MAX_SEND_QUEUE             0x400
    80 # define CHAR_MAX_SEND_QUEUE_MASK        0x3ff
    81 #else
    82 # define CHAR_MAX_SEND_QUEUE             0x80
    83 # define CHAR_MAX_SEND_QUEUE_MASK        0x7f
    84 #endif
    8573
    8674/*******************************************************************************
     
    146134
    147135    /** Internal send FIFO queue */
    148     uint8_t volatile            aSendQueue[CHAR_MAX_SEND_QUEUE];
    149     uint32_t volatile           iSendQueueHead;
    150     uint32_t volatile           iSendQueueTail;
     136    uint8_t volatile            u8SendByte;
     137    bool volatile               fSending;
     138    uint8_t                     Alignment[2];
    151139
    152140    /** Read/write statistics */
     
    193181    for (uint32_t i = 0; i < cbWrite; i++)
    194182    {
    195 #ifdef RT_OS_DARWIN /* don't wanna break the others here. */
    196         uint32_t iHead = ASMAtomicUoReadU32(&pThis->iSendQueueHead);
    197         uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail);
    198         int32_t  cbAvail = iTail > iHead
    199                          ? iTail - iHead - 1
    200                          : CHAR_MAX_SEND_QUEUE - (iHead - iTail) - 1;
    201         if (cbAvail <= 0)
    202         {
    203 # ifdef DEBUG
    204             uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now);
    205 # endif
    206             Log(("%s: dropping %d chars (cbAvail=%d iHead=%d iTail=%d)\n", __FUNCTION__, cbWrite - i , cbAvail, iHead, iTail));
    207             STAM_COUNTER_INC(&pThis->StatSendOverflows);
    208             break;
    209         }
    210 
    211         pThis->aSendQueue[iHead] = pbBuffer[i];
     183        if (ASMAtomicXchgBool(&pThis->fSending, true))
     184            return VERR_BUFFER_OVERFLOW;
     185
     186        pThis->u8SendByte = pbBuffer[i];
     187        RTSemEventSignal(pThis->SendSem);
    212188        STAM_COUNTER_INC(&pThis->StatBytesWritten);
    213         ASMAtomicWriteU32(&pThis->iSendQueueHead, (iHead + 1) & CHAR_MAX_SEND_QUEUE_MASK);
    214         if (cbAvail < CHAR_MAX_SEND_QUEUE / 4)
    215         {
    216             RTSemEventSignal(pThis->SendSem);
    217             RTThreadYield();
    218         }
    219 #else /* old code */
    220         uint32_t idx = ASMAtomicUoReadU32(&pThis->iSendQueueHead);
    221 
    222         pThis->aSendQueue[idx] = pbBuffer[i];
    223         idx = (idx + 1) & CHAR_MAX_SEND_QUEUE_MASK;
    224 
    225         STAM_COUNTER_INC(&pThis->StatBytesWritten);
    226         ASMAtomicWriteU32(&pThis->iSendQueueHead, idx);
    227 #endif /* old code */
    228     }
    229     RTSemEventSignal(pThis->SendSem);
     189    }
    230190    return VINF_SUCCESS;
    231191}
     
    522482        {
    523483            /* copy the send queue so we get a linear buffer with the maximal size. */
    524             uint8_t  abBuf[sizeof(pThis->aSendQueue)];
    525             uint32_t cb = 0;
    526             uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail);
    527             uint32_t iHead = ASMAtomicUoReadU32(&pThis->iSendQueueHead);
    528             if (iTail == iHead)
    529                 break;
    530             do
    531             {
    532                 abBuf[cb++] = pThis->aSendQueue[iTail];
    533                 iTail = (iTail + 1) & CHAR_MAX_SEND_QUEUE_MASK;
    534             } while (iTail != iHead);
    535 
    536             ASMAtomicWriteU32(&pThis->iSendQueueTail, iTail);
    537 
    538             /* write it. */
    539 #ifdef DEBUG
    540             uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now);
    541 #endif
     484            uint8_t ch = pThis->u8SendByte;
    542485#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD)
    543486
    544487            size_t cbWritten;
    545             rc = RTFileWrite(pThis->DeviceFile, abBuf, cb, &cbWritten);
     488            rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten);
    546489            if (rc == VERR_TRY_AGAIN)
    547490                cbWritten = 0;
    548             if (cbWritten < cb && (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN))
     491            if (cbWritten < 1 && (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN))
    549492            {
    550493                /* ok, block till the device is ready for more (O_NONBLOCK) effect. */
    551494                rc = VINF_SUCCESS;
    552                 uint8_t const *pbSrc = &abBuf[0];
    553495                while (pThread->enmState == PDMTHREADSTATE_RUNNING)
    554496                {
    555                     /* advance */
    556                     cb -= cbWritten;
    557                     pbSrc += cbWritten;
    558 
    559497                    /* wait */
    560498                    fd_set WrSet;
     
    564502                    FD_ZERO(&XcptSet);
    565503                    FD_SET(pThis->DeviceFile, &XcptSet);
     504# ifdef DEBUG
     505                    uint64_t u64Now = RTTimeMilliTS();
     506# endif
    566507                    rc = select(pThis->DeviceFile + 1, NULL, &WrSet, &XcptSet, NULL);
    567508                    /** @todo check rc? */
    568509
     510# ifdef DEBUG
     511                    Log2(("select wait for %dms\n", RTTimeMilliTS() - u64Now));
     512# endif
    569513                    /* try write more */
    570                     rc = RTFileWrite(pThis->DeviceFile, pbSrc, cb, &cbWritten);
     514                    rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten);
    571515                    if (rc == VERR_TRY_AGAIN)
    572516                        cbWritten = 0;
    573517                    else if (RT_FAILURE(rc))
    574518                        break;
    575                     else if (cbWritten >= cb)
     519                    else if (cbWritten >= 1)
    576520                        break;
    577521                    rc = VINF_SUCCESS;
     
    584528            memset(&pThis->overlappedSend, 0, sizeof(pThis->overlappedSend));
    585529            pThis->overlappedSend.hEvent = pThis->hEventSend;
    586             if (!WriteFile(pThis->hDeviceFile, abBuf, cb, &cbWritten, &pThis->overlappedSend))
     530            if (!WriteFile(pThis->hDeviceFile, &ch, 1, &cbWritten, &pThis->overlappedSend))
    587531            {
    588532                dwRet = GetLastError();
     
    609553                return rc;
    610554            }
     555            ASMAtomicXchgBool(&pThis->fSending, false);
     556            break;
    611557        } /* write loop */
    612558    }
     
    622568 * @param     pThread     The send thread.
    623569 */
    624 static DECLCALLBACK(int) drvHostSerialWakeupSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     570static DECLCALLBACK(int) drvHostSerialWakeupSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD /*pThread*/)
    625571{
    626572    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     
    894840 * @param     pThread     The send thread.
    895841 */
    896 static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)
     842static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD /*pThread*/)
    897843{
    898844    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
     
    11091055
    11101056    /* Empty the send queue */
    1111     pThis->iSendQueueTail = pThis->iSendQueueHead = 0;
    1112 
    11131057    RTSemEventDestroy(pThis->SendSem);
    11141058    pThis->SendSem = NIL_RTSEMEVENT;
     
    11671111 * @copydoc FNPDMDRVCONSTRUCT
    11681112 */
    1169 static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
     1113static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t /*fFlags*/)
    11701114{
    11711115    PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
Note: See TracChangeset for help on using the changeset viewer.

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