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); }
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); } }
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); } }
/* * 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); } } } }