/* static */ void OSMetaClass::printInstanceCounts() { OSCollectionIterator * classes; OSSymbol * className; OSMetaClass * meta; IOLockLock(sAllClassesLock); classes = OSCollectionIterator::withCollection(sAllClassesDict); assert(classes); while( (className = (OSSymbol *)classes->getNextObject())) { meta = (OSMetaClass *)sAllClassesDict->getObject(className); assert(meta); printf("%24s count: %03d x 0x%03x = 0x%06x\n", className->getCStringNoCopy(), meta->getInstanceCount(), meta->getClassSize(), meta->getInstanceCount() * meta->getClassSize() ); } printf("\n"); classes->release(); IOLockUnlock(sAllClassesLock); return; }
OSReturn OSMetaClass::postModLoad(void * loadHandle) { sAllClassesDict = OSDictionary::withCapacity(INIT_POOL_SIZE); assert(sAllClassesDict); printk("libkern_init0: class dict = %p\n", sAllClassesDict); printk("libkern_init0: initializing pool classes ...\n"); for (int i = 0; i < classInitPoolCount; i++) { OSMetaClass* pclass = classInitPool[i]; void** vt = (void**)pclass; printk("libkern_init0: [%d/%d] %s, vt %p\n", i, classInitPoolCount-1, pclass->className, vt[0]); pclass->taggedRetain(); /* fixup name */ pclass->className = OSSymbol::withCStringNoCopy((const char*)pclass->className); printk("\t * fixed class name (%p)\n", pclass->className); sAllClassesDict->setObject(pclass->className, pclass); printk("\t * inserted into class table\n"); } return 0; }
void OSMetaClass::reportModInstances(const char *kmodName) { OSSet *kmodClasses; OSCollectionIterator *iter; OSMetaClass *checkClass; kmodClasses = OSDynamicCast(OSSet, sKModClassesDict->getObject(kmodName)); if (!kmodClasses) return; iter = OSCollectionIterator::withCollection(kmodClasses); if (!iter) return; while ( (checkClass = (OSMetaClass *) iter->getNextObject()) ) if (checkClass->getInstanceCount()) { printf("%s: %s has %d instance(s)\n", kmodName, checkClass->getClassName(), checkClass->getInstanceCount()); } iter->release(); }
bool OSMetaClass::modHasInstance(const char *kmodName) { bool result = false; if (!loadLock) { loadLock = mutex_alloc(ETAP_IO_AHA); mutex_lock(loadLock); } else mutex_lock(loadLock); do { OSSet *kmodClasses; OSCollectionIterator *iter; OSMetaClass *checkClass; kmodClasses = OSDynamicCast(OSSet, sKModClassesDict->getObject(kmodName)); if (!kmodClasses) break; iter = OSCollectionIterator::withCollection(kmodClasses); if (!iter) break; while ( (checkClass = (OSMetaClass *) iter->getNextObject()) ) if (checkClass->getInstanceCount()) { result = true; break; } iter->release(); } while (false); mutex_unlock(loadLock); return result; }
static void _OSMetaClassConsiderUnloads(thread_call_param_t p0, thread_call_param_t p1) { OSSet *kmodClasses; OSSymbol *kmodName; OSCollectionIterator *kmods; OSCollectionIterator *classes; OSMetaClass *checkClass; kmod_info_t *ki = 0; kern_return_t ret; bool didUnload; mutex_lock(loadLock); do { kmods = OSCollectionIterator::withCollection(sKModClassesDict); if (!kmods) break; didUnload = false; while ( (kmodName = (OSSymbol *) kmods->getNextObject()) ) { if (ki) { kfree((vm_offset_t) ki, sizeof(kmod_info_t)); ki = 0; } ki = kmod_lookupbyname_locked((char *)kmodName->getCStringNoCopy()); if (!ki) continue; if (ki->reference_count) { continue; } kmodClasses = OSDynamicCast(OSSet, sKModClassesDict->getObject(kmodName)); classes = OSCollectionIterator::withCollection(kmodClasses); if (!classes) continue; while ((checkClass = (OSMetaClass *) classes->getNextObject()) && (0 == checkClass->getInstanceCount())) {} classes->release(); if (0 == checkClass) { OSRuntimeUnloadCPP(ki, 0); // call destructors ret = kmod_destroy(host_priv_self(), ki->id); didUnload = true; } } kmods->release(); } while (didUnload); mutex_unlock(loadLock); kmod_unload_cache(); }