VirtualBox

Changeset 4012 in vbox for trunk


Ignore:
Timestamp:
Aug 2, 2007 11:48:45 PM (17 years ago)
Author:
vboxsync
Message:

Hooked up the PDMThread stuff.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmdev.h

    r4011 r4012  
    21832183    DECLR3CALLBACKMEMBER(PRTTIMESPEC, pfnUTCNow,(PPDMDEVINS pDevIns, PRTTIMESPEC pTime));
    21842184
     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   
    21852206    /** Space reserved for future members.
    21862207     * @{ */
    2187     DECLR3CALLBACKMEMBER(void, pfnReserved1,(void));
    21882208    DECLR3CALLBACKMEMBER(void, pfnReserved2,(void));
    21892209    DECLR3CALLBACKMEMBER(void, pfnReserved3,(void));
     
    32963316    pDevIns->pDevHlp->pfnGetCpuId(pDevIns, iLeaf, pEax, pEbx, pEcx, pEdx);
    32973317}
     3318
     3319/**
     3320 * @copydoc PDMDEVHLP::pfnPDMThreadCreate
     3321 */
     3322DECLINLINE(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}
    32983327#endif /* IN_RING3 */
    32993328
  • trunk/include/VBox/pdmdrv.h

    r4011 r4012  
    555555    DECLR3CALLBACKMEMBER(int, pfnUSBRegisterHub,(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp));
    556556
     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
    557577    /** Just a safety precaution. */
    558578    uint32_t                        u32TheEnd;
     
    702722    return pDrvIns->pDrvHlp->pfnUSBRegisterHub(pDrvIns, pvReservedIn, ppvReservedHlp);
    703723}
     724
     725/**
     726 * @copydoc PDMDRVHLP::pfnPDMThreadCreate
     727 */
     728DECLINLINE(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}
    704733#endif /* IN_RING3 */
    705734
  • trunk/include/VBox/pdmthread.h

    r4010 r4012  
    274274#define PDMTHREAD_VERSION   0xef010000
    275275
     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 */
     291PDMR3DECL(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 */
     308PDMR3DECL(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 */
     323PDMR3DECL(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 */
     337PDMR3DECL(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 */
     350PDMR3DECL(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 */
     365PDMR3DECL(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 */
     380PDMR3DECL(int) PDMR3ThreadResume(PPDMTHREAD pThread);
     381#endif /* IN_RING3 */
    276382
    277383/** @} */
  • trunk/src/VBox/VMM/PDM.cpp

    r3852 r4012  
    371371     * Destroy all threads.
    372372     */
    373     ///@todo pdmR3ThreadDestroyAll(pVM);
     373    pdmR3ThreadDestroyAll(pVM);
    374374
    375375    /*
     
    627627     * Resume all threads.
    628628     */
    629     ///@todo pdmR3ThreadResumeAll(pVM);
     629    pdmR3ThreadResumeAll(pVM);
    630630
    631631    LogFlow(("PDMR3PowerOn: returns void\n"));
     
    717717     * Suspend all threads.
    718718     */
    719     ///@todo pdmR3ThreadSuspendAll(pVM);
     719    pdmR3ThreadSuspendAll(pVM);
    720720
    721721    LogFlow(("PDMR3Suspend: returns void\n"));
     
    760760     * Resume all threads.
    761761     */
    762     ///@todo pdmR3ThreadResumeAll(pVM);
     762    pdmR3ThreadResumeAll(pVM);
    763763
    764764    LogFlow(("PDMR3Resume: returns void\n"));
     
    803803     * Suspend all threads.
    804804     */
    805     ///@todo pdmR3ThreadSuspendAll(pVM);
     805    pdmR3ThreadSuspendAll(pVM);
    806806
    807807    LogFlow(("PDMR3PowerOff: returns void\n"));
  • trunk/src/VBox/VMM/PDMDevice.cpp

    r3857 r4012  
    131131static DECLCALLBACK(int) pdmR3DevHlp_CritSectInit(PPDMDEVINS pDevIns, PPDMCRITSECT pCritSect, const char *pszName);
    132132static DECLCALLBACK(PRTTIMESPEC) pdmR3DevHlp_UTCNow(PPDMDEVINS pDevIns, PRTTIMESPEC pTime);
     133static DECLCALLBACK(int) pdmR3DevHlp_PDMThreadCreate(PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
     134                                                     PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
    133135
    134136static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns);
     
    320322    pdmR3DevHlp_CritSectInit,
    321323    pdmR3DevHlp_UTCNow,
    322     0,
     324    pdmR3DevHlp_PDMThreadCreate,
    323325    0,
    324326    0,
     
    408410    pdmR3DevHlp_CritSectInit,
    409411    pdmR3DevHlp_UTCNow,
    410     0,
     412    pdmR3DevHlp_PDMThreadCreate,
    411413    0,
    412414    0,
     
    24052407
    24062408
     2409/** @copydoc PDMDEVHLP::pfnPDMThreadCreate */
     2410static 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
    24072426/** @copydoc PDMDEVHLP::pfnGetVM */
    24082427static DECLCALLBACK(PVM) pdmR3DevHlp_GetVM(PPDMDEVINS pDevIns)
  • trunk/src/VBox/VMM/PDMDriver.cpp

    r3857 r4012  
    9595static DECLCALLBACK(int) pdmR3DrvHlp_SUPCallVMMR0Ex(PPDMDRVINS pDrvIns, unsigned uOperation, void *pvArg, unsigned cbArg);
    9696static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp);
     97static DECLCALLBACK(int) pdmR3DrvHlp_PDMThreadCreate(PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
     98                                                     PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
    9799
    98100/** @def PDMDRV_ASSERT_DRVINS
     
    141143    pdmR3DrvHlp_SUPCallVMMR0Ex,
    142144    pdmR3DrvHlp_USBRegisterHub,
     145    pdmR3DrvHlp_PDMThreadCreate,
    143146    0 /* the end */
    144147};
     
    506509        AssertRC(rc);
    507510        /* PDM threads. */
    508         ///@todo rc = pdmR3DestroyDriver(pCur->Internal.s.pVM, pCur);
     511        rc = pdmR3ThreadDestroyDriver(pCur->Internal.s.pVM, pCur);
    509512        AssertRC(rc);
    510513        /* Finally, the driver it self. */
     
    10041007
    10051008
    1006 
    10071009/** @copydoc PDMDRVHLP::pfnUSBRegisterHub */
    10081010static DECLCALLBACK(int) pdmR3DrvHlp_USBRegisterHub(PPDMDRVINS pDrvIns, void *pvReservedIn, void **ppvReservedHlp)
     
    10201022}
    10211023
     1024
     1025/** @copydoc PDMDRVHLP::pfnPDMThreadCreate */
     1026static 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  
    2929#include <VBox/stam.h>
    3030#include <iprt/critsect.h>
     31#ifdef IN_RING3
     32# include <iprt/thread.h>
     33#endif
    3134
    3235__BEGIN_DECLS
     
    217220    /** Device type. */
    218221    PDMTHREADTYPE_DEVICE,
     222    /** USB Device type. */
     223    PDMTHREADTYPE_USB,
    219224    /** Driver type. */
    220225    PDMTHREADTYPE_DRIVER,
     
    254259# error "Invalid header PDM order. Include PDMInternal.h before VBox/pdm.h!"
    255260#endif
     261__END_DECLS
    256262#include <VBox/pdm.h>
    257 
     263__BEGIN_DECLS
    258264
    259265/**
     
    854860*   Internal Functions                                                         *
    855861*******************************************************************************/
     862#ifdef IN_RING3
    856863int         pdmR3CritSectInit(PVM pVM);
    857864int         pdmR3CritSectTerm(PVM pVM);
     
    881888void        pdmR3QueueRelocate(PVM pVM, RTGCINTPTR offDelta);
    882889
    883 void        pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
    884 void        pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
    885 void        pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
     890int         pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
     891                                    PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
     892int         pdmR3ThreadCreateUsb(PVM pVM, PPDMDRVINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
     893                                 PFNPDMTHREADWAKEUPUSB pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
     894int         pdmR3ThreadCreateDriver(PVM pVM, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
     895                                    PFNPDMTHREADWAKEUPDRV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
     896int         pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns);
     897int         pdmR3ThreadDestroyUsb(PVM pVM, PPDMUSBINS pUsbIns);
     898int         pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns);
    886899void        pdmR3ThreadDestroyAll(PVM pVM);
    887900int         pdmR3ThreadResumeAll(PVM pVM);
    888901int         pdmR3ThreadSuspendAll(PVM pVM);
     902
     903#endif /* IN_RING3 */
    889904
    890905#ifdef VBOX_WITH_PDM_LOCK
  • trunk/src/VBox/VMM/PDMThread.cpp

    r3548 r4012  
    6767        case PDMTHREADTYPE_DEVICE:
    6868            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);
    6973            break;
    7074
     
    168172
    169173
    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 */
     189int pdmR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
     190                            PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName)
    173191{
    174192    int rc = pdmR3ThreadNew(pVM, ppThread);
     
    180198        (*ppThread)->u.Dev.pfnThread = pfnThread;
    181199        (*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 */
     221int 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 */
     253int 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 */
     284PDMR3DECL(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 */
     314PDMR3DECL(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;
    182324        rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName);
    183325    }
     
    288430
    289431
    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 */
     442int pdmR3ThreadDestroyDevice(PVM pVM, PPDMDEVINS pDevIns)
    292443{
    293444    int rc = VINF_SUCCESS;
     
    312463
    313464
    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 */
     474int 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 */
     506int pdmR3ThreadDestroyDriver(PVM pVM, PPDMDRVINS pDrvIns)
    315507{
    316508    int rc = VINF_SUCCESS;
     
    350542        pThread = pNext;
    351543    }
    352     Assert(pVM->pdm.s.pThreads || pVM->pdm.s.pThreadsTail);
    353 }
    354 
    355 
     544    Assert(!pVM->pdm.s.pThreads && !pVM->pdm.s.pThreadsTail);
     545}
    356546
    357547
     
    504694                break;
    505695
     696            case PDMTHREADTYPE_USB:
     697                rc = pThread->u.Usb.pfnThread(pThread->u.Usb.pUsbIns, pThread);
     698                break;
     699
    506700            case PDMTHREADTYPE_DRIVER:
    507701                rc = pThread->u.Drv.pfnThread(pThread->u.Drv.pDrvIns, pThread);
     
    614808 * Suspends the thread.
    615809 *
    616  * This can be called the power off / suspend notifications to suspend the
     810 * This can be called at the power off / suspend notifications to suspend the
    617811 * 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 * 
    620814 * The caller is responsible for serializing the control operations on the
    621815 * thread. That basically means, always do these calls from the EMT.
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette