Changeset 638 in vbox
- Timestamp:
- Feb 5, 2007 2:18:05 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 18267
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r605 r638 62 62 #include <VBox/pgm.h> 63 63 #include <VBox/stam.h> 64 #include <VBox/vm.h> /* for VM_IS_EMT */ 64 65 #include <iprt/asm.h> 65 66 #include <iprt/assert.h> … … 239 240 RTTHREAD hSendThread; 240 241 #endif 241 uint32_t fPendingSend;242 242 243 243 /** Access critical section. */ … … 307 307 STAMCOUNTER StatXmitSync; 308 308 STAMCOUNTER StatXmitAsync; 309 STAMCOUNTER StatXmitInTxThread; 309 310 STAMPROFILE StatXmitQueueAsync; 310 311 #endif /* VBOX_WITH_STATISTICS */ … … 1001 1002 1002 1003 1003 #ifdef IN_RING31004 static DECLCALLBACK(void) pcnetXmitSendPackets(PCNetState *pData);1005 #endif1006 1007 /**1008 * Wrapper for PDMCritSectEnter1009 */1010 #define PCNetCritSectEnter(pCritSect, rcBusy) \1011 PDMCritSectEnter(pCritSect, rcBusy);1012 1013 /**1014 * Wrapper for PDMCritSectLeave1015 *1016 * Generic, but primarily intended for the receive thread that has grabbed the critical section1017 */1018 #ifdef IN_RING31019 #define PCNetCritSectLeave(pData) \1020 if (ASMAtomicCmpXchgU32(&pData->fPendingSend, 0, 1)) \1021 { \1022 STAM_COUNTER_INC(&pData->StatDeferredXmit); \1023 pcnetXmitSendPackets(pData); \1024 } \1025 PDMCritSectLeave(&pData->CritSect)1026 #else1027 #define PCNetCritSectLeave(pData) \1028 PDMCritSectLeave(&pData->CritSect)1029 #endif /* IN_RING3 */1030 1031 /**1032 * Wrapper for PDMR3CritSectTryEnter1033 */1034 #define PCNetCritSectTryEnter(pData) \1035 PDMR3CritSectTryEnter(&pData->CritSect)1036 1037 1004 #ifdef PCNET_NO_POLLING 1038 1005 # ifndef IN_RING3 … … 1068 1035 uint32_t offsetTDRA = (GCPhysFault - pData->GCTDRA); 1069 1036 1070 int rc = P CNetCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);1037 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 1071 1038 if (VBOX_SUCCESS(rc)) 1072 1039 { … … 1077 1044 pcnetUpdateIrq(pData); 1078 1045 1079 P CNetCritSectLeave(pData);1046 PDMCritSectLeave(&pData->CritSect); 1080 1047 return VINF_SUCCESS; 1081 1048 } … … 1135 1102 ) 1136 1103 { 1137 int rc = P CNetCritSectEnter(&pData->CritSect, VERR_SEM_BUSY);1104 int rc = PDMCritSectEnter(&pData->CritSect, VERR_SEM_BUSY); 1138 1105 AssertReleaseRC(rc); 1139 1106 /* Check if we can do something now */ 1140 1107 pcnetPollRxTx(pData); 1141 1108 pcnetUpdateIrq(pData); 1142 P CNetCritSectLeave(pData);1109 PDMCritSectLeave(&pData->CritSect); 1143 1110 } 1144 1111 } … … 1857 1824 int rc; 1858 1825 1826 /** @note We must only access the queued transmit packets from EMT. Below we assume we don't need to grab the critical section while accessing 1827 * this data. 1828 */ 1829 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 1830 1831 /* Return immediately if there's nothing to do. (grabbing the critical section can be expensive) */ 1832 if (RT_UNLIKELY(pData->iFrame == 0)) 1833 { 1834 STAM_COUNTER_INC(&pData->aStatFlushCounts[pData->iFrame]); 1835 return; 1836 } 1837 1859 1838 STAM_PROFILE_START(&pData->StatXmitQueue, a); 1860 1839 STAM_COUNTER_INC(&pData->aStatFlushCounts[pData->iFrame]); 1861 rc = PCNetCritSectTryEnter(pData);1862 if (rc != VINF_SUCCESS)1863 {1864 /* Somebody else grabbed the critical section (most likely the receive thread) */1865 Assert(!pData->fPendingSend);1866 1867 ASMAtomicCmpXchgU32(&pData->fPendingSend, 1, 0);1868 1869 /* If we can't get the critsect now, then whoever owns it will send the packets for us (see PCNetCritSectLeave) */1870 rc = PCNetCritSectTryEnter(pData);1871 if (rc != VINF_SUCCESS)1872 {1873 STAM_COUNTER_INC(&pData->StatDeferredXmitPending);1874 STAM_COUNTER_DEC(&pData->aStatFlushCounts[pData->iFrame]);1875 STAM_PROFILE_STOP(&pData->StatXmitQueue, a);1876 return;1877 }1878 1879 /* We were too late (or got rescheduled in an unfortunate way (iFrame=0), so let's just continue. */1880 pData->fPendingSend = 0;1881 }1882 1883 AssertReleaseRC(rc);1884 1840 Log(("#%d pcnetXmitQueueConsumer: iFrame=%d\n", PCNETSTATE_2_DEVINS(pData)->iInstance, pData->iFrame)); 1885 1841 … … 1947 1903 if (pData->iFrame) 1948 1904 { 1905 /** @note this part needs to be protected; perhaps we can change the code to drop this requirement. */ 1906 rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 1907 AssertReleaseRC(rc); 1908 1949 1909 /* Update TXSTRT and TINT. */ 1950 1910 pData->aCSR[4] |= 0x0004; /* set TXSTRT */ 1951 1911 pData->aCSR[0] |= 0x0200; /* set TINT */ 1952 1912 pcnetUpdateIrq(pData); 1913 1914 PDMCritSectLeave(&pData->CritSect); 1953 1915 } 1954 1916 #endif … … 1962 1924 pData->Led.Actual.s.fWriting = 0; 1963 1925 1964 PCNetCritSectLeave(pData);1965 1926 STAM_PROFILE_STOP(&pData->StatXmitQueue, a); 1966 1927 } … … 2011 1972 DECLINLINE(void) pcnetXmitFlushFrames(PCNetState *pData) 2012 1973 { 1974 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2013 1975 if (pData->iFrame) 2014 1976 { … … 2039 2001 { 2040 2002 const uint32_t iFrame = pData->iFrame; 2003 2004 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2005 2041 2006 pData->aFrames[iFrame].cb = -1; 2042 2007 } … … 2049 2014 { 2050 2015 const uint32_t iFrame = pData->iFrame; 2016 2017 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2018 2051 2019 if ( fForceFlush 2052 2020 || cb > sizeof(pData->abFrameBuf) - pData->aFrames[iFrame].off) … … 2064 2032 { 2065 2033 const uint32_t iFrame = pData->iFrame; 2034 2035 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2036 2066 2037 pData->aFrames[iFrame].pvR3 = pv; 2067 2038 pData->aFrames[iFrame].cb = cbFrame; … … 2076 2047 { 2077 2048 const uint32_t iFrame = pData->iFrame; 2049 2050 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2051 2078 2052 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, 2079 2053 &pData->abFrameBuf[pData->aFrames[iFrame].off], … … 2089 2063 { 2090 2064 const uint32_t iFrame = pData->iFrame; 2065 2066 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2067 2091 2068 PDMDevHlpPhysRead(pData->CTXSUFF(pDevIns), GCPhysFrame, 2092 2069 &pData->abFrameBuf[pData->aFrames[iFrame].off + pData->aFrames[iFrame].cb], … … 2103 2080 { 2104 2081 const uint32_t iFrame = ++pData->iFrame; 2082 2083 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2084 2105 2085 if (iFrame == ELEMENTS(pData->aFrames)) 2106 2086 pcnetXmitFlushFrames(pData); … … 2137 2117 { 2138 2118 Assert(pData->iFrame == 0); 2119 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2120 2139 2121 pData->Led.Asserted.s.fReading = pData->Led.Actual.s.fReading = 1; 2140 2122 if (HOST_IS_OWNER(CSR_CRST(pData))) … … 2155 2137 * recursion when flushing a queue. 2156 2138 */ 2157 if (pData->fTransmitting) 2139 if ( pData->fTransmitting 2140 || !VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))) 2158 2141 return; 2142 2143 Assert(VM_IS_EMT(PDMDevHlpGetVM(PCNETSTATE_2_DEVINS(pData)))); 2159 2144 2160 2145 if (RT_UNLIKELY(!CSR_TXON(pData))) … … 3123 3108 { 3124 3109 STAM_PROFILE_ADV_START(&pData->StatAPROMRead, a); 3125 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE);3110 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE); 3126 3111 if (rc == VINF_SUCCESS) 3127 3112 { 3128 3113 *pu32 = pcnetAPROMReadU8(pData, Port); 3129 P CNetCritSectLeave(pData);3114 PDMCritSectLeave(&pData->CritSect); 3130 3115 } 3131 3116 STAM_PROFILE_ADV_STOP(&pData->StatAPROMRead, a); … … 3159 3144 { 3160 3145 STAM_PROFILE_ADV_START(&pData->StatAPROMWrite, a); 3161 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE);3146 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE); 3162 3147 if (rc == VINF_SUCCESS) 3163 3148 { 3164 3149 pcnetAPROMWriteU8(pData, Port, u32); 3165 P CNetCritSectLeave(pData);3150 PDMCritSectLeave(&pData->CritSect); 3166 3151 } 3167 3152 STAM_PROFILE_ADV_STOP(&pData->StatAPROMWrite, a); … … 3196 3181 3197 3182 STAM_PROFILE_ADV_START(&pData->CTXSUFF(StatIORead), a); 3198 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_READ);3183 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_READ); 3199 3184 if (rc == VINF_SUCCESS) 3200 3185 { … … 3207 3192 break; 3208 3193 } 3209 P CNetCritSectLeave(pData);3194 PDMCritSectLeave(&pData->CritSect); 3210 3195 } 3211 3196 STAM_PROFILE_ADV_STOP(&pData->CTXSUFF(StatIORead), a); … … 3234 3219 3235 3220 STAM_PROFILE_ADV_START(&pData->CTXSUFF(StatIOWrite), a); 3236 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE);3221 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_IOPORT_WRITE); 3237 3222 if (rc == VINF_SUCCESS) 3238 3223 { … … 3246 3231 break; 3247 3232 } 3248 P CNetCritSectLeave(pData);3233 PDMCritSectLeave(&pData->CritSect); 3249 3234 } 3250 3235 STAM_PROFILE_ADV_STOP(&pData->CTXSUFF(StatIOWrite), a); … … 3278 3263 { 3279 3264 STAM_PROFILE_ADV_START(&pData->CTXSUFF(StatMMIORead), a); 3280 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_MMIO_READ);3265 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_MMIO_READ); 3281 3266 if (rc == VINF_SUCCESS) 3282 3267 { … … 3291 3276 break; 3292 3277 } 3293 P CNetCritSectLeave(pData);3278 PDMCritSectLeave(&pData->CritSect); 3294 3279 } 3295 3280 STAM_PROFILE_ADV_STOP(&pData->CTXSUFF(StatMMIORead), a); … … 3327 3312 { 3328 3313 STAM_PROFILE_ADV_START(&pData->CTXSUFF(StatMMIOWrite), a); 3329 rc = P CNetCritSectEnter(&pData->CritSect, VINF_IOM_HC_MMIO_WRITE);3314 rc = PDMCritSectEnter(&pData->CritSect, VINF_IOM_HC_MMIO_WRITE); 3330 3315 if (rc == VINF_SUCCESS) 3331 3316 { … … 3340 3325 break; 3341 3326 } 3342 P CNetCritSectLeave(pData);3327 PDMCritSectLeave(&pData->CritSect); 3343 3328 } 3344 3329 // else rc == VINF_IOM_HC_MMIO_WRITE => handle in ring3 … … 3366 3351 3367 3352 STAM_PROFILE_ADV_START(&pData->StatTimer, a); 3368 rc = P CNetCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);3353 rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3369 3354 AssertReleaseRC(rc); 3370 3355 3371 3356 pcnetPollTimer(pData); 3372 3357 3373 P CNetCritSectLeave(pData);3358 PDMCritSectLeave(&pData->CritSect); 3374 3359 STAM_PROFILE_ADV_STOP(&pData->StatTimer, a); 3375 3360 } … … 3389 3374 { 3390 3375 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3391 int rc = P CNetCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);3376 int rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3392 3377 AssertReleaseRC(rc); 3393 3378 … … 3412 3397 pDevIns->iInstance, pData->cLinkDownReported)); 3413 3398 3414 P CNetCritSectLeave(pData);3399 PDMCritSectLeave(&pData->CritSect); 3415 3400 } 3416 3401 … … 3538 3523 pData->fAm79C973 ? "Am79C973" : "Am79C970A", pData->fGCEnabled ? " GC" : "", pData->fR0Enabled ? " R0" : ""); 3539 3524 3540 P CNetCritSectEnter(&pData->CritSect, VERR_INTERNAL_ERROR); /* Take it here so we know why we're hanging... */3525 PDMCritSectEnter(&pData->CritSect, VERR_INTERNAL_ERROR); /* Take it here so we know why we're hanging... */ 3541 3526 3542 3527 pHlp->pfnPrintf(pHlp, … … 3730 3715 } 3731 3716 3732 P CNetCritSectLeave(pData);3717 PDMCritSectLeave(&pData->CritSect); 3733 3718 } 3734 3719 … … 3877 3862 PCNetState *pData = INETWORKPORT_2_DATA(pInterface); 3878 3863 3879 rc = P CNetCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);3864 rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3880 3865 AssertReleaseRC(rc); 3881 3866 3882 3867 cb = pcnetCanReceiveNoSync(pData); 3883 3868 3884 P CNetCritSectLeave(pData);3869 PDMCritSectLeave(&pData->CritSect); 3885 3870 return cb; 3886 3871 } … … 3902 3887 3903 3888 STAM_PROFILE_ADV_START(&pData->StatReceive, a); 3904 rc = P CNetCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED);3889 rc = PDMCritSectEnter(&pData->CritSect, VERR_PERMISSION_DENIED); 3905 3890 AssertReleaseRC(rc); 3906 3891 … … 3910 3895 pData->Led.Actual.s.fReading = 0; 3911 3896 3912 P CNetCritSectLeave(pData);3897 PDMCritSectLeave(&pData->CritSect); 3913 3898 STAM_PROFILE_ADV_STOP(&pData->StatReceive, a); 3914 3899 … … 4372 4357 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatXmitSync, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of sync packet xmits", "/Devices/PCNet%d/Xmit/Sync", iInstance); 4373 4358 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatXmitAsync, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of async packet xmits", "/Devices/PCNet%d/Xmit/ASync", iInstance); 4374 4359 PDMDevHlpSTAMRegisterF(pDevIns, &pData->StatXmitInTxThread, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Nr of packet xmits in rx thread", "/Devices/PCNet%d/Xmit/RxThread", iInstance); 4375 4360 4376 4361 unsigned i;
Note:
See TracChangeset
for help on using the changeset viewer.