IOReturn darwin_iwi4965::registerWithPolicyMaker(IOService * policyMaker) { IOReturn ret; // Initialize power management support state. _pmPowerState = kWiFiControllerPowerStateOn; _pmPolicyMaker = policyMaker; // No cheating here. Decouple the driver's handling of power change // requests from the power management work loop thread. Not strictly // necessary for the work that this driver is doing currently, but // useful as an example of how to do things in general. // // Allocate thread callouts for asynchronous power on and power off. // Allocation failure is not detected here, but before each use in // the setPowerState() method. _powerOffThreadCall = thread_call_allocate( (thread_call_func_t) handleSetPowerStateOff, (thread_call_param_t) this ); _powerOnThreadCall = thread_call_allocate( (thread_call_func_t) handleSetPowerStateOn, (thread_call_param_t) this ); ret = _pmPolicyMaker->registerPowerDriver(this, _wifiControllerPowerStateArray, kWiFiControllerPowerStateCount); return ret; }
int start_def_pager( __unused char *bs_device ) { /* MACH_PORT_FACE master_device_port; */ /* MACH_PORT_FACE security_port; */ __unused static char here[] = "main"; /* setup read buffers, etc */ default_pager_initialize(); #ifndef MACH_KERNEL default_pager(); #endif if (DEFAULT_PAGER_IS_ACTIVE) { /* start the backing store monitor, it runs on a callout thread */ default_pager_backing_store_monitor_callout = thread_call_allocate(default_pager_backing_store_monitor, NULL); if (!default_pager_backing_store_monitor_callout) panic("can't start backing store monitor thread"); thread_call_enter(default_pager_backing_store_monitor_callout); } return (0); }
void tcp_lro_init(void) { int i; bzero(lro_flow_list, sizeof (struct lro_flow) * TCP_LRO_NUM_FLOWS); for (i = 0; i < TCP_LRO_FLOW_MAP; i++) { lro_flow_map[i] = TCP_LRO_FLOW_UNINIT; } /* * allocate lock group attribute, group and attribute for tcp_lro_lock */ tcp_lro_mtx_grp_attr = lck_grp_attr_alloc_init(); tcp_lro_mtx_grp = lck_grp_alloc_init("tcplro", tcp_lro_mtx_grp_attr); tcp_lro_mtx_attr = lck_attr_alloc_init(); lck_mtx_init(&tcp_lro_lock, tcp_lro_mtx_grp, tcp_lro_mtx_attr); tcp_lro_timer = thread_call_allocate(tcp_lro_timer_proc, NULL); if (tcp_lro_timer == NULL) { panic_plain("%s: unable to allocate lro timer", __func__); } return; }
cyclic_id_t cyclic_add(cyc_handler_t *handler, cyc_time_t *when) { uint64_t now; wrap_thread_call_t *wrapTC = _MALLOC(sizeof(wrap_thread_call_t), M_TEMP, M_ZERO | M_WAITOK); if (NULL == wrapTC) return CYCLIC_NONE; wrapTC->TChdl = thread_call_allocate( _cyclic_apply, NULL ); wrapTC->hdlr = *handler; wrapTC->when = *when; ASSERT(when->cyt_when == 0); ASSERT(when->cyt_interval < WAKEUP_REAPER); nanoseconds_to_absolutetime(wrapTC->when.cyt_interval, (uint64_t *)&wrapTC->when.cyt_interval); now = mach_absolute_time(); wrapTC->deadline = now; clock_deadline_for_periodic_event( wrapTC->when.cyt_interval, now, &(wrapTC->deadline) ); (void)thread_call_enter1_delayed( wrapTC->TChdl, (void *)wrapTC, wrapTC->deadline ); return (cyclic_id_t)wrapTC; }
bool AppleRS232Serial::initForPM(IOService *provider) { IOReturn rc; ELG(0, provider, "initForPM - entry. provider="); PMinit(); // Initialize superclass variables provider->joinPMtree(this); // Attach into the power management hierarchy if (pm_vars == NULL) { // Did it work ALERT(0, provider, "initForPM - joinPMtree failed"); return false; } // Initialize power management support state. // if async on/off might need two of these fPowerThreadCall = thread_call_allocate(handleSetPowerState, (thread_call_param_t) this ); if (fPowerThreadCall == NULL) { // check early, check often ALERT(0, 0, "initForPM - failed to allocate thread"); return false; } // We've done the PMinit, so we're the policy mgr. Register w/ourselves as the driver (yuck) rc = registerPowerDriver(this, gOurPowerStates, kSCC_PowerStateCount); if (rc) { ALERT(0, rc, "initForPM - failed to registerPowerDriver"); return false; } ELG(0, rc, "initForPM - exit. rc="); return true; }/* end registerWithPolicyMaker */
void self::setTimeoutFunc(void) { debug(DEBUGF_MISC, "setting our timeout"); calloutEntry = (void *)thread_call_allocate((thread_call_func_t)Timeout, (thread_call_param_t)this); }
bool testthreadcall::start( IOService * provider ) { boolean_t ret; uint64_t deadline; IOLog("%s\n", __PRETTY_FUNCTION__); if (!super::start(provider)) { return false; } IOLog("Attempting thread_call_allocate\n"); tcall = thread_call_allocate(thread_call_test_func, this); IOLog("thread_call_t %p\n", tcall); tlock = IOSimpleLockAlloc(); IOLog("tlock %p\n", tlock); clock_interval_to_deadline(5, NSEC_PER_SEC, &deadline); IOLog("%d sec deadline is %llu\n", 5, deadline); ret = thread_call_enter_delayed(tcall, deadline); return true; }
void checkACStatusUpdate() { cancelACStatusUpdate(); isStatusThreadCanCancel = false; isStatusThreadCancelled = false; statusThread = thread_call_allocate(checkACStatusThread, NULL); thread_call_enter(statusThread); }
bool NoSleepExtension::start( IOService * provider ) { #ifdef DEBUG IOLog("%s[%p]::%s(%p)\n", getName(), this, __FUNCTION__, provider); #endif if( !super::start( provider )) return( false ); //task_t x = current_task(); //IOLog("task: %p, %p\n", x, bootstrap_port); delayTimer = thread_call_allocate(_switchOffUserSleepDisabled, (thread_call_param_t) this); isSleepStateInitialized = false; acSleepSuppressionState = kNoSleepStateDisabled; batterySleepSuppressionState = kNoSleepStateDisabled; forceClientMessage = false; isOnAC = true; pPowerSource = NULL; // This should be done ASAP, cause pRootDomain // is used later in other methods pRootDomain = getPMRootDomain(); UInt8 loadedState; OSReturn ret = readNVRAM(&loadedState); if(ret == kOSReturnSuccess) { unpackSleepState(loadedState, &batterySleepSuppressionState, &acSleepSuppressionState); } /// NoSleep will be activeted after matching with the IOPMPowerSource //updateSleepPowerState(); clamshellStateInterestNotifier = pRootDomain->registerInterest(gIOGeneralInterest, NoSleepExtension::_clamshellEventInterestHandler, this); registerService(); startPM(provider); IOLog("%s: successfully started\n", getName()); return true; }
void OSMetaClass::considerUnloads() { static thread_call_t unloadCallout; AbsoluteTime when; mutex_lock(loadLock); if (!unloadCallout) unloadCallout = thread_call_allocate(&_OSMetaClassConsiderUnloads, 0); thread_call_cancel(unloadCallout); clock_interval_to_deadline(sConsiderUnloadDelay, 1000 * 1000 * 1000, &when); thread_call_enter_delayed(unloadCallout, when); mutex_unlock(loadLock); }
int start_def_pager( __unused char *bs_device ) { /* MACH_PORT_FACE master_device_port; */ /* MACH_PORT_FACE security_port; MACH_PORT_FACE root_ledger_wired; MACH_PORT_FACE root_ledger_paged; */ __unused static char here[] = "main"; /* default_pager_host_port = ipc_port_make_send(realhost.host_priv_self); master_device_port = ipc_port_make_send(master_device_port); root_ledger_wired = ipc_port_make_send(root_wired_ledger_port); root_ledger_paged = ipc_port_make_send(root_paged_ledger_port); security_port = ipc_port_make_send(realhost.host_security_self); */ #if NORMA_VM norma_mk = 1; #else norma_mk = 0; #endif /* setup read buffers, etc */ default_pager_initialize(); #ifndef MACH_KERNEL default_pager(); #endif /* start the backing store monitor, it runs on a callout thread */ default_pager_backing_store_monitor_callout = thread_call_allocate(default_pager_backing_store_monitor, NULL); if (!default_pager_backing_store_monitor_callout) panic("can't start backing store monitor thread"); thread_call_enter(default_pager_backing_store_monitor_callout); return (0); }
/* * Allocate a thread call with a given priority. Importances * other than THREAD_CALL_PRIORITY_HIGH will be run in threads * with eager preemption enabled (i.e. may be aggressively preempted * by higher-priority threads which are not in the normal "urgent" bands). */ thread_call_t thread_call_allocate_with_priority( thread_call_func_t func, thread_call_param_t param0, thread_call_priority_t pri) { thread_call_t call; if (pri > THREAD_CALL_PRIORITY_LOW) { panic("Invalid pri: %d\n", pri); } call = thread_call_allocate(func, param0); call->tc_pri = pri; return call; }
thread_call_t dtrace_timeout(void (*func)(void *, void *), void* arg, uint64_t nanos) { #pragma unused(arg) thread_call_t call = thread_call_allocate(func, NULL); nanoseconds_to_absolutetime(nanos, &nanos); /* * This method does not use clock_deadline_for_periodic_event() because it is a one-shot, * and clock drift on later invocations is not a worry. */ uint64_t deadline = mach_absolute_time() + nanos; thread_call_enter_delayed(call, deadline); return call; }
IOReturn IOI2CDevice::InitializePowerManagement(void) { IOReturn status; static const IOPMPowerState ourPowerStates[kIOI2CPowerState_COUNT] = { // version capabilityFlags outputPowerCharacter inputPowerRequirement {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, kIOPMSleepCapability, kIOPMSleep, kIOPMSleep, 0, 0, 0, 0, 0, 0, 0, 0}, {1, kIOPMDeviceUsable, kIOPMDoze, kIOPMDoze, 0, 0, 0, 0, 0, 0, 0, 0}, {1, kIOPMDeviceUsable, kIOPMPowerOn, kIOPMPowerOn, 0, 0, 0, 0, 0, 0, 0, 0} }; DLOG("IOI2CDevice@%lx::InitializePowerManagement\n", fI2CAddress); // Initialize Power Management superclass variables from IOService.h PMinit(); fStateFlags |= kStateFlags_PMInit; // Join the Power Management tree from IOService.h fProvider->joinPMtree( this); if (0 == (fPowerStateThreadCall = thread_call_allocate(&IOI2CDevice::sPowerStateThreadCall, (thread_call_param_t) this))) { ERRLOG("IOI2CDevice Failed to allocate threadcall.\n"); return kIOReturnNoResources; } // Register ourselves for power state interest notifications from the controller. if (kIOReturnSuccess != (status = fProvider->callPlatformFunction("IOI2CPowerStateInterest", FALSE, (void *)this, (void *)true, NULL, NULL))) { ERRLOG("IOI2CDevice register IOI2CPowerStateInterest falied\n"); return status; } // Register ourselves as the power controller. if (kIOReturnSuccess != (status = registerPowerDriver( this, (IOPMPowerState *) ourPowerStates, kIOI2CPowerState_COUNT ))) { ERRLOG("IOI2CDevice Failed to registerPowerDriver.\n"); return status; } return status; }
void darwin_iwi3945::queue_te(int num, thread_call_func_t func, thread_call_param_t par, UInt32 timei, bool start) { if (tlink[num]) queue_td(num,NULL); //IWI_DEBUG("queue_te0 %d\n",tlink[num]); if (!tlink[num]) tlink[num]=thread_call_allocate(func,this); //IWI_DEBUG("queue_te1 %d\n",tlink[num]); uint64_t timei2; if (timei) clock_interval_to_deadline(timei,kMillisecondScale,&timei2); //IWI_DEBUG("queue_te time %d %d\n",timei,timei2); int r; if (start==true && tlink[num]) { if (!par && !timei) r=thread_call_enter(tlink[num]); if (!par && timei) r=thread_call_enter_delayed(tlink[num],timei2); if (par && !timei) r=thread_call_enter1(tlink[num],par); if (par && timei) r=thread_call_enter1_delayed(tlink[num],par,timei2); } //IWI_DEBUG("queue_te result %d\n",r); }
__private_extern__ devtimer_ref devtimer_create(devtimer_process_func process_func, void * arg0) { devtimer_ref timer; timer = _MALLOC(sizeof(*timer), M_DEVTIMER, M_WAITOK | M_ZERO); if (timer == NULL) { return (timer); } devtimer_retain(timer); timer->dt_callout = thread_call_allocate(devtimer_process, timer); if (timer->dt_callout == NULL) { _devtimer_printf("devtimer: thread_call_allocate failed\n"); devtimer_release(timer); timer = NULL; } timer->dt_process_func = process_func; timer->dt_arg0 = arg0; return (timer); }
bool IOHIKeyboard::start(IOService * provider) { if (!super::start(provider)) return false; /* * IOHIKeyboard serves both as a service and a nub (we lead a double * life). Register ourselves as a nub to kick off matching. */ AppendNewKeyboardReservedStructForService(this); KeyboardReserved * tempReservedStruct = GetKeyboardReservedStructEventForService(this); if (tempReservedStruct) { tempReservedStruct->repeat_thread_call = thread_call_allocate(_autoRepeat, this); } registerService(kIOServiceSynchronous); return true; }
int PEHaltRestart(unsigned int type) { IOPMrootDomain *pmRootDomain = IOService::getPMRootDomain(); bool noWaitForResponses; AbsoluteTime deadline; thread_call_t shutdown_hang; if(type == kPEHaltCPU || type == kPERestartCPU) { /* Notify IOKit PM clients of shutdown/restart Clients subscribe to this message with a call to IOService::registerInterest() */ /* Spawn a thread that will panic in 30 seconds. If all goes well the machine will be off by the time the timer expires. */ shutdown_hang = thread_call_allocate( &IOPMPanicOnShutdownHang, (thread_call_param_t) type); clock_interval_to_deadline( 30, kSecondScale, &deadline ); thread_call_enter1_delayed( shutdown_hang, 0, deadline ); noWaitForResponses = pmRootDomain->tellChangeDown2(type); /* This notification should have few clients who all do their work synchronously. In this "shutdown notification" context we don't give drivers the option of working asynchronously and responding later. PM internals make it very hard to wait for asynchronous replies. In fact, it's a bad idea to even be calling tellChangeDown2 from here at all. */ } if (gIOPlatform) return gIOPlatform->haltRestart(type); else return -1; }
SCSIPressurePathManager::PortBandwidthGlobals::PortBandwidthGlobals ( void ) { fPathsAllocated = 0; fLock = IOLockAlloc ( ); // Allocate enough space for kPressurePathTableIncrement ports for now. // We can grow the table if we have to... fCapacity = sizeof ( UInt64 ) * kPressurePathTableIncrement; fListHead = ( UInt64 * ) IOMalloc ( fCapacity ); bzero ( fListHead, fCapacity ); #if DEBUG_STATS gThread = thread_call_allocate ( ( thread_call_func_t ) PortBandwidthGlobals::sDumpDebugInfo, ( thread_call_param_t ) this ); SetTimer ( ); #endif /* DEBUG_STATS */ }
bool IOATABlockStorageDriver::start ( IOService * provider ) { IOReturn theErr = kIOReturnSuccess; IOWorkLoop * workLoop = NULL; OSNumber * numCommandObjects = NULL; STATUS_LOG ( ( "IOATABlockStorageDriver::start entering.\n" ) ); fATADevice = NULL; fCommandPool = NULL; fATAUnitID = kATAInvalidDeviceID; fATADeviceType = kUnknownATADeviceType; fATASocketType = kUnknownSocket; fAPMLevel = 0xFF; // First call start() in our superclass if ( super::start ( provider ) == false ) return false; // Cache our provider fATADevice = OSDynamicCast ( IOATADevice, provider ); if ( fATADevice == NULL ) return false; // Find out if the device type is ATA if ( fATADevice->getDeviceType ( ) != reportATADeviceType ( ) ) { ERROR_LOG ( ( "IOATABlockStorageDriver::start exiting, not an ATA device.\n" ) ); return false; } reserved = ( ExpansionData * ) IOMalloc ( sizeof ( ExpansionData ) ); bzero ( reserved, sizeof ( ExpansionData ) ); STATUS_LOG ( ( "IOATABlockStorageDriver::start opening device.\n" ) ); if ( fATADevice->open ( this ) == false ) return false; // Cache the drive unit number (master/slave assignment). fATAUnitID = fATADevice->getUnitID ( ); fATADeviceType = fATADevice->getDeviceType ( ); STATUS_LOG ( ( "IOATABlockStorageDriver::start fATAUnitID = %d.\n", ( UInt8 ) fATAUnitID ) ); STATUS_LOG ( ( "IOATABlockStorageDriver::start fATADeviceType is %d\n", ( UInt8 ) fATADeviceType ) ); bzero ( fDeviceIdentifyData, 512 ); fDeviceIdentifyBuffer = IOMemoryDescriptor::withAddress ( ( void * ) fDeviceIdentifyData, 512, kIODirectionIn ); assert ( fDeviceIdentifyBuffer != NULL ); fDeviceIdentifyBuffer->prepare ( ); numCommandObjects = OSDynamicCast ( OSNumber, getProperty ( "IOCommandPoolSize" ) ); fNumCommandObjects = numCommandObjects->unsigned32BitValue ( ); STATUS_LOG ( ( "IOATABlockStorageDriver::start fNumCommandObjects = %ld\n", fNumCommandObjects ) ); // Create an IOCommandGate (for power management support) and attach // this event source to the provider's workloop fCommandGate = IOCommandGate::commandGate ( this ); assert ( fCommandGate != NULL ); workLoop = getWorkLoop ( ); assert ( workLoop != NULL ); theErr = workLoop->addEventSource ( fCommandGate ); assert ( theErr == kIOReturnSuccess ); fCommandPool = IOCommandPool::commandPool ( this, workLoop, fNumCommandObjects ); assert ( fCommandPool != NULL ); allocateATACommandObjects ( ); // Inspect the provider if ( inspectDevice ( fATADevice ) == false ) return false; fCurrentPowerState = kIOATAPowerStateActive; fProposedPowerState = kIOATAPowerStateActive; fNumCommandsOutstanding = 0; fPowerTransitionInProgress = false; fPowerManagementThread = thread_call_allocate ( ( thread_call_func_t ) IOATABlockStorageDriver::sPowerManagement, ( thread_call_param_t ) this ); if ( fPowerManagementThread == NULL ) { ERROR_LOG ( ( "thread allocation failed.\n" ) ); return false; } // A policy-maker must make these calls to join the PM tree, // and to initialize its state PMinit ( ); // initialize power management variables setIdleTimerPeriod ( k5Minutes ); // 5 minute inactivity timer provider->joinPMtree ( this ); // join power management tree makeUsable ( ); fPowerManagementInitialized = true; initForPM ( ); return ( createNub ( provider ) ); }
/* * forkproc * * Description: Create a new process structure, given a parent process * structure. * * Parameters: parent_proc The parent process * * Returns: !NULL The new process structure * NULL Error (insufficient free memory) * * Note: When successful, the newly created process structure is * partially initialized; if a caller needs to deconstruct the * returned structure, they must call forkproc_free() to do so. */ proc_t forkproc(proc_t parent_proc) { proc_t child_proc; /* Our new process */ static int nextpid = 0, pidwrap = 0, nextpidversion = 0; int error = 0; struct session *sessp; uthread_t parent_uthread = (uthread_t)get_bsdthread_info(current_thread()); MALLOC_ZONE(child_proc, proc_t , sizeof *child_proc, M_PROC, M_WAITOK); if (child_proc == NULL) { printf("forkproc: M_PROC zone exhausted\n"); goto bad; } /* zero it out as we need to insert in hash */ bzero(child_proc, sizeof *child_proc); MALLOC_ZONE(child_proc->p_stats, struct pstats *, sizeof *child_proc->p_stats, M_PSTATS, M_WAITOK); if (child_proc->p_stats == NULL) { printf("forkproc: M_SUBPROC zone exhausted (p_stats)\n"); FREE_ZONE(child_proc, sizeof *child_proc, M_PROC); child_proc = NULL; goto bad; } MALLOC_ZONE(child_proc->p_sigacts, struct sigacts *, sizeof *child_proc->p_sigacts, M_SIGACTS, M_WAITOK); if (child_proc->p_sigacts == NULL) { printf("forkproc: M_SUBPROC zone exhausted (p_sigacts)\n"); FREE_ZONE(child_proc->p_stats, sizeof *child_proc->p_stats, M_PSTATS); FREE_ZONE(child_proc, sizeof *child_proc, M_PROC); child_proc = NULL; goto bad; } /* allocate a callout for use by interval timers */ child_proc->p_rcall = thread_call_allocate((thread_call_func_t)realitexpire, child_proc); if (child_proc->p_rcall == NULL) { FREE_ZONE(child_proc->p_sigacts, sizeof *child_proc->p_sigacts, M_SIGACTS); FREE_ZONE(child_proc->p_stats, sizeof *child_proc->p_stats, M_PSTATS); FREE_ZONE(child_proc, sizeof *child_proc, M_PROC); child_proc = NULL; goto bad; } /* * Find an unused PID. */ proc_list_lock(); nextpid++; retry: /* * If the process ID prototype has wrapped around, * restart somewhat above 0, as the low-numbered procs * tend to include daemons that don't exit. */ if (nextpid >= PID_MAX) { nextpid = 100; pidwrap = 1; } if (pidwrap != 0) { /* if the pid stays in hash both for zombie and runniing state */ if (pfind_locked(nextpid) != PROC_NULL) { nextpid++; goto retry; } if (pgfind_internal(nextpid) != PGRP_NULL) { nextpid++; goto retry; } if (session_find_internal(nextpid) != SESSION_NULL) { nextpid++; goto retry; } } nprocs++; child_proc->p_pid = nextpid; child_proc->p_idversion = nextpidversion++; #if 1 if (child_proc->p_pid != 0) { if (pfind_locked(child_proc->p_pid) != PROC_NULL) panic("proc in the list already\n"); } #endif /* Insert in the hash */ child_proc->p_listflag |= (P_LIST_INHASH | P_LIST_INCREATE); LIST_INSERT_HEAD(PIDHASH(child_proc->p_pid), child_proc, p_hash); proc_list_unlock(); /* * We've identified the PID we are going to use; initialize the new * process structure. */ child_proc->p_stat = SIDL; child_proc->p_pgrpid = PGRPID_DEAD; /* * The zero'ing of the proc was at the allocation time due to need * for insertion to hash. Copy the section that is to be copied * directly from the parent. */ bcopy(&parent_proc->p_startcopy, &child_proc->p_startcopy, (unsigned) ((caddr_t)&child_proc->p_endcopy - (caddr_t)&child_proc->p_startcopy)); /* * Some flags are inherited from the parent. * Duplicate sub-structures as needed. * Increase reference counts on shared objects. * The p_stats and p_sigacts substructs are set in vm_fork. */ child_proc->p_flag = (parent_proc->p_flag & (P_LP64 | P_TRANSLATED | P_AFFINITY)); if (parent_proc->p_flag & P_PROFIL) startprofclock(child_proc); /* * Note that if the current thread has an assumed identity, this * credential will be granted to the new process. */ child_proc->p_ucred = kauth_cred_get_with_ref(); #ifdef CONFIG_EMBEDDED lck_mtx_init(&child_proc->p_mlock, proc_lck_grp, proc_lck_attr); lck_mtx_init(&child_proc->p_fdmlock, proc_lck_grp, proc_lck_attr); #if CONFIG_DTRACE lck_mtx_init(&child_proc->p_dtrace_sprlock, proc_lck_grp, proc_lck_attr); #endif lck_spin_init(&child_proc->p_slock, proc_lck_grp, proc_lck_attr); #else /* !CONFIG_EMBEDDED */ lck_mtx_init(&child_proc->p_mlock, proc_mlock_grp, proc_lck_attr); lck_mtx_init(&child_proc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); #if CONFIG_DTRACE lck_mtx_init(&child_proc->p_dtrace_sprlock, proc_lck_grp, proc_lck_attr); #endif lck_spin_init(&child_proc->p_slock, proc_slock_grp, proc_lck_attr); #endif /* !CONFIG_EMBEDDED */ klist_init(&child_proc->p_klist); if (child_proc->p_textvp != NULLVP) { /* bump references to the text vnode */ /* Need to hold iocount across the ref call */ if (vnode_getwithref(child_proc->p_textvp) == 0) { error = vnode_ref(child_proc->p_textvp); vnode_put(child_proc->p_textvp); if (error != 0) child_proc->p_textvp = NULLVP; } } /* * Copy the parents per process open file table to the child; if * there is a per-thread current working directory, set the childs * per-process current working directory to that instead of the * parents. * * XXX may fail to copy descriptors to child */ child_proc->p_fd = fdcopy(parent_proc, parent_uthread->uu_cdir); #if SYSV_SHM if (parent_proc->vm_shm) { /* XXX may fail to attach shm to child */ (void)shmfork(parent_proc, child_proc); } #endif /* * inherit the limit structure to child */ proc_limitfork(parent_proc, child_proc); if (child_proc->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur != RLIM_INFINITY) { uint64_t rlim_cur = child_proc->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur; child_proc->p_rlim_cpu.tv_sec = (rlim_cur > __INT_MAX__) ? __INT_MAX__ : rlim_cur; } /* Intialize new process stats, including start time */ /* <rdar://6640543> non-zeroed portion contains garbage AFAICT */ bzero(&child_proc->p_stats->pstat_startzero, (unsigned) ((caddr_t)&child_proc->p_stats->pstat_endzero - (caddr_t)&child_proc->p_stats->pstat_startzero)); bzero(&child_proc->p_stats->user_p_prof, sizeof(struct user_uprof)); microtime(&child_proc->p_start); child_proc->p_stats->p_start = child_proc->p_start; /* for compat */ if (parent_proc->p_sigacts != NULL) (void)memcpy(child_proc->p_sigacts, parent_proc->p_sigacts, sizeof *child_proc->p_sigacts); else (void)memset(child_proc->p_sigacts, 0, sizeof *child_proc->p_sigacts); sessp = proc_session(parent_proc); if (sessp->s_ttyvp != NULL && parent_proc->p_flag & P_CONTROLT) OSBitOrAtomic(P_CONTROLT, &child_proc->p_flag); session_rele(sessp); /* * block all signals to reach the process. * no transition race should be occuring with the child yet, * but indicate that the process is in (the creation) transition. */ proc_signalstart(child_proc, 0); proc_transstart(child_proc, 0); child_proc->p_pcaction = (parent_proc->p_pcaction) & P_PCMAX; TAILQ_INIT(&child_proc->p_uthlist); TAILQ_INIT(&child_proc->p_aio_activeq); TAILQ_INIT(&child_proc->p_aio_doneq); /* Inherit the parent flags for code sign */ child_proc->p_csflags = parent_proc->p_csflags; /* * All processes have work queue locks; cleaned up by * reap_child_locked() */ workqueue_init_lock(child_proc); /* * Copy work queue information * * Note: This should probably only happen in the case where we are * creating a child that is a copy of the parent; since this * routine is called in the non-duplication case of vfork() * or posix_spawn(), then this information should likely not * be duplicated. * * <rdar://6640553> Work queue pointers that no longer point to code */ child_proc->p_wqthread = parent_proc->p_wqthread; child_proc->p_threadstart = parent_proc->p_threadstart; child_proc->p_pthsize = parent_proc->p_pthsize; child_proc->p_targconc = parent_proc->p_targconc; if ((parent_proc->p_lflag & P_LREGISTER) != 0) { child_proc->p_lflag |= P_LREGISTER; } child_proc->p_dispatchqueue_offset = parent_proc->p_dispatchqueue_offset; #if PSYNCH pth_proc_hashinit(child_proc); #endif /* PSYNCH */ #if CONFIG_LCTX child_proc->p_lctx = NULL; /* Add new process to login context (if any). */ if (parent_proc->p_lctx != NULL) { /* * <rdar://6640564> This should probably be delayed in the * vfork() or posix_spawn() cases. */ LCTX_LOCK(parent_proc->p_lctx); enterlctx(child_proc, parent_proc->p_lctx, 0); } #endif bad: return(child_proc); }
bool IrDAComm::init(AppleIrDASerial *driver, AppleIrDA *appleirda) { IOReturn rc; IOWorkLoop *workloop; XTRACE(kLogInit, 0, this); #if (hasTracing > 0) DebugLog("log info at 0x%lx", (uintptr_t)IrDALogGetInfo()); #endif require(driver, Fail); fState = kIrDACommStateStart; fDriver = driver; //fTimerSrc = nil; fTimer = nil; fQoS = nil; fIrDA = nil; fIrComm = nil; fWriteBusy = false; fGate = nil; fStartCounter = 0; // counter for initial connection attempts fStop_thread = nil; if (!super::init()) return false; fQoS = driver->GetIrDAQoS(); require(fQoS, Fail); workloop = fDriver->getWorkLoop(); require(workloop, Fail); fStop_thread = thread_call_allocate(stop_thread, this); require(fStop_thread, Fail); fIrDA = TIrGlue::tIrGlue(fDriver, appleirda, workloop, fQoS); // create irda stack require(fIrDA, Fail); fIrComm = IrComm::irComm(fIrDA, this); // create an ircomm object require(fIrComm, Fail); fGate = IOCommandGate::commandGate(this, 0); // create a new command gate for our access to IrDA require(fGate, Fail); rc = workloop->addEventSource(fGate); // add it to the usb workloop require(rc == kIOReturnSuccess, Fail); fTimer = CTimer::cTimer(workloop, this, &IrDAComm::TimerRoutine); require(fTimer, Fail); fTimer->StartTimer(100, 0); // 100ms delay after init and then startup //fTimerSrc = IOTimerEventSource::timerEventSource ( driver, &::timeoutRoutine); // create an io timer //require(fTimerSrc, Fail); // //rc = workloop->addEventSource(fTimerSrc); //require(rc == kIOReturnSuccess, Fail); // //rc = fTimerSrc->setTimeoutMS(100); // 100 ms delay after init'ing //require(rc == kIOReturnSuccess, Fail); return true; Fail: return false; } /* end Initialize */
void AppleACPIBatteryDevice::waitingForSystemStartup() { thread_call_t t = thread_call_allocate((thread_call_func_t)startThread, this); thread_call_enter(t); }
__private_extern__ chud_timer_t chudxnu_timer_alloc(chudxnu_timer_callback_func_t func, uint32_t param0) { return (chud_timer_t)thread_call_allocate((thread_call_func_t)func, (thread_call_param_t)param0); }
bool IOEthernetInterface::init(IONetworkController * controller) { OSObject * obj; _reserved = IONew( ExpansionData, 1 ); if( _reserved == 0 ) return false; memset(_reserved, 0, sizeof(ExpansionData)); if ( super::init(controller) == false ) return false; // initialize enet specific fields. setInterfaceType(IFT_ETHER); setMaxTransferUnit( ETHERMTU ); setMediaAddressLength( ETHER_ADDR_LEN ); setMediaHeaderLength( ETHER_HDR_LEN ); setFlags( IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS, IFF_RUNNING | IFF_MULTICAST ); // Add an IONetworkData with room to hold an IOEthernetStats structure. // This class does not reference the data object created, and no harm // is done if the data object is released or replaced. IONetworkData * data = IONetworkData::withInternalBuffer( kIOEthernetStatsKey, sizeof(IOEthernetStats)); if (data) { addNetworkData(data); data->release(); } _inputEventThreadCall = thread_call_allocate( handleEthernetInputEvent, this ); if (!_inputEventThreadCall) return false; // Create and initialize the filter dictionaries. _requiredFilters = OSDictionary::withCapacity(2); _activeFilters = OSDictionary::withCapacity(2); if ( (_requiredFilters == 0) || (_activeFilters == 0) ) return false; obj = controller->copyProperty(kIOPacketFilters); if (obj && ((_supportedFilters = OSDynamicCast(OSDictionary, obj)) == 0)) obj->release(); if (!_supportedFilters) return false; // Cache the bit mask of wake filters supported by the driver. // This value will not change. _supportedWakeFilters = GET_SUPPORTED_FILTERS( gIOEthernetWakeOnLANFilterGroup ); // Retain the Disabled WOL filters OSNumber. // Its value will be updated live for link and WOL changed events. obj = _supportedFilters->getObject( gIOEthernetDisabledWakeOnLANFilterGroup ); _disabledWakeFilters = OSDynamicCast(OSNumber, obj); if (_disabledWakeFilters) _disabledWakeFilters->retain(); // Controller's Unicast (directed) and Broadcast filters should always // be enabled. Those bits should never be cleared. if ( !SET_REQUIRED_FILTERS( gIONetworkFilterGroup, kIOPacketFilterUnicast | kIOPacketFilterBroadcast ) || !SET_REQUIRED_FILTERS( gIOEthernetWakeOnLANFilterGroup, 0 ) || !SET_ACTIVE_FILTERS( gIONetworkFilterGroup, 0 ) || !SET_ACTIVE_FILTERS( gIOEthernetWakeOnLANFilterGroup, 0 ) ) { return false; } _publishedFeatureID = 0; // Publish filter dictionaries to property table. setProperty( kIORequiredPacketFilters, _requiredFilters ); setProperty( kIOActivePacketFilters, _activeFilters ); return true; }