Changeset 3548 in vbox
- Timestamp:
- Jul 11, 2007 11:39:50 AM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 22779
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/pdm.h
r3526 r3548 420 420 */ 421 421 PDMR3DECL(void) PDMR3CritSectFF(PVM pVM); 422 423 /** @} */ 424 425 426 /** @group grp_pdm_thread 427 * @{ 428 */ 429 430 /** 431 * The thread state 432 */ 433 typedef enum PDMTHREADSTATE 434 { 435 /** The usual invalid 0 entry. */ 436 PDMTHREADSTATE_INVALID = 0, 437 /** The thread is initializing. 438 * Prev state: none 439 * Next state: suspended, terminating (error) */ 440 PDMTHREADSTATE_INITIALIZING, 441 /** The thread has been asked to suspend. 442 * Prev state: running 443 * Next state: suspended */ 444 PDMTHREADSTATE_SUSPENDING, 445 /** The thread is supended. 446 * Prev state: suspending, initializing 447 * Next state: resuming, terminated. */ 448 PDMTHREADSTATE_SUSPENDED, 449 /** The thread is active. 450 * Prev state: suspended 451 * Next state: running, terminating. */ 452 PDMTHREADSTATE_RESUMING, 453 /** The thread is active. 454 * Prev state: resuming 455 * Next state: suspending, terminating. */ 456 PDMTHREADSTATE_RUNNING, 457 /** The thread has been asked to terminate. 458 * Prev state: initializing, suspended, resuming, running 459 * Next state: terminated. */ 460 PDMTHREADSTATE_TERMINATING, 461 /** The thread is terminating / has terminated. 462 * Prev state: terminating 463 * Next state: none */ 464 PDMTHREADSTATE_TERMINATED, 465 /** The usual 32-bit hack. */ 466 PDMTHREADSTATE_32BIT_HACK = 0x7fffffff 467 } PDMTHREADSTATE; 468 469 /** A pointer to a PDM thread. */ 470 typedef R3PTRTYPE(struct PDMTHREAD *) PPDMTHREAD; 471 /** A pointer to a pointer to a PDM thread. */ 472 typedef PPDMTHREAD *PPPDMTHREAD; 473 474 /** 475 * PDM thread, device variation. 476 * 477 * @returns VBox status code. 478 * @param pDevIns The device instance. 479 * @param pThread The PDM thread data. 480 */ 481 typedef int FNPDMTHREADDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread); 482 /** Pointer to a FNPDMTHREADDEV(). */ 483 typedef FNPDMTHREADDEV *PFNPDMTHREADDEV; 484 485 /** 486 * PDM thread, driver variation. 487 * 488 * @returns VBox status code. 489 * @param pDrvIns The driver instance. 490 * @param pThread The PDM thread data. 491 */ 492 typedef int FNPDMTHREADDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread); 493 /** Pointer to a FNPDMTHREADDRV(). */ 494 typedef FNPDMTHREADDRV *PFNPDMTHREADDRV; 495 496 /** 497 * PDM thread, driver variation. 498 * 499 * @returns VBox status code. 500 * @param pVM The VM handle. 501 * @param pThread The PDM thread data. 502 */ 503 typedef int FNPDMTHREADINT(PVM pVM, PPDMTHREAD pThread); 504 /** Pointer to a FNPDMTHREADINT(). */ 505 typedef FNPDMTHREADINT *PFNPDMTHREADINT; 506 507 /** 508 * PDM thread, driver variation. 509 * 510 * @returns VBox status code. 511 * @param pThread The PDM thread data. 512 */ 513 typedef int FNPDMTHREADEXT(PPDMTHREAD pThread); 514 /** Pointer to a FNPDMTHREADEXT(). */ 515 typedef FNPDMTHREADEXT *PFNPDMTHREADEXT; 516 517 518 519 /** 520 * PDM thread wakup call, device variation. 521 * 522 * @returns VBox status code. 523 * @param pDevIns The device instance. 524 * @param pThread The PDM thread data. 525 */ 526 typedef int FNPDMTHREADWAKEUPDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread); 527 /** Pointer to a FNPDMTHREADDEV(). */ 528 typedef FNPDMTHREADWAKEUPDEV *PFNPDMTHREADWAKEUPDEV; 529 530 /** 531 * PDM thread wakup call, driver variation. 532 * 533 * @returns VBox status code. 534 * @param pDrvIns The driver instance. 535 * @param pThread The PDM thread data. 536 */ 537 typedef int FNPDMTHREADWAKEUPDRV(PPDMDRVINS pDrvIns, PPDMTHREAD pThread); 538 /** Pointer to a FNPDMTHREADDRV(). */ 539 typedef FNPDMTHREADWAKEUPDRV *PFNPDMTHREADWAKEUPDRV; 540 541 /** 542 * PDM thread wakup call, internal variation. 543 * 544 * @returns VBox status code. 545 * @param pVM The VM handle. 546 * @param pThread The PDM thread data. 547 */ 548 typedef int FNPDMTHREADWAKEUPINT(PVM pVM, PPDMTHREAD pThread); 549 /** Pointer to a FNPDMTHREADWAKEUPINT(). */ 550 typedef FNPDMTHREADWAKEUPINT *PFNPDMTHREADWAKEUPINT; 551 552 /** 553 * PDM thread wakup call, external variation. 554 * 555 * @returns VBox status code. 556 * @param pThread The PDM thread data. 557 */ 558 typedef int FNPDMTHREADWAKEUPEXT(PPDMTHREAD pThread); 559 /** Pointer to a FNPDMTHREADEXT(). */ 560 typedef FNPDMTHREADWAKEUPEXT *PFNPDMTHREADWAKEUPEXT; 561 562 563 /** 564 * PDM Thread instance data. 565 */ 566 typedef struct PDMTHREAD 567 { 568 /** PDMTHREAD_VERSION. */ 569 uint32_t u32Version; 570 /** The thread state. */ 571 PDMTHREADSTATE volatile enmState; 572 /** The thread handle. */ 573 RTTHREAD Thread; 574 /** The user parameter. */ 575 R3PTRTYPE(void *) pvUser; 576 /** Data specific to the kind of thread. 577 * This should really be in PDMTHREADINT, but is placed here because of the 578 * function pointer typedefs. So, don't touch these, please. 579 */ 580 union 581 { 582 /** PDMTHREADTYPE_DEVICE data. */ 583 struct 584 { 585 /** The device instance. */ 586 PPDMDEVINSR3 pDevIns; 587 /** The thread function. */ 588 R3PTRTYPE(PFNPDMTHREADDEV) pfnThread; 589 /** Thread. */ 590 R3PTRTYPE(PFNPDMTHREADWAKEUPDEV) pfnWakeup; 591 } Dev; 592 593 /** PDMTHREADTYPE_DRIVER data. */ 594 struct 595 { 596 /** The driver instance. */ 597 R3PTRTYPE(PPDMDRVINS) pDrvIns; 598 /** The thread function. */ 599 R3PTRTYPE(PFNPDMTHREADDRV) pfnThread; 600 /** Thread. */ 601 R3PTRTYPE(PFNPDMTHREADWAKEUPDRV) pfnWakeup; 602 } Drv; 603 604 /** PDMTHREADTYPE_INTERNAL data. */ 605 struct 606 { 607 /** The thread function. */ 608 R3PTRTYPE(PFNPDMTHREADINT) pfnThread; 609 /** Thread. */ 610 R3PTRTYPE(PFNPDMTHREADWAKEUPINT) pfnWakeup; 611 } Int; 612 613 /** PDMTHREADTYPE_EXTERNAL data. */ 614 struct 615 { 616 /** The thread function. */ 617 R3PTRTYPE(PFNPDMTHREADEXT) pfnThread; 618 /** Thread. */ 619 R3PTRTYPE(PFNPDMTHREADWAKEUPEXT) pfnWakeup; 620 } Ext; 621 } u; 622 623 /** Internal data. */ 624 union 625 { 626 #ifdef PDMTHREADINT_DECLARED 627 PDMTHREADINT s; 628 #endif 629 uint8_t padding[64]; 630 } Internal; 631 } PDMTHREAD; 632 633 /** PDMTHREAD::u32Version value. */ 634 #define PDMTHREAD_VERSION 0xef010000 635 422 636 423 637 /** @} */ -
trunk/src/VBox/VMM/Makefile.kmk
r2981 r3548 46 46 VMMR3_DEFS += PDMLDR_FAKE_MODE 47 47 endif 48 endif 48 endif 49 49 VMMR3_INCS := \ 50 50 PATM \ … … 76 76 PDMCritSect.cpp \ 77 77 PDMQueue.cpp \ 78 PDMThread.cpp \ 78 79 PGM.cpp \ 79 80 PGMHandler.cpp \ -
trunk/src/VBox/VMM/PDMInternal.h
r3520 r3548 39 39 */ 40 40 41 /******************************************************************************* 42 * Structures and Typedefs * 43 *******************************************************************************/ 44 41 45 /** Pointer to a PDM Device. */ 42 46 typedef struct PDMDEV *PPDMDEV; … … 96 100 #if GC_ARCH_BITS == 32 97 101 uint32_t Alignment0; 98 #endif 102 #endif 99 103 } PDMDEVINSINT; 100 104 … … 148 152 #if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32 149 153 uint32_t padding; 150 #endif 151 /** Event semaphore that is scheduled to be signaled upon leaving the 154 #endif 155 /** Event semaphore that is scheduled to be signaled upon leaving the 152 156 * critical section. This is Ring-3 only of course. */ 153 157 RTSEMEVENT EventToSignal; … … 163 167 164 168 169 /** 170 * The usual device/driver/internal/external stuff. 171 */ 172 typedef enum 173 { 174 /** The usual invalid entry. */ 175 PDMTHREADTYPE_INVALID = 0, 176 /** Device type. */ 177 PDMTHREADTYPE_DEVICE, 178 /** Driver type. */ 179 PDMTHREADTYPE_DRIVER, 180 /** Internal type. */ 181 PDMTHREADTYPE_INTERNAL, 182 /** External type. */ 183 PDMTHREADTYPE_EXTERNAL, 184 /** The usual 32-bit hack. */ 185 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff 186 } PDMTHREADTYPE; 187 188 189 /** 190 * The internal structure for the thread. 191 */ 192 typedef struct PDMTHREADINT 193 { 194 /** The VM pointer. */ 195 PVMR3 pVM; 196 /** The event semaphore the thread blocks on. */ 197 RTSEMEVENTMULTI BlockEvent; 198 /** Pointer to the next thread. */ 199 R3PTRTYPE(struct PDMTHREAD *) pNext; 200 /** The thread type. */ 201 PDMTHREADTYPE enmType; 202 } PDMTHREADINT; 203 204 205 165 206 /* Must be included after PDMDEVINSINT is defined. */ 166 207 #define PDMDEVINSINT_DECLARED 167 208 #define PDMDRVINSINT_DECLARED 168 209 #define PDMCRITSECTINT_DECLARED 210 #define PDMTHREADINT_DECLARED 169 211 #ifdef __VBox_pdm_h__ 170 212 # error "Invalid header PDM order. Include PDMInternal.h before VBox/pdm.h!" … … 363 405 PCIADDRESSSPACE enmType, PFNPCIIOREGIONMAP pfnCallback)); 364 406 /** @copydoc PDMPCIBUSREG::pfnSetConfigCallbacksHC */ 365 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, 407 DECLR3CALLBACKMEMBER(void, pfnSetConfigCallbacksR3,(PPDMDEVINS pDevIns, PPCIDEVICE pPciDev, PFNPCICONFIGREAD pfnRead, 366 408 PPFNPCICONFIGREAD ppfnReadOld, PFNPCICONFIGWRITE pfnWrite, PPFNPCICONFIGWRITE ppfnWriteOld)); 367 409 /** @copydoc PDMPCIBUSREG::pfnSaveExecHC */ … … 556 598 #if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32 557 599 uint32_t Alignment0; 558 #endif 600 #endif 559 601 } aFreeItems[1]; 560 602 } PDMQUEUE; … … 591 633 #if HC_ARCH_BITS == 64 592 634 uint32_t Alignment0; 593 #endif 635 #endif 594 636 /** Parameters to the operation. */ 595 637 union PDMDEVHLPTASKPARAMS … … 678 720 GCPTRTYPE(struct PDMQUEUE *) pQueueFlushGC; 679 721 722 #if HC_ARCH_BITS == 64 723 uint32_t padding0; 724 #endif 725 726 /** Head of the PDM Thread list. (singly linked) */ 727 R3PTRTYPE(PPDMTHREAD) pThreads; 728 /** Tail of the PDM Thread list. (singly linked) */ 729 R3PTRTYPE(PPDMTHREAD) pThreadsTail; 730 680 731 /** TEMPORARY HACKS FOR NETWORK POLLING. 681 732 * @todo fix NAT and kill this! 682 733 * @{ */ 683 734 RTUINT cPollers; 735 #if HC_ARCH_BITS == 64 736 RTUINT padding1; 737 #endif 684 738 HCPTRTYPE(PFNPDMDRVPOLLER) apfnPollers[16]; 685 739 HCPTRTYPE(PPDMDRVINS) aDrvInsPollers[16]; -
trunk/src/VBox/VMM/PDMThread.cpp
r3523 r3548 32 32 #include <VBox/log.h> 33 33 #include <iprt/asm.h> 34 #include <iprt/semaphore.h> 34 35 #include <iprt/assert.h> 35 36 #include <iprt/thread.h> 36 37 38 /** @group grp_pdm_thread39 * @{40 */41 42 /**43 * The thread state44 */45 typedef enum PDMTHREADSTATE46 {47 /** The usual invalid 0 entry. */48 PDMTHREADSTATE_INVALID = 0,49 /** The thread is initializing.50 * Prev state: none51 * Next state: suspended, terminating (error) */52 PDMTHREADSTATE_INITIALIZING,53 /** The thread has been asked to suspend.54 * Prev state: running55 * Next state: suspended */56 PDMTHREADSTATE_SUSPENDING,57 /** The thread is supended.58 * Prev state: suspending, initializing59 * Next state: resuming, terminated. */60 PDMTHREADSTATE_SUSPENDED,61 /** The thread is active.62 * Prev state: suspended63 * Next state: running, terminating. */64 PDMTHREADSTATE_RESUMING,65 /** The thread is active.66 * Prev state: resuming67 * Next state: suspending, terminating. */68 PDMTHREADSTATE_RUNNING,69 /** The thread has been asked to terminate.70 * Prev state: initializing, suspended, resuming, running71 * Next state: terminated. */72 PDMTHREADSTATE_TERMINATING,73 /** The thread is terminating / has terminated.74 * Prev state: terminating75 * Next state: none */76 PDMTHREADSTATE_TERMINATED,77 /** The usual 32-bit hack. */78 PDMTHREADSTATE_32BIT_HACK = 0x7fffffff79 } PDMTHREADSTATE;80 81 /** A pointer to an PDM thread. */82 typedef HCPTRTYPE(struct PDMTHREAD *) PPDMTHREAD;83 84 /**85 * PDM thread, device variation.86 *87 * @returns VBox status code.88 * @param pDevIns The device instance.89 * @param pThread The PDM thread data.90 */91 typedef int FNPDMTHREADDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);92 /** Pointer to a FNPDMTHREADDEV(). */93 typedef FNPDMTHREADDEV *PFNPDMTHREADDEV;94 95 /**96 * PDM thread, driver variation.97 *98 * @returns VBox status code.99 * @param pDrvIns The driver instance.100 * @param pThread The PDM thread data.101 */102 typedef int FNPDMTHREADDRV(PPDMDEVINS pDrvIns, PPDMTHREAD pThread);103 /** Pointer to a FNPDMTHREADDRV(). */104 typedef FNPDMTHREADDRV *PFNPDMTHREADDRV;105 106 /**107 * PDM thread, driver variation.108 *109 * @returns VBox status code.110 * @param pVM The VM handle.111 * @param pThread The PDM thread data.112 */113 typedef int FNPDMTHREADINT(PVM pVM, PPDMTHREAD pThread);114 /** Pointer to a FNPDMTHREADINT(). */115 typedef FNPDMTHREADINT *PFNPDMTHREADINT;116 117 /**118 * PDM thread, driver variation.119 *120 * @returns VBox status code.121 * @param pThread The PDM thread data.122 */123 typedef int FNPDMTHREADEXT(PPDMTHREAD pThread);124 /** Pointer to a FNPDMTHREADEXT(). */125 typedef FNPDMTHREADEXT *PFNPDMTHREADEXT;126 127 128 129 /**130 * PDM thread wakup call, device variation.131 *132 * @returns VBox status code.133 * @param pDevIns The device instance.134 * @param pThread The PDM thread data.135 */136 typedef int FNPDMTHREADWAKEUPDEV(PPDMDEVINS pDevIns, PPDMTHREAD pThread);137 /** Pointer to a FNPDMTHREADDEV(). */138 typedef FNPDMTHREADWAKEUPDEV *PFNPDMTHREADWAKEUPDEV;139 140 /**141 * PDM thread wakup call, driver variation.142 *143 * @returns VBox status code.144 * @param pDrvIns The driver instance.145 * @param pThread The PDM thread data.146 */147 typedef int FNPDMTHREADWAKEUPDRV(PPDMDEVINS pDrvIns, PPDMTHREAD pThread);148 /** Pointer to a FNPDMTHREADDRV(). */149 typedef FNPDMTHREADWAKEUPDRV *PFNPDMTHREADWAKEUPDRV;150 151 /**152 * PDM thread wakup call, internal variation.153 *154 * @returns VBox status code.155 * @param pVM The VM handle.156 * @param pThread The PDM thread data.157 */158 typedef int FNPDMTHREADWAKEUPINT(PVM pVM, PPDMTHREAD pThread);159 /** Pointer to a FNPDMTHREADWAKEUPINT(). */160 typedef FNPDMTHREADWAKEUPINT *PFNPDMTHREADWAKEUPINT;161 162 /**163 * PDM thread wakup call, external variation.164 *165 * @returns VBox status code.166 * @param pThread The PDM thread data.167 */168 typedef int FNPDMTHREADWAKEUPEXT(PPDMTHREAD pThread);169 /** Pointer to a FNPDMTHREADEXT(). */170 typedef FNPDMTHREADWAKEUPEXT *PFNPDMTHREADWAKEUPEXT;171 172 173 /** The usual device/driver/internal/external stuff. */174 typedef enum175 {176 /** The usual invalid entry. */177 PDMTHREADTYPE_INVALID = 0,178 /** Device type. */179 PDMTHREADTYPE_DEVICE,180 /** Driver type. */181 PDMTHREADTYPE_DRIVER,182 /** Internal type. */183 PDMTHREADTYPE_INTERNAL,184 /** External type. */185 PDMTHREADTYPE_EXTERNAL,186 /** The usual 32-bit hack. */187 PDMTHREADTYPE_32BIT_HACK = 0x7fffffff188 } PDMTHREADTYPE;189 190 /**191 * The internal structure for the thread.192 */193 typedef struct PDMTHREADINT194 {195 /** The VM pointer. */196 PVMR3 pVM;197 /** The event semaphore the thread blocks on. */198 RTSEMEVENTMULTI BlockEvent;199 /** The thread type. */200 PDMTHREADTYPE enmType;201 union202 {203 struct204 {205 /** The device instance. */206 PPDMDEVINSR3 pDevIns;207 /** The thread function. */208 R3PTRTYPE(PFNPDMTHREADDEV) pfnThread;209 /** Thread. */210 R3PTRTYPE(PFNPDMTHREADWAKEUPDEV) pfnWakeup;211 } Dev;212 213 struct214 {215 /** The driver instance. */216 PPDMDRVINSR3 pDrvIns;217 /** The thread function. */218 R3PTRTYPE(PFNPDMTHREADDRV) pfnThread;219 /** Thread. */220 R3PTRTYPE(PFNPDMTHREADWAKEUPDRV) pfnWakeup;221 } Drv;222 223 } u;224 } PDMTHREADINT;225 226 227 typedef struct PDMTHREAD228 {229 #define PDMTHREAD_VERSION 0x10000000230 /** PDMTHREAD_VERSION. */231 uint32_t u32Version;232 /** The thread state. */233 PDMTHREADSTATE volatile enmState;234 /** The thread handle. */235 RTTHREAD Thread;236 /** The user parameter. */237 R3PTRTYPE(void *) pvUser;238 239 /** Internal data. */240 union241 {242 #ifdef PDMTHREADINT_DECLARED243 PDMTHREADINT s;244 #endif245 uint8_t padding[64];246 } Internal;247 } PDMTHREAD;248 249 250 251 /** @} */252 37 253 38 … … 258 43 259 44 45 /** 46 * Wrapper around ASMAtomicCmpXchgSize. 47 */ 48 DECLINLINE(bool) pdmR3AtomicCmpXchgState(PPDMTHREAD pThread, PDMTHREADSTATE enmNewState, PDMTHREADSTATE enmOldState) 49 { 50 bool fRc; 51 ASMAtomicCmpXchgSize(&pThread->enmState, enmNewState, enmOldState, fRc); 52 return fRc; 53 } 54 260 55 261 56 /** … … 271 66 { 272 67 case PDMTHREADTYPE_DEVICE: 273 rc = pThread-> Internal.s.u.Dev.pfnWakeup(pThread->Internal.s.u.Dev.pDevIns, pThread);68 rc = pThread->u.Dev.pfnWakeup(pThread->u.Dev.pDevIns, pThread); 274 69 break; 275 70 276 71 case PDMTHREADTYPE_DRIVER: 277 rc = pThread-> Internal.s.u.Drv.pfnWakeup(pThread->Internal.s.u.Drv.pDrvIns, pThread);72 rc = pThread->u.Drv.pfnWakeup(pThread->u.Drv.pDrvIns, pThread); 278 73 break; 279 74 280 75 case PDMTHREADTYPE_INTERNAL: 281 rc = pThread-> Internal.s.u.Int.pfnWakeup(pThread->Internal.s.pVM, pThread);76 rc = pThread->u.Int.pfnWakeup(pThread->Internal.s.pVM, pThread); 282 77 break; 283 78 284 79 case PDMTHREADTYPE_EXTERNAL: 285 rc = pThread-> Internal.s.u.Int.pfnWakeup(pThread);80 rc = pThread->u.Ext.pfnWakeup(pThread); 286 81 break; 287 82 … … 303 98 * @param ppThread Where to store the pointer to the instance. 304 99 */ 305 static int pdmR3ThreadNew(PVM pVM, PP DMTHREAD ppThread)100 static int pdmR3ThreadNew(PVM pVM, PPPDMTHREAD ppThread) 306 101 { 307 102 PPDMTHREAD pThread; 308 int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_THREAD, sizeof(*p Queue), (void **)&pThread);103 int rc = MMR3HeapAllocZEx(pVM, MM_TAG_PDM_THREAD, sizeof(*pThread), (void **)&pThread); 309 104 if (RT_FAILURE(rc)) 310 105 return rc; … … 312 107 pThread->u32Version = PDMTHREAD_VERSION; 313 108 pThread->enmState = PDMTHREADSTATE_INITIALIZING; 314 pThread->Thread = RT_NILTHREAD;109 pThread->Thread = NIL_RTTHREAD; 315 110 pThread->Internal.s.pVM = pVM; 316 111 … … 326 121 * @returns VBox status code. 327 122 * @param pVM The VM handle. 123 * @param ppThread Where the thread instance data handle is. 124 * @param cbStack The stack size, see RTThreadCreate(). 328 125 * @param enmType The thread type, see RTThreadCreate(). 329 * @param cbStack The stack size, see RTThreadCreate().330 126 * @param pszName The thread name, see RTThreadCreate(). 331 * @param ppThread Where the thread instance data handle is. 332 */ 333 static int pdmR3ThreadInit(PVM pVM, RTTHREADTYPE enmType, size_t cbStack, const char *pszName, PPPDMTHREAD ppThread) 127 */ 128 static int pdmR3ThreadInit(PVM pVM, PPPDMTHREAD ppThread, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 334 129 { 335 130 PPDMTHREAD pThread = *ppThread; 336 131 337 132 /* 338 133 * Initialize the remainder of the structure. … … 343 138 if (RT_SUCCESS(rc)) 344 139 { 345 /* 140 /* 346 141 * Create the thread and wait for it to initialize. 347 142 */ … … 349 144 if (RT_SUCCESS(rc)) 350 145 { 351 rc = RTThread Wait(pThread->Thread, 60*1000);352 if ( RT_SUCCESS(rc) 353 && pThread->enmState != PDMTHREADSTATE_SUSPEND )146 rc = RTThreadUserWait(pThread->Thread, 60*1000); 147 if ( RT_SUCCESS(rc) 148 && pThread->enmState != PDMTHREADSTATE_SUSPENDED) 354 149 rc = VERR_INTERNAL_ERROR; 355 150 if (RT_SUCCESS(rc)) 356 151 { 357 rc = RTThread Reset(pThread->Thread);152 rc = RTThreadUserReset(pThread->Thread); 358 153 AssertRC(rc); 359 154 return rc; … … 368 163 MMHyperFree(pVM, pThread); 369 164 *ppThread = NULL; 370 371 return rc; 372 } 373 374 375 376 PDMR3DECL(int) PDMR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, void *pvUser, PFNPDMTHREADDEV pfnThread,165 166 return rc; 167 } 168 169 170 171 PDMR3DECL(int) PDMR3ThreadCreateDevice(PVM pVM, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread, 377 172 PFNPDMTHREADWAKEUPDEV pfnWakeup, size_t cbStack, RTTHREADTYPE enmType, const char *pszName) 378 173 { … … 380 175 if (RT_SUCCESS(rc)) 381 176 { 177 (*ppThread)->pvUser = pvUser; 382 178 (*ppThread)->Internal.s.enmType = PDMTHREADTYPE_DEVICE; 383 (*ppThread)-> Internal.s.u.Dev.pDevIns = pDevIns;384 (*ppThread)-> Internal.s.u.Dev.pfnThread = pfnThread;385 (*ppThread)-> Internal.s.u.Dev.pfnWakeup = pfnWakeup;386 rc = pdmR3ThreadInit(pVM, p Thread);179 (*ppThread)->u.Dev.pDevIns = pDevIns; 180 (*ppThread)->u.Dev.pfnThread = pfnThread; 181 (*ppThread)->u.Dev.pfnWakeup = pfnWakeup; 182 rc = pdmR3ThreadInit(pVM, ppThread, cbStack, enmType, pszName); 387 183 } 388 184 return rc; … … 396 192 * 397 193 * @returns VBox status code. 398 * This reflects the success off destroying the thread and not the exit code 194 * This reflects the success off destroying the thread and not the exit code 399 195 * of the thread as this is stored in *pRcThread. 400 196 * @param pThread The thread to destroy. … … 413 209 PVM pVM = pThread->Internal.s.pVM; 414 210 VM_ASSERT_EMT(pVM); 415 211 416 212 /* 417 213 * Advance the thread to the terminating state. … … 426 222 { 427 223 case PDMTHREADSTATE_RUNNING: 428 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))224 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 429 225 continue; 430 226 rc = pdmR3ThreadWakeup(pThread); … … 435 231 case PDMTHREADSTATE_RESUMING: 436 232 case PDMTHREADSTATE_INITIALIZING: 437 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))233 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 438 234 continue; 439 235 break; … … 469 265 { 470 266 PPDMTHREAD pPrev = pVM->pdm.s.pThreads; 471 while (pPrev && pPrev-> pNext != pThread)267 while (pPrev && pPrev->Internal.s.pNext != pThread) 472 268 pPrev = pPrev->Internal.s.pNext; 473 269 Assert(pPrev); … … 498 294 499 295 AssertPtr(pDevIns); 500 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 296 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 501 297 while (pThread) 502 298 { 503 299 PPDMTHREAD pNext = pThread->Internal.s.pNext; 504 300 if ( pThread->Internal.s.enmType == PDMTHREADTYPE_DEVICE 505 && pThread-> Internal.s.u.Dev.pDevIns == pDevIns)301 && pThread->u.Dev.pDevIns == pDevIns) 506 302 { 507 303 int rc2 = PDMR3ThreadDestroy(pThread, NULL); … … 509 305 rc = rc2; 510 306 } 307 pThread = pNext; 511 308 } 512 309 … … 520 317 521 318 AssertPtr(pDrvIns); 522 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 319 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 523 320 while (pThread) 524 321 { 525 322 PPDMTHREAD pNext = pThread->Internal.s.pNext; 526 323 if ( pThread->Internal.s.enmType == PDMTHREADTYPE_DRIVER 527 && pThread-> Internal.s.u.Drv.pDrvIns == pDrvIns)324 && pThread->u.Drv.pDrvIns == pDrvIns) 528 325 { 529 326 int rc2 = PDMR3ThreadDestroy(pThread, NULL); … … 531 328 rc = rc2; 532 329 } 330 pThread = pNext; 533 331 } 534 332 … … 540 338 * Called For VM power off. 541 339 * 542 * @param pVM 340 * @param pVM The VM handle. 543 341 */ 544 342 void pdmR3ThreadDestroyAll(PVM pVM) 545 343 { 546 AssertPtr(pDevIns); 547 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 344 PPDMTHREAD pThread = pVM->pdm.s.pThreads; 548 345 while (pThread) 549 346 { 550 347 PPDMTHREAD pNext = pThread->Internal.s.pNext; 551 348 int rc2 = PDMR3ThreadDestroy(pThread, NULL); 552 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 553 rc = rc2; 554 } 555 556 return rc; 557 } 558 559 560 561 562 /** 563 * Initiate termination of the thread (self) because something failed in a bad way. 349 AssertRC(rc2); 350 pThread = pNext; 351 } 352 Assert(pVM->pdm.s.pThreads || pVM->pdm.s.pThreadsTail); 353 } 354 355 356 357 358 /** 359 * Initiate termination of the thread (self) because something failed in a bad way. 564 360 * 565 361 * @param pThread The PDM thread. … … 576 372 case PDMTHREADSTATE_RESUMING: 577 373 case PDMTHREADSTATE_RUNNING: 578 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))374 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 579 375 continue; 580 376 break; … … 595 391 596 392 /** 597 * Called by the PDM thread in response to a wakeup call with 393 * Called by the PDM thread in response to a wakeup call with 598 394 * suspending as the new state. 599 395 * 600 * The thread will block in side this call until the state is changed in 601 * response to a VM state change or to the device/driver/whatever calling the 396 * The thread will block in side this call until the state is changed in 397 * response to a VM state change or to the device/driver/whatever calling the 602 398 * PDMR3ThreadResume API. 603 399 * … … 612 408 */ 613 409 AssertPtr(pThread); 614 Assert (pThread->u32Version == PGMTHREAD_VERSION, VERR_INVALID_MAGIC);410 AssertReturn(pThread->u32Version == PDMTHREAD_VERSION, VERR_INVALID_MAGIC); 615 411 Assert(pThread->Thread == RTThreadSelf() || pThread->enmState == PDMTHREADSTATE_INITIALIZING); 616 412 PDMTHREADSTATE enmState = pThread->enmState; … … 622 418 */ 623 419 int rc = VERR_WRONG_ORDER; 624 if ( ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_SUSPENDED, enmState))420 if (pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_SUSPENDED, enmState)) 625 421 { 626 422 rc = RTThreadUserSignal(pThread->Thread); 627 423 if (RT_SUCCESS(rc)) 628 424 { 629 rc = RTSemEventMultiWait(pThread->Internal.s.BlockEvent, RT_IN FINITE_WAIT);425 rc = RTSemEventMultiWait(pThread->Internal.s.BlockEvent, RT_INDEFINITE_WAIT); 630 426 if ( RT_SUCCESS(rc) 631 427 && pThread->enmState != PDMTHREADSTATE_SUSPENDED) 632 428 return rc; 633 429 634 430 if (RT_SUCCESS(rc)) 635 431 rc = VERR_INTERNAL_ERROR; … … 637 433 } 638 434 639 AssertMsgFailed(("rc=%d enmState=%d\n", rc, pThread->enmState)) :435 AssertMsgFailed(("rc=%d enmState=%d\n", rc, pThread->enmState)); 640 436 pdmR3ThreadBailMeOut(pThread); 641 437 return rc; … … 652 448 * @returns VBox status code. 653 449 * On failure, terminate the thread. 654 * @param pThread The PDM thread. 450 * @param pThread The PDM thread. 655 451 */ 656 452 PDMR3DECL(int) PDMR3ThreadIAmRunning(PPDMTHREAD pThread) … … 666 462 */ 667 463 int rc = VERR_WRONG_ORDER; 668 if ( ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_RUNNING, PDMTHREADSTATE_RESUMING))464 if (pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_RUNNING, PDMTHREADSTATE_RESUMING)) 669 465 { 670 466 rc = RTThreadUserSignal(pThread->Thread); … … 672 468 return rc; 673 469 } 674 675 AssertMsgFailed(("rc=%d enmState=%d\n", rc, pThread->enmState)) :470 471 AssertMsgFailed(("rc=%d enmState=%d\n", rc, pThread->enmState)); 676 472 pdmR3ThreadBailMeOut(pThread); 677 473 return rc; … … 682 478 * The PDM thread function. 683 479 * 684 * @returns return from pfnThread. 480 * @returns return from pfnThread. 685 481 * 686 482 * @param Thread The thread handle. … … 695 491 * The run loop. 696 492 * 697 * It handles simple thread functions which returns when they see a suspending 698 * request and leaves the PDMR3ThreadIAmSuspending and PDMR3ThreadIAmRunning 493 * It handles simple thread functions which returns when they see a suspending 494 * request and leaves the PDMR3ThreadIAmSuspending and PDMR3ThreadIAmRunning 699 495 * parts to us. 700 496 */ … … 705 501 { 706 502 case PDMTHREADTYPE_DEVICE: 707 rc = pThread-> Internal.s.u.Dev.pfnThread(pThread->Internal.s.u.Dev.pDevIns, pThread);708 break; 709 503 rc = pThread->u.Dev.pfnThread(pThread->u.Dev.pDevIns, pThread); 504 break; 505 710 506 case PDMTHREADTYPE_DRIVER: 711 rc = pThread-> Internal.s.u.Drv.pfnThread(pThread->Internal.s.u.Drv.pDrvIns, pThread);712 break; 713 507 rc = pThread->u.Drv.pfnThread(pThread->u.Drv.pDrvIns, pThread); 508 break; 509 714 510 case PDMTHREADTYPE_INTERNAL: 715 rc = pThread-> Internal.s.u.Int.pfnThread(pThread->Internal.s.pVM, pThread);716 break; 717 511 rc = pThread->u.Int.pfnThread(pThread->Internal.s.pVM, pThread); 512 break; 513 718 514 case PDMTHREADTYPE_EXTERNAL: 719 rc = pThread-> Internal.s.u.Int.pfnThread(pThread);720 break; 721 515 rc = pThread->u.Ext.pfnThread(pThread); 516 break; 517 722 518 default: 723 519 AssertMsgFailed(("%d\n", pThread->Internal.s.enmType)); … … 728 524 break; 729 525 730 /* 731 * If this is a simple thread function, the state will be suspending 526 /* 527 * If this is a simple thread function, the state will be suspending 732 528 * or initializing now. If it isn't we're supposed to terminate. 733 529 */ … … 759 555 PDMTHREADSTATE enmState = pThread->enmState; 760 556 if ( enmState == PDMTHREADSTATE_TERMINATING 761 || ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))762 break; 763 } 764 765 ASMAtomicXchg U32(&pThread->enmState, PDMTHREADSTATE_TERMINATED);557 || pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 558 break; 559 } 560 561 ASMAtomicXchgSize(&pThread->enmState, PDMTHREADSTATE_TERMINATED); 766 562 int rc2 = RTThreadUserSignal(Thread); AssertRC(rc2); 767 563 768 564 Log(("PDMThread: Terminating thread %RTthrd / %p / '%s': %Rrc\n", Thread, pThread, RTThreadGetName(Thread), rc)); 769 565 return rc; … … 772 568 773 569 /** 774 * Initiate termination of the thread because something failed in a bad way. 570 * Initiate termination of the thread because something failed in a bad way. 775 571 * 776 572 * @param pThread The PDM thread. … … 785 581 case PDMTHREADSTATE_SUSPENDING: 786 582 case PDMTHREADSTATE_SUSPENDED: 787 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))583 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 788 584 continue; 789 585 RTSemEventMultiSignal(pThread->Internal.s.BlockEvent); … … 791 587 792 588 case PDMTHREADSTATE_RESUMING: 793 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))589 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 794 590 continue; 795 591 break; 796 592 797 593 case PDMTHREADSTATE_RUNNING: 798 if (! ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_TERMINATING, enmState))594 if (!pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_TERMINATING, enmState)) 799 595 continue; 800 596 pdmR3ThreadWakeup(pThread); … … 818 614 * Suspends the thread. 819 615 * 820 * This can be called the power off / suspend notifications to suspend the 616 * This can be called the power off / suspend notifications to suspend the 821 617 * PDM thread a bit early. The thread will be automatically suspend upon 822 618 * return from these two notification callbacks (devices/drivers). 823 619 * 824 * The caller is responsible for serializing the control operations on the 620 * The caller is responsible for serializing the control operations on the 825 621 * thread. That basically means, always do these calls from the EMT. 826 622 * … … 834 630 */ 835 631 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 836 AssertReturn(pThread->u32Version == P GMTHREAD_VERSION, VERR_INVALID_MAGIC);632 AssertReturn(pThread->u32Version == PDMTHREAD_VERSION, VERR_INVALID_MAGIC); 837 633 Assert(pThread->Thread != RTThreadSelf()); 838 634 … … 847 643 { 848 644 rc = VERR_WRONG_ORDER; 849 if ( ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_SUSPENDING, PDMTHREADSTATE_RUNNING))645 if (pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_SUSPENDING, PDMTHREADSTATE_RUNNING)) 850 646 { 851 647 rc = pdmR3ThreadWakeup(pThread); … … 857 653 if (pThread->enmState != PDMTHREADSTATE_SUSPENDED) 858 654 rc = RTThreadUserWait(pThread->Thread, 60*1000); 859 if ( RT_SUCCESS(rc) 655 if ( RT_SUCCESS(rc) 860 656 && pThread->enmState != PDMTHREADSTATE_SUSPENDED) 861 657 rc = VERR_INTERNAL_ERROR; … … 879 675 * Suspend all running threads. 880 676 * 881 * This is called by PDMR3Suspend() and PDMR3PowerOff() after all the devices 677 * This is called by PDMR3Suspend() and PDMR3PowerOff() after all the devices 882 678 * and drivers have been notified about the suspend / power off. 883 * 679 * 884 680 * @return VBox status code. 885 681 * @param pVM The VM handle. … … 887 683 int pdmR3ThreadSuspendAll(PVM pVM) 888 684 { 889 for (PPDMTHREAD pThread = pVM->pdm.s.pThreads; pThread = pThread->Internal.s.pNext)685 for (PPDMTHREAD pThread = pVM->pdm.s.pThreads; pThread; pThread = pThread->Internal.s.pNext) 890 686 switch (pThread->enmState) 891 687 { … … 908 704 * Resumes the thread. 909 705 * 910 * This can be called the power on / resume notifications to resume the 706 * This can be called the power on / resume notifications to resume the 911 707 * PDM thread a bit early. The thread will be automatically resumed upon 912 708 * return from these two notification callbacks (devices/drivers). 913 709 * 914 * The caller is responsible for serializing the control operations on the 710 * The caller is responsible for serializing the control operations on the 915 711 * thread. That basically means, always do these calls from the EMT. 916 712 * … … 924 720 */ 925 721 AssertPtrReturn(pThread, VERR_INVALID_POINTER); 926 AssertReturn(pThread->u32Version == P GMTHREAD_VERSION, VERR_INVALID_MAGIC);722 AssertReturn(pThread->u32Version == PDMTHREAD_VERSION, VERR_INVALID_MAGIC); 927 723 Assert(pThread->Thread != RTThreadSelf()); 928 724 … … 934 730 { 935 731 rc = VERR_WRONG_ORDER; 936 if ( ASMAtomicCmpXchgU32(&pThread->enmState, PDMTHREADSTATE_RESUMING, PDMTHREADSTATE_SUSPENDED))732 if (pdmR3AtomicCmpXchgState(pThread, PDMTHREADSTATE_RESUMING, PDMTHREADSTATE_SUSPENDED)) 937 733 { 938 734 rc = RTSemEventMultiSignal(pThread->Internal.s.BlockEvent); … … 943 739 */ 944 740 rc = RTThreadUserWait(pThread->Thread, 60*1000); 945 if ( RT_SUCCESS(rc) 946 && pThread->e mState != PDMTHREADSTATE_RUNNING)741 if ( RT_SUCCESS(rc) 742 && pThread->enmState != PDMTHREADSTATE_RUNNING) 947 743 rc = VERR_INTERNAL_ERROR; 948 744 if (RT_SUCCESS(rc)) … … 964 760 * Resumes all threads not running. 965 761 * 966 * This is called by PDMR3Resume() and PDMR3PowerOn() after all the devices 762 * This is called by PDMR3Resume() and PDMR3PowerOn() after all the devices 967 763 * and drivers have been notified about the resume / power on . 968 * 764 * 969 765 * @return VBox status code. 970 766 * @param pVM The VM handle. … … 972 768 int pdmR3ThreadResumeAll(PVM pVM) 973 769 { 974 for (PPDMTHREAD pThread = pVM->pdm.s.pThreads; pThread = pThread->Internal.s.pNext)770 for (PPDMTHREAD pThread = pVM->pdm.s.pThreads; pThread; pThread = pThread->Internal.s.pNext) 975 771 switch (pThread->enmState) 976 772 {
Note:
See TracChangeset
for help on using the changeset viewer.