[3854] | 1 | /** @file
|
---|
| 2 | * PDM - Pluggable Device Manager, Threads.
|
---|
| 3 | */
|
---|
| 4 |
|
---|
| 5 | /*
|
---|
[8155] | 6 | * Copyright (C) 2006-2007 Sun Microsystems, Inc.
|
---|
[3854] | 7 | *
|
---|
| 8 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
| 9 | * available from http://www.virtualbox.org. This file is free software;
|
---|
| 10 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
[5999] | 11 | * General Public License (GPL) as published by the Free Software
|
---|
| 12 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
| 13 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
| 14 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
| 15 | *
|
---|
| 16 | * The contents of this file may alternatively be used under the terms
|
---|
| 17 | * of the Common Development and Distribution License Version 1.0
|
---|
| 18 | * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
|
---|
| 19 | * VirtualBox OSE distribution, in which case the provisions of the
|
---|
| 20 | * CDDL are applicable instead of those of the GPL.
|
---|
| 21 | *
|
---|
| 22 | * You may elect to license modified versions of this file under the
|
---|
| 23 | * terms and conditions of either the GPL or the CDDL or both.
|
---|
[8155] | 24 | *
|
---|
| 25 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
|
---|
| 26 | * Clara, CA 95054 USA or visit http://www.sun.com if you need
|
---|
| 27 | * additional information or have any questions.
|
---|
[3854] | 28 | */
|
---|
| 29 |
|
---|
| 30 | #ifndef ___VBox_pdmthread_h
|
---|
| 31 | #define ___VBox_pdmthread_h
|
---|
| 32 |
|
---|
[4010] | 33 | #include <VBox/cdefs.h>
|
---|
| 34 | #include <VBox/types.h>
|
---|
| 35 | #ifdef IN_RING3
|
---|
| 36 | # include <iprt/thread.h>
|
---|
| 37 | #endif
|
---|
| 38 |
|
---|
[3854] | 39 | __BEGIN_DECLS
|
---|
| 40 |
|
---|
| 41 | /** @group grp_pdm_thread Threads
|
---|
| 42 | * @ingroup grp_pdm
|
---|
| 43 | * @{
|
---|
| 44 | */
|
---|
| 45 |
|
---|
| 46 | /**
|
---|
| 47 | * The thread state
|
---|
| 48 | */
|
---|
| 49 | typedef enum PDMTHREADSTATE
|
---|
| 50 | {
|
---|
| 51 | /** The usual invalid 0 entry. */
|
---|
| 52 | PDMTHREADSTATE_INVALID = 0,
|
---|
| 53 | /** The thread is initializing.
|
---|
| 54 | * Prev state: none
|
---|
| 55 | * Next state: suspended, terminating (error) */
|
---|
| 56 | PDMTHREADSTATE_INITIALIZING,
|
---|
| 57 | /** The thread has been asked to suspend.
|
---|
| 58 | * Prev state: running
|
---|
| 59 | * Next state: suspended */
|
---|
| 60 | PDMTHREADSTATE_SUSPENDING,
|
---|
| 61 | /** The thread is supended.
|
---|
| 62 | * Prev state: suspending, initializing
|
---|
| 63 | * Next state: resuming, terminated. */
|
---|
| 64 | PDMTHREADSTATE_SUSPENDED,
|
---|
| 65 | /** The thread is active.
|
---|
| 66 | * Prev state: suspended
|
---|
| 67 | * Next state: running, terminating. */
|
---|
| 68 | PDMTHREADSTATE_RESUMING,
|
---|
| 69 | /** The thread is active.
|
---|
| 70 | * Prev state: resuming
|
---|
| 71 | * Next state: suspending, terminating. */
|
---|
| 72 | PDMTHREADSTATE_RUNNING,
|
---|
| 73 | /** The thread has been asked to terminate.
|
---|
| 74 | * Prev state: initializing, suspended, resuming, running
|
---|
| 75 | * Next state: terminated. */
|
---|
| 76 | PDMTHREADSTATE_TERMINATING,
|
---|
| 77 | /** The thread is terminating / has terminated.
|
---|
| 78 | * Prev state: terminating
|
---|
| 79 | * Next state: none */
|
---|
| 80 | PDMTHREADSTATE_TERMINATED,
|
---|
| 81 | /** The usual 32-bit hack. */
|
---|
| 82 | PDMTHREADSTATE_32BIT_HACK = 0x7fffffff
|
---|
| 83 | } PDMTHREADSTATE;
|
---|
| 84 |
|
---|
| 85 | /** A pointer to a PDM thread. */
|
---|
| 86 | typedef R3PTRTYPE(struct PDMTHREAD *) PPDMTHREAD;
|
---|
| 87 | /** A pointer to a pointer to a PDM thread. */
|
---|
| 88 | typedef PPDMTHREAD *PPPDMTHREAD;
|
---|
| 89 |
|
---|
| 90 | /**
|
---|
| 91 | * PDM thread, device variation.
|
---|
| 92 | *
|
---|
| 93 | * @returns VBox status code.
|
---|
| 94 | * @param pDevIns The device instance.
|
---|
| 95 | * @param pThread The PDM thread data.
|
---|
| 96 | */
|
---|
| 97 | typedef int FNPDMTHREADDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
|
---|
| 98 | /** Pointer to a FNPDMTHREADDEV(). */
|
---|
| 99 | typedef FNPDMTHREADDEV *PFNPDMTHREADDEV;
|
---|
| 100 |
|
---|
| 101 | /**
|
---|
[4010] | 102 | * PDM thread, USB device variation.
|
---|
| 103 | *
|
---|
| 104 | * @returns VBox status code.
|
---|
| 105 | * @param pUsbIns The USB device instance.
|
---|
| 106 | * @param pThread The PDM thread data.
|
---|
| 107 | */
|
---|
| 108 | typedef int FNPDMTHREADUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
|
---|
| 109 | /** Pointer to a FNPDMTHREADUSB(). */
|
---|
| 110 | typedef FNPDMTHREADUSB *PFNPDMTHREADUSB;
|
---|
| 111 |
|
---|
| 112 | /**
|
---|
[3854] | 113 | * PDM thread, driver variation.
|
---|
| 114 | *
|
---|
| 115 | * @returns VBox status code.
|
---|
| 116 | * @param pDrvIns The driver instance.
|
---|
| 117 | * @param pThread The PDM thread data.
|
---|
| 118 | */
|
---|
| 119 | typedef int FNPDMTHREADDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
|
---|
| 120 | /** Pointer to a FNPDMTHREADDRV(). */
|
---|
| 121 | typedef FNPDMTHREADDRV *PFNPDMTHREADDRV;
|
---|
| 122 |
|
---|
| 123 | /**
|
---|
| 124 | * PDM thread, driver variation.
|
---|
| 125 | *
|
---|
| 126 | * @returns VBox status code.
|
---|
| 127 | * @param pVM The VM handle.
|
---|
| 128 | * @param pThread The PDM thread data.
|
---|
| 129 | */
|
---|
| 130 | typedef int FNPDMTHREADINT(PVM pVM, PPDMTHREAD pThread);
|
---|
| 131 | /** Pointer to a FNPDMTHREADINT(). */
|
---|
| 132 | typedef FNPDMTHREADINT *PFNPDMTHREADINT;
|
---|
| 133 |
|
---|
| 134 | /**
|
---|
| 135 | * PDM thread, driver variation.
|
---|
| 136 | *
|
---|
| 137 | * @returns VBox status code.
|
---|
| 138 | * @param pThread The PDM thread data.
|
---|
| 139 | */
|
---|
| 140 | typedef int FNPDMTHREADEXT(PPDMTHREAD pThread);
|
---|
| 141 | /** Pointer to a FNPDMTHREADEXT(). */
|
---|
| 142 | typedef FNPDMTHREADEXT *PFNPDMTHREADEXT;
|
---|
| 143 |
|
---|
| 144 |
|
---|
| 145 |
|
---|
| 146 | /**
|
---|
[4010] | 147 | * PDM thread wakeup call, device variation.
|
---|
[3854] | 148 | *
|
---|
| 149 | * @returns VBox status code.
|
---|
| 150 | * @param pDevIns The device instance.
|
---|
| 151 | * @param pThread The PDM thread data.
|
---|
| 152 | */
|
---|
| 153 | typedef int FNPDMTHREADWAKEUPDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);
|
---|
| 154 | /** Pointer to a FNPDMTHREADDEV(). */
|
---|
| 155 | typedef FNPDMTHREADWAKEUPDEV *PFNPDMTHREADWAKEUPDEV;
|
---|
| 156 |
|
---|
| 157 | /**
|
---|
[4010] | 158 | * PDM thread wakeup call, device variation.
|
---|
[3854] | 159 | *
|
---|
| 160 | * @returns VBox status code.
|
---|
[4010] | 161 | * @param pUsbIns The USB device instance.
|
---|
| 162 | * @param pThread The PDM thread data.
|
---|
| 163 | */
|
---|
| 164 | typedef int FNPDMTHREADWAKEUPUSB(PPDMUSBINS pUsbIns, PPDMTHREAD pThread);
|
---|
| 165 | /** Pointer to a FNPDMTHREADUSB(). */
|
---|
| 166 | typedef FNPDMTHREADWAKEUPUSB *PFNPDMTHREADWAKEUPUSB;
|
---|
| 167 |
|
---|
| 168 | /**
|
---|
| 169 | * PDM thread wakeup call, driver variation.
|
---|
| 170 | *
|
---|
| 171 | * @returns VBox status code.
|
---|
[3854] | 172 | * @param pDrvIns The driver instance.
|
---|
| 173 | * @param pThread The PDM thread data.
|
---|
| 174 | */
|
---|
| 175 | typedef int FNPDMTHREADWAKEUPDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread);
|
---|
| 176 | /** Pointer to a FNPDMTHREADDRV(). */
|
---|
| 177 | typedef FNPDMTHREADWAKEUPDRV *PFNPDMTHREADWAKEUPDRV;
|
---|
| 178 |
|
---|
| 179 | /**
|
---|
[4010] | 180 | * PDM thread wakeup call, internal variation.
|
---|
[3854] | 181 | *
|
---|
| 182 | * @returns VBox status code.
|
---|
| 183 | * @param pVM The VM handle.
|
---|
| 184 | * @param pThread The PDM thread data.
|
---|
| 185 | */
|
---|
| 186 | typedef int FNPDMTHREADWAKEUPINT(PVM pVM, PPDMTHREAD pThread);
|
---|
| 187 | /** Pointer to a FNPDMTHREADWAKEUPINT(). */
|
---|
| 188 | typedef FNPDMTHREADWAKEUPINT *PFNPDMTHREADWAKEUPINT;
|
---|
| 189 |
|
---|
| 190 | /**
|
---|
[4010] | 191 | * PDM thread wakeup call, external variation.
|
---|
[3854] | 192 | *
|
---|
| 193 | * @returns VBox status code.
|
---|
| 194 | * @param pThread The PDM thread data.
|
---|
| 195 | */
|
---|
| 196 | typedef int FNPDMTHREADWAKEUPEXT(PPDMTHREAD pThread);
|
---|
| 197 | /** Pointer to a FNPDMTHREADEXT(). */
|
---|
| 198 | typedef FNPDMTHREADWAKEUPEXT *PFNPDMTHREADWAKEUPEXT;
|
---|
| 199 |
|
---|
| 200 |
|
---|
| 201 | /**
|
---|
| 202 | * PDM Thread instance data.
|
---|
| 203 | */
|
---|
| 204 | typedef struct PDMTHREAD
|
---|
| 205 | {
|
---|
| 206 | /** PDMTHREAD_VERSION. */
|
---|
| 207 | uint32_t u32Version;
|
---|
| 208 | /** The thread state. */
|
---|
| 209 | PDMTHREADSTATE volatile enmState;
|
---|
| 210 | /** The thread handle. */
|
---|
| 211 | RTTHREAD Thread;
|
---|
| 212 | /** The user parameter. */
|
---|
| 213 | R3PTRTYPE(void *) pvUser;
|
---|
| 214 | /** Data specific to the kind of thread.
|
---|
| 215 | * This should really be in PDMTHREADINT, but is placed here because of the
|
---|
| 216 | * function pointer typedefs. So, don't touch these, please.
|
---|
| 217 | */
|
---|
| 218 | union
|
---|
| 219 | {
|
---|
| 220 | /** PDMTHREADTYPE_DEVICE data. */
|
---|
| 221 | struct
|
---|
| 222 | {
|
---|
| 223 | /** The device instance. */
|
---|
| 224 | PPDMDEVINSR3 pDevIns;
|
---|
| 225 | /** The thread function. */
|
---|
| 226 | R3PTRTYPE(PFNPDMTHREADDEV) pfnThread;
|
---|
| 227 | /** Thread. */
|
---|
[4421] | 228 | R3PTRTYPE(PFNPDMTHREADWAKEUPDEV) pfnWakeUp;
|
---|
[3854] | 229 | } Dev;
|
---|
| 230 |
|
---|
[4010] | 231 | /** PDMTHREADTYPE_USB data. */
|
---|
| 232 | struct
|
---|
| 233 | {
|
---|
| 234 | /** The device instance. */
|
---|
| 235 | PPDMUSBINS pUsbIns;
|
---|
| 236 | /** The thread function. */
|
---|
| 237 | R3PTRTYPE(PFNPDMTHREADUSB) pfnThread;
|
---|
| 238 | /** Thread. */
|
---|
[4421] | 239 | R3PTRTYPE(PFNPDMTHREADWAKEUPUSB) pfnWakeUp;
|
---|
[4010] | 240 | } Usb;
|
---|
| 241 |
|
---|
[3854] | 242 | /** PDMTHREADTYPE_DRIVER data. */
|
---|
| 243 | struct
|
---|
| 244 | {
|
---|
| 245 | /** The driver instance. */
|
---|
| 246 | R3PTRTYPE(PPDMDRVINS) pDrvIns;
|
---|
| 247 | /** The thread function. */
|
---|
| 248 | R3PTRTYPE(PFNPDMTHREADDRV) pfnThread;
|
---|
| 249 | /** Thread. */
|
---|
[4421] | 250 | R3PTRTYPE(PFNPDMTHREADWAKEUPDRV) pfnWakeUp;
|
---|
[3854] | 251 | } Drv;
|
---|
| 252 |
|
---|
| 253 | /** PDMTHREADTYPE_INTERNAL data. */
|
---|
| 254 | struct
|
---|
| 255 | {
|
---|
| 256 | /** The thread function. */
|
---|
| 257 | R3PTRTYPE(PFNPDMTHREADINT) pfnThread;
|
---|
| 258 | /** Thread. */
|
---|
[4421] | 259 | R3PTRTYPE(PFNPDMTHREADWAKEUPINT) pfnWakeUp;
|
---|
[3854] | 260 | } Int;
|
---|
| 261 |
|
---|
| 262 | /** PDMTHREADTYPE_EXTERNAL data. */
|
---|
| 263 | struct
|
---|
| 264 | {
|
---|
| 265 | /** The thread function. */
|
---|
| 266 | R3PTRTYPE(PFNPDMTHREADEXT) pfnThread;
|
---|
| 267 | /** Thread. */
|
---|
[4421] | 268 | R3PTRTYPE(PFNPDMTHREADWAKEUPEXT) pfnWakeUp;
|
---|
[3854] | 269 | } Ext;
|
---|
| 270 | } u;
|
---|
| 271 |
|
---|
| 272 | /** Internal data. */
|
---|
| 273 | union
|
---|
| 274 | {
|
---|
| 275 | #ifdef PDMTHREADINT_DECLARED
|
---|
| 276 | PDMTHREADINT s;
|
---|
| 277 | #endif
|
---|
| 278 | uint8_t padding[64];
|
---|
| 279 | } Internal;
|
---|
| 280 | } PDMTHREAD;
|
---|
| 281 |
|
---|
| 282 | /** PDMTHREAD::u32Version value. */
|
---|
| 283 | #define PDMTHREAD_VERSION 0xef010000
|
---|
| 284 |
|
---|
[4012] | 285 | #ifdef IN_RING3
|
---|
| 286 | /**
|
---|
| 287 | * Creates a PDM thread for internal use in the VM.
|
---|
| 288 | *
|
---|
| 289 | * @returns VBox status code.
|
---|
| 290 | * @param pVM The VM handle.
|
---|
| 291 | * @param ppThread Where to store the thread 'handle'.
|
---|
| 292 | * @param pvUser The user argument to the thread function.
|
---|
| 293 | * @param pfnThread The thread function.
|
---|
[4421] | 294 | * @param pfnWakeUp The wakup callback. This is called on the EMT thread when
|
---|
[4012] | 295 | * a state change is pending.
|
---|
| 296 | * @param cbStack See RTThreadCreate.
|
---|
| 297 | * @param enmType See RTThreadCreate.
|
---|
| 298 | * @param pszName See RTThreadCreate.
|
---|
| 299 | */
|
---|
| 300 | PDMR3DECL(int) PDMR3ThreadCreate(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread,
|
---|
[4421] | 301 | PFNPDMTHREADWAKEUPINT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
|
---|
[3854] | 302 |
|
---|
[4012] | 303 | /**
|
---|
| 304 | * Creates a PDM thread for VM use by some external party.
|
---|
| 305 | *
|
---|
| 306 | * @returns VBox status code.
|
---|
| 307 | * @param pVM The VM handle.
|
---|
| 308 | * @param ppThread Where to store the thread 'handle'.
|
---|
| 309 | * @param pvUser The user argument to the thread function.
|
---|
| 310 | * @param pfnThread The thread function.
|
---|
[4421] | 311 | * @param pfnWakeUp The wakup callback. This is called on the EMT thread when
|
---|
[4012] | 312 | * a state change is pending.
|
---|
| 313 | * @param cbStack See RTThreadCreate.
|
---|
| 314 | * @param enmType See RTThreadCreate.
|
---|
| 315 | * @param pszName See RTThreadCreate.
|
---|
| 316 | */
|
---|
| 317 | PDMR3DECL(int) PDMR3ThreadCreateExternal(PVM pVM, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread,
|
---|
[4421] | 318 | PFNPDMTHREADWAKEUPEXT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
|
---|
[4012] | 319 |
|
---|
| 320 | /**
|
---|
| 321 | * Destroys a PDM thread.
|
---|
| 322 | *
|
---|
| 323 | * This will wakeup the thread, tell it to terminate, and wait for it terminate.
|
---|
| 324 | *
|
---|
| 325 | * @returns VBox status code.
|
---|
| 326 | * This reflects the success off destroying the thread and not the exit code
|
---|
| 327 | * of the thread as this is stored in *pRcThread.
|
---|
| 328 | * @param pThread The thread to destroy.
|
---|
| 329 | * @param pRcThread Where to store the thread exit code. Optional.
|
---|
| 330 | * @thread The emulation thread (EMT).
|
---|
| 331 | */
|
---|
| 332 | PDMR3DECL(int) PDMR3ThreadDestroy(PPDMTHREAD pThread, int *pRcThread);
|
---|
| 333 |
|
---|
| 334 | /**
|
---|
| 335 | * Called by the PDM thread in response to a wakeup call with
|
---|
| 336 | * suspending as the new state.
|
---|
| 337 | *
|
---|
| 338 | * The thread will block in side this call until the state is changed in
|
---|
| 339 | * response to a VM state change or to the device/driver/whatever calling the
|
---|
| 340 | * PDMR3ThreadResume API.
|
---|
| 341 | *
|
---|
| 342 | * @returns VBox status code.
|
---|
| 343 | * On failure, terminate the thread.
|
---|
| 344 | * @param pThread The PDM thread.
|
---|
| 345 | */
|
---|
| 346 | PDMR3DECL(int) PDMR3ThreadIAmSuspending(PPDMTHREAD pThread);
|
---|
| 347 |
|
---|
| 348 | /**
|
---|
| 349 | * Called by the PDM thread in response to a resuming state.
|
---|
| 350 | *
|
---|
| 351 | * The purpose of this API is to tell the PDMR3ThreadResume caller that
|
---|
| 352 | * the the PDM thread has successfully resumed. It will also do the
|
---|
| 353 | * state transition from the resuming to the running state.
|
---|
| 354 | *
|
---|
| 355 | * @returns VBox status code.
|
---|
| 356 | * On failure, terminate the thread.
|
---|
| 357 | * @param pThread The PDM thread.
|
---|
| 358 | */
|
---|
| 359 | PDMR3DECL(int) PDMR3ThreadIAmRunning(PPDMTHREAD pThread);
|
---|
| 360 |
|
---|
| 361 | /**
|
---|
| 362 | * Suspends the thread.
|
---|
| 363 | *
|
---|
| 364 | * This can be called at the power off / suspend notifications to suspend the
|
---|
| 365 | * PDM thread a bit early. The thread will be automatically suspend upon
|
---|
| 366 | * completion of the device/driver notification cycle.
|
---|
| 367 | *
|
---|
| 368 | * The caller is responsible for serializing the control operations on the
|
---|
| 369 | * thread. That basically means, always do these calls from the EMT.
|
---|
| 370 | *
|
---|
| 371 | * @returns VBox status code.
|
---|
| 372 | * @param pThread The PDM thread.
|
---|
| 373 | */
|
---|
| 374 | PDMR3DECL(int) PDMR3ThreadSuspend(PPDMTHREAD pThread);
|
---|
| 375 |
|
---|
| 376 | /**
|
---|
| 377 | * Resumes the thread.
|
---|
| 378 | *
|
---|
| 379 | * This can be called the power on / resume notifications to resume the
|
---|
| 380 | * PDM thread a bit early. The thread will be automatically resumed upon
|
---|
| 381 | * return from these two notification callbacks (devices/drivers).
|
---|
| 382 | *
|
---|
| 383 | * The caller is responsible for serializing the control operations on the
|
---|
| 384 | * thread. That basically means, always do these calls from the EMT.
|
---|
| 385 | *
|
---|
| 386 | * @returns VBox status code.
|
---|
| 387 | * @param pThread The PDM thread.
|
---|
| 388 | */
|
---|
| 389 | PDMR3DECL(int) PDMR3ThreadResume(PPDMTHREAD pThread);
|
---|
| 390 | #endif /* IN_RING3 */
|
---|
| 391 |
|
---|
[3854] | 392 | /** @} */
|
---|
| 393 |
|
---|
| 394 | __END_DECLS
|
---|
| 395 |
|
---|
| 396 | #endif
|
---|