X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b226f5e54a60dc81db17b1260381d7dbfea3cdf1..0a7de7458d150b5d4dffc935ba399be265ef0a1a:/iokit/Kernel/IOPerfControl.cpp diff --git a/iokit/Kernel/IOPerfControl.cpp b/iokit/Kernel/IOPerfControl.cpp index e5ece3480..f90699c34 100644 --- a/iokit/Kernel/IOPerfControl.cpp +++ b/iokit/Kernel/IOPerfControl.cpp @@ -12,192 +12,220 @@ #define super OSObject OSDefineMetaClassAndStructors(IOPerfControlClient, OSObject); -bool IOPerfControlClient::init(IOService *driver, uint64_t maxWorkCapacity) +bool +IOPerfControlClient::init(IOService *driver, uint64_t maxWorkCapacity) { - if (!super::init()) - return false; - - interface = PerfControllerInterface{ - .version = 0, - .registerDevice = - [](IOService *device) { - return kIOReturnSuccess; - }, - .unregisterDevice = - [](IOService *device) { - return kIOReturnSuccess; - }, - .workCanSubmit = - [](IOService *device, PerfControllerInterface::WorkState *state, WorkSubmitArgs *args) { - return false; - }, - .workSubmit = - [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkSubmitArgs *args) { - }, - .workBegin = - [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkBeginArgs *args) { - }, - .workEnd = - [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkEndArgs *args, bool done) { - }, - }; - - interfaceLock = IOLockAlloc(); - if (!interfaceLock) - goto error; - - deviceRegistrationList = OSSet::withCapacity(4); - if (!deviceRegistrationList) - goto error; - - bzero(workTable, sizeof(workTable)); - memset(&workTable[kIOPerfControlClientWorkUntracked], ~0, sizeof(WorkTableEntry)); - workTableNextIndex = kIOPerfControlClientWorkUntracked + 1; - - workTableLock = IOSimpleLockAlloc(); - if (!workTableLock) - goto error; - - // TODO: check sum(maxWorkCapacities) < table size - - return true; + if (!super::init()) { + return false; + } + + interface = PerfControllerInterface{ + .version = 0, + .registerDevice = + [](IOService *device) { + return kIOReturnSuccess; + }, + .unregisterDevice = + [](IOService *device) { + return kIOReturnSuccess; + }, + .workCanSubmit = + [](IOService *device, PerfControllerInterface::WorkState *state, WorkSubmitArgs *args) { + return false; + }, + .workSubmit = + [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkSubmitArgs *args) { + }, + .workBegin = + [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkBeginArgs *args) { + }, + .workEnd = + [](IOService *device, uint64_t token, PerfControllerInterface::WorkState *state, WorkEndArgs *args, bool done) { + }, + }; + + interfaceLock = IOLockAlloc(); + if (!interfaceLock) { + goto error; + } + + deviceRegistrationList = OSSet::withCapacity(4); + if (!deviceRegistrationList) { + goto error; + } + + bzero(workTable, sizeof(workTable)); + memset(&workTable[kIOPerfControlClientWorkUntracked], ~0, sizeof(WorkTableEntry)); + workTableNextIndex = kIOPerfControlClientWorkUntracked + 1; + + workTableLock = IOSimpleLockAlloc(); + if (!workTableLock) { + goto error; + } + + // TODO: check sum(maxWorkCapacities) < table size + + return true; error: - if (interfaceLock) - IOLockFree(interfaceLock); - if (deviceRegistrationList) - deviceRegistrationList->release(); - if (workTableLock) - IOSimpleLockFree(workTableLock); - return false; + if (interfaceLock) { + IOLockFree(interfaceLock); + } + if (deviceRegistrationList) { + deviceRegistrationList->release(); + } + if (workTableLock) { + IOSimpleLockFree(workTableLock); + } + return false; } IOPerfControlClient *_Atomic gSharedClient = nullptr; -IOPerfControlClient *IOPerfControlClient::copyClient(IOService *driver, uint64_t maxWorkCapacity) +IOPerfControlClient * +IOPerfControlClient::copyClient(IOService *driver, uint64_t maxWorkCapacity) { - IOPerfControlClient *client = atomic_load_explicit(&gSharedClient, memory_order_acquire); - if (client == nullptr) { - IOPerfControlClient *expected = client; - client = new IOPerfControlClient; - if (!client || !client->init(driver, maxWorkCapacity)) - panic("could not create IOPerfControlClient"); - if (!atomic_compare_exchange_strong_explicit(&gSharedClient, &expected, client, memory_order_acq_rel, - memory_order_acquire)) { - client->release(); - client = expected; - } - } - // TODO: add maxWorkCapacity to existing client - client->retain(); - return client; + IOPerfControlClient *client = atomic_load_explicit(&gSharedClient, memory_order_acquire); + if (client == nullptr) { + IOPerfControlClient *expected = client; + client = new IOPerfControlClient; + if (!client || !client->init(driver, maxWorkCapacity)) { + panic("could not create IOPerfControlClient"); + } + if (!atomic_compare_exchange_strong_explicit(&gSharedClient, &expected, client, memory_order_acq_rel, + memory_order_acquire)) { + client->release(); + client = expected; + } + } + // TODO: add maxWorkCapacity to existing client + client->retain(); + return client; } -uint64_t IOPerfControlClient::allocateToken(thread_group *thread_group) +uint64_t +IOPerfControlClient::allocateToken(thread_group *thread_group) { - uint64_t token = kIOPerfControlClientWorkUntracked; + uint64_t token = kIOPerfControlClientWorkUntracked; - return token; + return token; } -void IOPerfControlClient::deallocateToken(uint64_t token) +void +IOPerfControlClient::deallocateToken(uint64_t token) { } -bool IOPerfControlClient::getEntryForToken(uint64_t token, IOPerfControlClient::WorkTableEntry &entry) +bool +IOPerfControlClient::getEntryForToken(uint64_t token, IOPerfControlClient::WorkTableEntry &entry) { - if (token == kIOPerfControlClientWorkUntracked) - return false; - - if (token >= kWorkTableNumEntries) - panic("Invalid work token (%llu): index out of bounds.", token); - - entry = workTable[token]; - auto *thread_group = entry.thread_group; - assertf(thread_group, "Invalid work token: %llu", token); - return thread_group != nullptr; + if (token == kIOPerfControlClientWorkUntracked) { + return false; + } + + if (token >= kWorkTableNumEntries) { + panic("Invalid work token (%llu): index out of bounds.", token); + } + + entry = workTable[token]; + auto *thread_group = entry.thread_group; + assertf(thread_group, "Invalid work token: %llu", token); + return thread_group != nullptr; } -void IOPerfControlClient::markEntryStarted(uint64_t token, bool started) +void +IOPerfControlClient::markEntryStarted(uint64_t token, bool started) { - if (token == kIOPerfControlClientWorkUntracked) - return; + if (token == kIOPerfControlClientWorkUntracked) { + return; + } - if (token >= kWorkTableNumEntries) - panic("Invalid work token (%llu): index out of bounds.", token); + if (token >= kWorkTableNumEntries) { + panic("Invalid work token (%llu): index out of bounds.", token); + } - workTable[token].started = started; + workTable[token].started = started; } -IOReturn IOPerfControlClient::registerDevice(__unused IOService *driver, IOService *device) +IOReturn +IOPerfControlClient::registerDevice(__unused IOService *driver, IOService *device) { - IOReturn ret = kIOReturnSuccess; + IOReturn ret = kIOReturnSuccess; - IOLockLock(interfaceLock); + IOLockLock(interfaceLock); - if (interface.version > 0) - ret = interface.registerDevice(device); - else - deviceRegistrationList->setObject(device); + if (interface.version > 0) { + ret = interface.registerDevice(device); + } else { + deviceRegistrationList->setObject(device); + } - IOLockUnlock(interfaceLock); + IOLockUnlock(interfaceLock); - return ret; + return ret; } -void IOPerfControlClient::unregisterDevice(__unused IOService *driver, IOService *device) +void +IOPerfControlClient::unregisterDevice(__unused IOService *driver, IOService *device) { - IOLockLock(interfaceLock); + IOLockLock(interfaceLock); - if (interface.version > 0) - interface.unregisterDevice(device); - else - deviceRegistrationList->removeObject(device); + if (interface.version > 0) { + interface.unregisterDevice(device); + } else { + deviceRegistrationList->removeObject(device); + } - IOLockUnlock(interfaceLock); + IOLockUnlock(interfaceLock); } -uint64_t IOPerfControlClient::workSubmit(IOService *device, WorkSubmitArgs *args) +uint64_t +IOPerfControlClient::workSubmit(IOService *device, WorkSubmitArgs *args) { - return kIOPerfControlClientWorkUntracked; + return kIOPerfControlClientWorkUntracked; } -uint64_t IOPerfControlClient::workSubmitAndBegin(IOService *device, WorkSubmitArgs *submitArgs, WorkBeginArgs *beginArgs) +uint64_t +IOPerfControlClient::workSubmitAndBegin(IOService *device, WorkSubmitArgs *submitArgs, WorkBeginArgs *beginArgs) { - return kIOPerfControlClientWorkUntracked; + return kIOPerfControlClientWorkUntracked; } -void IOPerfControlClient::workBegin(IOService *device, uint64_t token, WorkBeginArgs *args) +void +IOPerfControlClient::workBegin(IOService *device, uint64_t token, WorkBeginArgs *args) { } -void IOPerfControlClient::workEnd(IOService *device, uint64_t token, WorkEndArgs *args, bool done) +void +IOPerfControlClient::workEnd(IOService *device, uint64_t token, WorkEndArgs *args, bool done) { } -IOReturn IOPerfControlClient::registerPerformanceController(PerfControllerInterface pci) +IOReturn +IOPerfControlClient::registerPerformanceController(PerfControllerInterface pci) { - IOReturn result = kIOReturnError; + IOReturn result = kIOReturnError; - IOLockLock(interfaceLock); + IOLockLock(interfaceLock); - if (interface.version == 0 && pci.version > 0) { - assert(pci.registerDevice && pci.unregisterDevice && pci.workCanSubmit && pci.workSubmit && pci.workBegin && pci.workEnd); - result = kIOReturnSuccess; + if (interface.version == 0 && pci.version > 0) { + assert(pci.registerDevice && pci.unregisterDevice && pci.workCanSubmit && pci.workSubmit && pci.workBegin && pci.workEnd); + result = kIOReturnSuccess; - OSObject *obj; - while ((obj = deviceRegistrationList->getAnyObject())) { - IOService *device = OSDynamicCast(IOService, obj); - if (device) - pci.registerDevice(device); - deviceRegistrationList->removeObject(obj); - } + OSObject *obj; + while ((obj = deviceRegistrationList->getAnyObject())) { + IOService *device = OSDynamicCast(IOService, obj); + if (device) { + pci.registerDevice(device); + } + deviceRegistrationList->removeObject(obj); + } - interface = pci; - } + interface = pci; + } - IOLockUnlock(interfaceLock); + IOLockUnlock(interfaceLock); - return result; + return result; }