Какова цель помещения потока в очередь ожидания с условием, когда разрешено входить только одному потоку? - PullRequest
0 голосов
/ 26 мая 2018

По этому запросу

ssize_t foo_read(struct file *filp, char *buf, size_t count,loff_t *ppos)
{
    foo_dev_t * foo_dev = filp->private_data;
    if (down_interruptible(&foo_dev->sem)
        return -ERESTARTSYS;
    foo_dev->intr = 0;
    outb(DEV_FOO_READ, DEV_FOO_CONTROL_PORT);
    wait_event_interruptible(foo_dev->wait, (foo_dev->intr= =1));
    if (put_user(foo_dev->data, buf))
        return -EFAULT;
    up(&foo_dev->sem);
    return 1;
}

С таким завершением

irqreturn_t foo_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    foo->data = inb(DEV_FOO_DATA_PORT);
    foo->intr = 1;
    wake_up_interruptible(&foo->wait);
    return 1;
}

При условии, что foo_dev-> sem изначально равен 1, тогда только одному потоку разрешено выполнять раздел после down_interruptible (& foo_dev-> sem) и потоки, ожидающие этого семафора, имеют смысл поместить в очередь. (Как я понимаю, создание в foo_dev-> sem больше единицы будет проблемой в этом коде).

Так что, если только один проходВсегда, что использовать foo_dev-> очередь ожидания, нельзя ли приостановить текущий поток, сохранить его указатель как глобальный * curr и разбудить его, когда он завершит свой запрос?

1 Ответ

0 голосов
/ 27 мая 2018

Да, можно поставить один поток для ожидания (используя set_current_state() и schedule()) и возобновить его позже (используя wake_up_process).

Но для этого требуется написание некоторого кода для проверки условий пробуждения и возможного отсутствия потока для пробуждения.

Waitqueues предоставляют готовые функции и макросы для ожидания при условии и пробуждения его позже, поэтому полученный код становится намного короче : одиночный макрос wait_event_interruptible() обрабатывает проверку на событие и переводит поток в спящий режим, а одиночный макрос wake_up_interruptible() обрабатывает возобновление возможно отсутствующего потока.

...