Changeset 12361 in vbox for trunk/src/VBox/Devices
- Timestamp:
- Sep 10, 2008 3:05:50 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Serial/DrvHostSerial.cpp
r12355 r12361 132 132 133 133 /** Internal send FIFO queue */ 134 uint8_t 135 uint32_t 136 uint32_t 134 uint8_t volatile aSendQueue[CHAR_MAX_SEND_QUEUE]; 135 uint32_t volatile iSendQueueHead; 136 uint32_t volatile iSendQueueTail; 137 137 138 138 /** Read/write statistics */ … … 182 182 LogFlow(("%s: pvBuf=%#p cbWrite=%d\n", __FUNCTION__, pvBuf, cbWrite)); 183 183 184 for (uint32_t i =0;i<cbWrite;i++)184 for (uint32_t i = 0; i < cbWrite; i++) 185 185 { 186 uint32_t idx = pThis->iSendQueueHead; 186 #ifdef RT_OS_DARWIN /* don't wanna break the others here. */ 187 uint32_t iHead = ASMAtomicUoReadU32(&pThis->iSendQueueHead); 188 uint32_t iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail); 189 int32_t cbAvail = iTail > iHead 190 ? iHead + CHAR_MAX_SEND_QUEUE - iTail - 1 191 : CHAR_MAX_SEND_QUEUE - (iHead - iTail) - 1; 192 if (cbAvail <= 0) 193 { 194 Log(("%s: dropping %d chars (cbAvail=%d iHead=%d iTail=%d)\n", __FUNCTION__, cbWrite - i , cbAvial, iHead, iTail)); 195 break; 196 } 197 198 pThis->aSendQueue[iHead] = pbBuffer[i]; 199 STAM_COUNTER_INC(&pThis->StatBytesWritten); 200 ASMAtomicWriteU32(&pThis->iSendQueueHead, (iHead + 1) & CHAR_MAX_SEND_QUEUE_MASK); 201 if (cbAvail < CHAR_MAX_SEND_QUEUE / 4) 202 { 203 RTSemEventSignal(pThis->SendSem); 204 RTThreadYield(); 205 } 206 #else 207 uint32_t idx = ASMAtomicUoReadU32(&pThis->iSendQueueHead); 187 208 188 209 pThis->aSendQueue[idx] = pbBuffer[i]; … … 190 211 191 212 STAM_COUNTER_INC(&pThis->StatBytesWritten); 192 ASMAtomicXchgU32(&pThis->iSendQueueHead, idx); 213 ASMAtomicWriteU32(&pThis->iSendQueueHead, idx); 214 #endif 193 215 } 194 216 RTSemEventSignal(pThis->SendSem); … … 450 472 * Write the character to the host device. 451 473 */ 474 uint32_t iTail; 452 475 while ( pThread->enmState == PDMTHREADSTATE_RUNNING 453 && pThis->iSendQueueTail != pThis->iSendQueueHead)476 && (iTail = ASMAtomicUoReadU32(&pThis->iSendQueueTail)) != ASMAtomicUoReadU32(&pThis->iSendQueueHead)) 454 477 { 478 /** @todo process more than one byte? */ 455 479 unsigned cbProcessed = 1; 480 uint8_t abBuf[1]; 481 abBuf[0] = pThis->aSendQueue[iTail]; 456 482 457 483 #if defined(RT_OS_LINUX) || defined(RT_OS_DARWIN) 458 484 459 rc = RTFileWrite(pThis->DeviceFile, &pThis->aSendQueue[pThis->iSendQueueTail], cbProcessed, NULL);485 rc = RTFileWrite(pThis->DeviceFile, abBuf, cbProcessed, NULL); 460 486 461 487 #elif defined(RT_OS_WINDOWS) … … 465 491 pThis->overlappedSend.hEvent = pThis->hEventSend; 466 492 467 if (!WriteFile(pThis->hDeviceFile, &pThis->aSendQueue[pThis->iSendQueueTail], cbProcessed, &cbBytesWritten, &pThis->overlappedSend))493 if (!WriteFile(pThis->hDeviceFile, abBuf, cbProcessed, &cbBytesWritten, &pThis->overlappedSend)) 468 494 { 469 495 dwRet = GetLastError(); … … 488 514 if (RT_SUCCESS(rc)) 489 515 { 490 Assert(cbProcessed); 491 pThis->iSendQueueTail++; 492 pThis->iSendQueueTail &= CHAR_MAX_SEND_QUEUE_MASK; 516 Assert(cbProcessed == 1); 517 ASMAtomicWriteU32(&pThis->iSendQueueTail, (iTail + 1) & CHAR_MAX_SEND_QUEUE_MASK); 493 518 } 494 519 else if (RT_FAILURE(rc)) 495 520 { 496 521 LogRel(("HostSerial#%d: Serial Write failed with %Rrc; terminating send thread\n", pDrvIns->iInstance, rc)); 497 return VINF_SUCCESS;522 return rc; 498 523 } 499 524 }
Note:
See TracChangeset
for help on using the changeset viewer.