/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <kern/queue.h>
+#include <kern/sched_prim.h>
extern "C" void console_suspend();
extern "C" void console_resume();
extern "C" kern_return_t
IOCPURunPlatformQuiesceActions(void)
{
+ assert(preemption_enabled() == false);
return iocpu_run_platform_actions(&gActionQueues[kQueueQuiesce], 0, 0U - 1,
NULL, NULL, NULL, TRUE);
}
extern "C" kern_return_t
IOCPURunPlatformActiveActions(void)
{
+ assert(preemption_enabled() == false);
return iocpu_run_platform_actions(&gActionQueues[kQueueActive], 0, 0U - 1,
NULL, NULL, NULL, TRUE);
}
}
#if defined(__arm__) || defined(__arm64__)
-static perfmon_interrupt_handler_func pmi_handler = 0;
+static perfmon_interrupt_handler_func pmi_handler = NULL;
kern_return_t
PE_cpu_perfmon_interrupt_install_handler(perfmon_interrupt_handler_func handler)
}
if (enable) {
- targetCPU->getProvider()->registerInterrupt(1, targetCPU, (IOInterruptAction)pmi_handler, 0);
+ targetCPU->getProvider()->registerInterrupt(1, targetCPU, (IOInterruptAction)pmi_handler, NULL);
targetCPU->getProvider()->enableInterrupt(1);
} else {
targetCPU->getProvider()->disableInterrupt(1);
iter = IORegistryIterator::iterateOver( gIOServicePlane,
kIORegistryIterateRecursively );
if (iter) {
- all = 0;
+ all = NULL;
do{
if (all) {
all->release();
currentShutdownTarget = NULL;
#endif
+ integer_t old_pri;
+ thread_t self = current_thread();
+
+ /*
+ * We need to boost this thread's priority to the maximum kernel priority to
+ * ensure we can urgently preempt ANY thread currently executing on the
+ * target CPU. Note that realtime threads have their own mechanism to eventually
+ * demote their priority below MAXPRI_KERNEL if they hog the CPU for too long.
+ */
+ old_pri = thread_kern_get_pri(self);
+ thread_kern_set_pri(self, thread_kern_get_kernel_maxpri());
+
// Sleep the CPUs.
cnt = numCPUs;
while (cnt--) {
rootDomain->tracePoint( kIOPMTracePointSleepPlatformDriver );
rootDomain->stop_watchdog_timer();
- // Now sleep the boot CPU.
+ /*
+ * Now sleep the boot CPU, including calling the kQueueQuiesce actions.
+ * The system sleeps here.
+ */
+
bootCPU->haltCPU();
+ /*
+ * The system is now coming back from sleep on the boot CPU.
+ * The kQueueActive actions have already been called.
+ */
+
rootDomain->start_watchdog_timer();
rootDomain->tracePoint( kIOPMTracePointWakePlatformActions );
#if defined(__arm64__)
sched_restore_recommended_cores_after_sleep();
#endif
+
+ thread_kern_set_pri(self, old_pri);
}
bool
return true;
}
+void
+IOCPU::detach(IOService *provider)
+{
+ super::detach(provider);
+ IOLockLock(gIOCPUsLock);
+ unsigned int index = gIOCPUs->getNextIndexOfObject(this, 0);
+ if (index != (unsigned int)-1) {
+ gIOCPUs->removeObject(index);
+ }
+ IOLockUnlock(gIOCPUsLock);
+}
+
OSObject *
IOCPU::getProperty(const OSSymbol *aKey) const
{
OSString *stateStr;
IOReturn result;
- if (dict == 0) {
+ if (dict == NULL) {
return kIOReturnUnsupported;
}
stateStr = OSDynamicCast(OSString, dict->getObject(gIOCPUStateKey));
- if (stateStr != 0) {
+ if (stateStr != NULL) {
result = IOUserClient::clientHasPrivilege(current_task(), kIOClientPrivilegeAdministrator);
if (result != kIOReturnSuccess) {
return result;
numCPUs = cpus;
vectors = (IOInterruptVector *)IOMalloc(numSources * sizeof(IOInterruptVector));
- if (vectors == 0) {
+ if (vectors == NULL) {
return kIOReturnNoMemory;
}
bzero(vectors, numSources * sizeof(IOInterruptVector));
OSData *tmpData;
long tmpLong;
- if ((service->getProperty(gIOInterruptControllersKey) != 0) &&
- (service->getProperty(gIOInterruptSpecifiersKey) != 0)) {
+ if ((service->getProperty(gIOInterruptControllersKey) != NULL) &&
+ (service->getProperty(gIOInterruptSpecifiersKey) != NULL)) {
return;
}
assert(numCPUs > 0);
- ml_install_interrupt_handler(cpu, cpu->getCPUNumber(), this, handler, 0);
+ ml_install_interrupt_handler(cpu, cpu->getCPUNumber(), this, handler, NULL);
IOTakeLock(vectors[0].interruptLock);
++enabledCPUs;
{
IOInterruptVector *vector;
+ // Interrupts must be enabled, as this can allocate memory.
+ assert(ml_get_interrupts_enabled() == TRUE);
+
if (source >= numSources) {
return kIOReturnNoResources;
}
int /*source*/,
int *interruptType)
{
- if (interruptType == 0) {
+ if (interruptType == NULL) {
return kIOReturnBadArgument;
}