Внутреннее устройство ядра Linux 2.4




Заблокированные операции над семафорами


Возвращаемое значение из , равное 1 означает, что последовательность операций не была выполнена из-за того, что один из семафоров был заблокирован. В этом случае инициализируется новый элемент очереди содержимым данной последовательности операций. Если какая либо из операций изменяет состояние семафора, то новый элемент добавляется в конец очереди, в противном случае новый элемент добавляется в начало очереди.

В поле semsleeping текущей задачи заносится указатель на очередь ожидания . Задача переводится в состояние TASK_INTERRUPTIBLE и поле sleeper структуры инициализируется указателем на текущую задачу. Далее снимается глобальная блокировка семафора и вызывается планировщик schedule(), чтобы перевести задачу в разряд "спящих".

После пробуждения задача повторно выполняет глобальную блокировку семафора, определяет причину пробуждения и реагирует на нее соответствующим образом:

  • Если набор семафоров был удален, то в вызывающую программу возвращается код ошибки EIDRM.
  • Если поле status в структуре установлено в 1, то задача была разбужена для повторной попытки выполнения операций над семафорами. В этом случае повторно вызывается для выполнения последовательности операций Если try_atomic_semop() вернула 1, то задача снова блокируется, как описано выше. Иначе возвращается 0 либо соответствующий код ошибки. Перед выходом из sys_semop() сбрасывается поле current->semsleeping и удаляется из очереди. Если какая либо из операций производила изменения (увеличение или уменьшение), то вызывается , которая проходит через очередь операций, ожидающих выполнения, для данного набора семафоров и активирует все ожидающие процессы, которые больше не нужно блокировать.
  • Если поле status в структуре НЕ

    установлено в 1 и не была удалена из очереди, то это означает, что задача была разбужена по прерыванию. В этом случае в вызывающую программу возвращается код ошибки EINTR. Перед возвратом сбрасывается поле current->semsleeping и удаляется из очереди. А так же вызывается , если какая либо из операций производила изменения.

  • Если поле status в структуре НЕ

    установлено в 1, а была удалена из очереди, то это означает, что заданная последовательность операций уже была выполнена в . Поле status содержит либо 0, либо код ошибки, это значение и возвращается в вызывающую программу.




  • Содержание  Назад  Вперед