Changeset 35769 in vbox
- Timestamp:
- Jan 28, 2011 3:12:13 PM (14 years ago)
- svn:sync-xref-src-repo-rev:
- 69733
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp
r35353 r35769 71 71 #include "VBoxDD.h" 72 72 73 74 /** Size of the send fifo queue (in bytes) */75 #ifdef RT_OS_DARWIN76 /** @todo This is really desperate, but it seriously looks like77 * the data is arriving way too fast for us to push over. 960078 * baud and zoc reports sending at 12000+ chars/sec... */79 # define CHAR_MAX_SEND_QUEUE 0x40080 # define CHAR_MAX_SEND_QUEUE_MASK 0x3ff81 #else82 # define CHAR_MAX_SEND_QUEUE 0x8083 # define CHAR_MAX_SEND_QUEUE_MASK 0x7f84 #endif85 73 86 74 /******************************************************************************* … … 146 134 147 135 /** Internal send FIFO queue */ 148 uint8_t volatile aSendQueue[CHAR_MAX_SEND_QUEUE];149 uint32_t volatile iSendQueueHead;150 uint 32_t volatile iSendQueueTail;136 uint8_t volatile u8SendByte; 137 bool volatile fSending; 138 uint8_t Alignment[2]; 151 139 152 140 /** Read/write statistics */ … … 193 181 for (uint32_t i = 0; i < cbWrite; i++) 194 182 { 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); 212 188 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 } 230 190 return VINF_SUCCESS; 231 191 } … … 522 482 { 523 483 /* 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; 542 485 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_FREEBSD) 543 486 544 487 size_t cbWritten; 545 rc = RTFileWrite(pThis->DeviceFile, abBuf, cb, &cbWritten);488 rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten); 546 489 if (rc == VERR_TRY_AGAIN) 547 490 cbWritten = 0; 548 if (cbWritten < cb&& (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN))491 if (cbWritten < 1 && (RT_SUCCESS(rc) || rc == VERR_TRY_AGAIN)) 549 492 { 550 493 /* ok, block till the device is ready for more (O_NONBLOCK) effect. */ 551 494 rc = VINF_SUCCESS; 552 uint8_t const *pbSrc = &abBuf[0];553 495 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 554 496 { 555 /* advance */556 cb -= cbWritten;557 pbSrc += cbWritten;558 559 497 /* wait */ 560 498 fd_set WrSet; … … 564 502 FD_ZERO(&XcptSet); 565 503 FD_SET(pThis->DeviceFile, &XcptSet); 504 # ifdef DEBUG 505 uint64_t u64Now = RTTimeMilliTS(); 506 # endif 566 507 rc = select(pThis->DeviceFile + 1, NULL, &WrSet, &XcptSet, NULL); 567 508 /** @todo check rc? */ 568 509 510 # ifdef DEBUG 511 Log2(("select wait for %dms\n", RTTimeMilliTS() - u64Now)); 512 # endif 569 513 /* try write more */ 570 rc = RTFileWrite(pThis->DeviceFile, pbSrc, cb, &cbWritten);514 rc = RTFileWrite(pThis->DeviceFile, &ch, 1, &cbWritten); 571 515 if (rc == VERR_TRY_AGAIN) 572 516 cbWritten = 0; 573 517 else if (RT_FAILURE(rc)) 574 518 break; 575 else if (cbWritten >= cb)519 else if (cbWritten >= 1) 576 520 break; 577 521 rc = VINF_SUCCESS; … … 584 528 memset(&pThis->overlappedSend, 0, sizeof(pThis->overlappedSend)); 585 529 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)) 587 531 { 588 532 dwRet = GetLastError(); … … 609 553 return rc; 610 554 } 555 ASMAtomicXchgBool(&pThis->fSending, false); 556 break; 611 557 } /* write loop */ 612 558 } … … 622 568 * @param pThread The send thread. 623 569 */ 624 static DECLCALLBACK(int) drvHostSerialWakeupSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)570 static DECLCALLBACK(int) drvHostSerialWakeupSendThread(PPDMDRVINS pDrvIns, PPDMTHREAD /*pThread*/) 625 571 { 626 572 PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL); … … 894 840 * @param pThread The send thread. 895 841 */ 896 static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread)842 static DECLCALLBACK(int) drvHostSerialWakeupRecvThread(PPDMDRVINS pDrvIns, PPDMTHREAD /*pThread*/) 897 843 { 898 844 PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL); … … 1109 1055 1110 1056 /* Empty the send queue */ 1111 pThis->iSendQueueTail = pThis->iSendQueueHead = 0;1112 1113 1057 RTSemEventDestroy(pThis->SendSem); 1114 1058 pThis->SendSem = NIL_RTSEMEVENT; … … 1167 1111 * @copydoc FNPDMDRVCONSTRUCT 1168 1112 */ 1169 static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)1113 static DECLCALLBACK(int) drvHostSerialConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t /*fFlags*/) 1170 1114 { 1171 1115 PDRVHOSTSERIAL pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTSERIAL);
Note:
See TracChangeset
for help on using the changeset viewer.