Функция sys_semctl, которая реализует системный вызов semctl, имеет много общего с функцией sys_msgctl. Поэтому здесь мы опишем только интересные различия, в частности, те команды sys_semctl, которые не имеют аналогов в sys_msgctl.
Команды GETVAL, GETPID, GETNCNT, GETZCNT и SETVAL оперируют с отдельными семафорами, а не с наборами семафоров, поэтому в этих случаях нужно вначале проверить соответствие диапазону предоставленного параметра. Если semnum находится в диапазоне, переменная curr становится указателем на соответствующий семафор.
Почти такой же набор команд — GETVAL, GETPID, GETNCNT и GETZCNT — предусматривает чтение или вычисление одного фрагмента информации о семафоре. Эта работа выполняется здесь. Обратите внимание, что верхние биты члена sempid обнуляются по маске в строке ; позже мы покажем, для чего это нужно.
Команда GETALL представляет собой запрос на получение всех значений всех семафоров в этом наборе семафоров. Как и во многих других командах, вся работа по ее выполнению не сосредоточена в одном месте; вскоре мы опишем остальное.
Команда SETVAL устанавливает семафор в заданное значение, безусловно, в заданных пределах. Опять-таки, в данный момент выполняется только часть работы, в основном, проверка диапазона.
Команда SETALL — это обобщение SETVAL; она устанавливает значения всех семафоров в этом наборе. Как и в SETVAL, в данный момент выполняется только работа по настройке, например, проверка диапазона.
Здесь начинается остальная часть программной реализации команды GETALL.
Проверка того, что процесс имеет разрешение на чтение значений семафоров. Эта проверка разрешений дублирует выполняемую в строке .
Копирует значения семафоров в локальный массив sem_io, а затем копирует их оттуда в пространство пользователя.
Остальная часть работы по выполнению команды SETVAL начинается здесь.
Поскольку семафор принимает новое значение, все зарегистрированные корректировки отмены для семафора semnum являются недействительными. В этом цикле выполняется установка их в 0, чтобы они больше не имели силы.
Устанавливает значение семафора в значение, предоставленное вызывающей программой, и вызывает функцию update_queue (строка ) для активизации всех процессов, которые ожидают возникших в результате этого условий.
Основная часть программной реализации команды SETALL начинается здесь.
Все значения семафоров установлены в значения, предоставленные вызывающей программой.
Все корректировки отмены, относящиеся ко всем семафорам в наборе, установлены в нуль. Здесь не происходит ничего особенного, если семафор устанавливается в значение, которое он уже имел, и не должно происходить. Если вызывающая программа хочет установить в новое значение все семафоры, кроме одного, она не может имитировать это поведение, устанавливая данный семафор в то значение, которое он уже имел. Вместо этого, она должна использовать команду SETVAL для всех семафоров в наборе, кроме того, который не должен измениться.