Exemple #1
0
/*
 *	sched_call_thread:
 *
 *	Call out invoked by the scheduler.  Used only for high-priority
 *	thread call group.
 */
static void
sched_call_thread(
		int				type,
		__unused	thread_t		thread)
{
	thread_call_group_t		group;

	group = &thread_call_groups[THREAD_CALL_PRIORITY_HIGH]; /* XXX */

	thread_call_lock_spin();

	switch (type) {

		case SCHED_CALL_BLOCK:
			--group->active_count;
			if (group->pending_count > 0)
				thread_call_wake(group);
			break;

		case SCHED_CALL_UNBLOCK:
			group->active_count++;
			break;
	}

	thread_call_unlock();
}
Exemple #2
0
boolean_t
thread_call_enter1(
    thread_call_t			call,
    thread_call_param_t		param1)
{
	boolean_t				result = TRUE;
	thread_call_group_t		group = &thread_call_group0;
	spl_t					s;
    
	s = splsched();
	thread_call_lock_spin();
    
    if (call->queue != &group->pending_queue) {
    	result = _pending_call_enqueue(call, group);
		
		if (group->active_count == 0)
			thread_call_wake(group);
	}

	call->param1 = param1;

	thread_call_unlock();
	splx(s);

	return (result);
}
Exemple #3
0
/*
 *	_pending_call_enqueue:
 *
 *	Place an entry at the end of the
 *	pending queue, to be executed soon.
 *
 *	Returns TRUE if the entry was already
 *	on a queue.
 *
 *	Called with thread_call_lock held.
 */
static __inline__ boolean_t
_pending_call_enqueue(
    thread_call_t		call,
	thread_call_group_t	group)
{
	queue_head_t		*old_queue;

	old_queue = call_entry_enqueue_tail(CE(call), &group->pending_queue);

	if (old_queue == NULL) {
		call->tc_submit_count++;
	}

	group->pending_count++;

	thread_call_wake(group);

	return (old_queue != NULL);
}
Exemple #4
0
/*
 *	thread_call_func:
 *
 *	Enqueue a function callout.
 *
 *	Guarantees { function, argument }
 *	uniqueness if unique_call is TRUE.
 */
void
thread_call_func(
    thread_call_func_t		func,
    thread_call_param_t		param,
    boolean_t				unique_call)
{
    thread_call_t			call;
	thread_call_group_t		group = &thread_call_group0;
    spl_t					s;
    
    s = splsched();
    thread_call_lock_spin();
    
    call = TC(queue_first(&group->pending_queue));
    
	while (unique_call && !queue_end(&group->pending_queue, qe(call))) {
    	if (	call->func == func			&&
				call->param0 == param			) {
			break;
		}
	
		call = TC(queue_next(qe(call)));
    }
    
    if (!unique_call || queue_end(&group->pending_queue, qe(call))) {
		call = _internal_call_allocate();
		call->func			= func;
		call->param0		= param;
		call->param1		= NULL;
	
		_pending_call_enqueue(call, group);
		
		if (group->active_count == 0)
			thread_call_wake(group);
    }

    thread_call_unlock();
    splx(s);
}
Exemple #5
0
/*
 *	sched_call_thread:
 *
 *	Call out invoked by the scheduler.
 */
static void
sched_call_thread(
	int				type,
__unused	thread_t		thread)
{
	thread_call_group_t		group = &thread_call_group0;

	thread_call_lock_spin();

	switch (type) {

	case SCHED_CALL_BLOCK:
		if (--group->active_count == 0 && group->pending_count > 0)
			thread_call_wake(group);
		break;

	case SCHED_CALL_UNBLOCK:
		group->active_count++;
		break;
	}

	thread_call_unlock();
}
Exemple #6
0
void
thread_call_delayed_timer(
	timer_call_param_t				p0,
	__unused timer_call_param_t		p1
)
{
    thread_call_t			call;
	thread_call_group_t		group = p0;
	boolean_t				new_pending = FALSE;
	uint64_t				timestamp;

	thread_call_lock_spin();

	timestamp = mach_absolute_time();
    
    call = TC(queue_first(&group->delayed_queue));
    
    while (!queue_end(&group->delayed_queue, qe(call))) {
    	if (call->deadline <= timestamp) {
			_pending_call_enqueue(call, group);
			new_pending = TRUE;
		}
		else
			break;
	    
		call = TC(queue_first(&group->delayed_queue));
    }

	if (!queue_end(&group->delayed_queue, qe(call)))
		_set_delayed_call_timer(call, group);

    if (new_pending && group->active_count == 0)
		thread_call_wake(group);

    thread_call_unlock();
}