Changeset 98088 in vbox
- Timestamp:
- Jan 16, 2023 12:57:07 AM (23 months ago)
- Location:
- trunk/src/VBox/Main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/include/ConsoleImpl.h
r98086 r98088 1068 1068 /** @name LEDs and their management 1069 1069 * @{ */ 1070 /** Read/write lock separating LED allocations (write) from queries (read). */ 1071 RWLockHandle mLedLock; 1070 1072 /** Number of LED sets in use in maLedSets. */ 1071 1073 uint32_t mcLedSets; -
trunk/src/VBox/Main/src-client/ConsoleImpl.cpp
r98086 r98088 427 427 #endif 428 428 , mBusMgr(NULL) 429 , mLedLock(LOCKCLASS_LISTOFOTHEROBJECTS /* must be higher than LOCKCLASS_OTHEROBJECT */) 429 430 , m_pKeyStore(NULL) 430 431 , mpIfSecKey(NULL) … … 879 880 } 880 881 881 /* Release memory held by the LED sets . */882 /* Release memory held by the LED sets (no need to take lock). */ 882 883 for (size_t idxSet = 0; idxSet < mcLedSets; idxSet++) 883 884 { 884 885 RTMemFree(maLedSets[idxSet].papLeds); 885 RTMemFree(maLedSets[idxSet].paSubTypes);886 886 maLedSets[idxSet].papLeds = NULL; 887 887 maLedSets[idxSet].paSubTypes = NULL; … … 2828 2828 { 2829 2829 /* 2830 * Note: we don't lock the console object here because2831 * readAndClearLed() should be thread safe.2832 */2833 /** @todo r=bird: readAndClearLed is safe, provided that we're not running at the2834 * same time as Console::i_allocateDriverLeds. This assumption is not correct2835 * during VM construction. */2836 2837 /*2838 2830 * Make a roadmap of which DeviceType_T LED types are wanted: 2839 2831 */ … … 2854 2846 /* 2855 2847 * Collect all the LEDs in a single sweep through all drivers' sets: 2848 * 2849 * Because this method can be called by the frontend and others while the 2850 * VM is being constructed, we use a dedicated lock to prevent stumbling 2851 * into the allocator. 2856 2852 */ 2857 2853 PDMLEDCORE aLEDs[DeviceType_End] = { {0} }; 2858 2854 Assert(aLEDs[1].u32 == 0 && aLEDs[DeviceType_End / 2].u32 == 0 && aLEDs[DeviceType_End - 1].u32 == 0); /* paranoia */ 2859 uint32_t idxSet = mcLedSets; 2860 while (idxSet-- > 0) 2861 { 2862 /* Look inside this driver's set of LEDs and check if the types mask overlap with the request: */ 2863 PLEDSET pLS = &maLedSets[idxSet]; 2864 if (pLS->fTypes & fWanted) 2865 { 2866 uint32_t const cLeds = pLS->cLeds; 2867 PPDMLED const * const papSrcLeds = pLS->papLeds; 2868 2869 /* Multi-type drivers (e.g. SCSI) have a subtype array which must be matched. */ 2870 DeviceType_T const *paSubTypes = pLS->paSubTypes; 2871 if (paSubTypes) 2872 for (uint32_t idxLed = 0; idxLed < cLeds; idxLed++) 2855 { 2856 AutoReadLock alock(mLedLock COMMA_LOCKVAL_SRC_POS); 2857 uint32_t idxSet = mcLedSets; 2858 while (idxSet-- > 0) 2859 { 2860 /* Look inside this driver's set of LEDs and check if the types mask overlap with the request: */ 2861 PLEDSET pLS = &maLedSets[idxSet]; 2862 if (pLS->fTypes & fWanted) 2863 { 2864 uint32_t const cLeds = pLS->cLeds; 2865 PPDMLED const * const papSrcLeds = pLS->papLeds; 2866 2867 /* Multi-type drivers (e.g. SCSI) have a subtype array which must be matched. */ 2868 DeviceType_T const *paSubTypes = pLS->paSubTypes; 2869 if (paSubTypes) 2870 for (uint32_t idxLed = 0; idxLed < cLeds; idxLed++) 2871 { 2872 DeviceType_T const enmType = paSubTypes[idxLed]; 2873 Assert((unsigned)enmType < (unsigned)DeviceType_End); 2874 if (fWanted & RT_BIT_32((unsigned)enmType)) 2875 aLEDs[enmType].u32 |= readAndClearLed(papSrcLeds[idxLed]); 2876 } 2877 /* Single-type drivers (e.g. floppy) have the type in ->enmType */ 2878 else 2873 2879 { 2874 DeviceType_T const enmType = paSubTypes[idxLed]; 2875 Assert((unsigned)enmType < (unsigned)DeviceType_End); 2876 if (fWanted & RT_BIT_32((unsigned)enmType)) 2877 aLEDs[enmType].u32 |= readAndClearLed(papSrcLeds[idxLed]); 2880 uint32_t const idxType = ASMBitFirstSetU32(pLS->fTypes) - 1; 2881 for (uint32_t idxLed = 0; idxLed < cLeds; idxLed++) 2882 aLEDs[idxType].u32 |= readAndClearLed(papSrcLeds[idxLed]); 2878 2883 } 2879 /* Single-type drivers (e.g. floppy) have the type in ->enmType */2880 else2881 {2882 uint32_t const idxType = ASMBitFirstSetU32(pLS->fTypes) - 1;2883 for (uint32_t idxLed = 0; idxLed < cLeds; idxLed++)2884 aLEDs[idxType].u32 |= readAndClearLed(papSrcLeds[idxLed]);2885 2884 } 2886 2885 } -
trunk/src/VBox/Main/src-client/ConsoleImpl2.cpp
r98086 r98088 674 674 Assert(!(fTypes & (RT_BIT_32(DeviceType_Null) | ~(RT_BIT_32(DeviceType_End) - 1)))); 675 675 676 /* Grab a LED set entry before we start allocating anything so the destructor can do the cleanups. */ 677 AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS); /* Caller should have this already. Need protect mcLedSets check and update. */ 678 AssertStmt(mcLedSets < RT_ELEMENTS(maLedSets), 679 throw ConfigError("AllocateDriverPapLeds", VERR_OUT_OF_RANGE, "Too many LED sets")); 680 uint32_t const idxLedSet = mcLedSets++; 681 PLEDSET pLS = &maLedSets[idxLedSet]; 682 pLS->papLeds = (PPDMLED *)RTMemAllocZ(sizeof(PPDMLED) * cLeds); 683 AssertStmt(pLS->papLeds, throw E_OUTOFMEMORY); 684 pLS->cLeds = cLeds; 685 pLS->fTypes = fTypes; 686 pLS->paSubTypes = NULL; 687 688 if (ppaSubTypes) 676 /* Preallocate the arrays we need, bunching them together. */ 677 AssertCompile((unsigned)DeviceType_Null == 0); 678 PPDMLED *papLeds = (PPDMLED *)RTMemAllocZ((sizeof(PPDMLED) + (ppaSubTypes ? sizeof(**ppaSubTypes) : 0)) * cLeds); 679 AssertStmt(papLeds, throw E_OUTOFMEMORY); 680 681 /* Take the LED lock in allocation mode and see if there are more LED set entries availalbe. */ 689 682 { 690 AssertCompile((unsigned)DeviceType_Null == 0); 691 *ppaSubTypes = pLS->paSubTypes = (DeviceType_T *)RTMemAllocZ(sizeof(DeviceType_T) * cLeds); 692 AssertStmt(pLS->paSubTypes, throw E_OUTOFMEMORY); 683 AutoWriteLock alock(mLedLock COMMA_LOCKVAL_SRC_POS); 684 uint32_t const idxLedSet = mcLedSets; 685 if (idxLedSet < RT_ELEMENTS(maLedSets)) 686 { 687 /* Initialize the set and return the index. */ 688 PLEDSET pLS = &maLedSets[idxLedSet]; 689 pLS->papLeds = papLeds; 690 pLS->cLeds = cLeds; 691 pLS->fTypes = fTypes; 692 if (ppaSubTypes) 693 *ppaSubTypes = pLS->paSubTypes = (DeviceType_T *)&papLeds[cLeds]; 694 else 695 pLS->paSubTypes = NULL; 696 697 mcLedSets = idxLedSet + 1; 698 LogRel2(("return idxLedSet=%d (mcLedSets=%u out of max %zu)\n", idxLedSet, mcLedSets, RT_ELEMENTS(maLedSets))); 699 return idxLedSet; 700 } 693 701 } 694 702 695 LogRel2(("mcLedSets = %d, RT_ELEMENTS(maLedSets) = %d\n", mcLedSets, RT_ELEMENTS(maLedSets))); 696 return idxLedSet; 703 RTMemFree(papLeds); 704 AssertFailed(); 705 throw ConfigError("AllocateDriverPapLeds", VERR_OUT_OF_RANGE, "Too many LED sets"); 697 706 } 698 707
Note:
See TracChangeset
for help on using the changeset viewer.