Changeset 45152 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Mar 23, 2013 8:36:23 PM (12 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/EM.cpp
r45108 r45152 1409 1409 1410 1410 if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT)) 1411 PDMCritSect FF(pVCpu);1411 PDMCritSectBothFF(pVCpu); 1412 1412 1413 1413 /* Update CR3 (Nested Paging case for HM). */ -
trunk/src/VBox/VMM/VMMR3/PDM.cpp
r45024 r45152 343 343 pUVM->pdm.s.pModules = NULL; 344 344 pUVM->pdm.s.pCritSects = NULL; 345 pUVM->pdm.s.pRwCritSects = NULL; 345 346 return RTCritSectInit(&pUVM->pdm.s.ListCritSect); 346 347 } … … 374 375 * Initialize critical sections first. 375 376 */ 376 int rc = pdmR3CritSect InitStats(pVM);377 int rc = pdmR3CritSectBothInitStats(pVM); 377 378 if (RT_SUCCESS(rc)) 378 379 rc = PDMR3CritSectInit(pVM, &pVM->pdm.s.CritSect, RT_SRC_POS, "PDM"); … … 458 459 * Critical sections. 459 460 */ 460 pdmR3CritSect Relocate(pVM);461 pdmR3CritSectBothRelocate(pVM); 461 462 462 463 /* … … 660 661 TMR3TimerDestroyDevice(pVM, pDevIns); 661 662 SSMR3DeregisterDevice(pVM, pDevIns, NULL, 0); 662 pdmR3CritSect DeleteDevice(pVM, pDevIns);663 pdmR3CritSectBothDeleteDevice(pVM, pDevIns); 663 664 pdmR3ThreadDestroyDevice(pVM, pDevIns); 664 665 PDMR3QueueDestroyDevice(pVM, pDevIns); … … 702 703 */ 703 704 PDMR3CritSectDelete(&pVM->pdm.s.CritSect); 704 /* The MiscCritSect is deleted by PDMR3CritSect Term. */705 /* The MiscCritSect is deleted by PDMR3CritSectBothTerm later. */ 705 706 706 707 LogFlow(("PDMR3Term: returns %Rrc\n", VINF_SUCCESS)); … … 726 727 727 728 Assert(pUVM->pdm.s.pCritSects == NULL); 729 Assert(pUVM->pdm.s.pRwCritSects == NULL); 728 730 RTCritSectDelete(&pUVM->pdm.s.ListCritSect); 729 731 } -
trunk/src/VBox/VMM/VMMR3/PDMCritSect.cpp
r44528 r45152 23 23 #include "PDMInternal.h" 24 24 #include <VBox/vmm/pdmcritsect.h> 25 #include <VBox/vmm/pdmcritsectrw.h> 25 26 #include <VBox/vmm/mm.h> 26 27 #include <VBox/vmm/vm.h> … … 41 42 *******************************************************************************/ 42 43 static int pdmR3CritSectDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTINT pCritSect, PPDMCRITSECTINT pPrev, bool fFinal); 44 static int pdmR3CritSectRwDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTRWINT pCritSect, PPDMCRITSECTRWINT pPrev, bool fFinal); 43 45 44 46 … … 50 52 * @param pVM Pointer to the VM. 51 53 */ 52 int pdmR3CritSect InitStats(PVM pVM)54 int pdmR3CritSectBothInitStats(PVM pVM) 53 55 { 54 56 STAM_REG(pVM, &pVM->pdm.s.StatQueuedCritSectLeaves, STAMTYPE_COUNTER, "/PDM/QueuedCritSectLeaves", STAMUNIT_OCCURENCES, … … 63 65 * @param pVM Pointer to the VM. 64 66 */ 65 void pdmR3CritSect Relocate(PVM pVM)67 void pdmR3CritSectBothRelocate(PVM pVM) 66 68 { 67 69 PUVM pUVM = pVM->pUVM; … … 69 71 70 72 for (PPDMCRITSECTINT pCur = pUVM->pdm.s.pCritSects; 73 pCur; 74 pCur = pCur->pNext) 75 pCur->pVMRC = pVM->pVMRC; 76 77 for (PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 71 78 pCur; 72 79 pCur = pCur->pNext) … … 91 98 * @remark Don't confuse this with PDMR3CritSectDelete. 92 99 */ 93 VMM DECL(int) PDMR3CritSectTerm(PVM pVM)100 VMMR3_INT_DECL(int) PDMR3CritSectBothTerm(PVM pVM) 94 101 { 95 102 PUVM pUVM = pVM->pUVM; … … 100 107 { 101 108 int rc2 = pdmR3CritSectDeleteOne(pVM, pUVM, pUVM->pdm.s.pCritSects, NULL, true /* final */); 109 AssertRC(rc2); 110 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 111 rc = rc2; 112 } 113 114 while (pUVM->pdm.s.pRwCritSects) 115 { 116 int rc2 = pdmR3CritSectRwDeleteOne(pVM, pUVM, pUVM->pdm.s.pRwCritSects, NULL, true /* final */); 102 117 AssertRC(rc2); 103 118 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) … … 127 142 { 128 143 VM_ASSERT_EMT(pVM); 144 Assert(pCritSect->Core.u32Magic != RTCRITSECT_MAGIC); 129 145 130 146 /* … … 168 184 pCritSect->fUsedByTimerOrSimilar = false; 169 185 pCritSect->EventToSignal = NIL_RTSEMEVENT; 170 pCritSect->pNext = pVM->pUVM->pdm.s.pCritSects;171 186 pCritSect->pszName = pszName; 172 pVM->pUVM->pdm.s.pCritSects = pCritSect; 187 173 188 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLock, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSects/%s/ContentionRZLock", pCritSect->pszName); 174 189 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZUnlock,STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSects/%s/ContentionRZUnlock", pCritSect->pszName); … … 177 192 STAMR3RegisterF(pVM, &pCritSect->StatLocked, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, NULL, "/PDM/CritSects/%s/Locked", pCritSect->pszName); 178 193 #endif 194 195 PUVM pUVM = pVM->pUVM; 196 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 197 pCritSect->pNext = pUVM->pdm.s.pCritSects; 198 pUVM->pdm.s.pCritSects = pCritSect; 199 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 200 179 201 return VINF_SUCCESS; 180 202 } … … 191 213 192 214 /** 215 * Initializes a read/write critical section and inserts it into the list. 216 * 217 * @returns VBox status code. 218 * @param pVM Pointer to the VM. 219 * @param pCritSect The read/write critical section. 220 * @param pvKey The owner key. 221 * @param RT_SRC_POS_DECL The source position. 222 * @param pszName The name of the critical section (for statistics). 223 * @param pszNameFmt Format string for naming the critical section. For 224 * statistics and lock validation. 225 * @param va Arguments for the format string. 226 */ 227 static int pdmR3CritSectRwInitOne(PVM pVM, PPDMCRITSECTRWINT pCritSect, void *pvKey, RT_SRC_POS_DECL, 228 const char *pszNameFmt, va_list va) 229 { 230 VM_ASSERT_EMT(pVM); 231 Assert(pCritSect->Core.u32Magic != RTCRITSECTRW_MAGIC); 232 233 /* 234 * Allocate the semaphores. 235 */ 236 AssertCompile(sizeof(SUPSEMEVENT) == sizeof(pCritSect->Core.hEvtWrite)); 237 int rc = SUPSemEventCreate(pVM->pSession, (PSUPSEMEVENT)&pCritSect->Core.hEvtWrite); 238 if (RT_SUCCESS(rc)) 239 { 240 AssertCompile(sizeof(SUPSEMEVENTMULTI) == sizeof(pCritSect->Core.hEvtRead)); 241 rc = SUPSemEventMultiCreate(pVM->pSession, (PSUPSEMEVENT)&pCritSect->Core.hEvtRead); 242 if (RT_SUCCESS(rc)) 243 { 244 /* Only format the name once. */ 245 char *pszName = RTStrAPrintf2V(pszNameFmt, va); /** @todo plug the "leak"... */ 246 if (pszName) 247 { 248 pCritSect->Core.pValidatorRead = NULL; 249 pCritSect->Core.pValidatorWrite = NULL; 250 #ifdef PDMCRITSECT_STRICT 251 # ifdef RT_LOCK_STRICT_ORDER 252 RTLOCKVALCLASS hClass = RTLockValidatorClassForSrcPos(RT_SRC_POS_ARGS, "%s", pszName); 253 # else 254 RTLOCKVALCLASS hClass = NIL_RTLOCKVALCLASS; 255 # endif 256 rc = RTLockValidatorRecExclCreate(&pCritSect->Core.pValidatorWrite, hClass, RTLOCKVAL_SUB_CLASS_NONE, 257 pCritSect, true, "%s", pszName); 258 if (RT_SUCCESS(rc)) 259 rc = RTLockValidatorRecSharedCreate(&pCritSect->Core.pValidatorRead, hClass, RTLOCKVAL_SUB_CLASS_NONE, 260 pCritSect, false /*fSignaller*/, true, "%s", pszName); 261 #endif 262 if (RT_SUCCESS(rc)) 263 { 264 /* 265 * Initialize the structure (first bit is c&p from RTCritSectRwInitEx). 266 */ 267 pCritSect->Core.u32Magic = RTCRITSECTRW_MAGIC_DEAD; 268 pCritSect->Core.fNeedReset = false; 269 pCritSect->Core.u64State = 0; 270 pCritSect->Core.hNativeWriter = NIL_RTNATIVETHREAD; 271 pCritSect->Core.cWriterReads = 0; 272 pCritSect->Core.cWriteRecursions = 0; 273 pCritSect->Core.pValidatorWrite = NULL; 274 pCritSect->Core.pValidatorRead = NULL; 275 #if HC_ARCH_BITS == 32 276 pCritSect->Core.HCPtrPadding = NIL_RTHCPTR; 277 #endif 278 pCritSect->pVMR3 = pVM; 279 pCritSect->pVMR0 = pVM->pVMR0; 280 pCritSect->pVMRC = pVM->pVMRC; 281 pCritSect->pvKey = pvKey; 282 pCritSect->pszName = pszName; 283 284 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZEnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZEnterExcl", pCritSect->pszName); 285 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLeaveExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZLeaveExcl", pCritSect->pszName); 286 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZEnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZEnterShared", pCritSect->pszName); 287 STAMR3RegisterF(pVM, &pCritSect->StatContentionRZLeaveShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionRZLeaveShared", pCritSect->pszName); 288 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterExcl", pCritSect->pszName); 289 STAMR3RegisterF(pVM, &pCritSect->StatContentionR3EnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/ContentionR3EnterShared", pCritSect->pszName); 290 STAMR3RegisterF(pVM, &pCritSect->StatRZEnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/RZEnterExcl", pCritSect->pszName); 291 STAMR3RegisterF(pVM, &pCritSect->StatRZEnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/RZEnterShared", pCritSect->pszName); 292 STAMR3RegisterF(pVM, &pCritSect->StatR3EnterExcl, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/R3EnterExcl", pCritSect->pszName); 293 STAMR3RegisterF(pVM, &pCritSect->StatR3EnterShared, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, NULL, "/PDM/CritSectsRw/%s/R3EnterShared", pCritSect->pszName); 294 #ifdef VBOX_WITH_STATISTICS 295 STAMR3RegisterF(pVM, &pCritSect->StatWriteLocked, STAMTYPE_PROFILE_ADV, STAMVISIBILITY_ALWAYS, STAMUNIT_TICKS_PER_OCCURENCE, NULL, "/PDM/CritSectsRw/%s/WriteLocked", pCritSect->pszName); 296 #endif 297 298 PUVM pUVM = pVM->pUVM; 299 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 300 pCritSect->pNext = pUVM->pdm.s.pRwCritSects; 301 pUVM->pdm.s.pRwCritSects = pCritSect; 302 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 303 304 return VINF_SUCCESS; 305 } 306 307 RTStrFree(pszName); 308 } 309 else 310 rc = VERR_NO_STR_MEMORY; 311 SUPSemEventMultiClose(pVM->pSession, (SUPSEMEVENT)pCritSect->Core.hEvtRead); 312 } 313 SUPSemEventClose(pVM->pSession, (SUPSEMEVENT)pCritSect->Core.hEvtWrite); 314 } 315 return rc; 316 } 317 318 319 /** 193 320 * Initializes a PDM critical section for internal use. 194 321 * 195 322 * The PDM critical sections are derived from the IPRT critical sections, but 196 * works in GCas well.323 * works in ring-0 and raw-mode context as well. 197 324 * 198 325 * @returns VBox status code. … … 204 331 * statistics and lock validation. 205 332 * @param ... Arguments for the format string. 206 * @thread EMT (0)333 * @thread EMT 207 334 */ 208 335 VMMR3DECL(int) PDMR3CritSectInit(PVM pVM, PPDMCRITSECT pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...) … … 221 348 222 349 /** 350 * Initializes a PDM read/write critical section for internal use. 351 * 352 * The PDM read/write critical sections are derived from the IPRT read/write 353 * critical sections, but works in ring-0 and raw-mode context as well. 354 * 355 * @returns VBox status code. 356 * @param pVM Pointer to the VM. 357 * @param pDevIns Device instance. 358 * @param pCritSect Pointer to the read/write critical section. 359 * @param RT_SRC_POS_DECL Use RT_SRC_POS. 360 * @param pszNameFmt Format string for naming the critical section. For 361 * statistics and lock validation. 362 * @param ... Arguments for the format string. 363 * @thread EMT 364 */ 365 VMMR3DECL(int) PDMR3CritSectRwInit(PVM pVM, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, const char *pszNameFmt, ...) 366 { 367 #if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 32 368 AssertCompile(sizeof(pCritSect->padding) >= sizeof(pCritSect->s)); 369 #endif 370 Assert(RT_ALIGN_P(pCritSect, sizeof(uintptr_t)) == pCritSect); 371 va_list va; 372 va_start(va, pszNameFmt); 373 int rc = pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pCritSect, RT_SRC_POS_ARGS, pszNameFmt, va); 374 va_end(va); 375 return rc; 376 } 377 378 379 /** 223 380 * Initializes a PDM critical section for a device. 224 *225 * The PDM critical sections are derived from the IPRT critical sections, but226 * works in GC as well.227 381 * 228 382 * @returns VBox status code. … … 238 392 { 239 393 return pdmR3CritSectInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va); 394 } 395 396 397 /** 398 * Initializes a PDM read/write critical section for a device. 399 * 400 * @returns VBox status code. 401 * @param pVM Pointer to the VM. 402 * @param pDevIns Device instance. 403 * @param pCritSect Pointer to the read/write critical section. 404 * @param pszNameFmt Format string for naming the critical section. For 405 * statistics and lock validation. 406 * @param va Arguments for the format string. 407 */ 408 int pdmR3CritSectRwInitDevice(PVM pVM, PPDMDEVINS pDevIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 409 const char *pszNameFmt, va_list va) 410 { 411 return pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pDevIns, RT_SRC_POS_ARGS, pszNameFmt, va); 240 412 } 241 413 … … 279 451 va_start(va, pszNameFmt); 280 452 int rc = pdmR3CritSectInitOne(pVM, &pCritSect->s, pDrvIns, RT_SRC_POS_ARGS, pszNameFmt, va); 453 va_end(va); 454 return rc; 455 } 456 457 458 /** 459 * Initializes a PDM read/write critical section for a driver. 460 * 461 * @returns VBox status code. 462 * @param pVM Pointer to the VM. 463 * @param pDrvIns Driver instance. 464 * @param pCritSect Pointer to the read/write critical section. 465 * @param pszNameFmt Format string for naming the critical section. For 466 * statistics and lock validation. 467 * @param ... Arguments for the format string. 468 */ 469 int pdmR3CritSectRwInitDriver(PVM pVM, PPDMDRVINS pDrvIns, PPDMCRITSECTRW pCritSect, RT_SRC_POS_DECL, 470 const char *pszNameFmt, ...) 471 { 472 va_list va; 473 va_start(va, pszNameFmt); 474 int rc = pdmR3CritSectRwInitOne(pVM, &pCritSect->s, pDrvIns, RT_SRC_POS_ARGS, pszNameFmt, va); 281 475 va_end(va); 282 476 return rc; … … 349 543 350 544 /** 545 * Deletes one read/write critical section. 546 * 547 * @returns VBox status code. 548 * 549 * @param pVM Pointer to the VM. 550 * @param pCritSect The read/write critical section. 551 * @param pPrev The previous critical section in the list. 552 * @param fFinal Set if this is the final call and statistics shouldn't be deregistered. 553 * 554 * @remarks Caller must have entered the ListCritSect. 555 */ 556 static int pdmR3CritSectRwDeleteOne(PVM pVM, PUVM pUVM, PPDMCRITSECTRWINT pCritSect, PPDMCRITSECTRWINT pPrev, bool fFinal) 557 { 558 /* 559 * Assert free waiters and so on (c&p from RTCritSectRwDelete). 560 */ 561 Assert(pCritSect->Core.u32Magic == RTCRITSECTRW_MAGIC); 562 //Assert(pCritSect->Core.cNestings == 0); 563 //Assert(pCritSect->Core.cLockers == -1); 564 Assert(pCritSect->Core.hNativeWriter == NIL_RTNATIVETHREAD); 565 566 /* 567 * Invalidate the structure and free the semaphores. 568 */ 569 if (!ASMAtomicCmpXchgU32(&pCritSect->Core.u32Magic, RTCRITSECTRW_MAGIC_DEAD, RTCRITSECTRW_MAGIC)) 570 AssertFailed(); 571 572 /* 573 * Unlink it. 574 */ 575 if (pPrev) 576 pPrev->pNext = pCritSect->pNext; 577 else 578 pUVM->pdm.s.pRwCritSects = pCritSect->pNext; 579 580 /* 581 * Delete it (parts taken from RTCritSectRwDelete). 582 * In case someone is waiting we'll signal the semaphore cLockers + 1 times. 583 */ 584 pCritSect->Core.fFlags = 0; 585 pCritSect->Core.u64State = 0; 586 587 SUPSEMEVENT hEvtWrite = (SUPSEMEVENT)pCritSect->Core.hEvtWrite; 588 pCritSect->Core.hEvtWrite = NIL_RTSEMEVENT; 589 AssertCompile(sizeof(hEvtWrite) == sizeof(pCritSect->Core.hEvtWrite)); 590 591 SUPSEMEVENTMULTI hEvtRead = (SUPSEMEVENTMULTI)pCritSect->Core.hEvtRead; 592 pCritSect->Core.hEvtRead = NIL_RTSEMEVENTMULTI; 593 AssertCompile(sizeof(hEvtRead) == sizeof(pCritSect->Core.hEvtRead)); 594 595 int rc1 = SUPSemEventClose(pVM->pSession, hEvtWrite); AssertRC(rc1); 596 int rc2 = SUPSemEventMultiClose(pVM->pSession, hEvtRead); AssertRC(rc2); 597 598 RTLockValidatorRecSharedDestroy(&pCritSect->Core.pValidatorRead); 599 RTLockValidatorRecExclDestroy(&pCritSect->Core.pValidatorWrite); 600 601 pCritSect->pNext = NULL; 602 pCritSect->pvKey = NULL; 603 pCritSect->pVMR3 = NULL; 604 pCritSect->pVMR0 = NIL_RTR0PTR; 605 pCritSect->pVMRC = NIL_RTRCPTR; 606 RTStrFree((char *)pCritSect->pszName); 607 pCritSect->pszName = NULL; 608 if (!fFinal) 609 { 610 STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterExcl); 611 STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveExcl); 612 STAMR3Deregister(pVM, &pCritSect->StatContentionRZEnterShared); 613 STAMR3Deregister(pVM, &pCritSect->StatContentionRZLeaveShared); 614 STAMR3Deregister(pVM, &pCritSect->StatRZEnterExcl); 615 STAMR3Deregister(pVM, &pCritSect->StatRZEnterShared); 616 STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterExcl); 617 STAMR3Deregister(pVM, &pCritSect->StatContentionR3EnterShared); 618 STAMR3Deregister(pVM, &pCritSect->StatR3EnterExcl); 619 STAMR3Deregister(pVM, &pCritSect->StatR3EnterShared); 620 #ifdef VBOX_WITH_STATISTICS 621 STAMR3Deregister(pVM, &pCritSect->StatWriteLocked); 622 #endif 623 } 624 625 return RT_SUCCESS(rc1) ? rc2 : rc1; 626 } 627 628 629 /** 351 630 * Deletes all critical sections with a give initializer key. 352 631 * … … 388 667 389 668 /** 390 * Deletes all undeleted critical sections initialized by a given device. 669 * Deletes all read/write critical sections with a give initializer key. 670 * 671 * @returns VBox status code. 672 * The entire list is processed on failure, so we'll only 673 * return the first error code. This shouldn't be a problem 674 * since errors really shouldn't happen here. 675 * @param pVM Pointer to the VM. 676 * @param pvKey The initializer key. 677 */ 678 static int pdmR3CritSectRwDeleteByKey(PVM pVM, void *pvKey) 679 { 680 /* 681 * Iterate the list and match key. 682 */ 683 PUVM pUVM = pVM->pUVM; 684 int rc = VINF_SUCCESS; 685 PPDMCRITSECTRWINT pPrev = NULL; 686 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 687 PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 688 while (pCur) 689 { 690 if (pCur->pvKey == pvKey) 691 { 692 int rc2 = pdmR3CritSectRwDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); 693 AssertRC(rc2); 694 if (RT_FAILURE(rc2) && RT_SUCCESS(rc)) 695 rc = rc2; 696 } 697 698 /* next */ 699 pPrev = pCur; 700 pCur = pCur->pNext; 701 } 702 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 703 return rc; 704 } 705 706 707 /** 708 * Deletes all undeleted critical sections (both types) initialized by a given 709 * device. 391 710 * 392 711 * @returns VBox status code. … … 394 713 * @param pDevIns The device handle. 395 714 */ 396 int pdmR3CritSectDeleteDevice(PVM pVM, PPDMDEVINS pDevIns) 397 { 398 return pdmR3CritSectDeleteByKey(pVM, pDevIns); 399 } 400 401 402 /** 403 * Deletes all undeleted critical sections initialized by a given driver. 715 int pdmR3CritSectBothDeleteDevice(PVM pVM, PPDMDEVINS pDevIns) 716 { 717 int rc1 = pdmR3CritSectDeleteByKey(pVM, pDevIns); 718 int rc2 = pdmR3CritSectRwDeleteByKey(pVM, pDevIns); 719 return RT_SUCCESS(rc1) ? rc2 : rc1; 720 } 721 722 723 /** 724 * Deletes all undeleted critical sections (both types) initialized by a given 725 * driver. 404 726 * 405 727 * @returns VBox status code. … … 407 729 * @param pDrvIns The driver handle. 408 730 */ 409 int pdmR3CritSectDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns) 410 { 411 return pdmR3CritSectDeleteByKey(pVM, pDrvIns); 731 int pdmR3CritSectBothDeleteDriver(PVM pVM, PPDMDRVINS pDrvIns) 732 { 733 int rc1 = pdmR3CritSectDeleteByKey(pVM, pDrvIns); 734 int rc2 = pdmR3CritSectRwDeleteByKey(pVM, pDrvIns); 735 return RT_SUCCESS(rc1) ? rc2 : rc1; 412 736 } 413 737 … … 453 777 454 778 /** 779 * Deletes the read/write critical section. 780 * 781 * @returns VBox status code. 782 * @param pCritSect The PDM read/write critical section to destroy. 783 */ 784 VMMR3DECL(int) PDMR3CritSectRwDelete(PPDMCRITSECTRW pCritSect) 785 { 786 if (!PDMCritSectRwIsInitialized(pCritSect)) 787 return VINF_SUCCESS; 788 789 /* 790 * Find and unlink it. 791 */ 792 PVM pVM = pCritSect->s.pVMR3; 793 PUVM pUVM = pVM->pUVM; 794 AssertReleaseReturn(pVM, VERR_PDM_CRITSECT_IPE); 795 PPDMCRITSECTRWINT pPrev = NULL; 796 RTCritSectEnter(&pUVM->pdm.s.ListCritSect); 797 PPDMCRITSECTRWINT pCur = pUVM->pdm.s.pRwCritSects; 798 while (pCur) 799 { 800 if (pCur == &pCritSect->s) 801 { 802 int rc = pdmR3CritSectRwDeleteOne(pVM, pUVM, pCur, pPrev, false /* not final */); 803 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 804 return rc; 805 } 806 807 /* next */ 808 pPrev = pCur; 809 pCur = pCur->pNext; 810 } 811 RTCritSectLeave(&pUVM->pdm.s.ListCritSect); 812 AssertReleaseMsgFailed(("pCritSect=%p wasn't found!\n", pCritSect)); 813 return VERR_PDM_CRITSECT_NOT_FOUND; 814 } 815 816 817 /** 455 818 * Gets the name of the critical section. 456 819 * … … 464 827 AssertPtrReturn(pCritSect, NULL); 465 828 AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECT_MAGIC, NULL); 829 return pCritSect->s.pszName; 830 } 831 832 833 /** 834 * Gets the name of the read/write critical section. 835 * 836 * 837 * @returns Pointer to the critical section name (read only) on success, 838 * NULL on failure (invalid critical section). 839 * @param pCritSect The read/write critical section. 840 */ 841 VMMR3DECL(const char *) PDMR3CritSectRwName(PCPDMCRITSECTRW pCritSect) 842 { 843 AssertPtrReturn(pCritSect, NULL); 844 AssertReturn(pCritSect->s.Core.u32Magic == RTCRITSECTRW_MAGIC, NULL); 466 845 return pCritSect->s.pszName; 467 846 } … … 557 936 558 937 /** 559 * Counts the critical sections owned by the calling thread, optionally 560 * returning a comma separated list naming them. 938 * PDMR3CritSectBothCountOwned worker. 939 * 940 * @param pszName The critical section name. 941 * @param ppszNames Pointer to the pszNames variable. 942 * @param pcchLeft Pointer to the cchLeft variable. 943 * @param fFirst Whether this is the first name or not. 944 */ 945 static void pdmR3CritSectAppendNameToList(char const *pszName, char **ppszNames, size_t *pcchLeft, bool fFirst) 946 { 947 size_t cchLeft = *pcchLeft; 948 if (cchLeft) 949 { 950 char *pszNames = *ppszNames; 951 952 /* try add comma. */ 953 if (fFirst) 954 { 955 *pszNames++ = ','; 956 if (--cchLeft) 957 { 958 *pszNames++ = ' '; 959 cchLeft--; 960 } 961 } 962 963 /* try copy the name. */ 964 if (cchLeft) 965 { 966 size_t const cchName = strlen(pszName); 967 if (cchName < cchLeft) 968 { 969 memcpy(pszNames, pszName, cchName); 970 pszNames += cchName; 971 cchLeft -= cchName; 972 } 973 else 974 { 975 if (cchLeft > 2) 976 { 977 memcpy(pszNames, pszName, cchLeft - 2); 978 pszNames += cchLeft - 2; 979 cchLeft = 2; 980 } 981 while (cchLeft-- > 0) 982 *pszNames++ = '+'; 983 } 984 } 985 *pszNames = '\0'; 986 987 *pcchLeft = cchLeft; 988 *ppszNames = pszNames; 989 } 990 } 991 992 993 /** 994 * Counts the critical sections (both type) owned by the calling thread, 995 * optionally returning a comma separated list naming them. 996 * 997 * Read ownerships are not included in non-strict builds. 561 998 * 562 999 * This is for diagnostic purposes only. … … 583 1020 * Iterate the critical sections. 584 1021 */ 1022 uint32_t cCritSects = 0; 1023 RTNATIVETHREAD const hNativeThread = RTThreadNativeSelf(); 585 1024 /* This is unsafe, but wtf. */ 586 RTNATIVETHREAD const hNativeThread = RTThreadNativeSelf();587 uint32_t cCritSects = 0;588 1025 for (PPDMCRITSECTINT pCur = pVM->pUVM->pdm.s.pCritSects; 589 1026 pCur; … … 594 1031 { 595 1032 cCritSects++; 596 597 /* 598 * Copy the name if there is space. Fun stuff. 599 */ 600 if (cchLeft) 601 { 602 /* try add comma. */ 603 if (cCritSects != 1) 604 { 605 *pszNames++ = ','; 606 if (--cchLeft) 607 { 608 *pszNames++ = ' '; 609 cchLeft--; 610 } 611 } 612 613 /* try copy the name. */ 614 if (cchLeft) 615 { 616 size_t const cchName = strlen(pCur->pszName); 617 if (cchName < cchLeft) 618 { 619 memcpy(pszNames, pCur->pszName, cchName); 620 pszNames += cchName; 621 cchLeft -= cchName; 622 } 623 else 624 { 625 if (cchLeft > 2) 626 { 627 memcpy(pszNames, pCur->pszName, cchLeft - 2); 628 pszNames += cchLeft - 2; 629 cchLeft = 2; 630 } 631 while (cchLeft-- > 0) 632 *pszNames++ = '+'; 633 } 634 } 635 *pszNames = '\0'; 636 } 1033 pdmR3CritSectAppendNameToList(pCur->pszName, &pszNames, &cchLeft, cCritSects == 1); 1034 } 1035 } 1036 1037 /* This is unsafe, but wtf. */ 1038 for (PPDMCRITSECTRWINT pCur = pVM->pUVM->pdm.s.pRwCritSects; 1039 pCur; 1040 pCur = pCur->pNext) 1041 { 1042 if ( pCur->Core.hNativeWriter == hNativeThread 1043 || PDMCritSectRwIsReadOwner((PPDMCRITSECTRW)pCur, false /*fWannaHear*/) ) 1044 { 1045 cCritSects++; 1046 pdmR3CritSectAppendNameToList(pCur->pszName, &pszNames, &cchLeft, cCritSects == 1); 637 1047 } 638 1048 } … … 650 1060 * @param pVM Pointer to the VM. 651 1061 */ 652 VMMR3 DECL(void) PDMR3CritSectLeaveAll(PVM pVM)1062 VMMR3_INT_DECL(void) PDMR3CritSectLeaveAll(PVM pVM) 653 1063 { 654 1064 RTNATIVETHREAD const hNativeSelf = RTThreadNativeSelf(); -
trunk/src/VBox/VMM/VMMR3/PDMDriver.cpp
r44358 r45152 962 962 963 963 /* PDM critsects. */ 964 rc = pdmR3CritSect DeleteDriver(pVM, pCur);964 rc = pdmR3CritSectBothDeleteDriver(pVM, pCur); 965 965 AssertRC(rc); 966 966 -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r45024 r45152 781 781 * references to it are still working. 782 782 */ 783 PDMR3CritSect Term(pVM);783 PDMR3CritSectBothTerm(pVM); 784 784 785 785 /* … … 2440 2440 AssertRC(rc); 2441 2441 SSMR3Term(pVM); 2442 rc = PDMR3CritSect Term(pVM);2442 rc = PDMR3CritSectBothTerm(pVM); 2443 2443 AssertRC(rc); 2444 2444 rc = MMR3Term(pVM); -
trunk/src/VBox/VMM/VMMR3/VMM.cpp
r44971 r45152 2098 2098 */ 2099 2099 if (VMCPU_FF_ISPENDING(pVCpu, VMCPU_FF_PDM_CRITSECT)) 2100 PDMCritSect FF(pVCpu);2100 PDMCritSectBothFF(pVCpu); 2101 2101 2102 2102 switch (pVCpu->vmm.s.enmCallRing3Operation)
Note:
See TracChangeset
for help on using the changeset viewer.