Changeset 7831 in vbox for trunk/src/VBox
- Timestamp:
- Apr 9, 2008 12:31:12 PM (17 years ago)
- Location:
- trunk/src/VBox/Devices/Network
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r7795 r7831 114 114 115 115 #if HC_ARCH_BITS == 64 116 uint32_t Alignment ;116 uint32_t Alignment1; 117 117 #endif 118 118 … … 137 137 uint16_t aMII[MII_MAX_REG]; 138 138 uint16_t u16CSR0LastSeenByGuest; 139 uint16_t Alignment 0[HC_ARCH_BITS == 32 ? 2 : 4];139 uint16_t Alignment2[HC_ARCH_BITS == 32 ? 2 : 4]; 140 140 /** Last time we polled the queues */ 141 141 uint64_t u64LastPoll; … … 144 144 uint32_t cbSendFrame; 145 145 #if HC_ARCH_BITS == 64 146 uint32_t Alignment 2;146 uint32_t Alignment3; 147 147 #endif 148 148 /** Buffer address of current send frame */ … … 215 215 /** Access critical section. */ 216 216 PDMCRITSECT CritSect; 217 /** Event semaphore for blocking on receive. */ 218 RTSEMEVENT hEventOutOfRxSpace; 219 /** We are waiting/about to start waiting for more receive buffers. */ 220 bool volatile fMaybeOutOfSpace; 221 uint8_t Alignment5[HC_ARCH_BITS == 64 ? 7 : 3]; 217 222 218 223 #ifdef PCNET_NO_POLLING … … 233 238 234 239 #if HC_ARCH_BITS == 64 235 uint32_t Alignment 3;240 uint32_t Alignment6; 236 241 #endif 237 242 … … 278 283 STAMPROFILEADV StatRdtePollGC; 279 284 STAMPROFILEADV StatRdtePollHC; 285 STAMPROFILE StatRxOverflow; 286 STAMCOUNTER StatRxOverflowWakeup; 280 287 STAMCOUNTER aStatXmitFlush[16]; 281 288 STAMCOUNTER aStatXmitChainCounts[16]; … … 295 302 STAMCOUNTER StatRingWriteFailedGC; 296 303 297 STAMCOUNTER StatRingWriteOutside RangeHC;298 STAMCOUNTER StatRingWriteOutsideR angeR0;299 STAMCOUNTER StatRingWriteOutside RangeGC;304 STAMCOUNTER StatRingWriteOutsideHC; 305 STAMCOUNTER StatRingWriteOutsideR0; 306 STAMCOUNTER StatRingWriteOutsideGC; 300 307 # endif 301 308 #endif /* VBOX_WITH_STATISTICS */ … … 1163 1170 else 1164 1171 { 1165 STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteOutside Range)); ;1172 STAM_COUNTER_INC(&CTXALLSUFF(pData->StatRingWriteOutside)); ; 1166 1173 return VINF_SUCCESS; /* outside of the ring range */ 1167 1174 } … … 1564 1571 1565 1572 #ifdef IN_RING3 1573 static DECLCALLBACK(void) pcnetWakeupReceive(PPDMDEVINS pDevIns) 1574 { 1575 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 1576 STAM_COUNTER_INC(&pData->StatRxOverflowWakeup); 1577 if (pData->hEventOutOfRxSpace != NIL_RTSEMEVENT) 1578 RTSemEventSignal(pData->hEventOutOfRxSpace); 1579 } 1580 1566 1581 static DECLCALLBACK(bool) pcnetCanRxQueueConsumer(PPDMDEVINS pDevIns, PPDMQUEUEITEMCORE pItem) 1567 1582 { 1568 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 1569 if (pData->pDrv) 1570 pData->pDrv->pfnNotifyCanReceive(pData->pDrv); 1583 pcnetWakeupReceive(pDevIns); 1571 1584 return true; 1572 1585 } 1573 #endif 1586 #endif /* IN_RING3 */ 1574 1587 1575 1588 … … 1615 1628 CSR_CRBC(pData) = rmd.rmd1.bcnt; /* Receive Byte Count */ 1616 1629 CSR_CRST(pData) = ((uint32_t *)&rmd)[1] >> 16; /* Receive Status */ 1630 if (pData->fMaybeOutOfSpace) 1631 { 1617 1632 #ifdef IN_RING3 1618 if (pData->pDrv) 1619 pData->pDrv->pfnNotifyCanReceive(pData->pDrv); 1633 pcnetWakeupReceive(PCNETSTATE_2_DEVINS(pData)); 1620 1634 #else 1621 PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(CTXSUFF(pData->pCanRxQueue)); 1622 if (pItem) 1623 PDMQueueInsert(CTXSUFF(pData->pCanRxQueue), pItem); 1624 #endif 1635 PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(CTXSUFF(pData->pCanRxQueue)); 1636 if (pItem) 1637 PDMQueueInsert(CTXSUFF(pData->pCanRxQueue), pItem); 1638 #endif 1639 } 1625 1640 } 1626 1641 else … … 4224 4239 * This must be called before the pfnRecieve() method is called. 4225 4240 * 4226 * @returns Number of bytes the driver can receive.4241 * @returns VBox status code. 4227 4242 * @param pInterface Pointer to the interface structure containing the called function pointer. 4228 * @thread EMT 4229 */ 4230 static DECLCALLBACK(size_t) pcnetCanReceive(PPDMINETWORKPORT pInterface) 4231 { 4232 size_t cb = 0; 4233 int rc; 4234 PCNetState *pData = INETWORKPORT_2_DATA(pInterface); 4235 4236 rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 4243 */ 4244 static int pcnetCanReceive(PCNetState *pData) 4245 { 4246 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 4237 4247 AssertReleaseRC(rc); 4248 4249 rc = VERR_NET_NO_BUFFER_SPACE; 4238 4250 4239 4251 if (RT_LIKELY(!CSR_DRX(pData) && !CSR_STOP(pData) && !CSR_SPND(pData))) … … 4242 4254 pcnetRdtePoll(pData); 4243 4255 4244 if (HOST_IS_OWNER(CSR_CRST(pData))) 4245 { 4256 if (RT_UNLIKELY(HOST_IS_OWNER(CSR_CRST(pData)))) 4246 4257 /** @todo Notify the guest _now_. Will potentially increase the interrupt load */ 4247 4258 pData->aCSR[0] |= 0x1000; /* Set MISS flag */ 4259 else 4260 rc = VINF_SUCCESS; 4261 } 4262 4263 PDMCritSectLeave(&pData->CritSect); 4264 return rc; 4265 } 4266 4267 /** 4268 * 4269 */ 4270 static DECLCALLBACK(int) pcnetWaitReceiveAvail(PPDMINETWORKPORT pInterface, unsigned cMillies) 4271 { 4272 PCNetState *pData = INETWORKPORT_2_DATA(pInterface); 4273 4274 int rc = pcnetCanReceive(pData); 4275 if (RT_SUCCESS(rc)) 4276 return VINF_SUCCESS; 4277 if (RT_UNLIKELY(cMillies == 0)) 4278 return VERR_NET_NO_BUFFER_SPACE; 4279 4280 rc = VERR_INTERRUPTED; 4281 ASMAtomicXchgBool(&pData->fMaybeOutOfSpace, true); 4282 STAM_PROFILE_START(&pData->StatRxOverflow, a); 4283 while (RT_LIKELY(PDMDevHlpVMState(pData->CTXSUFF(pDevIns)) == VMSTATE_RUNNING)) 4284 { 4285 int rc2 = pcnetCanReceive(pData); 4286 if (RT_SUCCESS(rc2)) 4287 { 4288 rc = VINF_SUCCESS; 4289 break; 4248 4290 } 4249 else 4250 { 4251 /* byte count stored in two's complement 12 bits wide */ 4252 Log(("#%d pcnetCanReceiveNoSync %d bytes\n", PCNET_INST_NR, 4096 - CSR_CRBC(pData))); 4253 cb = 4096 - CSR_CRBC(pData); 4254 } 4255 } 4256 4257 PDMCritSectLeave(&pData->CritSect); 4258 return cb; 4259 } 4260 4291 LogFlow(("pcnetWaitReceiveAvail: waiting cMillies=%u...\n", cMillies)); 4292 RTSemEventWait(pData->hEventOutOfRxSpace, cMillies); 4293 } 4294 STAM_PROFILE_STOP(&pData->StatRxOverflow, a); 4295 ASMAtomicXchgBool(&pData->fMaybeOutOfSpace, false); 4296 4297 return rc; 4298 } 4261 4299 4262 4300 /** … … 4457 4495 RTSemEventDestroy(pData->hSendEventSem); 4458 4496 pData->hSendEventSem = NIL_RTSEMEVENT; 4497 RTSemEventSignal(pData->hEventOutOfRxSpace); 4498 RTSemEventDestroy(pData->hEventOutOfRxSpace); 4459 4499 PDMR3CritSectDelete(&pData->CritSect); 4460 4500 } … … 4559 4599 pData->IBase.pfnQueryInterface = pcnetQueryInterface; 4560 4600 /* INeworkPort */ 4561 pData->INetworkPort.pfn CanReceive = pcnetCanReceive;4601 pData->INetworkPort.pfnWaitReceiveAvail = pcnetWaitReceiveAvail; 4562 4602 pData->INetworkPort.pfnReceive = pcnetReceive; 4563 4603 /* INetworkConfig */ … … 4702 4742 return rc; 4703 4743 4744 rc = RTSemEventCreate(&pData->hEventOutOfRxSpace); 4745 AssertRC(rc); 4746 4704 4747 /* 4705 4748 * Create the transmit queue. … … 4797 4840 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatAPROMRead, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling APROM reads", "/Devices/PCNet%d/IO/APROMRead", iInstance); 4798 4841 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatAPROMWrite, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling APROM writes", "/Devices/PCNet%d/IO/APROMWrite", iInstance); 4799 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOReadGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNetIO reads in GC", "/Devices/PCNet%d/IO/ReadGC", iInstance); 4800 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOReadHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNetIO reads in HC", "/Devices/PCNet%d/IO/ReadHC", iInstance); 4801 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOWriteGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet IO writes in GC", "/Devices/PCNet%d/IO/WriteGC", iInstance); 4802 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOWriteHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet IO writes in HC", "/Devices/PCNet%d/IO/WriteHC", iInstance); 4803 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTimer, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet Timer", "/Devices/PCNet%d/Timer", iInstance); 4804 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet receive", "/Devices/PCNet%d/Receive", iInstance); 4842 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOReadGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO reads in GC", "/Devices/PCNet%d/IO/ReadGC", iInstance); 4843 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOReadHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO reads in HC", "/Devices/PCNet%d/IO/ReadHC", iInstance); 4844 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOWriteGC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO writes in GC", "/Devices/PCNet%d/IO/WriteGC", iInstance); 4845 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatIOWriteHC, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling IO writes in HC", "/Devices/PCNet%d/IO/WriteHC", iInstance); 4846 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTimer, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling Timer", "/Devices/PCNet%d/Timer", iInstance); 4847 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling receive", "/Devices/PCNet%d/Receive", iInstance); 4848 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRxOverflow, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling RX overflows", "/Devices/PCNet%d/RxOverflow", iInstance); 4849 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRxOverflowWakeup, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Nr of RX overflow wakeups", "/Devices/PCNet%d/RxOverflowWakeup", iInstance); 4805 4850 #endif 4806 4851 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatReceiveBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data received", "/Devices/PCNet%d/ReceiveBytes", iInstance); 4807 4852 #ifdef VBOX_WITH_STATISTICS 4808 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet transmit in HC","/Devices/PCNet%d/Transmit/Total", iInstance);4853 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling transmits in HC", "/Devices/PCNet%d/Transmit/Total", iInstance); 4809 4854 #endif 4810 4855 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatTransmitBytes, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES, "Amount of data transmitted", "/Devices/PCNet%d/TransmitBytes", iInstance); … … 4829 4874 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatXmitSkipCurrent, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "", "/Devices/PCNet%d/Xmit/Skipped", iInstance, i + 1); 4830 4875 4831 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatInterrupt, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet interrupt checks","/Devices/PCNet%d/UpdateIRQ", iInstance);4832 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatPollTimer, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling PCNet poll timer","/Devices/PCNet%d/PollTimer", iInstance);4876 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatInterrupt, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling interrupt checks", "/Devices/PCNet%d/UpdateIRQ", iInstance); 4877 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatPollTimer, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling poll timer", "/Devices/PCNet%d/PollTimer", iInstance); 4833 4878 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatMIIReads, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of MII reads", "/Devices/PCNet%d/MIIReads", iInstance); 4834 4879 # ifdef PCNET_NO_POLLING … … 4841 4886 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of failed ring page writes", "/Devices/PCNet%d/Ring/R0/Failed", iInstance); 4842 4887 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteFailedGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of failed ring page writes", "/Devices/PCNet%d/Ring/GC/Failed", iInstance); 4843 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutside RangeHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range","/Devices/PCNet%d/Ring/HC/Outside", iInstance);4844 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideR angeR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range","/Devices/PCNet%d/Ring/R0/Outside", iInstance);4845 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutside RangeGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring range","/Devices/PCNet%d/Ring/GC/Outside", iInstance);4888 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideHC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring","/Devices/PCNet%d/Ring/HC/Outside", iInstance); 4889 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideR0, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring","/Devices/PCNet%d/Ring/R0/Outside", iInstance); 4890 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatRingWriteOutsideGC, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of monitored writes outside ring","/Devices/PCNet%d/Ring/GC/Outside", iInstance); 4846 4891 # endif /* PCNET_NO_POLLING */ 4847 4892 #endif -
trunk/src/VBox/Devices/Network/DrvIntNet.cpp
r6300 r7831 78 78 /** Event semaphore the Thread waits on while the VM is suspended. */ 79 79 RTSEMEVENT EventSuspended; 80 /** Indicates that we're in waiting for recieve space to become available. */81 bool volatile fOutOfSpace;82 /** Event semaphore the Thread sleeps on while polling for more83 * buffer space to become available.84 * @todo We really need the network device to signal this! */85 RTSEMEVENT EventOutOfSpace;86 80 /** Set if the link is down. 87 81 * When the link is down all incoming packets will be dropped. */ … … 95 89 /** Profiling packet receive runs. */ 96 90 STAMPROFILEADV StatReceive; 97 /** Number of receive overflows. */98 STAMPROFILE StatRecvOverflows;99 91 #endif /* VBOX_WITH_STATISTICS */ 100 92 … … 315 307 316 308 /** 317 * More receive buffer has become available.318 *319 * This is called when the NIC frees up receive buffers.320 *321 * @param pInterface Pointer to the interface structure containing the called function pointer.322 * @remark This function isn't called by pcnet nor yet.323 * @thread EMT324 */325 static DECLCALLBACK(void) drvIntNetNotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)326 {327 PDRVINTNET pThis = PDMINETWORKCONNECTOR_2_DRVINTNET(pInterface);328 if (pThis->fOutOfSpace)329 {330 LogFlow(("drvIntNetNotifyCanReceive: signaling\n"));331 RTSemEventSignal(pThis->EventOutOfSpace);332 }333 }334 335 336 /**337 309 * Wait for space to become available up the driver/device chain. 338 310 * … … 347 319 LogFlow(("drvIntNetAsyncIoWaitForSpace: cbFrame=%zu\n", cbFrame)); 348 320 STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a); 349 STAM_PROFILE_START(&pData->StatRecvOverflows, b); 350 351 ASMAtomicXchgSize(&pThis->fOutOfSpace, true); 352 int rc; 353 unsigned cYields = 0; 354 for (;;) 355 { 356 /* yield/sleep */ 357 if ( !RTThreadYield() 358 || ++cYields % 100 == 0) 359 { 360 /** @todo we need a callback from the device which can wake us up here. */ 361 rc = RTSemEventWait(pThis->EventOutOfSpace, 1); 362 if ( VBOX_FAILURE(rc) 363 && rc != VERR_TIMEOUT) 364 break; 365 } 366 if (pThis->enmState != ASYNCSTATE_RUNNING) 367 { 368 rc = VERR_STATE_CHANGED; 369 break; 370 } 371 372 /* retry */ 373 size_t cbMax = pThis->pPort->pfnCanReceive(pThis->pPort); 374 if (cbMax >= cbFrame) 375 { 376 rc = VINF_SUCCESS; 377 break; 378 } 379 } 380 ASMAtomicXchgSize(&pThis->fOutOfSpace, false); 381 382 STAM_PROFILE_STOP(&pThis->StatRecvOverflows, b); 321 int rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, RT_INDEFINITE_WAIT); 383 322 STAM_PROFILE_ADV_START(&pThis->StatReceive, a); 384 323 LogFlow(("drvIntNetAsyncIoWaitForSpace: returns %Vrc\n", rc)); … … 431 370 */ 432 371 size_t cbFrame = pHdr->cbFrame; 433 size_t cbMax = pThis->pPort->pfn CanReceive(pThis->pPort);372 size_t cbMax = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, 0); 434 373 if (cbMax >= cbFrame) 435 374 { … … 657 596 ASMAtomicXchgSize(&pThis->enmState, ASYNCSTATE_TERMINATE); 658 597 ASMAtomicXchgSize(&pThis->fLinkDown, true); 659 RTSEMEVENT EventOutOfSpace = pThis->EventOutOfSpace;660 pThis->EventOutOfSpace = NIL_RTSEMEVENT;661 598 RTSEMEVENT EventSuspended = pThis->EventSuspended; 662 599 pThis->EventSuspended = NIL_RTSEMEVENT; … … 681 618 if (pThis->Thread != NIL_RTTHREAD) 682 619 { 683 if (EventOutOfSpace != NIL_RTSEMEVENT)684 RTSemEventSignal(EventOutOfSpace);685 620 if (EventSuspended != NIL_RTSEMEVENT) 686 621 RTSemEventSignal(EventSuspended); … … 693 628 * Destroy the semaphores. 694 629 */ 695 if (EventOutOfSpace != NIL_RTSEMEVENT)696 RTSemEventDestroy(EventOutOfSpace);697 630 if (EventSuspended != NIL_RTSEMEVENT) 698 631 RTSemEventDestroy(EventSuspended); … … 721 654 pThis->Thread = NIL_RTTHREAD; 722 655 pThis->EventSuspended = NIL_RTSEMEVENT; 723 pThis->EventOutOfSpace = NIL_RTSEMEVENT;724 656 pThis->enmState = ASYNCSTATE_SUSPENDED; 725 657 pThis->fActivateEarly = false; … … 730 662 pThis->INetworkConnector.pfnSetPromiscuousMode = drvIntNetSetPromiscuousMode; 731 663 pThis->INetworkConnector.pfnNotifyLinkChanged = drvIntNetNotifyLinkChanged; 732 pThis->INetworkConnector.pfnNotifyCanReceive = drvIntNetNotifyCanReceive;733 664 734 665 /* … … 809 740 */ 810 741 rc = RTSemEventCreate(&pThis->EventSuspended); 811 if (VBOX_FAILURE(rc))812 return rc;813 rc = RTSemEventCreate(&pThis->EventOutOfSpace);814 742 if (VBOX_FAILURE(rc)) 815 743 return rc; … … 871 799 RTStrPrintf(szStatName, sizeof(szStatName), "/Net/IntNet%d/Receive", pDrvIns->iInstance); 872 800 pDrvIns->pDrvHlp->pfnSTAMRegister(pDrvIns, &pThis->StatReceive, STAMTYPE_PROFILE, szStatName, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs."); 873 RTStrPrintf(szStatName, sizeof(szStatName), "/Net/IntNet%d/RecvOverflows", pDrvIns->iInstance);874 pDrvIns->pDrvHlp->pfnSTAMRegister(pDrvIns, &pThis->StatRecvOverflows, STAMTYPE_PROFILE, szStatName, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling packet receive overflows.");875 801 RTStrPrintf(szStatName, sizeof(szStatName), "/Net/IntNet%d/Transmit", pDrvIns->iInstance); 876 802 pDrvIns->pDrvHlp->pfnSTAMRegister(pDrvIns, &pThis->StatTransmit, STAMTYPE_PROFILE, szStatName, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs."); -
trunk/src/VBox/Devices/Network/DrvNAT.cpp
r6374 r7831 158 158 159 159 /** 160 * More receive buffer has become available.161 *162 * This is called when the NIC frees up receive buffers.163 *164 * @param pInterface Pointer to the interface structure containing the called function pointer.165 * @thread EMT166 */167 static DECLCALLBACK(void) drvNATNotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)168 {169 LogFlow(("drvNATNotifyCanReceive:\n"));170 /** @todo do something useful here. */171 }172 173 174 /**175 160 * Poller callback. 176 161 */ … … 215 200 return 0; 216 201 217 return pData->pPort->pfnCanReceive(pData->pPort); 202 int rc = pData->pPort->pfnWaitReceiveAvail(pData->pPort, 0); 203 return RT_SUCCESS(rc); 218 204 } 219 205 … … 405 391 pData->INetworkConnector.pfnSetPromiscuousMode = drvNATSetPromiscuousMode; 406 392 pData->INetworkConnector.pfnNotifyLinkChanged = drvNATNotifyLinkChanged; 407 pData->INetworkConnector.pfnNotifyCanReceive = drvNATNotifyCanReceive;408 393 409 394 /* -
trunk/src/VBox/Devices/Network/DrvNetSniffer.cpp
r5999 r7831 183 183 184 184 /** 185 * More receive buffer has become available.186 *187 * This is called when the NIC frees up receive buffers.188 *189 * @param pInterface Pointer to the interface structure containing the called function pointer.190 * @thread EMT191 */192 static DECLCALLBACK(void) drvNetSnifferNotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)193 {194 LogFlow(("drvNetSnifferNotifyCanReceive:\n"));195 PDRVNETSNIFFER pData = PDMINETWORKCONNECTOR_2_DRVNETSNIFFER(pInterface);196 if (pData->pConnector)197 pData->pConnector->pfnNotifyCanReceive(pData->pConnector);198 }199 200 201 /**202 185 * Check how much data the device/driver can receive data now. 203 186 * This must be called before the pfnRecieve() method is called. … … 207 190 * @thread EMT 208 191 */ 209 static DECLCALLBACK( size_t) drvNetSnifferCanReceive(PPDMINETWORKPORT pInterface)192 static DECLCALLBACK(int) drvNetSnifferWaitReceiveAvail(PPDMINETWORKPORT pInterface, unsigned cMillies) 210 193 { 211 194 PDRVNETSNIFFER pData = PDMINETWORKPORT_2_DRVNETSNIFFER(pInterface); 212 return pData->pPort->pfn CanReceive(pData->pPort);195 return pData->pPort->pfnWaitReceiveAvail(pData->pPort, cMillies); 213 196 } 214 197 … … 335 318 pData->INetworkConnector.pfnSetPromiscuousMode = drvNetSnifferSetPromiscuousMode; 336 319 pData->INetworkConnector.pfnNotifyLinkChanged = drvNetSnifferNotifyLinkChanged; 337 pData->INetworkConnector.pfnNotifyCanReceive = drvNetSnifferNotifyCanReceive;338 320 /* INetworkPort */ 339 pData->INetworkPort.pfn CanReceive = drvNetSnifferCanReceive;340 pData->INetworkPort.pfnReceive = drvNetSnifferReceive;321 pData->INetworkPort.pfnWaitReceiveAvail = drvNetSnifferWaitReceiveAvail; 322 pData->INetworkPort.pfnReceive = drvNetSnifferReceive; 341 323 342 324 /* -
trunk/src/VBox/Devices/Network/DrvTAP.cpp
r7799 r7831 114 114 /** Reader thread. */ 115 115 PPDMTHREAD pThread; 116 /** We are waiting for more receive buffers. */117 bool volatile fMaybeOutOfSpace;118 /** Event semaphore for blocking on receive. */119 RTSEMEVENT EventOutOfSpace;120 116 121 117 #ifdef VBOX_WITH_STATISTICS … … 132 128 /** Profiling packet receive runs. */ 133 129 STAMPROFILEADV StatReceive; 134 /** Profiling receive descriptor overflows. */135 STAMPROFILE StatRecvOverflows;136 130 #endif /* VBOX_WITH_STATISTICS */ 137 131 … … 228 222 229 223 /** 230 * More receive buffer has become available.231 *232 * This is called when the NIC frees up receive buffers.233 *234 * @param pInterface Pointer to the interface structure containing the called function pointer.235 * @thread EMT236 */237 static DECLCALLBACK(void) drvTAPNotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)238 {239 PDRVTAP pData = PDMINETWORKCONNECTOR_2_DRVTAP(pInterface);240 241 LogFlow(("drvTAPNotifyCanReceive:\n"));242 /** @todo r=bird: A better solution would be to ditch the NotifyCanReceive callback and243 * instead change the CanReceive to do all the work. That is, CanReceive244 * will not return until there are receive buffers available. This will245 * reduce the amount of code duplication, and would permit pcnet to avoid246 * queuing unnecessary ring-3 tasks.247 */248 if (pData->fMaybeOutOfSpace)249 RTSemEventSignal(pData->EventOutOfSpace);250 }251 252 253 /**254 224 * Asynchronous I/O thread for handling receive. 255 225 * … … 267 237 268 238 STAM_PROFILE_ADV_START(&pData->StatReceive, a); 269 270 int rc = RTSemEventCreate(&pData->EventOutOfSpace);271 AssertRC(rc);272 239 273 240 /* … … 288 255 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a); 289 256 errno=0; 290 rc = poll(&aFDs[0], ELEMENTS(aFDs), -1 /* infinite */);257 int rc = poll(&aFDs[0], ELEMENTS(aFDs), -1 /* infinite */); 291 258 292 259 /* this might have changed in the meantime */ … … 331 298 * overflow error to allocate more receive buffers 332 299 */ 333 ASMAtomicXchgBool(&pData->fMaybeOutOfSpace, true); 334 size_t cbMax = pData->pPort->pfnCanReceive(pData->pPort); 335 if (cbMax == 0) 336 { 337 /** @todo receive overflow handling needs serious improving! */ 338 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a); 339 STAM_PROFILE_START(&pData->StatRecvOverflows, b); 340 while ( cbMax == 0 341 && pThread->enmState == PDMTHREADSTATE_RUNNING) 342 { 343 LogFlow(("drvTAPAsyncIoThread: cbMax=%d cbRead=%d waiting...\n", cbMax, cbRead)); 344 /* We get signalled by the network driver. 50ms is just for sanity */ 345 RTSemEventWait(pData->EventOutOfSpace, 50); 346 cbMax = pData->pPort->pfnCanReceive(pData->pPort); 347 } 348 STAM_PROFILE_STOP(&pData->StatRecvOverflows, b); 349 STAM_PROFILE_ADV_START(&pData->StatReceive, a); 350 } 351 ASMAtomicXchgBool(&pData->fMaybeOutOfSpace, false); 352 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 300 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a); 301 int rc = pData->pPort->pfnWaitReceiveAvail(pData->pPort, RT_INDEFINITE_WAIT); 302 STAM_PROFILE_ADV_START(&pData->StatReceive, a); 303 if (RT_FAILURE(rc)) 353 304 break; 354 305 … … 405 356 406 357 407 rc = RTSemEventDestroy(pData->EventOutOfSpace);408 AssertRC(rc);409 pData->EventOutOfSpace = NIL_RTSEMEVENT;410 411 358 LogFlow(("drvTAPAsyncIoThread: returns %Vrc\n", VINF_SUCCESS)); 412 359 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a); … … 425 372 { 426 373 PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP); 427 428 /* Ensure that it does not spin in the CanReceive loop.429 (May assert in IPRT if we're really unlucky.) */430 if (pData->fMaybeOutOfSpace)431 RTSemEventSignal(pData->EventOutOfSpace);432 374 433 375 int rc = RTFileWrite(pData->PipeWrite, "", 1, NULL); … … 956 898 pData->INetworkConnector.pfnSetPromiscuousMode = drvTAPSetPromiscuousMode; 957 899 pData->INetworkConnector.pfnNotifyLinkChanged = drvTAPNotifyLinkChanged; 958 pData->INetworkConnector.pfnNotifyCanReceive = drvTAPNotifyCanReceive;959 900 960 901 /* … … 1093 1034 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Drivers/TAP%d/Transmit", pDrvIns->iInstance); 1094 1035 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Drivers/TAP%d/Receive", pDrvIns->iInstance); 1095 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatRecvOverflows, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling packet receive overflows.", "/Drivers/TAP%d/RecvOverflows", pDrvIns->iInstance);1096 1036 #endif /* VBOX_WITH_STATISTICS */ 1097 1037 -
trunk/src/VBox/Devices/Network/DrvTAPOs2.cpp
r6300 r7831 62 62 /** Receiver thread. */ 63 63 PPDMTHREAD pThread; 64 /** Event semaphore for blocking on receive. */65 RTSEMEVENT EventOutOfSpace;66 /** We are checking or waiting for more receive buffers. */67 bool volatile fMaybeOutOfSpace;68 64 /** Set if the link is down. 69 65 * When the link is down all incoming packets will be dropped. */ … … 87 83 /** Profiling packet receive runs. */ 88 84 STAMPROFILEADV StatReceive; 89 STAMPROFILE StatRecvOverflows;90 85 #endif /* VBOX_WITH_STATISTICS */ 91 86 … … 209 204 LogFlow(("%s: NotifyLinkChanged: enmLinkState=%d %d->%d\n", pThis->szName, pThis->fLinkDown, fLinkDown)); 210 205 ASMAtomicXchgBool(&pThis->fLinkDown, fLinkDown); 211 }212 213 214 /**215 * More receive buffer has become available.216 *217 * This is called when the NIC frees up receive buffers.218 *219 * @param pInterface Pointer to the interface structure containing the called function pointer.220 * @thread EMT221 */222 static DECLCALLBACK(void) drvTAPOs2NotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)223 {224 PDRVTAPOS2 pThis = PDMINETWORKCONNECTOR_2_DRVTAPOS2(pInterface);225 226 /* don't waste time signalling the semaphore unnecessary */227 if (!pThis->fMaybeOutOfSpace)228 LogFlow(("%s: NotifyCanReceive: fMaybeOutOfSpace=false\n", pThis->szName));229 else230 {231 LogFlow(("%s: NotifyCanReceive: fMaybeOutOfSpace=true\n", pThis->szName));232 RTSemEventSignal(pThis->EventOutOfSpace);233 }234 206 } 235 207 … … 282 254 * Wait for the device to have some room. 283 255 */ 284 ASMAtomicXchgBool(&pThis->fMaybeOutOfSpace, true); 285 size_t cbMax = pThis->pPort->pfnCanReceive(pThis->pPort); 286 if (cbMax == 0) 287 { 288 STAM_PROFILE_ADV_STOP(&pThis->StatReceive, a); 289 STAM_PROFILE_START(&pThis->StatRecvOverflows, b); 290 while ( cbMax == 0 291 && pThread->enmState == PDMTHREADSTATE_RUNNING) 292 { 293 LogFlow(("%s: ReceiveThread: cbMax=%d cbRead=%d waiting...\n", pThis->szName, cbMax, cbRead)); 294 RTSemEventWait(pThis->EventOutOfSpace, 50); 295 cbMax = pThis->pPort->pfnCanReceive(pThis->pPort); 296 } 297 STAM_PROFILE_STOP(&pThis->StatRecvOverflows, b); 298 STAM_PROFILE_ADV_START(&pThis->StatReceive, a); 299 } 300 ASMAtomicXchgBool(&pThis->fMaybeOutOfSpace, false); 301 if (pThread->enmState != PDMTHREADSTATE_RUNNING) 302 break; /* just drop it, no big deal. */ 256 rc = pThis->pPort->pfnWaitReceiveAvail(pThis->pPort, RT_INDEFINITE_WAIT); 257 if (RT_FAILURE(rc)) 258 break; 303 259 304 260 /* … … 358 314 AssertMsg(orc == 0, ("%d\n", orc)); NOREF(orc); 359 315 360 /* wake it up if it's waiting for receive buffers. */361 if (pThis->fMaybeOutOfSpace)362 RTSemEventSignal(pThis->EventOutOfSpace);363 364 316 return VINF_SUCCESS; 365 317 } … … 405 357 406 358 /* PDM will destroy the thread for us, it's suspended right now. */ 407 408 /*409 * Destroy the out-of-space event semaphore.410 */411 if (pThis->EventOutOfSpace != NIL_RTSEMEVENTMULTI)412 {413 int rc = RTSemEventDestroy(pThis->EventOutOfSpace);414 AssertRC(rc);415 pThis->EventOutOfSpace = NIL_RTSEMEVENTMULTI;416 }417 359 418 360 /* … … 473 415 pThis->INetworkConnector.pfnSetPromiscuousMode = drvTAPOs2SetPromiscuousMode; 474 416 pThis->INetworkConnector.pfnNotifyLinkChanged = drvTAPOs2NotifyLinkChanged; 475 pThis->INetworkConnector.pfnNotifyCanReceive = drvTAPOs2NotifyCanReceive;476 417 477 418 /* … … 590 531 pThis->szName, pThis->iLan, pThis->iConnectedTo, Parm[0], Parm[1])); 591 532 592 /*593 * Create the out-of-space semaphore and the async receiver thread.594 */595 rc = RTSemEventCreate(&pThis->EventOutOfSpace);596 AssertRCReturn(rc, rc);597 598 533 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pThis->pThread, pThis, drvTAPOs2ReceiveThread, drvTAPOs2WakeupReceiveThread, 599 534 0, RTTHREADTYPE_IO, pThis->szName); … … 610 545 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Drivers/TAP%d/Transmit", pDrvIns->iInstance); 611 546 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Drivers/TAP%d/Receive", pDrvIns->iInstance); 612 PDMDrvHlpSTAMRegisterF(pDrvIns, &pThis->StatRecvOverflows, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling packet receive overflows.", "/Drivers/TAP%d/RecvOverflows", pDrvIns->iInstance);613 547 #endif /* VBOX_WITH_STATISTICS */ 614 548 -
trunk/src/VBox/Devices/Network/DrvTAPWin32.cpp
r7321 r7831 18 18 19 19 20 #define ASYNC_NETIO21 22 20 /******************************************************************************* 23 21 * Header Files * … … 32 30 #include <iprt/string.h> 33 31 #include <iprt/thread.h> 34 #ifdef ASYNC_NETIO35 32 #include <iprt/asm.h> 36 33 #include <iprt/semaphore.h> 37 #endif38 34 39 35 #include <windows.h> … … 68 64 TAP_VERSION tapVersion; 69 65 70 #ifdef ASYNC_NETIO71 66 /** The thread handle. NIL_RTTHREAD if no thread. */ 72 RTTHREAD hThread;67 PPDMTHREAD pThread; 73 68 /** The event semaphore the thread is waiting on. */ 74 69 HANDLE hHaltAsyncEventSem; 75 /** We are waiting for more receive buffers. */76 uint32_t volatile fOutOfSpace;77 /** Event semaphore for blocking on receive. */78 RTSEMEVENT EventOutOfSpace;79 #endif80 70 81 71 #ifdef DEBUG … … 97 87 /** Profiling packet receive runs. */ 98 88 STAMPROFILEADV StatReceive; 99 # ifdef ASYNC_NETIO100 89 STAMPROFILE StatRecvOverflows; 101 # endif102 90 #endif /* VBOX_WITH_STATISTICS */ 103 91 } DRVTAP, *PDRVTAP; … … 191 179 192 180 /** 193 * More receive buffer has become available.194 *195 * This is called when the NIC frees up receive buffers.196 *197 * @param pInterface Pointer to the interface structure containing the called function pointer.198 * @thread EMT199 */200 static DECLCALLBACK(void) drvTAPW32NotifyCanReceive(PPDMINETWORKCONNECTOR pInterface)201 {202 PDRVTAP pData = PDMINETWORKCONNECTOR_2_DRVTAP(pInterface);203 204 LogFlow(("drvTAPW32NotifyCanReceive:\n"));205 if (ASMAtomicXchgU32(&pData->fOutOfSpace, false))206 RTSemEventSignal(pData->EventOutOfSpace);207 }208 209 210 #ifndef ASYNC_NETIO211 /**212 * Poller callback.213 */214 static DECLCALLBACK(void) drvTAPW32Poller(PPDMDRVINS pDrvIns)215 {216 DWORD rc = ERROR_SUCCESS;217 PDRVTAP pData = PDMINS2DATA(pDrvIns, PDRVTAP);218 STAM_PROFILE_ADV_START(&pData->StatReceive, a);219 220 /* check how much the device/driver can receive now. */221 size_t cbMax = pData->pPort->pfnCanReceive(pData->pPort);222 223 while (cbMax)224 {225 if (cbMax > 0 && !pData->overlappedRead.hEvent)226 {227 BOOL bRet;228 229 cbMax = RT_MIN(cbMax, sizeof(pData->readBuffer));230 memset(&pData->overlappedRead, 0, sizeof(pData->overlappedRead));231 pData->overlappedRead.hEvent = pData->hEventRead;232 bRet = ReadFile(pData->hFile, pData->readBuffer, cbMax, &pData->dwNumberOfBytesRead, &pData->overlappedRead);233 if (bRet == FALSE)234 {235 rc = GetLastError();236 AssertMsg(rc == ERROR_SUCCESS || rc == ERROR_IO_PENDING || rc == ERROR_MORE_DATA, ("ReadFileEx failed with rc=%d\n", rc));237 if (rc != ERROR_IO_PENDING && rc != ERROR_MORE_DATA)238 break;239 }240 }241 if (cbMax)242 {243 DWORD dwNumberOfBytesTransferred = 0;244 245 if (GetOverlappedResult(pData->hFile, &pData->overlappedRead, &dwNumberOfBytesTransferred, FALSE) == TRUE)246 {247 /* push it to the driver. */248 Log2(("drvTAPW32Poller%d: cbRead=%#x\n"249 "%.*Vhxd\n", pData->InstanceNr,250 dwNumberOfBytesTransferred, dwNumberOfBytesTransferred, pData->readBuffer));251 252 STAM_COUNTER_INC(&pData->StatPktRecv);253 STAM_COUNTER_ADD(&pData->StatPktRecvBytes, dwNumberOfBytesTransferred);254 255 #ifdef DEBUG256 pData->dwLastWriteTime = timeGetTime();257 Log(("drvTAPW32Receive %d bytes at %08x - delta %x\n", dwNumberOfBytesTransferred,258 pData->dwLastWriteTime, pData->dwLastWriteTime - pData->dwLastReadTime));259 #endif260 261 rc = pData->pPort->pfnReceive(pData->pPort, pData->readBuffer, dwNumberOfBytesTransferred);262 AssertRC(rc);263 264 memset(&pData->overlappedRead, 0, sizeof(pData->overlappedRead));265 }266 else267 {268 rc = GetLastError();269 Assert(rc == ERROR_IO_INCOMPLETE);270 271 /* reset overlapped structure on aborted read operation */272 if (rc != ERROR_IO_INCOMPLETE)273 {274 memset(&pData->overlappedRead, 0, sizeof(pData->overlappedRead));275 }276 break;277 }278 }279 cbMax = pData->pPort->pfnCanReceive(pData->pPort);280 }281 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a);282 }283 #else /* !ASYNC_NETIO */284 /**285 181 * Async I/O thread for an interface. 286 182 */ 287 static DECLCALLBACK(int) drvTAPW32AsyncIo (RTTHREAD ThreadSelf, void *pvUser)183 static DECLCALLBACK(int) drvTAPW32AsyncIoThread(PPDMDRVINS pDrvIns, PPDMTHREAD pThread) 288 184 { 289 185 PDRVTAP pData = (PDRVTAP)pvUser; … … 291 187 DWORD rc = ERROR_SUCCESS, dwNumberOfBytesTransferred; 292 188 189 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 190 return VINF_SUCCESS; 191 293 192 Assert(pData); 294 193 haWait[0] = pData->hEventRead; 295 194 haWait[1] = pData->hHaltAsyncEventSem; 296 297 rc = RTSemEventCreate(&pData->EventOutOfSpace);298 AssertRC(rc);299 195 300 196 while(1) … … 326 222 327 223 /* Not very nice, but what else can we do? */ 328 size_t cbMax = pData->pPort->pfnCanReceive(pData->pPort); 329 if (cbMax == 0) 330 { 331 STAM_PROFILE_START(&pData->StatRecvOverflows, b); 332 while (cbMax == 0) 333 { 334 #if 1 335 ASMAtomicXchgU32(&pData->fOutOfSpace, true); 336 RTSemEventWait(pData->EventOutOfSpace, 50); 337 #else 338 RTThreadSleep(16); /* @todo right value? */ 339 #endif 340 /* Check if the VM was terminated */ 341 rc = WaitForSingleObject(haWait[1], 0); 342 if (rc == WAIT_OBJECT_0) 343 { 344 STAM_PROFILE_STOP(&pData->StatRecvOverflows, b); 345 goto exit_thread; 346 } 347 348 cbMax = pData->pPort->pfnCanReceive(pData->pPort); 349 } 350 ASMAtomicXchgU32(&pData->fOutOfSpace, false); 351 STAM_PROFILE_STOP(&pData->StatRecvOverflows, b); 352 Assert(cbMax >= dwNumberOfBytesTransferred); 353 } 224 rc = pData->pPort->pfnWaitReceiveAvail(pData->pPort, RT_INDEFINITE_WAIT); 225 if (RT_FAILURE(rc)) 226 break; 354 227 355 228 STAM_COUNTER_INC(&pData->StatPktRecv); … … 364 237 } 365 238 366 exit_thread:367 239 SetEvent(pData->hHaltAsyncEventSem); 368 240 Log(("drvTAPW32AsyncIo: exit thread!!\n")); 369 241 return VINF_SUCCESS; 370 242 } 371 #endif /* !ASYNC_NETIO */372 243 373 244 /** … … 412 283 LogFlow(("drvTAPW32Destruct\n")); 413 284 414 #ifdef ASYNC_NETIO415 285 /** @todo this isn't a safe method to notify the async thread; it might be using the instance 416 286 * data after we've been destroyed; could wait for it to terminate, but that's not … … 418 288 */ 419 289 SetEvent(pData->hHaltAsyncEventSem); 420 421 /* Ensure that it does not spin in the CanReceive loop. Do it _after_ we set set the422 * hHaltAsyncEventSem to ensure that we don't go into the loop again immediately. */423 if (ASMAtomicXchgU32(&pData->fOutOfSpace, false))424 RTSemEventSignal(pData->EventOutOfSpace);425 290 426 291 /* Yield or else our async thread will never acquire the event semaphore */ … … 428 293 /* Wait for the async thread to quit; up to half a second */ 429 294 WaitForSingleObject(pData->hHaltAsyncEventSem, 500); 430 #endif431 295 432 296 mediastatus.fConnect = FALSE; … … 466 330 pData->INetworkConnector.pfnSetPromiscuousMode = drvTAPW32SetPromiscuousMode; 467 331 pData->INetworkConnector.pfnNotifyLinkChanged = drvTAPW32NotifyLinkChanged; 468 pData->INetworkConnector.pfnNotifyCanReceive = drvTAPW32NotifyCanReceive;469 332 470 333 /* … … 560 423 memset(&pData->overlappedRead, 0, sizeof(pData->overlappedRead)); 561 424 562 #ifdef ASYNC_NETIO563 425 pData->hHaltAsyncEventSem = CreateEvent(NULL, FALSE, FALSE, NULL); 564 426 565 427 /* Create asynchronous thread */ 566 rc = RTThreadCreate(&pData->hThread, drvTAPW32AsyncIo, (void *)pData, 128*1024, RTTHREADTYPE_IO, 0, "TAP");567 AssertRC (rc);428 rc = PDMDrvHlpPDMThreadCreate(pDrvIns, &pData->pThread, pData, drvTAPW32AsyncIoThread, drvTAPW32AsyncIoWakeup, 128 * _1K, RTTHREADTYPE_IO, "TAP"); 429 AssertRCReturn(rc, rc); 568 430 569 431 Assert(pData->hThread != NIL_RTTHREAD && pData->hHaltAsyncEventSem != NULL); 570 #else571 /*572 * Register poller573 */574 rc = pDrvIns->pDrvHlp->pfnPDMPollerRegister(pDrvIns, drvTAPW32Poller);575 AssertRC(rc);576 #endif577 432 578 433 #ifdef VBOX_WITH_STATISTICS … … 586 441 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatTransmit, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet transmit runs.", "/Drivers/TAP%d/Transmit", pDrvIns->iInstance); 587 442 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatReceive, STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_CALL, "Profiling packet receive runs.", "/Drivers/TAP%d/Receive", pDrvIns->iInstance); 588 # ifdef ASYNC_NETIO589 443 PDMDrvHlpSTAMRegisterF(pDrvIns, &pData->StatRecvOverflows,STAMTYPE_PROFILE, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, "Profiling packet receive overflows.", "/Drivers/TAP%d/RecvOverflows", pDrvIns->iInstance); 590 # endif591 444 #endif 592 445
Note:
See TracChangeset
for help on using the changeset viewer.