Ejemplo n.º 1
0
void
thread_deallocate(
	thread_t			thread)
{
	task_t				task;

	if (thread == THREAD_NULL)
		return;

	if (thread_deallocate_internal(thread) > 0)
		return;


	ipc_thread_terminate(thread);

	task = thread->task;

#ifdef MACH_BSD 
	{
		void *ut = thread->uthread;

		thread->uthread = NULL;
		uthread_zone_free(ut);
	}
#endif  /* MACH_BSD */   

	if (thread->t_ledger)
		ledger_dereference(thread->t_ledger);
	if (thread->t_threadledger)
		ledger_dereference(thread->t_threadledger);

	if (thread->kernel_stack != 0)
		stack_free(thread);

	lck_mtx_destroy(&thread->mutex, &thread_lck_grp);
	machine_thread_destroy(thread);

	task_deallocate(task);

	zfree(thread_zone, thread);
}
Ejemplo n.º 2
0
Archivo: pmap.c Proyecto: DJHartley/xnu
/**
 * pmap_destroy
 *
 * Destroy the current pmap and all mappings inside of it.
 */
void
pmap_destroy(pmap_t pmap)
{
    int refcount;

    assert(pmap != NULL);
    
    PMAP_LOCK(pmap);
    refcount = --(pmap->ref_count);
    PMAP_UNLOCK(pmap);
    
    if(refcount) {
        /* Still in use! */
        return;
    }
    
    ledger_dereference(pmap->ledger);
    zfree(pmap_zone, pmap);
    return;
}
Ejemplo n.º 3
0
int
thread_set_cpulimit(int action, uint8_t percentage, uint64_t interval_ns)
{
	thread_t	thread = current_thread(); 
	ledger_t	l;
	uint64_t 	limittime = 0;
	uint64_t	abstime = 0;

	assert(percentage <= 100);

	if (percentage == 0) {
		/*
		 * Remove CPU limit, if any exists.
		 */
		if (thread->t_threadledger != LEDGER_NULL) {
			/*
			 * The only way to get a per-thread ledger is via CPU limits.
			 */
			assert(thread->options & (TH_OPT_PROC_CPULIMIT | TH_OPT_PRVT_CPULIMIT));
			ledger_dereference(thread->t_threadledger);
			thread->t_threadledger = LEDGER_NULL;
			thread->options &= ~(TH_OPT_PROC_CPULIMIT | TH_OPT_PRVT_CPULIMIT);
		}

		return (0);
	}

 	l = thread->t_threadledger;
	if (l == LEDGER_NULL) {
		/*
		 * This thread doesn't yet have a per-thread ledger; so create one with the CPU time entry active.
		 */
		if ((l = ledger_instantiate(thread_ledger_template, LEDGER_CREATE_INACTIVE_ENTRIES)) == LEDGER_NULL)
			return (KERN_RESOURCE_SHORTAGE);

		/*
		 * We are the first to create this thread's ledger, so only activate our entry.
		 */
		ledger_entry_setactive(l, thread_ledgers.cpu_time);
		thread->t_threadledger = l;
	}

	/*
	 * The limit is specified as a percentage of CPU over an interval in nanoseconds.
	 * Calculate the amount of CPU time that the thread needs to consume in order to hit the limit.
	 */
	limittime = (interval_ns * percentage) / 100;
	nanoseconds_to_absolutetime(limittime, &abstime); 
	ledger_set_limit(l, thread_ledgers.cpu_time, abstime);
	/*
	 * Refill the thread's allotted CPU time every interval_ns nanoseconds.
	 */
	ledger_set_period(l, thread_ledgers.cpu_time, interval_ns);

	/*
	 * Ledgers supports multiple actions for one ledger entry, so we do too.
	 */
	if (action == THREAD_CPULIMIT_EXCEPTION) {
		thread->options |= TH_OPT_PROC_CPULIMIT;
		ledger_set_action(l, thread_ledgers.cpu_time, LEDGER_ACTION_EXCEPTION);
	}

	if (action == THREAD_CPULIMIT_BLOCK) {
		thread->options |= TH_OPT_PRVT_CPULIMIT;
		/* The per-thread ledger template by default has a callback for CPU time */
		ledger_disable_callback(l, thread_ledgers.cpu_time);
		ledger_set_action(l, thread_ledgers.cpu_time, LEDGER_ACTION_BLOCK);
	}

	thread->t_threadledger = l;
	return (0);
}