/* * Same as __wtd_down, but sem->sleepers is not incremented when * coming from a wakeup. */ void wtd_down_common(struct semaphore * sem, struct worktodo *wtd, int do_incr) { int gotit; int sleepers; init_waitqueue_func_entry(&wtd->wait, __wtd_down_waiter); wtd->data = sem; spin_lock_irq(&semaphore_lock); sem->sleepers += do_incr; sleepers = sem->sleepers; gotit = add_wait_queue_exclusive_cond(&sem->wait, &wtd->wait, atomic_add_negative(sleepers - 1, &sem->count)); if (gotit) sem->sleepers = 0; else sem->sleepers = 1; spin_unlock_irq(&semaphore_lock); if (gotit) { wake_up(&sem->wait); wtd_queue(wtd); } }
void __wtd_down_waiter(wait_queue_t *wait) { struct worktodo *wtd = (struct worktodo *)wait; struct semaphore *sem = wtd->data; __remove_wait_queue(&sem->wait, &wtd->wait); wtd_push(wtd, __wtd_down_action, wtd); wtd_queue(wtd); }
static void skb_async_read_waiter(wait_queue_t *wait) { struct skb_async_info *info = (void *)wait; __remove_wait_queue(info->sk->sleep, &info->wtd.wait); wtd_queue(&info->wtd); }