Читаем Архитектура операционной системы UNIX полностью

Ядро считывает список операций oplist из адресного пространства задачи и проверяет корректность номеров семафоров, а также наличие у процесса необходимых разрешений на чтение и корректировку семафоров (Рисунок 11.15). Если таких разрешений не имеется, системная функция завершается неудачно. Если ядру приходится приостанавливать свою работу при обращении к списку операций, оно возвращает семафорам их прежние значения и находится в состоянии приостанова до наступления ожидаемого события, после чего системная функция запускается вновь. Поскольку ядро хранит коды операций над семафорами в глобальном списке, оно вновь считывает этот список из пространства задачи, когда перезапускает системную функцию. Таким образом, операции выполняются комплексно — или все за один сеанс или ни одной.

алгоритм semop /* операции над семафором */

входная информация:

 (1) дескриптор семафора

 (2) список операций над семафором

 (3) количество элементов в списке

выходная информация: исходное значение семафора

{

 проверить корректность дескриптора семафора;

start:

 считать список операций над семафором из пространства задачи в пространство ядра;

 проверить наличие разрешений на выполнение всех операций;

 for (каждой операции в списке) {

  if (код операции имеет положительное значение) {

  прибавить код операции к значению семафора;

  if (для данной операции установлен флаг UNDO)

   скорректировать структуру восстановления для данного процесса;

  вывести из состояния приостанова все процессы, ожидающие увеличения значения семафора;

 }

 else

  if (код операции имеет отрицательное значение) {

   if (код операции + значение семафора ›= 0) {

    прибавить код операции к значению семафора;

    if (флаг UNDO установлен)

     скорректировать структуру восстановления для данного процесса;

    if (значение семафора равно 0)

     вывести из состояния приостанова все процессы, ожидающие обнуления значения семафора;

   continue;

  }

  выполнить все произведенные над семафором в данном сеансе операции в обратной последовательности (восстановить старое значение семафора);

  если (флаги не велят приостанавливаться)

   вернуться с ошибкой;

  приостановиться (до тех пор, пока значение семафора не увеличится);

  перейти на start;  /* повторить цикл с самого начала */

 }

 else { /* код операции равен нулю */

  if (значение семафора отлично от нуля) {

   выполнить все произведенные над семафором в данном сеансе операции в обратной последовательности (восстановить старое значение семафора);

    if (флаги не велят приостанавливаться) return ошибку;

    sleep (до тех пор, пока значение семафора не станет нулевым);

    goto start; /* повторить цикл */

   }

  }

 } /* конец цикла */

 /* все операции над семафором выполнены */

 скорректировать значения полей, в которых хранится время последнего выполнения операций и идентификаторы процессов;

 вернуть исходное значение семафора, существовавшее в момент вызова функции semop;

}

Рисунок 11.15. Алгоритм выполнения операций над семафором

Перейти на страницу:

Все книги серии Серия книг по программному обеспечению издательства prentice hall

Похожие книги