Ядро Linux в комментариях

       

Ядро Linux в комментариях


Переменная предназначена для ускорения работы; она отслеживает следующего наименьшего кандидата в PID, который может быть зарезервирован. (Более точным ее именем было бы next_unsafe.) Когда значение last_pid увеличивается выше этого предела, весь список задач должен быть проверен на предмет того, является ли кандидат в PID все еще зарезервированным (процесс, который первоначально зарезервировал его, может уже завершиться), поскольку просмотр всего списка может быть очень медленным, по возможности его следует избегать. Таким образом, выполняя просмотр, функция get_pid повторно вычисляет переменную next_safe — если какой-либо процесс завершился, это значение теперь может быть выше, и, следовательно, функция get_pid может быть в состоянии избежать некоторых будущих просмотров списка задач. (Переменная next_safe является статической и поэтому ее значение будет запомнено, когда функции get_pid в следующий раз потребуется выделить PID.)

Если новый процесс должен использовать PID совместно с его родительским процессом, возвращается PID родительского процесса.

Начинает поиск среди кандидатов в PID на предмет неиспользуемого значения. Поразрядный оператор AND лишь проверяет, не превышает ли новое значение переменной last_pid 32767 (максимальный допустимый PID), проверяя, не равен ли единице любой, кроме младших 15-и разрядов. Сомнительно, что разработчики ядра действительно нуждались в столь незначительном ускорении работы, но утверждать это трудно; по крайней мере, на момент написания этих строк gcc был недостаточно разумным, чтобы заметить эквивалентность и выбрать несколько более быструю форму, использованную в коде.

Если значение переменной last_pid превышает максимальное допустимое для нее значение, оно устанавливается равным 300. Это число лишено какого-либо особого смысла и является всего лишь еще одной попыткой ускорения работы. Идея заключается в том, что PID с низкими номерами как правило принадлежат долговременным «демонам», создаваемым во время начального запуска и никогда не прерывающимся. Поскольку они всегда занимают PID с низкими номерами, неиспользуемый PID будет найден быстрее, если несколько сот начальных значений никогда не будут считаться доступными для повторного использования. Поскольку количество допустимых PID в 64 раза превосходит максимальное количество задач, допускаемых одновременно (512), напрасная трата нескольких из них вполне оправдана во имя повышения быстродействия.


Поскольку значение last_pid превосходит максимальный допустимый PID, оно должно также превосходить значение next_safe; следовательно, следующая проверка if может быть пропущена.

Если значение переменной last_pid все же меньше значения переменной next_safe, ее новое значение доступно для использования. В противном случае необходимо проверить список задач.

Если текущее значение переменной last_pid принято, оно просто увеличивается, при необходимости устанавливаясь равным 300, и цикл запускается снова. На первый взгляд кажется, что этот цикл мог бы продолжаться вечно — что если все PID уже используются? Но недолгие размышления заставляют отмести такую возможность: максимальный размер списка задач равен максимальному количеству одновременно выполняющихся задач, а количество допустимых PID значительно больше этого числа. Следовательно, со временем цикл должен найти допустимый PID; это всего лишь вопрос времени.

Функция get_pid находит незанятый PID, который и возвращается.



Содержание раздела