2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 /* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
27 #include <libkern/OSReturn.h>
29 #include <libkern/c++/OSMetaClass.h>
31 #include <libkern/c++/OSObject.h>
32 #include <libkern/c++/OSCollectionIterator.h>
33 #include <libkern/c++/OSDictionary.h>
34 #include <libkern/c++/OSArray.h>
35 #include <libkern/c++/OSSet.h>
36 #include <libkern/c++/OSSymbol.h>
37 #include <libkern/c++/OSNumber.h>
38 #include <libkern/c++/OSSerialize.h>
39 #include <libkern/c++/OSLib.h>
40 #include <libkern/OSAtomic.h>
44 #include <sys/systm.h>
45 #include <mach/mach_types.h>
46 #include <kern/lock.h>
47 #include <kern/clock.h>
48 #include <kern/thread_call.h>
49 #include <kern/host.h>
50 #include <mach/kmod.h>
51 #include <mach/mach_interface.h>
53 extern void OSRuntimeUnloadCPP(kmod_info_t
*ki
, void *);
56 extern int debug_container_malloc_size
;
57 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
60 #endif /* OSALLOCDEBUG */
65 kCompletedBootstrap
= 0,
67 kMakingDictionaries
= 2
68 } sBootstrapState
= kNoDictionaries
;
70 static const int kClassCapacityIncrement
= 40;
71 static const int kKModCapacityIncrement
= 10;
72 static OSDictionary
*sAllClassesDict
, *sKModClassesDict
, *sSortedByClassesDict
;
74 static mutex_t
*loadLock
;
75 static struct StalledData
{
78 unsigned int capacity
;
80 OSMetaClass
**classes
;
83 static unsigned int sConsiderUnloadDelay
= 60; /* secs */
85 static const char OSMetaClassBasePanicMsg
[] =
86 "OSMetaClassBase::_RESERVEDOSMetaClassBase%d called\n";
89 void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
90 { panic(OSMetaClassBasePanicMsg
, 0); }
91 void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
92 { panic(OSMetaClassBasePanicMsg
, 1); }
93 void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
94 { panic(OSMetaClassBasePanicMsg
, 2); }
95 #endif /* SLOT_USED */
97 // As these slots are used move them up inside the #if above
98 void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
99 { panic(OSMetaClassBasePanicMsg
, 3); }
100 void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
101 { panic(OSMetaClassBasePanicMsg
, 4); }
102 void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
103 { panic(OSMetaClassBasePanicMsg
, 5); }
104 void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
105 { panic(OSMetaClassBasePanicMsg
, 6); }
108 * These used to be inline in the header but gcc didn't believe us
109 * Now we MUST pull the inline out at least until the compiler is
112 // Helper inlines for runtime type preprocessor macros
113 OSMetaClassBase
*OSMetaClassBase::
114 safeMetaCast(const OSMetaClassBase
*me
, const OSMetaClass
*toType
)
115 { return (me
)? me
->metaCast(toType
) : 0; }
117 bool OSMetaClassBase::
118 checkTypeInst(const OSMetaClassBase
*inst
, const OSMetaClassBase
*typeinst
)
120 const OSMetaClass
*toType
= OSTypeIDInst(typeinst
);
121 return typeinst
&& inst
&& (0 != inst
->metaCast(toType
));
125 // If you need this slot you had better setup an IOCTL style interface.
126 // 'Cause the whole kernel world depends on OSMetaClassBase and YOU
127 // CANT change the VTABLE size ever.
128 void OSMetaClassBase::_RESERVEDOSMetaClassBase7()
129 { panic(OSMetaClassBasePanicMsg
, 7); }
131 OSMetaClassBase::OSMetaClassBase()
135 OSMetaClassBase::~OSMetaClassBase()
139 thisVTable
= (void **) this;
140 *thisVTable
= (void *) -1UL;
143 bool OSMetaClassBase::isEqualTo(const OSMetaClassBase
*anObj
) const
145 return this == anObj
;
148 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSMetaClass
*toMeta
) const
150 return toMeta
->checkMetaCast(this);
153 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSSymbol
*toMetaSymb
) const
155 return OSMetaClass::checkMetaCastWithName(toMetaSymb
, this);
158 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSString
*toMetaStr
) const
160 const OSSymbol
*tempSymb
= OSSymbol::withString(toMetaStr
);
161 OSMetaClassBase
*ret
= 0;
163 ret
= metaCast(tempSymb
);
169 OSMetaClassBase
*OSMetaClassBase::metaCast(const char *toMetaCStr
) const
171 const OSSymbol
*tempSymb
= OSSymbol::withCString(toMetaCStr
);
172 OSMetaClassBase
*ret
= 0;
174 ret
= metaCast(tempSymb
);
180 class OSMetaClassMeta
: public OSMetaClass
184 OSObject
*alloc() const;
186 OSMetaClassMeta::OSMetaClassMeta()
187 : OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass
))
189 OSObject
*OSMetaClassMeta::alloc() const { return 0; }
191 static OSMetaClassMeta sOSMetaClassMeta
;
193 const OSMetaClass
* const OSMetaClass::metaClass
= &sOSMetaClassMeta
;
194 const OSMetaClass
* OSMetaClass::getMetaClass() const
195 { return &sOSMetaClassMeta
; }
197 static const char OSMetaClassPanicMsg
[] =
198 "OSMetaClass::_RESERVEDOSMetaClass%d called\n";
200 void OSMetaClass::_RESERVEDOSMetaClass0()
201 { panic(OSMetaClassPanicMsg
, 0); }
202 void OSMetaClass::_RESERVEDOSMetaClass1()
203 { panic(OSMetaClassPanicMsg
, 1); }
204 void OSMetaClass::_RESERVEDOSMetaClass2()
205 { panic(OSMetaClassPanicMsg
, 2); }
206 void OSMetaClass::_RESERVEDOSMetaClass3()
207 { panic(OSMetaClassPanicMsg
, 3); }
208 void OSMetaClass::_RESERVEDOSMetaClass4()
209 { panic(OSMetaClassPanicMsg
, 4); }
210 void OSMetaClass::_RESERVEDOSMetaClass5()
211 { panic(OSMetaClassPanicMsg
, 5); }
212 void OSMetaClass::_RESERVEDOSMetaClass6()
213 { panic(OSMetaClassPanicMsg
, 6); }
214 void OSMetaClass::_RESERVEDOSMetaClass7()
215 { panic(OSMetaClassPanicMsg
, 7); }
217 void OSMetaClass::logError(OSReturn result
)
222 case kOSMetaClassNoInit
:
223 msg
="OSMetaClass::preModLoad wasn't called, runtime internal error";
225 case kOSMetaClassNoDicts
:
226 msg
="Allocation failure for Metaclass internal dictionaries"; break;
227 case kOSMetaClassNoKModSet
:
228 msg
="Allocation failure for internal kmodule set"; break;
229 case kOSMetaClassNoInsKModSet
:
230 msg
="Can't insert the KMod set into the module dictionary"; break;
231 case kOSMetaClassDuplicateClass
:
232 msg
="Duplicate class"; break;
233 case kOSMetaClassNoSuper
:
234 msg
="Can't associate a class with its super class"; break;
235 case kOSMetaClassInstNoSuper
:
236 msg
="Instance construction, unknown super class."; break;
238 case kOSMetaClassInternal
:
239 msg
="runtime internal error"; break;
240 case kOSReturnSuccess
:
246 OSMetaClass::OSMetaClass(const char *inClassName
,
247 const OSMetaClass
*inSuperClass
,
248 unsigned int inClassSize
)
251 classSize
= inClassSize
;
252 superClassLink
= inSuperClass
;
254 className
= (const OSSymbol
*) inClassName
;
257 printf("OSMetaClass::preModLoad wasn't called for %s, "
258 "runtime internal error\n", inClassName
);
259 } else if (!sStalled
->result
) {
260 // Grow stalled array if neccessary
261 if (sStalled
->count
>= sStalled
->capacity
) {
262 OSMetaClass
**oldStalled
= sStalled
->classes
;
263 int oldSize
= sStalled
->capacity
* sizeof(OSMetaClass
*);
264 int newSize
= oldSize
265 + kKModCapacityIncrement
* sizeof(OSMetaClass
*);
267 sStalled
->classes
= (OSMetaClass
**) kalloc(newSize
);
268 if (!sStalled
->classes
) {
269 sStalled
->classes
= oldStalled
;
270 sStalled
->result
= kOSMetaClassNoTempData
;
274 sStalled
->capacity
+= kKModCapacityIncrement
;
275 memmove(sStalled
->classes
, oldStalled
, oldSize
);
276 kfree((vm_offset_t
)oldStalled
, oldSize
);
277 ACCUMSIZE(newSize
- oldSize
);
280 sStalled
->classes
[sStalled
->count
++] = this;
284 OSMetaClass::~OSMetaClass()
287 OSCollectionIterator
*iter
;
289 if (sAllClassesDict
) {
290 sAllClassesDict
->removeObject(className
);
291 className
->release();
294 iter
= OSCollectionIterator::withCollection(sKModClassesDict
);
299 while ( (iterKey
= (OSSymbol
*) iter
->getNextObject()) ) {
301 kmodClassSet
= (OSSet
*) sKModClassesDict
->getObject(iterKey
);
302 if (kmodClassSet
&& kmodClassSet
->containsObject(this)) {
303 kmodClassSet
->removeObject(this);
313 // First pass find class in stalled list
314 for (i
= 0; i
< sStalled
->count
; i
++)
315 if (this == sStalled
->classes
[i
])
318 if (i
< sStalled
->count
) {
320 if (i
< sStalled
->count
)
321 memmove(&sStalled
->classes
[i
], &sStalled
->classes
[i
+1],
322 (sStalled
->count
- i
) * sizeof(OSMetaClass
*));
327 void *OSMetaClass::operator new(size_t size
) { return 0; }
328 void OSMetaClass::retain() const { }
329 void OSMetaClass::release() const { }
330 void OSMetaClass::release(int when
) const { }
331 void OSMetaClass::taggedRetain(const void *tag
) const { }
332 void OSMetaClass::taggedRelease(const void *tag
) const { }
333 void OSMetaClass::taggedRelease(const void *tag
, const int when
) const { }
334 int OSMetaClass::getRetainCount() const { return 0; }
336 const char *OSMetaClass::getClassName() const
338 return className
->getCStringNoCopy();
341 unsigned int OSMetaClass::getClassSize() const
346 void *OSMetaClass::preModLoad(const char *kmodName
)
349 loadLock
= mutex_alloc(0);
350 mutex_lock(loadLock
);
353 mutex_lock(loadLock
);
355 sStalled
= (StalledData
*) kalloc(sizeof(*sStalled
));
357 sStalled
->classes
= (OSMetaClass
**)
358 kalloc(kKModCapacityIncrement
* sizeof(OSMetaClass
*));
359 if (!sStalled
->classes
) {
360 kfree((vm_offset_t
) sStalled
, sizeof(*sStalled
));
363 ACCUMSIZE((kKModCapacityIncrement
* sizeof(OSMetaClass
*)) + sizeof(*sStalled
));
365 sStalled
->result
= kOSReturnSuccess
;
366 sStalled
->capacity
= kKModCapacityIncrement
;
368 sStalled
->kmodName
= kmodName
;
369 bzero(sStalled
->classes
, kKModCapacityIncrement
* sizeof(OSMetaClass
*));
375 bool OSMetaClass::checkModLoad(void *loadHandle
)
377 return sStalled
&& loadHandle
== sStalled
378 && sStalled
->result
== kOSReturnSuccess
;
381 OSReturn
OSMetaClass::postModLoad(void *loadHandle
)
383 OSReturn result
= kOSReturnSuccess
;
385 OSSymbol
*myname
= 0;
387 if (!sStalled
|| loadHandle
!= sStalled
) {
388 logError(kOSMetaClassInternal
);
389 return kOSMetaClassInternal
;
392 if (sStalled
->result
)
393 result
= sStalled
->result
;
394 else switch (sBootstrapState
) {
395 case kNoDictionaries
:
396 sBootstrapState
= kMakingDictionaries
;
397 // No break; fall through
399 case kMakingDictionaries
:
400 sKModClassesDict
= OSDictionary::withCapacity(kKModCapacityIncrement
);
401 sAllClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
402 sSortedByClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
403 if (!sAllClassesDict
|| !sKModClassesDict
|| !sSortedByClassesDict
) {
404 result
= kOSMetaClassNoDicts
;
407 // No break; fall through
409 case kCompletedBootstrap
:
412 myname
= OSSymbol::withCStringNoCopy(sStalled
->kmodName
);
414 if (!sStalled
->count
)
415 break; // Nothing to do so just get out
417 // First pass checking classes aren't already loaded
418 for (i
= 0; i
< sStalled
->count
; i
++) {
419 OSMetaClass
*me
= sStalled
->classes
[i
];
421 if (0 != sAllClassesDict
->getObject((const char *) me
->className
)) {
422 printf("Class \"%s\" is duplicate\n", (const char *) me
->className
);
423 result
= kOSMetaClassDuplicateClass
;
427 if (i
!= sStalled
->count
)
430 kmodSet
= OSSet::withCapacity(sStalled
->count
);
432 result
= kOSMetaClassNoKModSet
;
436 if (!sKModClassesDict
->setObject(myname
, kmodSet
)) {
437 result
= kOSMetaClassNoInsKModSet
;
441 // Second pass symbolling strings and inserting classes in dictionary
442 for (i
= 0; i
< sStalled
->count
; i
++) {
443 OSMetaClass
*me
= sStalled
->classes
[i
];
445 OSSymbol::withCStringNoCopy((const char *) me
->className
);
447 sAllClassesDict
->setObject(me
->className
, me
);
448 kmodSet
->setObject(me
);
449 sSortedByClassesDict
->setObject((const OSSymbol
*)me
, myname
);
451 sBootstrapState
= kCompletedBootstrap
;
456 result
= kOSMetaClassInternal
;
467 ACCUMSIZE(-(sStalled
->capacity
* sizeof(OSMetaClass
*)
468 + sizeof(*sStalled
)));
469 kfree((vm_offset_t
) sStalled
->classes
,
470 sStalled
->capacity
* sizeof(OSMetaClass
*));
471 kfree((vm_offset_t
) sStalled
, sizeof(*sStalled
));
476 mutex_unlock(loadLock
);
481 void OSMetaClass::instanceConstructed() const
483 // if ((0 == OSIncrementAtomic((SInt32 *)&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
484 if ((0 == OSIncrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
485 superClassLink
->instanceConstructed();
488 void OSMetaClass::instanceDestructed() const
490 if ((1 == OSDecrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
491 superClassLink
->instanceDestructed();
493 if( ((int) instanceCount
) < 0)
494 printf("%s: bad retain(%d)", getClassName(), instanceCount
);
497 bool OSMetaClass::modHasInstance(const char *kmodName
)
502 loadLock
= mutex_alloc(0);
503 mutex_lock(loadLock
);
506 mutex_lock(loadLock
);
510 OSCollectionIterator
*iter
;
511 OSMetaClass
*checkClass
;
513 kmodClasses
= OSDynamicCast(OSSet
,
514 sKModClassesDict
->getObject(kmodName
));
518 iter
= OSCollectionIterator::withCollection(kmodClasses
);
522 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
523 if (checkClass
->getInstanceCount()) {
531 mutex_unlock(loadLock
);
536 void OSMetaClass::reportModInstances(const char *kmodName
)
539 OSCollectionIterator
*iter
;
540 OSMetaClass
*checkClass
;
542 kmodClasses
= OSDynamicCast(OSSet
,
543 sKModClassesDict
->getObject(kmodName
));
547 iter
= OSCollectionIterator::withCollection(kmodClasses
);
551 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
552 if (checkClass
->getInstanceCount()) {
553 printf("%s: %s has %d instance(s)\n",
555 checkClass
->getClassName(),
556 checkClass
->getInstanceCount());
562 extern "C" kern_return_t
kmod_unload_cache(void);
564 static void _OSMetaClassConsiderUnloads(thread_call_param_t p0
,
565 thread_call_param_t p1
)
569 OSCollectionIterator
*kmods
;
570 OSCollectionIterator
*classes
;
571 OSMetaClass
*checkClass
;
576 mutex_lock(loadLock
);
580 kmods
= OSCollectionIterator::withCollection(sKModClassesDict
);
585 while ( (kmodName
= (OSSymbol
*) kmods
->getNextObject()) ) {
588 kfree((vm_offset_t
) ki
, sizeof(kmod_info_t
));
592 ki
= kmod_lookupbyname_locked((char *)kmodName
->getCStringNoCopy());
596 if (ki
->reference_count
) {
600 kmodClasses
= OSDynamicCast(OSSet
,
601 sKModClassesDict
->getObject(kmodName
));
602 classes
= OSCollectionIterator::withCollection(kmodClasses
);
606 while ((checkClass
= (OSMetaClass
*) classes
->getNextObject())
607 && (0 == checkClass
->getInstanceCount()))
611 if (0 == checkClass
) {
612 OSRuntimeUnloadCPP(ki
, 0); // call destructors
613 ret
= kmod_destroy(host_priv_self(), ki
->id
);
623 mutex_unlock(loadLock
);
628 void OSMetaClass::considerUnloads()
630 static thread_call_t unloadCallout
;
633 mutex_lock(loadLock
);
636 unloadCallout
= thread_call_allocate(&_OSMetaClassConsiderUnloads
, 0);
638 thread_call_cancel(unloadCallout
);
639 clock_interval_to_deadline(sConsiderUnloadDelay
, 1000 * 1000 * 1000, &when
);
640 thread_call_enter_delayed(unloadCallout
, when
);
642 mutex_unlock(loadLock
);
645 const OSMetaClass
*OSMetaClass::getMetaClassWithName(const OSSymbol
*name
)
647 OSMetaClass
*retMeta
= 0;
653 retMeta
= (OSMetaClass
*) sAllClassesDict
->getObject(name
);
655 if (!retMeta
&& sStalled
)
657 // Oh dear we have to scan the stalled list and walk the
658 // the stalled list manually.
659 const char *cName
= name
->getCStringNoCopy();
662 // find class in stalled list
663 for (i
= 0; i
< sStalled
->count
; i
++) {
664 retMeta
= sStalled
->classes
[i
];
665 if (0 == strcmp(cName
, (const char *) retMeta
->className
))
669 if (i
< sStalled
->count
)
676 OSObject
*OSMetaClass::allocClassWithName(const OSSymbol
*name
)
679 mutex_lock(loadLock
);
681 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
684 result
= meta
->alloc();
688 mutex_unlock(loadLock
);
693 OSObject
*OSMetaClass::allocClassWithName(const OSString
*name
)
695 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
696 OSObject
*result
= allocClassWithName(tmpKey
);
701 OSObject
*OSMetaClass::allocClassWithName(const char *name
)
703 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
704 OSObject
*result
= allocClassWithName(tmpKey
);
710 OSMetaClassBase
*OSMetaClass::
711 checkMetaCastWithName(const OSSymbol
*name
, const OSMetaClassBase
*in
)
713 OSMetaClassBase
* result
;
714 mutex_lock(loadLock
);
715 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
718 result
= meta
->checkMetaCast(in
);
722 mutex_unlock(loadLock
);
726 OSMetaClassBase
*OSMetaClass::
727 checkMetaCastWithName(const OSString
*name
, const OSMetaClassBase
*in
)
729 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
730 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
735 OSMetaClassBase
*OSMetaClass::
736 checkMetaCastWithName(const char *name
, const OSMetaClassBase
*in
)
738 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
739 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
745 OSMetaClass::checkMetaCast
746 checkMetaCast(const OSMetaClassBase *check)
748 Check to see if the 'check' object has this object in it's metaclass chain. Returns check if it is indeed a kind of the current meta class, 0 otherwise.
750 Generally this method is not invoked directly but is used to implement the OSMetaClassBase::metaCast member function.
752 See also OSMetaClassBase::metaCast
755 OSMetaClassBase
*OSMetaClass::checkMetaCast(const OSMetaClassBase
*check
) const
757 const OSMetaClass
* const toMeta
= this;
758 const OSMetaClass
*fromMeta
;
760 for (fromMeta
= check
->getMetaClass(); ; fromMeta
= fromMeta
->superClassLink
) {
761 if (toMeta
== fromMeta
)
762 return (OSMetaClassBase
*) check
; // Discard const
764 if (!fromMeta
->superClassLink
)
771 void OSMetaClass::reservedCalled(int ind
) const
773 const char *cname
= className
->getCStringNoCopy();
774 panic("%s::_RESERVED%s%d called\n", cname
, cname
, ind
);
777 const OSMetaClass
*OSMetaClass::getSuperClass() const
779 return superClassLink
;
782 const OSSymbol
*OSMetaClass::getKmodName() const
784 return sSortedByClassesDict
->getObject((const OSSymbol
*)this);
787 unsigned int OSMetaClass::getInstanceCount() const
789 return instanceCount
;
792 void OSMetaClass::printInstanceCounts()
794 OSCollectionIterator
*classes
;
798 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
802 while( (className
= (OSSymbol
*)classes
->getNextObject())) {
803 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
806 printf("%24s count: %03d x 0x%03x = 0x%06x\n",
807 className
->getCStringNoCopy(),
808 meta
->getInstanceCount(),
809 meta
->getClassSize(),
810 meta
->getInstanceCount() * meta
->getClassSize() );
816 OSDictionary
* OSMetaClass::getClassDictionary()
818 panic("OSMetaClass::getClassDictionary(): Obsoleted\n");
822 bool OSMetaClass::serialize(OSSerialize
*s
) const
824 panic("OSMetaClass::serialize(): Obsoleted\n");
828 void OSMetaClass::serializeClassDictionary(OSDictionary
*serializeDictionary
)
830 OSDictionary
*classDict
;
832 classDict
= OSDictionary::withCapacity(sAllClassesDict
->getCount());
836 mutex_lock(loadLock
);
838 OSCollectionIterator
*classes
;
839 const OSSymbol
*className
;
841 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
845 while ((className
= (const OSSymbol
*) classes
->getNextObject())) {
846 const OSMetaClass
*meta
;
849 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
850 count
= OSNumber::withNumber(meta
->getInstanceCount(), 32);
852 classDict
->setObject(className
, count
);
858 serializeDictionary
->setObject("Classes", classDict
);
861 mutex_unlock(loadLock
);
863 classDict
->release();