Exemplo n.º 1
0
static void xnsynch_clear_boost(struct xnsynch *synch,
				struct xnthread *owner)
{
	struct xnthread *target;
	struct xnsynch *hsynch;
	struct xnpholder *h;
	int wprio;

	removepq(&owner->claimq, &synch->link);
	__clrbits(synch->status, XNSYNCH_CLAIMED);
	wprio = w_bprio(owner);

	if (emptypq_p(&owner->claimq)) {
		xnthread_clear_state(owner, XNBOOST);
		target = owner;
	} else {
		/* Find the highest priority needed to enforce the PIP. */
		hsynch = link2synch(getheadpq(&owner->claimq));
		h = getheadpq(&hsynch->pendq);
		XENO_BUGON(NUCLEUS, h == NULL);
		target = link2thread(h, plink);
		if (w_cprio(target) > wprio)
			wprio = w_cprio(target);
		else
			target = owner;
	}

	if (w_cprio(owner) != wprio &&
	    !xnthread_test_state(owner, XNZOMBIE))
		xnsynch_renice_thread(owner, target);
}
Exemplo n.º 2
0
void xnsynch_release_all_ownerships(xnthread_t *thread)
{
	xnpholder_t *holder, *nholder;

	for (holder = getheadpq(&thread->claimq); holder != NULL;
	     holder = nholder) {
		/* Since xnsynch_wakeup_one_sleeper() alters the claim
		   queue, we need to be conservative while scanning
		   it. */
		xnsynch_t *synch = link2synch(holder);
		nholder = nextpq(&thread->claimq, holder);
		xnsynch_wakeup_one_sleeper(synch);
		if (synch->cleanup)
			synch->cleanup(synch);
	}
}
Exemplo n.º 3
0
void xnsynch_release_all_ownerships(struct xnthread *thread)
{
	struct xnpholder *holder, *nholder;
	struct xnsynch *synch;

	for (holder = getheadpq(&thread->claimq); holder != NULL;
	     holder = nholder) {
		/*
		 * Since xnsynch_release() alters the claim queue, we
		 * need to be conservative while scanning it.
		 */
		synch = link2synch(holder);
		nholder = nextpq(&thread->claimq, holder);
		xnsynch_release_thread(synch, thread);
		if (synch->cleanup)
			synch->cleanup(synch);
	}
}
Exemplo n.º 4
0
/*
 * Detect when a thread is about to relax while holding a
 * synchronization object currently claimed by another thread, which
 * bears the TWARNSW bit (thus advertising a concern about potential
 * spurious relaxes and priority inversion). By relying on the claim
 * queue, we restrict the checks to PIP-enabled objects, but that
 * already covers most of the use cases anyway.
 */
void xnsynch_detect_claimed_relax(struct xnthread *owner)
{
	struct xnpholder *hs, *ht;
	struct xnthread *sleeper;
	struct xnsynch *synch;

	for (hs = getheadpq(&owner->claimq); hs != NULL;
	     hs = nextpq(&owner->claimq, hs)) {
		synch = link2synch(hs);
		for (ht = getheadpq(&synch->pendq); ht != NULL;
		     ht = nextpq(&synch->pendq, ht)) {
			sleeper = link2thread(ht, plink);
			if (xnthread_test_state(sleeper, XNTRAPSW)) {
				xnthread_set_info(sleeper, XNSWREP);
				xnshadow_send_sig(sleeper, SIGDEBUG,
						  SIGDEBUG_MIGRATE_PRIOINV, 1);
			}
		}
	}
}