2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
26 #include <libkern/OSReturn.h>
28 #include <libkern/c++/OSMetaClass.h>
30 #include <libkern/c++/OSObject.h>
31 #include <libkern/c++/OSCollectionIterator.h>
32 #include <libkern/c++/OSDictionary.h>
33 #include <libkern/c++/OSArray.h>
34 #include <libkern/c++/OSSet.h>
35 #include <libkern/c++/OSSymbol.h>
36 #include <libkern/c++/OSNumber.h>
37 #include <libkern/c++/OSSerialize.h>
38 #include <libkern/c++/OSLib.h>
39 #include <libkern/OSAtomic.h>
41 #include <IOKit/pwr_mgt/RootDomain.h>
42 #include <IOKit/IOMessage.h>
46 #include <sys/systm.h>
47 #include <mach/mach_types.h>
48 #include <kern/lock.h>
49 #include <kern/clock.h>
50 #include <kern/thread_call.h>
51 #include <kern/host.h>
52 #include <mach/kmod.h>
53 #include <mach/mach_interface.h>
55 extern void OSRuntimeUnloadCPP(kmod_info_t
*ki
, void *);
58 extern int debug_container_malloc_size
;
59 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
62 #endif /* OSALLOCDEBUG */
67 kCompletedBootstrap
= 0,
69 kMakingDictionaries
= 2
70 } sBootstrapState
= kNoDictionaries
;
72 static const int kClassCapacityIncrement
= 40;
73 static const int kKModCapacityIncrement
= 10;
74 static OSDictionary
*sAllClassesDict
, *sKModClassesDict
, *sSortedByClassesDict
;
76 static mutex_t
*loadLock
= 0;
77 static struct StalledData
{
80 unsigned int capacity
;
82 OSMetaClass
**classes
;
85 static unsigned int sConsiderUnloadDelay
= 60; /* secs */
86 static bool unloadsEnabled
= true; // set to false when system going to sleep
87 static thread_call_t unloadCallout
= 0;
89 static const char OSMetaClassBasePanicMsg
[] =
90 "OSMetaClassBase::_RESERVEDOSMetaClassBase%d called\n";
93 void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
94 { panic(OSMetaClassBasePanicMsg
, 0); }
95 void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
96 { panic(OSMetaClassBasePanicMsg
, 1); }
97 void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
98 { panic(OSMetaClassBasePanicMsg
, 2); }
99 #endif /* SLOT_USED */
101 // As these slots are used move them up inside the #if above
102 void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
103 { panic(OSMetaClassBasePanicMsg
, 3); }
104 void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
105 { panic(OSMetaClassBasePanicMsg
, 4); }
106 void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
107 { panic(OSMetaClassBasePanicMsg
, 5); }
108 void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
109 { panic(OSMetaClassBasePanicMsg
, 6); }
112 * These used to be inline in the header but gcc didn't believe us
113 * Now we MUST pull the inline out at least until the compiler is
116 // Helper inlines for runtime type preprocessor macros
117 OSMetaClassBase
*OSMetaClassBase::
118 safeMetaCast(const OSMetaClassBase
*me
, const OSMetaClass
*toType
)
119 { return (me
)? me
->metaCast(toType
) : 0; }
121 bool OSMetaClassBase::
122 checkTypeInst(const OSMetaClassBase
*inst
, const OSMetaClassBase
*typeinst
)
124 const OSMetaClass
*toType
= OSTypeIDInst(typeinst
);
125 return typeinst
&& inst
&& (0 != inst
->metaCast(toType
));
129 // If you need this slot you had better setup an IOCTL style interface.
130 // 'Cause the whole kernel world depends on OSMetaClassBase and YOU
131 // CANT change the VTABLE size ever.
132 void OSMetaClassBase::_RESERVEDOSMetaClassBase7()
133 { panic(OSMetaClassBasePanicMsg
, 7); }
135 OSMetaClassBase::OSMetaClassBase()
139 OSMetaClassBase::~OSMetaClassBase()
143 thisVTable
= (void **) this;
144 *thisVTable
= (void *) -1UL;
147 bool OSMetaClassBase::isEqualTo(const OSMetaClassBase
*anObj
) const
149 return this == anObj
;
152 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSMetaClass
*toMeta
) const
154 return toMeta
->checkMetaCast(this);
157 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSSymbol
*toMetaSymb
) const
159 return OSMetaClass::checkMetaCastWithName(toMetaSymb
, this);
162 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSString
*toMetaStr
) const
164 const OSSymbol
*tempSymb
= OSSymbol::withString(toMetaStr
);
165 OSMetaClassBase
*ret
= 0;
167 ret
= metaCast(tempSymb
);
173 OSMetaClassBase
*OSMetaClassBase::metaCast(const char *toMetaCStr
) const
175 const OSSymbol
*tempSymb
= OSSymbol::withCString(toMetaCStr
);
176 OSMetaClassBase
*ret
= 0;
178 ret
= metaCast(tempSymb
);
184 class OSMetaClassMeta
: public OSMetaClass
188 OSObject
*alloc() const;
190 OSMetaClassMeta::OSMetaClassMeta()
191 : OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass
))
193 OSObject
*OSMetaClassMeta::alloc() const { return 0; }
195 static OSMetaClassMeta sOSMetaClassMeta
;
197 const OSMetaClass
* const OSMetaClass::metaClass
= &sOSMetaClassMeta
;
198 const OSMetaClass
* OSMetaClass::getMetaClass() const
199 { return &sOSMetaClassMeta
; }
201 static const char OSMetaClassPanicMsg
[] =
202 "OSMetaClass::_RESERVEDOSMetaClass%d called\n";
204 void OSMetaClass::_RESERVEDOSMetaClass0()
205 { panic(OSMetaClassPanicMsg
, 0); }
206 void OSMetaClass::_RESERVEDOSMetaClass1()
207 { panic(OSMetaClassPanicMsg
, 1); }
208 void OSMetaClass::_RESERVEDOSMetaClass2()
209 { panic(OSMetaClassPanicMsg
, 2); }
210 void OSMetaClass::_RESERVEDOSMetaClass3()
211 { panic(OSMetaClassPanicMsg
, 3); }
212 void OSMetaClass::_RESERVEDOSMetaClass4()
213 { panic(OSMetaClassPanicMsg
, 4); }
214 void OSMetaClass::_RESERVEDOSMetaClass5()
215 { panic(OSMetaClassPanicMsg
, 5); }
216 void OSMetaClass::_RESERVEDOSMetaClass6()
217 { panic(OSMetaClassPanicMsg
, 6); }
218 void OSMetaClass::_RESERVEDOSMetaClass7()
219 { panic(OSMetaClassPanicMsg
, 7); }
221 void OSMetaClass::logError(OSReturn result
)
226 case kOSMetaClassNoInit
:
227 msg
="OSMetaClass::preModLoad wasn't called, runtime internal error";
229 case kOSMetaClassNoDicts
:
230 msg
="Allocation failure for Metaclass internal dictionaries"; break;
231 case kOSMetaClassNoKModSet
:
232 msg
="Allocation failure for internal kmodule set"; break;
233 case kOSMetaClassNoInsKModSet
:
234 msg
="Can't insert the KMod set into the module dictionary"; break;
235 case kOSMetaClassDuplicateClass
:
236 msg
="Duplicate class"; break;
237 case kOSMetaClassNoSuper
:
238 msg
="Can't associate a class with its super class"; break;
239 case kOSMetaClassInstNoSuper
:
240 msg
="Instance construction, unknown super class."; break;
242 case kOSMetaClassInternal
:
243 msg
="runtime internal error"; break;
244 case kOSReturnSuccess
:
250 OSMetaClass::OSMetaClass(const char *inClassName
,
251 const OSMetaClass
*inSuperClass
,
252 unsigned int inClassSize
)
255 classSize
= inClassSize
;
256 superClassLink
= inSuperClass
;
258 className
= (const OSSymbol
*) inClassName
;
261 printf("OSMetaClass::preModLoad wasn't called for %s, "
262 "runtime internal error\n", inClassName
);
263 } else if (!sStalled
->result
) {
264 // Grow stalled array if neccessary
265 if (sStalled
->count
>= sStalled
->capacity
) {
266 OSMetaClass
**oldStalled
= sStalled
->classes
;
267 int oldSize
= sStalled
->capacity
* sizeof(OSMetaClass
*);
268 int newSize
= oldSize
269 + kKModCapacityIncrement
* sizeof(OSMetaClass
*);
271 sStalled
->classes
= (OSMetaClass
**) kalloc(newSize
);
272 if (!sStalled
->classes
) {
273 sStalled
->classes
= oldStalled
;
274 sStalled
->result
= kOSMetaClassNoTempData
;
278 sStalled
->capacity
+= kKModCapacityIncrement
;
279 memmove(sStalled
->classes
, oldStalled
, oldSize
);
280 kfree(oldStalled
, oldSize
);
281 ACCUMSIZE(newSize
- oldSize
);
284 sStalled
->classes
[sStalled
->count
++] = this;
288 OSMetaClass::~OSMetaClass()
291 OSCollectionIterator
*iter
;
293 if (sAllClassesDict
) {
294 sAllClassesDict
->removeObject(className
);
295 className
->release();
298 iter
= OSCollectionIterator::withCollection(sKModClassesDict
);
303 while ( (iterKey
= (OSSymbol
*) iter
->getNextObject()) ) {
305 kmodClassSet
= (OSSet
*) sKModClassesDict
->getObject(iterKey
);
306 if (kmodClassSet
&& kmodClassSet
->containsObject(this)) {
307 kmodClassSet
->removeObject(this);
317 // First pass find class in stalled list
318 for (i
= 0; i
< sStalled
->count
; i
++)
319 if (this == sStalled
->classes
[i
])
322 if (i
< sStalled
->count
) {
324 if (i
< sStalled
->count
)
325 memmove(&sStalled
->classes
[i
], &sStalled
->classes
[i
+1],
326 (sStalled
->count
- i
) * sizeof(OSMetaClass
*));
331 void *OSMetaClass::operator new(size_t size
) { return 0; }
332 void OSMetaClass::retain() const { }
333 void OSMetaClass::release() const { }
334 void OSMetaClass::release(int when
) const { }
335 void OSMetaClass::taggedRetain(const void *tag
) const { }
336 void OSMetaClass::taggedRelease(const void *tag
) const { }
337 void OSMetaClass::taggedRelease(const void *tag
, const int when
) const { }
338 int OSMetaClass::getRetainCount() const { return 0; }
340 const char *OSMetaClass::getClassName() const
342 return className
->getCStringNoCopy();
345 unsigned int OSMetaClass::getClassSize() const
350 void *OSMetaClass::preModLoad(const char *kmodName
)
353 loadLock
= mutex_alloc(0);
354 mutex_lock(loadLock
);
357 mutex_lock(loadLock
);
359 sStalled
= (StalledData
*) kalloc(sizeof(*sStalled
));
361 sStalled
->classes
= (OSMetaClass
**)
362 kalloc(kKModCapacityIncrement
* sizeof(OSMetaClass
*));
363 if (!sStalled
->classes
) {
364 kfree(sStalled
, sizeof(*sStalled
));
367 ACCUMSIZE((kKModCapacityIncrement
* sizeof(OSMetaClass
*)) + sizeof(*sStalled
));
369 sStalled
->result
= kOSReturnSuccess
;
370 sStalled
->capacity
= kKModCapacityIncrement
;
372 sStalled
->kmodName
= kmodName
;
373 bzero(sStalled
->classes
, kKModCapacityIncrement
* sizeof(OSMetaClass
*));
379 bool OSMetaClass::checkModLoad(void *loadHandle
)
381 return sStalled
&& loadHandle
== sStalled
382 && sStalled
->result
== kOSReturnSuccess
;
385 OSReturn
OSMetaClass::postModLoad(void *loadHandle
)
387 OSReturn result
= kOSReturnSuccess
;
389 OSSymbol
*myname
= 0;
391 if (!sStalled
|| loadHandle
!= sStalled
) {
392 logError(kOSMetaClassInternal
);
393 return kOSMetaClassInternal
;
396 if (sStalled
->result
)
397 result
= sStalled
->result
;
398 else switch (sBootstrapState
) {
399 case kNoDictionaries
:
400 sBootstrapState
= kMakingDictionaries
;
401 // No break; fall through
403 case kMakingDictionaries
:
404 sKModClassesDict
= OSDictionary::withCapacity(kKModCapacityIncrement
);
405 sAllClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
406 sSortedByClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
407 if (!sAllClassesDict
|| !sKModClassesDict
|| !sSortedByClassesDict
) {
408 result
= kOSMetaClassNoDicts
;
411 // No break; fall through
413 case kCompletedBootstrap
:
416 myname
= (OSSymbol
*)OSSymbol::withCStringNoCopy(sStalled
->kmodName
);
418 if (!sStalled
->count
)
419 break; // Nothing to do so just get out
421 // First pass checking classes aren't already loaded
422 for (i
= 0; i
< sStalled
->count
; i
++) {
423 OSMetaClass
*me
= sStalled
->classes
[i
];
425 if (0 != sAllClassesDict
->getObject((const char *) me
->className
)) {
426 printf("Class \"%s\" is duplicate\n", (const char *) me
->className
);
427 result
= kOSMetaClassDuplicateClass
;
431 if (i
!= sStalled
->count
)
434 kmodSet
= OSSet::withCapacity(sStalled
->count
);
436 result
= kOSMetaClassNoKModSet
;
440 if (!sKModClassesDict
->setObject(myname
, kmodSet
)) {
441 result
= kOSMetaClassNoInsKModSet
;
445 // Second pass symbolling strings and inserting classes in dictionary
446 for (i
= 0; i
< sStalled
->count
; i
++) {
447 OSMetaClass
*me
= sStalled
->classes
[i
];
449 OSSymbol::withCStringNoCopy((const char *) me
->className
);
451 sAllClassesDict
->setObject(me
->className
, me
);
452 kmodSet
->setObject(me
);
453 sSortedByClassesDict
->setObject((const OSSymbol
*)me
, myname
);
455 sBootstrapState
= kCompletedBootstrap
;
460 result
= kOSMetaClassInternal
;
471 ACCUMSIZE(-(sStalled
->capacity
* sizeof(OSMetaClass
*)
472 + sizeof(*sStalled
)));
473 kfree(sStalled
->classes
,
474 sStalled
->capacity
* sizeof(OSMetaClass
*));
475 kfree(sStalled
, sizeof(*sStalled
));
480 mutex_unlock(loadLock
);
485 void OSMetaClass::instanceConstructed() const
487 // if ((0 == OSIncrementAtomic((SInt32 *)&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
488 if ((0 == OSIncrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
489 superClassLink
->instanceConstructed();
492 void OSMetaClass::instanceDestructed() const
494 if ((1 == OSDecrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
495 superClassLink
->instanceDestructed();
497 if( ((int) instanceCount
) < 0)
498 printf("%s: bad retain(%d)", getClassName(), instanceCount
);
501 bool OSMetaClass::modHasInstance(const char *kmodName
)
506 loadLock
= mutex_alloc(0);
507 mutex_lock(loadLock
);
510 mutex_lock(loadLock
);
514 OSCollectionIterator
*iter
;
515 OSMetaClass
*checkClass
;
517 kmodClasses
= OSDynamicCast(OSSet
,
518 sKModClassesDict
->getObject(kmodName
));
522 iter
= OSCollectionIterator::withCollection(kmodClasses
);
526 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
527 if (checkClass
->getInstanceCount()) {
535 mutex_unlock(loadLock
);
540 void OSMetaClass::reportModInstances(const char *kmodName
)
543 OSCollectionIterator
*iter
;
544 OSMetaClass
*checkClass
;
546 kmodClasses
= OSDynamicCast(OSSet
,
547 sKModClassesDict
->getObject(kmodName
));
551 iter
= OSCollectionIterator::withCollection(kmodClasses
);
555 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
556 if (checkClass
->getInstanceCount()) {
557 printf("%s: %s has %d instance(s)\n",
559 checkClass
->getClassName(),
560 checkClass
->getInstanceCount());
569 IOReturn
OSMetaClassSystemSleepOrWake(UInt32 messageType
)
571 mutex_lock(loadLock
);
573 /* If the system is going to sleep, cancel the reaper thread timer
574 * and mark unloads disabled in case it just fired but hasn't
575 * taken the lock yet. If we are coming back from sleep, just
576 * set unloads enabled; IOService's normal operation will cause
577 * unloads to be considered soon enough.
579 if (messageType
== kIOMessageSystemWillSleep
) {
581 thread_call_cancel(unloadCallout
);
583 unloadsEnabled
= false;
584 } else if (messageType
== kIOMessageSystemHasPoweredOn
) {
585 unloadsEnabled
= true;
587 mutex_unlock(loadLock
);
589 return kIOReturnSuccess
;
594 extern "C" kern_return_t
kmod_unload_cache(void);
596 static void _OSMetaClassConsiderUnloads(thread_call_param_t p0
,
597 thread_call_param_t p1
)
601 OSCollectionIterator
*kmods
;
602 OSCollectionIterator
*classes
;
603 OSMetaClass
*checkClass
;
608 mutex_lock(loadLock
);
610 if (!unloadsEnabled
) {
611 mutex_unlock(loadLock
);
617 kmods
= OSCollectionIterator::withCollection(sKModClassesDict
);
622 while ( (kmodName
= (OSSymbol
*) kmods
->getNextObject()) ) {
625 kfree(ki
, sizeof(kmod_info_t
));
629 ki
= kmod_lookupbyname_locked((char *)kmodName
->getCStringNoCopy());
633 if (ki
->reference_count
) {
637 kmodClasses
= OSDynamicCast(OSSet
,
638 sKModClassesDict
->getObject(kmodName
));
639 classes
= OSCollectionIterator::withCollection(kmodClasses
);
643 while ((checkClass
= (OSMetaClass
*) classes
->getNextObject())
644 && (0 == checkClass
->getInstanceCount()))
648 if (0 == checkClass
) {
649 OSRuntimeUnloadCPP(ki
, 0); // call destructors
650 ret
= kmod_destroy(host_priv_self(), ki
->id
);
660 mutex_unlock(loadLock
);
665 void OSMetaClass::considerUnloads()
669 mutex_lock(loadLock
);
672 unloadCallout
= thread_call_allocate(&_OSMetaClassConsiderUnloads
, 0);
674 thread_call_cancel(unloadCallout
);
675 clock_interval_to_deadline(sConsiderUnloadDelay
, 1000 * 1000 * 1000, &when
);
676 thread_call_enter_delayed(unloadCallout
, when
);
678 mutex_unlock(loadLock
);
681 const OSMetaClass
*OSMetaClass::getMetaClassWithName(const OSSymbol
*name
)
683 OSMetaClass
*retMeta
= 0;
689 retMeta
= (OSMetaClass
*) sAllClassesDict
->getObject(name
);
691 if (!retMeta
&& sStalled
)
693 // Oh dear we have to scan the stalled list and walk the
694 // the stalled list manually.
695 const char *cName
= name
->getCStringNoCopy();
698 // find class in stalled list
699 for (i
= 0; i
< sStalled
->count
; i
++) {
700 retMeta
= sStalled
->classes
[i
];
701 if (0 == strcmp(cName
, (const char *) retMeta
->className
))
705 if (i
< sStalled
->count
)
712 OSObject
*OSMetaClass::allocClassWithName(const OSSymbol
*name
)
715 mutex_lock(loadLock
);
717 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
720 result
= meta
->alloc();
724 mutex_unlock(loadLock
);
729 OSObject
*OSMetaClass::allocClassWithName(const OSString
*name
)
731 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
732 OSObject
*result
= allocClassWithName(tmpKey
);
737 OSObject
*OSMetaClass::allocClassWithName(const char *name
)
739 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
740 OSObject
*result
= allocClassWithName(tmpKey
);
746 OSMetaClassBase
*OSMetaClass::
747 checkMetaCastWithName(const OSSymbol
*name
, const OSMetaClassBase
*in
)
749 OSMetaClassBase
* result
;
750 mutex_lock(loadLock
);
751 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
754 result
= meta
->checkMetaCast(in
);
758 mutex_unlock(loadLock
);
762 OSMetaClassBase
*OSMetaClass::
763 checkMetaCastWithName(const OSString
*name
, const OSMetaClassBase
*in
)
765 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
766 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
771 OSMetaClassBase
*OSMetaClass::
772 checkMetaCastWithName(const char *name
, const OSMetaClassBase
*in
)
774 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
775 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
781 OSMetaClass::checkMetaCast
782 checkMetaCast(const OSMetaClassBase *check)
784 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.
786 Generally this method is not invoked directly but is used to implement the OSMetaClassBase::metaCast member function.
788 See also OSMetaClassBase::metaCast
791 OSMetaClassBase
*OSMetaClass::checkMetaCast(const OSMetaClassBase
*check
) const
793 const OSMetaClass
* const toMeta
= this;
794 const OSMetaClass
*fromMeta
;
796 for (fromMeta
= check
->getMetaClass(); ; fromMeta
= fromMeta
->superClassLink
) {
797 if (toMeta
== fromMeta
)
798 return (OSMetaClassBase
*) check
; // Discard const
800 if (!fromMeta
->superClassLink
)
807 void OSMetaClass::reservedCalled(int ind
) const
809 const char *cname
= className
->getCStringNoCopy();
810 panic("%s::_RESERVED%s%d called\n", cname
, cname
, ind
);
813 const OSMetaClass
*OSMetaClass::getSuperClass() const
815 return superClassLink
;
818 const OSSymbol
*OSMetaClass::getKmodName() const
820 return (const OSSymbol
*)sSortedByClassesDict
->getObject((OSSymbol
*)this);
823 unsigned int OSMetaClass::getInstanceCount() const
825 return instanceCount
;
828 void OSMetaClass::printInstanceCounts()
830 OSCollectionIterator
*classes
;
834 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
838 while( (className
= (OSSymbol
*)classes
->getNextObject())) {
839 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
842 printf("%24s count: %03d x 0x%03x = 0x%06x\n",
843 className
->getCStringNoCopy(),
844 meta
->getInstanceCount(),
845 meta
->getClassSize(),
846 meta
->getInstanceCount() * meta
->getClassSize() );
852 OSDictionary
* OSMetaClass::getClassDictionary()
854 panic("OSMetaClass::getClassDictionary(): Obsoleted\n");
858 bool OSMetaClass::serialize(OSSerialize
*s
) const
860 panic("OSMetaClass::serialize(): Obsoleted\n");
864 void OSMetaClass::serializeClassDictionary(OSDictionary
*serializeDictionary
)
866 OSDictionary
*classDict
;
868 classDict
= OSDictionary::withCapacity(sAllClassesDict
->getCount());
872 mutex_lock(loadLock
);
874 OSCollectionIterator
*classes
;
875 const OSSymbol
*className
;
877 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
881 while ((className
= (const OSSymbol
*) classes
->getNextObject())) {
882 const OSMetaClass
*meta
;
885 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
886 count
= OSNumber::withNumber(meta
->getInstanceCount(), 32);
888 classDict
->setObject(className
, count
);
894 serializeDictionary
->setObject("Classes", classDict
);
897 mutex_unlock(loadLock
);
899 classDict
->release();