Changeset 12380 in vbox
- Timestamp:
- Sep 10, 2008 11:15:38 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp
r12363 r12380 139 139 STAMCOUNTER StatBytesRead; 140 140 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 141 146 } DRVHOSTSERIAL, *PDRVHOSTSERIAL; 142 147 … … 188 193 uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail); 189 194 int32_t cbAvail = iTail > iHead 190 ? i Head + CHAR_MAX_SEND_QUEUE - iTail- 1195 ? iTail - iHead - 1 191 196 : CHAR_MAX_SEND_QUEUE - (iHead - iTail) - 1; 192 197 if (cbAvail <= 0) 193 198 { 199 #ifdef DEBUG 200 uint64_t volatile u64Now = RTTimeNanoTS(); NOREF(u64Now); 201 #endif 194 202 Log(("%s: dropping %d chars (cbAvail=%d iHead=%d iTail=%d)\n", __FUNCTION__, cbWrite - i , cbAvail, iHead, iTail)); 203 STAM_COUNTER_INC(&pThis->StatSendOverflows); 195 204 break; 196 205 } … … 204 213 RTThreadYield(); 205 214 } 206 #else 215 #else /* old code */ 207 216 uint32_t idx = ASMAtomicUoReadU32(&pThis->iSendQueueHead); 208 217 … … 212 221 STAM_COUNTER_INC(&pThis->StatBytesWritten); 213 222 ASMAtomicWriteU32(&pThis->iSendQueueHead, idx); 214 #endif 223 #endif /* old code */ 215 224 } 216 225 RTSemEventSignal(pThis->SendSem); … … 472 481 * Write the character to the host device. 473 482 */ 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 */ 474 579 uint32_t iTail; 475 580 while ( pThread->enmState == PDMTHREADSTATE_RUNNING … … 523 628 } 524 629 } 630 #endif /* old code */ 525 631 } 526 632 … … 600 706 FD_SET(pThis->DeviceFile, &XcptSet); 601 707 FD_SET(pThis->WakeupPipeR, &XcptSet); 708 # if 1 /* it seems like this select is blocking the write... */ 602 709 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 603 714 if (rc == -1) 604 715 { … … 1251 1362 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatBytesWritten, STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_BYTES, "Nr of bytes written", "/Devices/HostSerial%d/Written", pDrvIns->iInstance); 1252 1363 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 1253 1367 1254 1368 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.