unsigned overcommit_wakes;
int state;
+ unsigned has_pollin;
};
struct pwqr_task {
wake_up_locked(&sb->wqh);
}
if (sb->running > sb->concurrency) {
+ printk(KERN_DEBUG "wake up poll");
wake_up_poll(&sb->wqh_poll, POLLIN);
+ sb->has_pollin = 1;
}
pwqr_sb_unlock_irqrestore(sb, flags);
}
kref_init(&sb->kref);
init_waitqueue_head(&sb->wqh);
+ init_waitqueue_head(&sb->wqh_poll);
sb->concurrency = num_online_cpus();
init_timer(&sb->timer);
sb->timer.function = pwqr_sb_timer_cb;
} else {
__pwqr_sb_update_state(sb, 0);
}
+ pwqt->notifier.ops = &pwqr_preempt_noop_ops;
pwqr_sb_unlock_irqrestore(sb, flags);
pwqr_sb_put(sb);
pwqt->sb = NULL;
hlist_del(&pwqt->link);
spin_unlock(&b->lock);
#endif
- pwqt->notifier.ops = &pwqr_preempt_noop_ops;
if (from_notifier) {
/* When called from sched_{out,in}, it's not allowed to
}
static void pwqr_task_noop_sched_out(struct preempt_notifier *notifier,
- struct task_struct *next)
+ struct task_struct *next)
{
}
if (unlikely(sb->state < 0)) {
pwqr_task_detach(pwqt, sb);
- pwqr_task_release(pwqt, true);
return;
}
if (unlikely(p->state & TASK_DEAD) || unlikely(sb->state < 0)) {
pwqr_task_detach(pwqt, sb);
- pwqr_task_release(pwqt, true);
+ if (p->state & TASK_DEAD)
+ pwqr_task_release(pwqt, true);
return;
}
if (p->state == 0 || (p->state & (__TASK_STOPPED | __TASK_TRACED)))
poll_wait(filp, &sb->wqh_poll, wait);
pwqr_sb_lock_irqsave(sb, flags);
- if (sb->running > sb->concurrency)
+ if (sb->has_pollin)
events |= POLLIN;
if (sb->state < 0)
events |= POLLHUP;
remove_wait_queue(&sb->wqh_poll, &wait);
__set_current_state(TASK_RUNNING);
}
- if (likely(rc == 0))
+ if (likely(rc == 0)) {
*cnt = sb->running - sb->concurrency;
+ sb->has_pollin = 0;
+ }
spin_unlock_irq(&sb->wqh.lock);
return rc;