Exemple #1
0
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);
}
Exemple #3
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;
}
Exemple #5
0
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 */
Exemple #6
0
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);
}
Exemple #7
0
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);
}
Exemple #11
0
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);
}
Exemple #12
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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);
}
Exemple #16
0
__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 ) );
	
}
Exemple #21
0
/*
 * 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);
}
Exemple #22
0
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;
}