コード例 #1
0
ファイル: semaphore.c プロジェクト: andreiw/polaris
/*
 * the semaphore is granted when the semaphore's
 * count is greater than zero and blocks when equal
 * to zero.
 */
void
sema_p(ksema_t *sp)
{
	sema_impl_t	*s;
	disp_lock_t	*sqlp;

	s = (sema_impl_t *)sp;
	sqlp = &SQHASH(s)->sq_lock;
	disp_lock_enter(sqlp);
	ASSERT(s->s_count >= 0);
	while (s->s_count == 0) {
		if (panicstr) {
			disp_lock_exit(sqlp);
			return;
		}
		thread_lock_high(curthread);
		SEMA_BLOCK(s, sqlp);
		thread_unlock_nopreempt(curthread);
		swtch();
		disp_lock_enter(sqlp);
	}
	s->s_count--;
	disp_lock_exit(sqlp);
}
コード例 #2
0
ファイル: condvar.c プロジェクト: BjoKaSH/mac-zfs
void
cv_broadcast(kcondvar_t *cvp)
{
	condvar_impl_t *cp = (condvar_impl_t *)cvp;

	/* make sure the cv_waiters field looks sane */
	ASSERT(cp->cv_waiters <= CV_MAX_WAITERS);
	if (cp->cv_waiters > 0) {
		sleepq_head_t *sqh = SQHASH(cp);
		disp_lock_enter(&sqh->sq_lock);
		ASSERT(CPU_ON_INTR(CPU) == 0);
		sleepq_wakeall_chan(&sqh->sq_queue, cp);
		cp->cv_waiters = 0;
		disp_lock_exit(&sqh->sq_lock);
	}
}
コード例 #3
0
ファイル: semaphore.c プロジェクト: andreiw/polaris
/*
 * try to acquire the semaphore. if the semaphore is greater than
 * zero, then the semaphore is granted and returns 1. otherwise
 * return 0.
 */
int
sema_tryp(ksema_t *sp)
{
	sema_impl_t	*s;
	sleepq_head_t	*sqh;

	int	gotit = 0;

	s = (sema_impl_t *)sp;
	sqh = SQHASH(s);
	disp_lock_enter(&sqh->sq_lock);
	if (s->s_count > 0) {
		s->s_count--;
		gotit = 1;
	}
	disp_lock_exit(&sqh->sq_lock);
	return (gotit);
}
コード例 #4
0
/*
 * Wake threads that are blocked in a turnstile.
 */
void
turnstile_wakeup(turnstile_t *ts, int qnum, int nthreads, kthread_t *owner)
{
	turnstile_chain_t *tc = &TURNSTILE_CHAIN(ts->ts_sobj);
	sleepq_t *sqp = &ts->ts_sleepq[qnum];

	ASSERT(DISP_LOCK_HELD(&tc->tc_lock));

	/*
	 * Waive any priority we may have inherited from this turnstile.
	 */
	if (ts->ts_inheritor != NULL) {
		turnstile_pi_waive(ts);
	}
	while (nthreads-- > 0) {
		kthread_t *t = sqp->sq_first;
		ASSERT(t->t_ts == ts);
		ASSERT(ts->ts_waiters > 1 || ts->ts_inheritor == NULL);
		DTRACE_SCHED1(wakeup, kthread_t *, t);
		turnstile_dequeue(t);
		CL_WAKEUP(t); /* previous thread lock, tc_lock, not dropped */
		/*
		 * If the caller did direct handoff of ownership,
		 * make the new owner inherit from this turnstile.
		 */
		if (t == owner) {
			kthread_t *wp = ts->ts_sleepq[TS_WRITER_Q].sq_first;
			kthread_t *rp = ts->ts_sleepq[TS_READER_Q].sq_first;
			pri_t wpri = wp ? DISP_PRIO(wp) : 0;
			pri_t rpri = rp ? DISP_PRIO(rp) : 0;
			turnstile_pi_inherit(ts, t, MAX(wpri, rpri));
			owner = NULL;
		}
		thread_unlock_high(t);		/* drop run queue lock */
	}
	if (owner != NULL)
		panic("turnstile_wakeup: owner %p not woken", (void *)owner);
	disp_lock_exit(&tc->tc_lock);
}
コード例 #5
0
/*
 * Drop the lock protecting the hash chain for sobj.
 */
void
turnstile_exit(void *sobj)
{
	disp_lock_exit(&TURNSTILE_CHAIN(sobj).tc_lock);
}
コード例 #6
0
ファイル: semaphore.c プロジェクト: andreiw/polaris
/*
 * similiar to sema_p except that it blocks at an interruptible
 * priority. if a signal is present then return 1 otherwise 0.
 */
int
sema_p_sig(ksema_t *sp)
{
	kthread_t	*t = curthread;
	klwp_t		*lwp = ttolwp(t);
	sema_impl_t	*s;
	disp_lock_t	*sqlp;

	if (lwp == NULL) {
		sema_p(sp);
		return (0);
	}

	s = (sema_impl_t *)sp;
	sqlp = &SQHASH(s)->sq_lock;
	disp_lock_enter(sqlp);
	ASSERT(s->s_count >= 0);
	while (s->s_count == 0) {
		proc_t *p = ttoproc(t);
		thread_lock_high(t);
		t->t_flag |= T_WAKEABLE;
		SEMA_BLOCK(s, sqlp);
		lwp->lwp_asleep = 1;
		lwp->lwp_sysabort = 0;
		thread_unlock_nopreempt(t);
		if (ISSIG(t, JUSTLOOKING) || MUSTRETURN(p, t))
			setrun(t);
		swtch();
		t->t_flag &= ~T_WAKEABLE;
		if (ISSIG(t, FORREAL) ||
		    lwp->lwp_sysabort || MUSTRETURN(p, t)) {
			kthread_t *sq, *tp;
			lwp->lwp_asleep = 0;
			lwp->lwp_sysabort = 0;
			disp_lock_enter(sqlp);
			sq = s->s_slpq;
			/*
			 * in case sema_v and interrupt happen
			 * at the same time, we need to pass the
			 * sema_v to the next thread.
			 */
			if ((sq != NULL) && (s->s_count > 0)) {
				tp = sq;
				ASSERT(THREAD_LOCK_HELD(tp));
				sq = sq->t_link;
				tp->t_link = NULL;
				DTRACE_SCHED1(wakeup, kthread_t *, tp);
				tp->t_sobj_ops = NULL;
				tp->t_wchan = NULL;
				ASSERT(tp->t_state == TS_SLEEP);
				CL_WAKEUP(tp);
				s->s_slpq = sq;
				disp_lock_exit_high(sqlp);
				thread_unlock(tp);
			} else {
				disp_lock_exit(sqlp);
			}
			return (1);
		}
		lwp->lwp_asleep = 0;
		disp_lock_enter(sqlp);
	}
	s->s_count--;
	disp_lock_exit(sqlp);
	return (0);
}