MCPcopy Create free account
hub / github.com/F-Stack/f-stack / wakeupshlk

Function wakeupshlk

freebsd/kern/kern_lock.c:309–398  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

307}
308
309static __inline int
310wakeupshlk(struct lock *lk, const char *file, int line)
311{
312 uintptr_t v, x, orig_x;
313 u_int realexslp;
314 int queue, wakeup_swapper;
315
316 wakeup_swapper = 0;
317 for (;;) {
318 x = lockmgr_read_value(lk);
319 if (lockmgr_sunlock_try(lk, &x))
320 break;
321
322 /*
323 * We should have a sharer with waiters, so enter the hard
324 * path in order to handle wakeups correctly.
325 */
326 sleepq_lock(&lk->lock_object);
327 orig_x = lockmgr_read_value(lk);
328retry_sleepq:
329 x = orig_x & (LK_ALL_WAITERS | LK_EXCLUSIVE_SPINNERS);
330 v = LK_UNLOCKED;
331
332 /*
333 * If the lock has exclusive waiters, give them preference in
334 * order to avoid deadlock with shared runners up.
335 * If interruptible sleeps left the exclusive queue empty
336 * avoid a starvation for the threads sleeping on the shared
337 * queue by giving them precedence and cleaning up the
338 * exclusive waiters bit anyway.
339 * Please note that lk_exslpfail count may be lying about
340 * the real number of waiters with the LK_SLEEPFAIL flag on
341 * because they may be used in conjunction with interruptible
342 * sleeps so lk_exslpfail might be considered an 'upper limit'
343 * bound, including the edge cases.
344 */
345 realexslp = sleepq_sleepcnt(&lk->lock_object,
346 SQ_EXCLUSIVE_QUEUE);
347 if ((x & LK_EXCLUSIVE_WAITERS) != 0 && realexslp != 0) {
348 if (lk->lk_exslpfail < realexslp) {
349 lk->lk_exslpfail = 0;
350 queue = SQ_EXCLUSIVE_QUEUE;
351 v |= (x & LK_SHARED_WAITERS);
352 } else {
353 lk->lk_exslpfail = 0;
354 LOCK_LOG2(lk,
355 "%s: %p has only LK_SLEEPFAIL sleepers",
356 __func__, lk);
357 LOCK_LOG2(lk,
358 "%s: %p waking up threads on the exclusive queue",
359 __func__, lk);
360 wakeup_swapper =
361 sleepq_broadcast(&lk->lock_object,
362 SLEEPQ_LK, 0, SQ_EXCLUSIVE_QUEUE);
363 queue = SQ_SHARED_QUEUE;
364 }
365
366 } else {

Callers 1

lockmgr_sunlock_hardFunction · 0.85

Calls 5

lockmgr_sunlock_tryFunction · 0.85
sleepq_lockFunction · 0.85
sleepq_sleepcntFunction · 0.85
sleepq_broadcastFunction · 0.85
sleepq_releaseFunction · 0.85

Tested by

no test coverage detected