2 * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* OSMetaClass.cpp created by gvdl on Fri 1998-11-17 */
32 #include <libkern/OSReturn.h>
34 #include <libkern/c++/OSMetaClass.h>
36 #include <libkern/c++/OSObject.h>
37 #include <libkern/c++/OSCollectionIterator.h>
38 #include <libkern/c++/OSDictionary.h>
39 #include <libkern/c++/OSArray.h>
40 #include <libkern/c++/OSSet.h>
41 #include <libkern/c++/OSSymbol.h>
42 #include <libkern/c++/OSNumber.h>
43 #include <libkern/c++/OSSerialize.h>
44 #include <libkern/c++/OSLib.h>
45 #include <libkern/OSAtomic.h>
47 #include <IOKit/pwr_mgt/RootDomain.h>
48 #include <IOKit/IOMessage.h>
52 #include <sys/systm.h>
53 #include <mach/mach_types.h>
54 #include <kern/lock.h>
55 #include <kern/clock.h>
56 #include <kern/thread_call.h>
57 #include <kern/host.h>
58 #include <mach/kmod.h>
59 #include <mach/mach_interface.h>
61 extern void OSRuntimeUnloadCPP(kmod_info_t
*ki
, void *);
64 extern int debug_container_malloc_size
;
65 #define ACCUMSIZE(s) do { debug_container_malloc_size += (s); } while(0)
68 #endif /* OSALLOCDEBUG */
73 kCompletedBootstrap
= 0,
75 kMakingDictionaries
= 2
76 } sBootstrapState
= kNoDictionaries
;
78 static const int kClassCapacityIncrement
= 40;
79 static const int kKModCapacityIncrement
= 10;
80 static OSDictionary
*sAllClassesDict
, *sKModClassesDict
, *sSortedByClassesDict
;
82 static mutex_t
*loadLock
= 0;
83 static struct StalledData
{
86 unsigned int capacity
;
88 OSMetaClass
**classes
;
91 static unsigned int sConsiderUnloadDelay
= 60; /* secs */
92 static bool unloadsEnabled
= true; // set to false when system going to sleep
93 static thread_call_t unloadCallout
= 0;
95 static const char OSMetaClassBasePanicMsg
[] =
96 "OSMetaClassBase::_RESERVEDOSMetaClassBase%d called\n";
99 void OSMetaClassBase::_RESERVEDOSMetaClassBase0()
100 { panic(OSMetaClassBasePanicMsg
, 0); }
101 void OSMetaClassBase::_RESERVEDOSMetaClassBase1()
102 { panic(OSMetaClassBasePanicMsg
, 1); }
103 void OSMetaClassBase::_RESERVEDOSMetaClassBase2()
104 { panic(OSMetaClassBasePanicMsg
, 2); }
105 #endif /* SLOT_USED */
107 // As these slots are used move them up inside the #if above
108 void OSMetaClassBase::_RESERVEDOSMetaClassBase3()
109 { panic(OSMetaClassBasePanicMsg
, 3); }
110 void OSMetaClassBase::_RESERVEDOSMetaClassBase4()
111 { panic(OSMetaClassBasePanicMsg
, 4); }
112 void OSMetaClassBase::_RESERVEDOSMetaClassBase5()
113 { panic(OSMetaClassBasePanicMsg
, 5); }
114 void OSMetaClassBase::_RESERVEDOSMetaClassBase6()
115 { panic(OSMetaClassBasePanicMsg
, 6); }
118 * These used to be inline in the header but gcc didn't believe us
119 * Now we MUST pull the inline out at least until the compiler is
122 // Helper inlines for runtime type preprocessor macros
123 OSMetaClassBase
*OSMetaClassBase::
124 safeMetaCast(const OSMetaClassBase
*me
, const OSMetaClass
*toType
)
125 { return (me
)? me
->metaCast(toType
) : 0; }
127 bool OSMetaClassBase::
128 checkTypeInst(const OSMetaClassBase
*inst
, const OSMetaClassBase
*typeinst
)
130 const OSMetaClass
*toType
= OSTypeIDInst(typeinst
);
131 return typeinst
&& inst
&& (0 != inst
->metaCast(toType
));
135 // If you need this slot you had better setup an IOCTL style interface.
136 // 'Cause the whole kernel world depends on OSMetaClassBase and YOU
137 // CANT change the VTABLE size ever.
138 void OSMetaClassBase::_RESERVEDOSMetaClassBase7()
139 { panic(OSMetaClassBasePanicMsg
, 7); }
141 OSMetaClassBase::OSMetaClassBase()
145 OSMetaClassBase::~OSMetaClassBase()
149 thisVTable
= (void **) this;
150 *thisVTable
= (void *) -1UL;
153 bool OSMetaClassBase::isEqualTo(const OSMetaClassBase
*anObj
) const
155 return this == anObj
;
158 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSMetaClass
*toMeta
) const
160 return toMeta
->checkMetaCast(this);
163 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSSymbol
*toMetaSymb
) const
165 return OSMetaClass::checkMetaCastWithName(toMetaSymb
, this);
168 OSMetaClassBase
*OSMetaClassBase::metaCast(const OSString
*toMetaStr
) const
170 const OSSymbol
*tempSymb
= OSSymbol::withString(toMetaStr
);
171 OSMetaClassBase
*ret
= 0;
173 ret
= metaCast(tempSymb
);
179 OSMetaClassBase
*OSMetaClassBase::metaCast(const char *toMetaCStr
) const
181 const OSSymbol
*tempSymb
= OSSymbol::withCString(toMetaCStr
);
182 OSMetaClassBase
*ret
= 0;
184 ret
= metaCast(tempSymb
);
190 class OSMetaClassMeta
: public OSMetaClass
194 OSObject
*alloc() const;
196 OSMetaClassMeta::OSMetaClassMeta()
197 : OSMetaClass("OSMetaClass", 0, sizeof(OSMetaClass
))
199 OSObject
*OSMetaClassMeta::alloc() const { return 0; }
201 static OSMetaClassMeta sOSMetaClassMeta
;
203 const OSMetaClass
* const OSMetaClass::metaClass
= &sOSMetaClassMeta
;
204 const OSMetaClass
* OSMetaClass::getMetaClass() const
205 { return &sOSMetaClassMeta
; }
207 static const char OSMetaClassPanicMsg
[] =
208 "OSMetaClass::_RESERVEDOSMetaClass%d called\n";
210 void OSMetaClass::_RESERVEDOSMetaClass0()
211 { panic(OSMetaClassPanicMsg
, 0); }
212 void OSMetaClass::_RESERVEDOSMetaClass1()
213 { panic(OSMetaClassPanicMsg
, 1); }
214 void OSMetaClass::_RESERVEDOSMetaClass2()
215 { panic(OSMetaClassPanicMsg
, 2); }
216 void OSMetaClass::_RESERVEDOSMetaClass3()
217 { panic(OSMetaClassPanicMsg
, 3); }
218 void OSMetaClass::_RESERVEDOSMetaClass4()
219 { panic(OSMetaClassPanicMsg
, 4); }
220 void OSMetaClass::_RESERVEDOSMetaClass5()
221 { panic(OSMetaClassPanicMsg
, 5); }
222 void OSMetaClass::_RESERVEDOSMetaClass6()
223 { panic(OSMetaClassPanicMsg
, 6); }
224 void OSMetaClass::_RESERVEDOSMetaClass7()
225 { panic(OSMetaClassPanicMsg
, 7); }
227 void OSMetaClass::logError(OSReturn result
)
232 case kOSMetaClassNoInit
:
233 msg
="OSMetaClass::preModLoad wasn't called, runtime internal error";
235 case kOSMetaClassNoDicts
:
236 msg
="Allocation failure for Metaclass internal dictionaries"; break;
237 case kOSMetaClassNoKModSet
:
238 msg
="Allocation failure for internal kmodule set"; break;
239 case kOSMetaClassNoInsKModSet
:
240 msg
="Can't insert the KMod set into the module dictionary"; break;
241 case kOSMetaClassDuplicateClass
:
242 msg
="Duplicate class"; break;
243 case kOSMetaClassNoSuper
:
244 msg
="Can't associate a class with its super class"; break;
245 case kOSMetaClassInstNoSuper
:
246 msg
="Instance construction, unknown super class."; break;
248 case kOSMetaClassInternal
:
249 msg
="runtime internal error"; break;
250 case kOSReturnSuccess
:
256 OSMetaClass::OSMetaClass(const char *inClassName
,
257 const OSMetaClass
*inSuperClass
,
258 unsigned int inClassSize
)
261 classSize
= inClassSize
;
262 superClassLink
= inSuperClass
;
264 className
= (const OSSymbol
*) inClassName
;
267 printf("OSMetaClass::preModLoad wasn't called for %s, "
268 "runtime internal error\n", inClassName
);
269 } else if (!sStalled
->result
) {
270 // Grow stalled array if neccessary
271 if (sStalled
->count
>= sStalled
->capacity
) {
272 OSMetaClass
**oldStalled
= sStalled
->classes
;
273 int oldSize
= sStalled
->capacity
* sizeof(OSMetaClass
*);
274 int newSize
= oldSize
275 + kKModCapacityIncrement
* sizeof(OSMetaClass
*);
277 sStalled
->classes
= (OSMetaClass
**) kalloc(newSize
);
278 if (!sStalled
->classes
) {
279 sStalled
->classes
= oldStalled
;
280 sStalled
->result
= kOSMetaClassNoTempData
;
284 sStalled
->capacity
+= kKModCapacityIncrement
;
285 memmove(sStalled
->classes
, oldStalled
, oldSize
);
286 kfree(oldStalled
, oldSize
);
287 ACCUMSIZE(newSize
- oldSize
);
290 sStalled
->classes
[sStalled
->count
++] = this;
294 OSMetaClass::~OSMetaClass()
297 OSCollectionIterator
*iter
;
299 if (sAllClassesDict
) {
300 sAllClassesDict
->removeObject(className
);
301 className
->release();
304 iter
= OSCollectionIterator::withCollection(sKModClassesDict
);
309 while ( (iterKey
= (OSSymbol
*) iter
->getNextObject()) ) {
311 kmodClassSet
= (OSSet
*) sKModClassesDict
->getObject(iterKey
);
312 if (kmodClassSet
&& kmodClassSet
->containsObject(this)) {
313 kmodClassSet
->removeObject(this);
323 // First pass find class in stalled list
324 for (i
= 0; i
< sStalled
->count
; i
++)
325 if (this == sStalled
->classes
[i
])
328 if (i
< sStalled
->count
) {
330 if (i
< sStalled
->count
)
331 memmove(&sStalled
->classes
[i
], &sStalled
->classes
[i
+1],
332 (sStalled
->count
- i
) * sizeof(OSMetaClass
*));
337 void *OSMetaClass::operator new(__unused
size_t size
) { return 0; }
338 void OSMetaClass::retain() const { }
339 void OSMetaClass::release() const { }
340 void OSMetaClass::release(__unused
int when
) const { }
341 void OSMetaClass::taggedRetain(__unused
const void *tag
) const { }
342 void OSMetaClass::taggedRelease(__unused
const void *tag
) const { }
343 void OSMetaClass::taggedRelease(__unused
const void *tag
, __unused
const int when
) const { }
344 int OSMetaClass::getRetainCount() const { return 0; }
346 const char *OSMetaClass::getClassName() const
348 return className
->getCStringNoCopy();
351 unsigned int OSMetaClass::getClassSize() const
356 void *OSMetaClass::preModLoad(const char *kmodName
)
359 loadLock
= mutex_alloc(0);
360 mutex_lock(loadLock
);
363 mutex_lock(loadLock
);
365 sStalled
= (StalledData
*) kalloc(sizeof(*sStalled
));
367 sStalled
->classes
= (OSMetaClass
**)
368 kalloc(kKModCapacityIncrement
* sizeof(OSMetaClass
*));
369 if (!sStalled
->classes
) {
370 kfree(sStalled
, sizeof(*sStalled
));
373 ACCUMSIZE((kKModCapacityIncrement
* sizeof(OSMetaClass
*)) + sizeof(*sStalled
));
375 sStalled
->result
= kOSReturnSuccess
;
376 sStalled
->capacity
= kKModCapacityIncrement
;
378 sStalled
->kmodName
= kmodName
;
379 bzero(sStalled
->classes
, kKModCapacityIncrement
* sizeof(OSMetaClass
*));
385 bool OSMetaClass::checkModLoad(void *loadHandle
)
387 return sStalled
&& loadHandle
== sStalled
388 && sStalled
->result
== kOSReturnSuccess
;
391 OSReturn
OSMetaClass::postModLoad(void *loadHandle
)
393 OSReturn result
= kOSReturnSuccess
;
395 OSSymbol
*myname
= 0;
397 if (!sStalled
|| loadHandle
!= sStalled
) {
398 logError(kOSMetaClassInternal
);
399 return kOSMetaClassInternal
;
402 if (sStalled
->result
)
403 result
= sStalled
->result
;
404 else switch (sBootstrapState
) {
405 case kNoDictionaries
:
406 sBootstrapState
= kMakingDictionaries
;
407 // No break; fall through
409 case kMakingDictionaries
:
410 sKModClassesDict
= OSDictionary::withCapacity(kKModCapacityIncrement
);
411 sAllClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
412 sSortedByClassesDict
= OSDictionary::withCapacity(kClassCapacityIncrement
);
413 if (!sAllClassesDict
|| !sKModClassesDict
|| !sSortedByClassesDict
) {
414 result
= kOSMetaClassNoDicts
;
417 // No break; fall through
419 case kCompletedBootstrap
:
422 myname
= (OSSymbol
*)OSSymbol::withCStringNoCopy(sStalled
->kmodName
);
424 if (!sStalled
->count
)
425 break; // Nothing to do so just get out
427 // First pass checking classes aren't already loaded
428 for (i
= 0; i
< sStalled
->count
; i
++) {
429 OSMetaClass
*me
= sStalled
->classes
[i
];
431 if (0 != sAllClassesDict
->getObject((const char *) me
->className
)) {
432 printf("Class \"%s\" is duplicate\n", (const char *) me
->className
);
433 result
= kOSMetaClassDuplicateClass
;
437 if (i
!= sStalled
->count
)
440 kmodSet
= OSSet::withCapacity(sStalled
->count
);
442 result
= kOSMetaClassNoKModSet
;
446 if (!sKModClassesDict
->setObject(myname
, kmodSet
)) {
447 result
= kOSMetaClassNoInsKModSet
;
451 // Second pass symbolling strings and inserting classes in dictionary
452 for (i
= 0; i
< sStalled
->count
; i
++) {
453 OSMetaClass
*me
= sStalled
->classes
[i
];
455 OSSymbol::withCStringNoCopy((const char *) me
->className
);
457 sAllClassesDict
->setObject(me
->className
, me
);
458 kmodSet
->setObject(me
);
459 sSortedByClassesDict
->setObject((const OSSymbol
*)me
, myname
);
461 sBootstrapState
= kCompletedBootstrap
;
466 result
= kOSMetaClassInternal
;
477 ACCUMSIZE(-(sStalled
->capacity
* sizeof(OSMetaClass
*)
478 + sizeof(*sStalled
)));
479 kfree(sStalled
->classes
,
480 sStalled
->capacity
* sizeof(OSMetaClass
*));
481 kfree(sStalled
, sizeof(*sStalled
));
486 mutex_unlock(loadLock
);
491 void OSMetaClass::instanceConstructed() const
493 // if ((0 == OSIncrementAtomic((SInt32 *)&(((OSMetaClass *) this)->instanceCount))) && superClassLink)
494 if ((0 == OSIncrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
495 superClassLink
->instanceConstructed();
498 void OSMetaClass::instanceDestructed() const
500 if ((1 == OSDecrementAtomic((SInt32
*) &instanceCount
)) && superClassLink
)
501 superClassLink
->instanceDestructed();
503 if( ((int) instanceCount
) < 0)
504 printf("%s: bad retain(%d)", getClassName(), instanceCount
);
507 bool OSMetaClass::modHasInstance(const char *kmodName
)
512 loadLock
= mutex_alloc(0);
513 mutex_lock(loadLock
);
516 mutex_lock(loadLock
);
520 OSCollectionIterator
*iter
;
521 OSMetaClass
*checkClass
;
523 kmodClasses
= OSDynamicCast(OSSet
,
524 sKModClassesDict
->getObject(kmodName
));
528 iter
= OSCollectionIterator::withCollection(kmodClasses
);
532 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
533 if (checkClass
->getInstanceCount()) {
541 mutex_unlock(loadLock
);
546 void OSMetaClass::reportModInstances(const char *kmodName
)
549 OSCollectionIterator
*iter
;
550 OSMetaClass
*checkClass
;
552 kmodClasses
= OSDynamicCast(OSSet
,
553 sKModClassesDict
->getObject(kmodName
));
557 iter
= OSCollectionIterator::withCollection(kmodClasses
);
561 while ( (checkClass
= (OSMetaClass
*) iter
->getNextObject()) )
562 if (checkClass
->getInstanceCount()) {
563 printf("%s: %s has %d instance(s)\n",
565 checkClass
->getClassName(),
566 checkClass
->getInstanceCount());
575 IOReturn
OSMetaClassSystemSleepOrWake(UInt32 messageType
)
577 mutex_lock(loadLock
);
579 /* If the system is going to sleep, cancel the reaper thread timer
580 * and mark unloads disabled in case it just fired but hasn't
581 * taken the lock yet. If we are coming back from sleep, just
582 * set unloads enabled; IOService's normal operation will cause
583 * unloads to be considered soon enough.
585 if (messageType
== kIOMessageSystemWillSleep
) {
587 thread_call_cancel(unloadCallout
);
589 unloadsEnabled
= false;
590 } else if (messageType
== kIOMessageSystemHasPoweredOn
) {
591 unloadsEnabled
= true;
593 mutex_unlock(loadLock
);
595 return kIOReturnSuccess
;
600 extern "C" kern_return_t
kmod_unload_cache(void);
602 static void _OSMetaClassConsiderUnloads(__unused thread_call_param_t p0
,
603 __unused thread_call_param_t p1
)
607 OSCollectionIterator
*kmods
;
608 OSCollectionIterator
*classes
;
609 OSMetaClass
*checkClass
;
614 mutex_lock(loadLock
);
616 if (!unloadsEnabled
) {
617 mutex_unlock(loadLock
);
623 kmods
= OSCollectionIterator::withCollection(sKModClassesDict
);
628 while ( (kmodName
= (OSSymbol
*) kmods
->getNextObject()) ) {
631 kfree(ki
, sizeof(kmod_info_t
));
635 ki
= kmod_lookupbyname_locked((char *)kmodName
->getCStringNoCopy());
639 if (ki
->reference_count
) {
643 kmodClasses
= OSDynamicCast(OSSet
,
644 sKModClassesDict
->getObject(kmodName
));
645 classes
= OSCollectionIterator::withCollection(kmodClasses
);
649 while ((checkClass
= (OSMetaClass
*) classes
->getNextObject())
650 && (0 == checkClass
->getInstanceCount()))
654 if (0 == checkClass
) {
655 OSRuntimeUnloadCPP(ki
, 0); // call destructors
656 ret
= kmod_destroy(host_priv_self(), ki
->id
);
666 mutex_unlock(loadLock
);
671 void OSMetaClass::considerUnloads()
675 mutex_lock(loadLock
);
678 unloadCallout
= thread_call_allocate(&_OSMetaClassConsiderUnloads
, 0);
680 thread_call_cancel(unloadCallout
);
681 clock_interval_to_deadline(sConsiderUnloadDelay
, 1000 * 1000 * 1000, &when
);
682 thread_call_enter_delayed(unloadCallout
, when
);
684 mutex_unlock(loadLock
);
687 const OSMetaClass
*OSMetaClass::getMetaClassWithName(const OSSymbol
*name
)
689 OSMetaClass
*retMeta
= 0;
695 retMeta
= (OSMetaClass
*) sAllClassesDict
->getObject(name
);
697 if (!retMeta
&& sStalled
)
699 // Oh dear we have to scan the stalled list and walk the
700 // the stalled list manually.
701 const char *cName
= name
->getCStringNoCopy();
704 // find class in stalled list
705 for (i
= 0; i
< sStalled
->count
; i
++) {
706 retMeta
= sStalled
->classes
[i
];
707 if (0 == strcmp(cName
, (const char *) retMeta
->className
))
711 if (i
< sStalled
->count
)
718 OSObject
*OSMetaClass::allocClassWithName(const OSSymbol
*name
)
721 mutex_lock(loadLock
);
723 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
726 result
= meta
->alloc();
730 mutex_unlock(loadLock
);
735 OSObject
*OSMetaClass::allocClassWithName(const OSString
*name
)
737 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
738 OSObject
*result
= allocClassWithName(tmpKey
);
743 OSObject
*OSMetaClass::allocClassWithName(const char *name
)
745 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
746 OSObject
*result
= allocClassWithName(tmpKey
);
752 OSMetaClassBase
*OSMetaClass::
753 checkMetaCastWithName(const OSSymbol
*name
, const OSMetaClassBase
*in
)
755 OSMetaClassBase
* result
;
756 mutex_lock(loadLock
);
757 const OSMetaClass
* const meta
= getMetaClassWithName(name
);
760 result
= meta
->checkMetaCast(in
);
764 mutex_unlock(loadLock
);
768 OSMetaClassBase
*OSMetaClass::
769 checkMetaCastWithName(const OSString
*name
, const OSMetaClassBase
*in
)
771 const OSSymbol
*tmpKey
= OSSymbol::withString(name
);
772 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
777 OSMetaClassBase
*OSMetaClass::
778 checkMetaCastWithName(const char *name
, const OSMetaClassBase
*in
)
780 const OSSymbol
*tmpKey
= OSSymbol::withCStringNoCopy(name
);
781 OSMetaClassBase
*result
= checkMetaCastWithName(tmpKey
, in
);
787 OSMetaClass::checkMetaCast
788 checkMetaCast(const OSMetaClassBase *check)
790 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.
792 Generally this method is not invoked directly but is used to implement the OSMetaClassBase::metaCast member function.
794 See also OSMetaClassBase::metaCast
797 OSMetaClassBase
*OSMetaClass::checkMetaCast(const OSMetaClassBase
*check
) const
799 const OSMetaClass
* const toMeta
= this;
800 const OSMetaClass
*fromMeta
;
802 for (fromMeta
= check
->getMetaClass(); ; fromMeta
= fromMeta
->superClassLink
) {
803 if (toMeta
== fromMeta
)
804 return (OSMetaClassBase
*) check
; // Discard const
806 if (!fromMeta
->superClassLink
)
813 void OSMetaClass::reservedCalled(int ind
) const
815 const char *cname
= className
->getCStringNoCopy();
816 panic("%s::_RESERVED%s%d called\n", cname
, cname
, ind
);
819 const OSMetaClass
*OSMetaClass::getSuperClass() const
821 return superClassLink
;
824 const OSSymbol
*OSMetaClass::getKmodName() const
826 return (const OSSymbol
*)sSortedByClassesDict
->getObject((OSSymbol
*)this);
829 unsigned int OSMetaClass::getInstanceCount() const
831 return instanceCount
;
834 void OSMetaClass::printInstanceCounts()
836 OSCollectionIterator
*classes
;
840 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
844 while( (className
= (OSSymbol
*)classes
->getNextObject())) {
845 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
848 printf("%24s count: %03d x 0x%03x = 0x%06x\n",
849 className
->getCStringNoCopy(),
850 meta
->getInstanceCount(),
851 meta
->getClassSize(),
852 meta
->getInstanceCount() * meta
->getClassSize() );
858 OSDictionary
* OSMetaClass::getClassDictionary()
860 panic("OSMetaClass::getClassDictionary(): Obsoleted\n");
864 bool OSMetaClass::serialize(__unused OSSerialize
*s
) const
866 panic("OSMetaClass::serialize(): Obsoleted\n");
870 void OSMetaClass::serializeClassDictionary(OSDictionary
*serializeDictionary
)
872 OSDictionary
*classDict
;
874 classDict
= OSDictionary::withCapacity(sAllClassesDict
->getCount());
878 mutex_lock(loadLock
);
880 OSCollectionIterator
*classes
;
881 const OSSymbol
*className
;
883 classes
= OSCollectionIterator::withCollection(sAllClassesDict
);
887 while ((className
= (const OSSymbol
*) classes
->getNextObject())) {
888 const OSMetaClass
*meta
;
891 meta
= (OSMetaClass
*) sAllClassesDict
->getObject(className
);
892 count
= OSNumber::withNumber(meta
->getInstanceCount(), 32);
894 classDict
->setObject(className
, count
);
900 serializeDictionary
->setObject("Classes", classDict
);
903 mutex_unlock(loadLock
);
905 classDict
->release();