- Timestamp:
- Aug 29, 2007 1:37:48 PM (17 years ago)
- Location:
- trunk/src/VBox/Devices
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Devices/Network/DevPCNet.cpp
r4196 r4422 47 47 */ 48 48 49 /** To enable the PDMThread based send thread code. 50 * This is just a emergency switch in case changes doesn't quite work and 51 * we want to get 1.5 out. 52 * @todo cleanup after 1.5. */ 53 #define USE_PDMTHREAD 1 54 49 55 /******************************************************************************* 50 56 * Header Files * … … 198 204 /** If set the link is temporarily down because of a saved state load. */ 199 205 bool fLinkTempDown; 200 /** This flag is set on SavePrep to prevent altering of memory after pgmR3Save() was called */ 206 /** This flag is set on SavePrep to prevent altering of memory after pgmR3Save() was called 207 * @todo r=bird: This is inadequate, we are not supposed to do anything at all while the VM 208 * isn't running. Naturally, the problem really lies with the driver and not 209 * the pcnet code. We will have to address this properly at some time. */ 201 210 bool fSaving; 202 211 … … 215 224 /** Async send thread */ 216 225 RTSEMEVENT hSendEventSem; 226 #ifdef USE_PDMTHREAD 227 /** The Async send thread. */ 228 PPDMTHREAD pSendThread; 229 #else 217 230 RTTHREAD hSendThread; 231 #endif 218 232 219 233 /** Access critical section. */ … … 2053 2067 { 2054 2068 int rc = pcnetXmitCompleteFrame(pData); 2069 #ifdef USE_PDMTHREAD 2070 AssertRCReturn(rc, rc); 2071 #else 2055 2072 if (VBOX_FAILURE(rc)) 2056 2073 return rc; /* can happen during termination */ 2074 #endif 2057 2075 } 2058 2076 } … … 2160 2178 { 2161 2179 int rc = pcnetXmitCompleteFrame(pData); 2180 #ifdef USE_PDMTHREAD 2181 AssertRCReturn(rc, rc); 2182 #else 2162 2183 if (VBOX_FAILURE(rc)) 2163 2184 return rc; /* can happen during termination */ 2185 #endif 2164 2186 } 2165 2187 else if (CSR_LOOP(pData) && !fDropFrame) … … 2223 2245 } 2224 2246 2247 2248 #ifdef USE_PDMTHREAD 2249 /** 2250 * Async I/O thread for delayed sending of packets. 2251 * 2252 * @returns VBox status code. Returning failure will naturally terminate the thread. 2253 * @param pDevIns The pcnet device instance. 2254 * @param pThread The thread. 2255 */ 2256 static DECLCALLBACK(int) pcnetAsyncSendThread(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 2257 { 2258 PCNetState *pThis = PDMINS2DATA(pDevIns, PCNetState *); 2259 2260 /* 2261 * We can enter this function in two states, initializing or resuming. 2262 * 2263 * The idea about the initializing bit is that we can do per-thread 2264 * initialization while the creator thread can still pick up errors. 2265 * At present, there is nothing to init, or at least nothing that 2266 * need initing in the thread. 2267 */ 2268 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING) 2269 return VINF_SUCCESS; 2270 2271 /* 2272 * Stay in the run-loop until we're supposed to leave the 2273 * running state. If something really bad happens, we'll 2274 * quit the loop while in the running state and return 2275 * an error status to PDM and let it terminate the thread. 2276 */ 2277 while (pThread->enmState == PDMTHREADSTATE_RUNNING) 2278 { 2279 /* 2280 * Block until we've got something to send or is supposed 2281 * to leave the running state. 2282 */ 2283 int rc = RTSemEventWait(pThis->hSendEventSem, RT_INDEFINITE_WAIT); 2284 AssertRCReturn(rc, rc); 2285 if (RT_UNLIKELY(pThread->enmState != PDMTHREADSTATE_RUNNING)) 2286 break; 2287 2288 /* 2289 * Perform async send. Mind that we might be requested to 2290 * suspended while waiting for the critical section. 2291 */ 2292 rc = PDMCritSectEnter(&pThis->CritSect, VERR_PERMISSION_DENIED); 2293 AssertReleaseRCReturn(rc, rc); 2294 2295 if (pThread->enmState == PDMTHREADSTATE_RUNNING) 2296 { 2297 rc = pcnetAsyncTransmit(pThis); 2298 AssertReleaseRC(rc); 2299 } 2300 2301 PDMCritSectLeave(&pThis->CritSect); 2302 } 2303 2304 /* The thread is being suspended or terminated. */ 2305 return VINF_SUCCESS; 2306 } 2307 2308 2309 /** 2310 * Unblock the send thread so it can respond to a state change. 2311 * 2312 * @returns VBox status code. 2313 * @param pDevIns The pcnet device instance. 2314 * @param pThread The send thread. 2315 */ 2316 static DECLCALLBACK(int) pcnetAsyncSendThreadWakeUp(PPDMDEVINS pDevIns, PPDMTHREAD pThread) 2317 { 2318 PCNetState *pThis = PDMINS2DATA(pDevIns, PCNetState *); 2319 return RTSemEventSignal(pThis->hSendEventSem); 2320 } 2321 2322 2323 #else /* USE_PDMTHREAD */ 2225 2324 /** 2226 2325 * Async I/O thread for delayed sending of packets. … … 2248 2347 return VINF_SUCCESS; 2249 2348 } 2349 #endif /* USE_PDMTHREAD */ 2250 2350 2251 2351 #endif /* IN_RING3 */ … … 2263 2363 pcnetTransmit(pData); 2264 2364 } 2365 2265 2366 2266 2367 /** … … 3994 4095 PCNetState *pData = PDMINS2DATA(pDevIns, PCNetState *); 3995 4096 3996 PDMCritSectEnter(&pData->CritSect, VERR_ACCESS_DENIED); 3997 3998 RTSemEventDestroy(pData->hSendEventSem); 3999 pData->hSendEventSem = 0; 4000 PDMCritSectLeave(&pData->CritSect); 4001 4002 PDMR3CritSectDelete(&pData->CritSect); 4097 if (PDMCritSectIsInitialized(&pData->CritSect)) 4098 { 4099 #ifdef USE_PDMTHREAD 4100 /* 4101 * At this point the send thread is suspended and will not enter 4102 * this module again. So, no coordination is needed here and PDM 4103 * will take care of terminating and cleaning up the thread. 4104 */ 4105 RTSemEventDestroy(pData->hSendEventSem); 4106 pData->hSendEventSem = NIL_RTSEMEVENT; 4107 PDMR3CritSectDelete(&pData->CritSect); 4108 #else 4109 PDMCritSectEnter(&pData->CritSect, VERR_ACCESS_DENIED); 4110 4111 RTSemEventDestroy(pData->hSendEventSem); 4112 pData->hSendEventSem = 0; 4113 4114 PDMCritSectLeave(&pData->CritSect); 4115 PDMR3CritSectDelete(&pData->CritSect); 4116 #endif 4117 } 4003 4118 return VINF_SUCCESS; 4004 4119 } … … 4270 4385 4271 4386 /* Create asynchronous thread */ 4387 #ifdef USE_PDMTHREAD 4388 rc = PDMDevHlpPDMThreadCreate(pDevIns, &pData->pSendThread, pData, pcnetAsyncSendThread, pcnetAsyncSendThreadWakeUp, 0, RTTHREADTYPE_IO, "PCNET_SEND"); 4389 AssertRCReturn(rc, rc); 4390 #else 4272 4391 rc = RTThreadCreate(&pData->hSendThread, pcnetAsyncSend, (void *)pData, 128*1024, RTTHREADTYPE_IO, 0, "PCNET_SEND"); 4273 4392 AssertRC(rc); 4393 #endif 4274 4394 4275 4395 #ifdef VBOX_WITH_STATISTICS -
trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
r4071 r4422 353 353 GEN_CHECK_OFF(PCNetState, pLedsConnector); 354 354 GEN_CHECK_OFF(PCNetState, hSendEventSem); 355 #ifdef USE_PDMTHREAD 356 GEN_CHECK_OFF(PCNetState, pSendThread); 357 #else 355 358 GEN_CHECK_OFF(PCNetState, hSendThread); 359 #endif 356 360 GEN_CHECK_OFF(PCNetState, CritSect); 357 361 GEN_CHECK_OFF(PCNetState, cPendingSends);
Note:
See TracChangeset
for help on using the changeset viewer.