VirtualBox

Changeset 12380 in vbox


Ignore:
Timestamp:
Sep 10, 2008 11:15:38 PM (16 years ago)
Author:
vboxsync
Message:

DrvHostSerial: darwin hacking.

File:
1 edited

Legend:

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

    r12363 r12380  
    139139    STAMCOUNTER                 StatBytesRead;
    140140    STAMCOUNTER                 StatBytesWritten;
     141#ifdef RT_OS_DARWIN
     142    /** The number of bytes we've dropped because the send queue
     143     * was full. */
     144    STAMCOUNTER                 StatSendOverflows;
     145#endif
    141146} DRVHOSTSERIAL, *PDRVHOSTSERIAL;
    142147
     
    188193        uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail);
    189194        int32_t  cbAvail = iTail > iHead
    190                          ? iHead + CHAR_MAX_SEND_QUEUE - iTail - 1
     195                         ? iTail - iHead - 1
    191196                         : CHAR_MAX_SEND_QUEUE - (iHead - iTail) - 1;
    192197        if (cbAvail <= 0)
    193198        {
     199#ifdef DEBUG
     200            uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now);
     201#endif
    194202            Log(("%s: dropping %d chars (cbAvail=%d iHead=%d iTail=%d)\n", __FUNCTION__, cbWrite - i , cbAvail, iHead, iTail));
     203            STAM_COUNTER_INC(&pThis->StatSendOverflows);
    195204            break;
    196205        }
     
    204213            RTThreadYield();
    205214        }
    206 #else
     215#else /* old code */
    207216        uint32_t idx = ASMAtomicUoReadU32(&pThis->iSendQueueHead);
    208217
     
    212221        STAM_COUNTER_INC(&pThis->StatBytesWritten);
    213222        ASMAtomicWriteU32(&pThis->iSendQueueHead, idx);
    214 #endif
     223#endif /* old code */
    215224    }
    216225    RTSemEventSignal(pThis->SendSem);
     
    472481         * Write the character to the host device.
    473482         */
     483#ifdef RT_OS_DARWIN
     484        while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     485        {
     486            /* copy the send queue so we get a linear buffer with the maximal size. */
     487            uint8_t  abBuf[sizeof(pThis->aSendQueue)];
     488            uint32_t cb = 0;
     489            uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail);
     490            uint32_t iHead = ASMAtomicUoReadU32(&pThis->iSendQueueHead);
     491            if (iTail == iHead)
     492                break;
     493            do
     494            {
     495                abBuf[cb++] = pThis->aSendQueue[iTail];
     496                iTail = (iTail + 1) & CHAR_MAX_SEND_QUEUE_MASK;
     497            } while (iTail != iHead);
     498
     499            ASMAtomicWriteU32(&pThis->iSendQueueTail, iTail);
     500
     501            /* write it. */
     502#ifdef DEBUG
     503            uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now);
     504#endif
     505#if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN)
     506
     507            size_t cbWritten;
     508            rc = RTFileWrite(pThis->DeviceFile, abBuf, cb, &cbWritten);
     509            if (rc == VERR_TRY_AGAIN)
     510                cbWritten = 0;
     511            if (cbWritten < cb && (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN))
     512            {
     513                /* ok, block till the device is ready for more (O_NONBLOCK) effect. */
     514                rc = VINF_SUCCESS;
     515                uint8_t const *pbSrc = &abBuf[0];
     516                while (pThread->enmState == PDMTHREADSTATE_RUNNING)
     517                {
     518                    /* advance */
     519                    cb -= cbWritten;
     520                    pbSrc += cbWritten;
     521
     522                    /* wait */
     523                    fd_set WrSet;
     524                    FD_ZERO(&WrSet);
     525                    FD_SET(pThis->DeviceFile, &WrSet);
     526                    //FD_SET(pThis->WakeupPipeR, &WrSet);
     527                    fd_set XcptSet;
     528                    FD_ZERO(&XcptSet);
     529                    FD_SET(pThis->DeviceFile, &XcptSet);
     530                    //FD_SET(pThis->WakeupPipeR, &XcptSet);
     531                    rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFile) + 1, NULL, &WrSet, &XcptSet, NULL);
     532                    /** @todo check rc? */
     533
     534                    /* try write more */
     535                    rc = RTFileWrite(pThis->DeviceFile, pbSrc, cb, &cbWritten);
     536                    if (rc == VERR_TRY_AGAIN)
     537                        cbWritten = 0;
     538                    else if (RT_FAILURE(rc))
     539                        break;
     540                    else if (cbWritten >= cb)
     541                        break;
     542                    rc = VINF_SUCCESS;
     543                } /* wait/write loop */
     544            }
     545
     546#elif defined(RT_OS_WINDOWS)
     547            /* perform an overlapped write operation. */
     548            DWORD cbWritten;
     549            memset(&pThis->overlappedSend, 0, sizeof(pThis->overlappedSend));
     550            pThis->overlappedSend.hEvent = pThis->hEventSend;
     551            if (!WriteFile(pThis->hDeviceFile, abBuf, cb, &cbWritten, &pThis->overlappedSend))
     552            {
     553                dwRet = GetLastError();
     554                if (dwRet == ERROR_IO_PENDING)
     555                {
     556                    /*
     557                     * write blocked, wait for completion or wakeup...
     558                     */
     559                    dwRet = WaitForMultipleObjects(2, haWait, FALSE, INFINITE);
     560                    if (dwRet != WAIT_OBJECT_0)
     561                    {
     562                        AssertMsg(pThread->enmState != PDMTHREADSTATE_RUNNING, ("The halt event sempahore is set but the thread is still in running state\n"));
     563                        break;
     564                    }
     565                }
     566                else
     567                    rc = RTErrConvertFromWin32(dwRet);
     568            }
     569
     570#endif
     571            if (RT_FAILURE(rc))
     572            {
     573                LogRel(("HostSerial#%d: Serial Write failed with %Rrc; terminating send thread\n", pDrvIns->iInstance, rc));
     574                return rc;
     575            }
     576        } /* write loop */
     577
     578#else /* old code */
    474579        uint32_t iTail;
    475580        while (   pThread->enmState == PDMTHREADSTATE_RUNNING
     
    523628            }
    524629        }
     630#endif /* old code */
    525631    }
    526632
     
    600706            FD_SET(pThis->DeviceFile, &XcptSet);
    601707            FD_SET(pThis->WakeupPipeR, &XcptSet);
     708# if 1 /* it seems like this select is blocking the write... */
    602709            rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFile) + 1, &RdSet, NULL, &XcptSet, NULL);
     710# else
     711            struct timeval tv = { 0, 1000 };
     712            rc = select(RT_MAX(pThis->WakeupPipeR, pThis->DeviceFile) + 1, &RdSet, NULL, &XcptSet, &tv);
     713# endif
    603714            if (rc == -1)
    604715            {
     
    12511362    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatBytesWritten,    STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes written",         "/Devices/HostSerial%d/Written", pDrvIns->iInstance);
    12521363    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatBytesRead,       STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes read",            "/Devices/HostSerial%d/Read", pDrvIns->iInstance);
     1364#ifdef RT_OS_DARWIN /* new Write code, not darwin specific. */
     1365    PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatSendOverflows,   STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes overflowed",      "/Devices/HostSerial%d/SendOverflow", pDrvIns->iInstance);
     1366#endif
    12531367
    12541368    return VINF_SUCCESS;
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