Ядро считывает список операций 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. Алгоритм выполнения операций над семафором
Вильям Л Саймон , Вильям Саймон , Наталья Владимировна Макеева , Нора Робертс , Юрий Викторович Щербатых
Зарубежная компьютерная, околокомпьютерная литература / ОС и Сети, интернет / Короткие любовные романы / Психология / Прочая справочная литература / Образование и наука / Книги по IT / Словари и Энциклопедии