- Timestamp:
- Aug 2, 2007 11:48:45 PM (17 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pdmdev.h
r4011 r4012 2183 2183 DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnUTCNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime)); 2184 2184 2185 /** 2186 * Creates a PDM thread. 2187 * 2188 * This differs from the RTThreadCreate() API in that PDM takes care of suspending, 2189 * resuming, and destroying the thread as the VM state changes. 2190 * 2191 * @returns VBox status code. 2192 * @param pDevIns The device instance. 2193 * @param ppThread Where to store the thread 'handle'. 2194 * @param pvUser The user argument to the thread function. 2195 * @param pfnThread The thread function. 2196 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 2197 * a state change is pending. 2198 * @param cbStack See RTThreadCreate. 2199 * @param enmType See RTThreadCreate. 2200 * @param pszName See RTThreadCreate. 2201 */ 2202 DECLR3CALLBACKMEMBER(int, pfnPDMThreadCreate,(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 2203 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)); 2204 2205 2185 2206 /** Space reserved for future members. 2186 2207 * @{ */ 2187 DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));2188 2208 DECLR3CALLBACKMEMBER(void, pfnReserved2,(void)); 2189 2209 DECLR3CALLBACKMEMBER(void, pfnReserved3,(void)); … … 3296 3316 pDevIns->pDevHlp->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx); 3297 3317 } 3318 3319 /** 3320 * @copydoc PDMDEVHLP::pfnPDMThreadCreate 3321 */ 3322 DECLINLINE(int) PDMDevHlpPDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 3323 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 3324 { 3325 return pDevIns->pDevHlp->pfnPDMThreadCreate(pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 3326 } 3298 3327 #endif /* IN_RING3 */ 3299 3328 -
trunk/include/VBox/pdmdrv.h
r4011 r4012 555 555 DECLR3CALLBACKMEMBER(int, pfnUSBRegisterHub,(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp)); 556 556 557 /** 558 * Creates a PDM thread. 559 * 560 * This differs from the RTThreadCreate() API in that PDM takes care of suspending, 561 * resuming, and destroying the thread as the VM state changes. 562 * 563 * @returns VBox status code. 564 * @param pDrvIns The driver instance. 565 * @param ppThread Where to store the thread 'handle'. 566 * @param pvUser The user argument to the thread function. 567 * @param pfnThread The thread function. 568 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 569 * a state change is pending. 570 * @param cbStack See RTThreadCreate. 571 * @param enmType See RTThreadCreate. 572 * @param pszName See RTThreadCreate. 573 */ 574 DECLR3CALLBACKMEMBER(int, pfnPDMThreadCreate,(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 575 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)); 576 557 577 /** Just a safety precaution. */ 558 578 uint32_t u32TheEnd; … … 702 722 return pDrvIns->pDrvHlp->pfnUSBRegisterHub(pDrvIns, pvReservedIn, ppvReservedHlp); 703 723 } 724 725 /** 726 * @copydoc PDMDRVHLP::pfnPDMThreadCreate 727 */ 728 DECLINLINE(int) PDMDrvHlpPDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 729 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 730 { 731 return pDrvIns->pDrvHlp->pfnPDMThreadCreate(pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 732 } 704 733 #endif /* IN_RING3 */ 705 734 -
trunk/include/VBox/pdmthread.h
r4010 r4012 274 274 #define PDMTHREAD_VERSION 0xef010000 275 275 276 #ifdef IN_RING3 277 /** 278 * Creates a PDM thread for internal use in the VM. 279 * 280 * @returns VBox status code. 281 * @param pVM The VM handle. 282 * @param ppThread Where to store the thread 'handle'. 283 * @param pvUser The user argument to the thread function. 284 * @param pfnThread The thread function. 285 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 286 * a state change is pending. 287 * @param cbStack See RTThreadCreate. 288 * @param enmType See RTThreadCreate. 289 * @param pszName See RTThreadCreate. 290 */ 291 PDMR3DECL(int) PDMR3ThreadCreate(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread, 292 PFNPDMTHREADWAKEUPINT pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 293 294 /** 295 * Creates a PDM thread for VM use by some external party. 296 * 297 * @returns VBox status code. 298 * @param pVM The VM handle. 299 * @param ppThread Where to store the thread 'handle'. 300 * @param pvUser The user argument to the thread function. 301 * @param pfnThread The thread function. 302 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 303 * a state change is pending. 304 * @param cbStack See RTThreadCreate. 305 * @param enmType See RTThreadCreate. 306 * @param pszName See RTThreadCreate. 307 */ 308 PDMR3DECL(int) PDMR3ThreadCreateExternal(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread, 309 PFNPDMTHREADWAKEUPEXT pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 310 311 /** 312 * Destroys a PDM thread. 313 * 314 * This will wakeup the thread, tell it to terminate, and wait for it terminate. 315 * 316 * @returns VBox status code. 317 * This reflects the success off destroying the thread and not the exit code 318 * of the thread as this is stored in *pRcThread. 319 * @param pThread The thread to destroy. 320 * @param pRcThread Where to store the thread exit code. Optional. 321 * @thread The emulation thread (EMT). 322 */ 323 PDMR3DECL(int) PDMR3ThreadDestroy(PPDMTHREAD pThread, int *pRcThread); 324 325 /** 326 * Called by the PDM thread in response to a wakeup call with 327 * suspending as the new state. 328 * 329 * The thread will block in side this call until the state is changed in 330 * response to a VM state change or to the device/driver/whatever calling the 331 * PDMR3ThreadResume API. 332 * 333 * @returns VBox status code. 334 * On failure, terminate the thread. 335 * @param pThread The PDM thread. 336 */ 337 PDMR3DECL(int) PDMR3ThreadIAmSuspending(PPDMTHREAD pThread); 338 339 /** 340 * Called by the PDM thread in response to a resuming state. 341 * 342 * The purpose of this API is to tell the PDMR3ThreadResume caller that 343 * the the PDM thread has successfully resumed. It will also do the 344 * state transition from the resuming to the running state. 345 * 346 * @returns VBox status code. 347 * On failure, terminate the thread. 348 * @param pThread The PDM thread. 349 */ 350 PDMR3DECL(int) PDMR3ThreadIAmRunning(PPDMTHREAD pThread); 351 352 /** 353 * Suspends the thread. 354 * 355 * This can be called at the power off / suspend notifications to suspend the 356 * PDM thread a bit early. The thread will be automatically suspend upon 357 * completion of the device/driver notification cycle. 358 * 359 * The caller is responsible for serializing the control operations on the 360 * thread. That basically means, always do these calls from the EMT. 361 * 362 * @returns VBox status code. 363 * @param pThread The PDM thread. 364 */ 365 PDMR3DECL(int) PDMR3ThreadSuspend(PPDMTHREAD pThread); 366 367 /** 368 * Resumes the thread. 369 * 370 * This can be called the power on / resume notifications to resume the 371 * PDM thread a bit early. The thread will be automatically resumed upon 372 * return from these two notification callbacks (devices/drivers). 373 * 374 * The caller is responsible for serializing the control operations on the 375 * thread. That basically means, always do these calls from the EMT. 376 * 377 * @returns VBox status code. 378 * @param pThread The PDM thread. 379 */ 380 PDMR3DECL(int) PDMR3ThreadResume(PPDMTHREAD pThread); 381 #endif /* IN_RING3 */ 276 382 277 383 /** @} */ -
trunk/src/VBox/VMM/PDM.cpp
r3852 r4012 371 371 * Destroy all threads. 372 372 */ 373 ///@todopdmR3ThreadDestroyAll(pVM);373 pdmR3ThreadDestroyAll(pVM); 374 374 375 375 /* … … 627 627 * Resume all threads. 628 628 */ 629 ///@todopdmR3ThreadResumeAll(pVM);629 pdmR3ThreadResumeAll(pVM); 630 630 631 631 LogFlow(("PDMR3PowerOn: returns void\n")); … … 717 717 * Suspend all threads. 718 718 */ 719 ///@todopdmR3ThreadSuspendAll(pVM);719 pdmR3ThreadSuspendAll(pVM); 720 720 721 721 LogFlow(("PDMR3Suspend: returns void\n")); … … 760 760 * Resume all threads. 761 761 */ 762 ///@todopdmR3ThreadResumeAll(pVM);762 pdmR3ThreadResumeAll(pVM); 763 763 764 764 LogFlow(("PDMR3Resume: returns void\n")); … … 803 803 * Suspend all threads. 804 804 */ 805 ///@todopdmR3ThreadSuspendAll(pVM);805 pdmR3ThreadSuspendAll(pVM); 806 806 807 807 LogFlow(("PDMR3PowerOff: returns void\n")); -
trunk/src/VBox/VMM/PDMDevice.cpp
r3857 r4012 131 131 static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName); 132 132 static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime); 133 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 134 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 133 135 134 136 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns); … … 320 322 pdmR3DevHlp_CritSectInit, 321 323 pdmR3DevHlp_UTCNow, 322 0,324 pdmR3DevHlp_PDMThreadCreate, 323 325 0, 324 326 0, … … 408 410 pdmR3DevHlp_CritSectInit, 409 411 pdmR3DevHlp_UTCNow, 410 0,412 pdmR3DevHlp_PDMThreadCreate, 411 413 0, 412 414 0, … … 2405 2407 2406 2408 2409 /** @copydoc PDMDEVHLP::pfnPDMThreadCreate */ 2410 static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 2411 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 2412 { 2413 PDMDEV_ASSERT_DEVINS(pDevIns); 2414 VM_ASSERT_EMT(pDevIns->Internal.s.pVMHC); 2415 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n", 2416 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName)); 2417 2418 int rc = pdmR3ThreadCreateDevice(pDevIns->Internal.s.pVMHC, pDevIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 2419 2420 LogFlow(("pdmR3DevHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, 2421 rc, *ppThread)); 2422 return rc; 2423 } 2424 2425 2407 2426 /** @copydoc PDMDEVHLP::pfnGetVM */ 2408 2427 static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns) -
trunk/src/VBox/VMM/PDMDriver.cpp
r3857 r4012 95 95 static DECLCALLBACK(int) pdmR3DrvHlp_SUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg); 96 96 static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp); 97 static DECLCALLBACK(int) pdmR3DrvHlp_PDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 98 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 97 99 98 100 /** @def PDMDRV_ASSERT_DRVINS … … 141 143 pdmR3DrvHlp_SUPCallVMMR0Ex, 142 144 pdmR3DrvHlp_USBRegisterHub, 145 pdmR3DrvHlp_PDMThreadCreate, 143 146 0 /* the end */ 144 147 }; … … 506 509 AssertRC(rc); 507 510 /* PDM threads. */ 508 ///@todo rc = pdmR3DestroyDriver(pCur->Internal.s.pVM, pCur);511 rc = pdmR3ThreadDestroyDriver(pCur->Internal.s.pVM, pCur); 509 512 AssertRC(rc); 510 513 /* Finally, the driver it self. */ … … 1004 1007 1005 1008 1006 1007 1009 /** @copydoc PDMDRVHLP::pfnUSBRegisterHub */ 1008 1010 static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp) … … 1020 1022 } 1021 1023 1024 1025 /** @copydoc PDMDRVHLP::pfnPDMThreadCreate */ 1026 static DECLCALLBACK(int) pdmR3DrvHlp_PDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 1027 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 1028 { 1029 PDMDRV_ASSERT_DRVINS(pDrvIns); 1030 VM_ASSERT_EMT(pDrvIns->Internal.s.pVM); 1031 LogFlow(("pdmR3DrvHlp_PDMThreadCreate: caller='%s'/%d: ppThread=%p pvUser=%p pfnThread=%p pfnWakeup=%p cbStack=%#zx enmType=%d pszName=%p:{%s}\n", 1032 pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName, pszName)); 1033 1034 int rc = pdmR3ThreadCreateDriver(pDrvIns->Internal.s.pVM, pDrvIns, ppThread, pvUser, pfnThread, pfnWakeup, cbStack, enmType, pszName); 1035 1036 LogFlow(("pdmR3DrvHlp_PDMThreadCreate: caller='%s'/%d: returns %Vrc *ppThread=%RTthrd\n", pDrvIns->pDrvReg->szDriverName, pDrvIns->iInstance, 1037 rc, *ppThread)); 1038 return rc; 1039 } 1040 -
trunk/src/VBox/VMM/PDMInternal.h
r3857 r4012 29 29 #include <VBox/stam.h> 30 30 #include <iprt/critsect.h> 31 #ifdef IN_RING3 32 # include <iprt/thread.h> 33 #endif 31 34 32 35 __BEGIN_DECLS … … 217 220 /** Device type. */ 218 221 PDMTHREADTYPE_DEVICE, 222 /** USB Device type. */ 223 PDMTHREADTYPE_USB, 219 224 /** Driver type. */ 220 225 PDMTHREADTYPE_DRIVER, … … 254 259 # error "Invalid header PDM order. Include PDMInternal.h before VBox/pdm.h!" 255 260 #endif 261 __END_DECLS 256 262 #include <VBox/pdm.h> 257 263 __BEGIN_DECLS 258 264 259 265 /** … … 854 860 * Internal Functions * 855 861 *******************************************************************************/ 862 #ifdef IN_RING3 856 863 int pdmR3CritSectInit(PVM pVM); 857 864 int pdmR3CritSectTerm(PVM pVM); … … 881 888 void pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta); 882 889 883 void pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns); 884 void pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns); 885 void pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns); 890 int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 891 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 892 int pdmR3ThreadCreateUsb(PVM pVM, PPDMDRVINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread, 893 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 894 int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 895 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName); 896 int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns); 897 int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns); 898 int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns); 886 899 void pdmR3ThreadDestroyAll(PVM pVM); 887 900 int pdmR3ThreadResumeAll(PVM pVM); 888 901 int pdmR3ThreadSuspendAll(PVM pVM); 902 903 #endif /* IN_RING3 */ 889 904 890 905 #ifdef VBOX_WITH_PDM_LOCK -
trunk/src/VBox/VMM/PDMThread.cpp
r3548 r4012 67 67 case PDMTHREADTYPE_DEVICE: 68 68 rc = pThread->u.Dev.pfnWakeup(pThread->u.Dev.pDevIns, pThread); 69 break; 70 71 case PDMTHREADTYPE_USB: 72 rc = pThread->u.Usb.pfnWakeup(pThread->u.Usb.pUsbIns, pThread); 69 73 break; 70 74 … … 168 172 169 173 170 171 PDMR3DECL(int) PDMR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 172 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 174 /** 175 * Device Helper for creating a thread associated with a device. 176 * 177 * @returns VBox status code. 178 * @param pVM The VM handle. 179 * @param pDevIns The device instance. 180 * @param ppThread Where to store the thread 'handle'. 181 * @param pvUser The user argument to the thread function. 182 * @param pfnThread The thread function. 183 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 184 * a state change is pending. 185 * @param cbStack See RTThreadCreate. 186 * @param enmType See RTThreadCreate. 187 * @param pszName See RTThreadCreate. 188 */ 189 int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 190 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 173 191 { 174 192 int rc = pdmR3ThreadNew(pVM, ppThread); … … 180 198 (*ppThread)->u.Dev.pfnThread = pfnThread; 181 199 (*ppThread)->u.Dev.pfnWakeup = pfnWakeup; 200 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 201 } 202 return rc; 203 } 204 205 206 /** 207 * USB Device Helper for creating a thread associated with an USB device. 208 * 209 * @returns VBox status code. 210 * @param pVM The VM handle. 211 * @param pUsbIns The USB device instance. 212 * @param ppThread Where to store the thread 'handle'. 213 * @param pvUser The user argument to the thread function. 214 * @param pfnThread The thread function. 215 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 216 * a state change is pending. 217 * @param cbStack See RTThreadCreate. 218 * @param enmType See RTThreadCreate. 219 * @param pszName See RTThreadCreate. 220 */ 221 int pdmR3ThreadCreateUsb(PVM pVM, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread, 222 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 223 { 224 int rc = pdmR3ThreadNew(pVM, ppThread); 225 if (RT_SUCCESS(rc)) 226 { 227 (*ppThread)->pvUser = pvUser; 228 (*ppThread)->Internal.s.enmType = PDMTHREADTYPE_USB; 229 (*ppThread)->u.Usb.pUsbIns = pUsbIns; 230 (*ppThread)->u.Usb.pfnThread = pfnThread; 231 (*ppThread)->u.Usb.pfnWakeup = pfnWakeup; 232 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 233 } 234 return rc; 235 } 236 237 238 /** 239 * Driver Helper for creating a thread associated with a driver. 240 * 241 * @returns VBox status code. 242 * @param pVM The VM handle. 243 * @param pDrvIns The driver instance. 244 * @param ppThread Where to store the thread 'handle'. 245 * @param pvUser The user argument to the thread function. 246 * @param pfnThread The thread function. 247 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 248 * a state change is pending. 249 * @param cbStack See RTThreadCreate. 250 * @param enmType See RTThreadCreate. 251 * @param pszName See RTThreadCreate. 252 */ 253 int pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread, 254 PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 255 { 256 int rc = pdmR3ThreadNew(pVM, ppThread); 257 if (RT_SUCCESS(rc)) 258 { 259 (*ppThread)->pvUser = pvUser; 260 (*ppThread)->Internal.s.enmType = PDMTHREADTYPE_DRIVER; 261 (*ppThread)->u.Drv.pDrvIns = pDrvIns; 262 (*ppThread)->u.Drv.pfnThread = pfnThread; 263 (*ppThread)->u.Drv.pfnWakeup = pfnWakeup; 264 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 265 } 266 return rc; 267 } 268 269 270 /** 271 * Creates a PDM thread for internal use in the VM. 272 * 273 * @returns VBox status code. 274 * @param pVM The VM handle. 275 * @param ppThread Where to store the thread 'handle'. 276 * @param pvUser The user argument to the thread function. 277 * @param pfnThread The thread function. 278 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 279 * a state change is pending. 280 * @param cbStack See RTThreadCreate. 281 * @param enmType See RTThreadCreate. 282 * @param pszName See RTThreadCreate. 283 */ 284 PDMR3DECL(int) PDMR3ThreadCreate(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread, 285 PFNPDMTHREADWAKEUPINT pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 286 { 287 int rc = pdmR3ThreadNew(pVM, ppThread); 288 if (RT_SUCCESS(rc)) 289 { 290 (*ppThread)->pvUser = pvUser; 291 (*ppThread)->Internal.s.enmType = PDMTHREADTYPE_INTERNAL; 292 (*ppThread)->u.Int.pfnThread = pfnThread; 293 (*ppThread)->u.Int.pfnWakeup = pfnWakeup; 294 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 295 } 296 return rc; 297 } 298 299 300 /** 301 * Creates a PDM thread for VM use by some external party. 302 * 303 * @returns VBox status code. 304 * @param pVM The VM handle. 305 * @param ppThread Where to store the thread 'handle'. 306 * @param pvUser The user argument to the thread function. 307 * @param pfnThread The thread function. 308 * @param pfnWakeup The wakup callback. This is called on the EMT thread when 309 * a state change is pending. 310 * @param cbStack See RTThreadCreate. 311 * @param enmType See RTThreadCreate. 312 * @param pszName See RTThreadCreate. 313 */ 314 PDMR3DECL(int) PDMR3ThreadCreateExternal(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread, 315 PFNPDMTHREADWAKEUPEXT pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 316 { 317 int rc = pdmR3ThreadNew(pVM, ppThread); 318 if (RT_SUCCESS(rc)) 319 { 320 (*ppThread)->pvUser = pvUser; 321 (*ppThread)->Internal.s.enmType = PDMTHREADTYPE_EXTERNAL; 322 (*ppThread)->u.Ext.pfnThread = pfnThread; 323 (*ppThread)->u.Ext.pfnWakeup = pfnWakeup; 182 324 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 183 325 } … … 288 430 289 431 290 291 PDMR3DECL(int) PDMR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns) 432 /** 433 * Destroys all threads associated with a device. 434 * 435 * This function is called by PDMDevice when a device is 436 * destroyed (not currently implemented). 437 * 438 * @returns VBox status code of the first failure. 439 * @param pVM The VM handle. 440 * @param pDevIns the device instance. 441 */ 442 int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns) 292 443 { 293 444 int rc = VINF_SUCCESS; … … 312 463 313 464 314 PDMR3DECL(int) PDMR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns) 465 /** 466 * Destroys all threads associated with an USB device. 467 * 468 * This function is called by PDMUsb when a device is destroyed. 469 * 470 * @returns VBox status code of the first failure. 471 * @param pVM The VM handle. 472 * @param pUsbIns The USB device instance. 473 */ 474 int pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns) 475 { 476 int rc = VINF_SUCCESS; 477 478 AssertPtr(pUsbIns); 479 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 480 while (pThread) 481 { 482 PPDMTHREAD pNext = pThread->Internal.s.pNext; 483 if ( pThread->Internal.s.enmType == PDMTHREADTYPE_DEVICE 484 && pThread->u.Usb.pUsbIns == pUsbIns) 485 { 486 int rc2 = PDMR3ThreadDestroy(pThread, NULL); 487 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 488 rc = rc2; 489 } 490 pThread = pNext; 491 } 492 493 return rc; 494 } 495 496 497 /** 498 * Destroys all threads associated with a driver. 499 * 500 * This function is called by PDMDriver when a driver is destroyed. 501 * 502 * @returns VBox status code of the first failure. 503 * @param pVM The VM handle. 504 * @param pDrvIns The driver instance. 505 */ 506 int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns) 315 507 { 316 508 int rc = VINF_SUCCESS; … … 350 542 pThread = pNext; 351 543 } 352 Assert(pVM->pdm.s.pThreads || pVM->pdm.s.pThreadsTail); 353 } 354 355 544 Assert(!pVM->pdm.s.pThreads && !pVM->pdm.s.pThreadsTail); 545 } 356 546 357 547 … … 504 694 break; 505 695 696 case PDMTHREADTYPE_USB: 697 rc = pThread->u.Usb.pfnThread(pThread->u.Usb.pUsbIns, pThread); 698 break; 699 506 700 case PDMTHREADTYPE_DRIVER: 507 701 rc = pThread->u.Drv.pfnThread(pThread->u.Drv.pDrvIns, pThread); … … 614 808 * Suspends the thread. 615 809 * 616 * This can be called the power off / suspend notifications to suspend the810 * This can be called at the power off / suspend notifications to suspend the 617 811 * PDM thread a bit early. The thread will be automatically suspend upon 618 * return from these two notification callbacks (devices/drivers).619 * 812 * completion of the device/driver notification cycle. 813 * 620 814 * The caller is responsible for serializing the control operations on the 621 815 * thread. That basically means, always do these calls from the EMT.
Note:
See TracChangeset
for help on using the changeset viewer.