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

       

Sigismember


Опять-таки, код похож на код sigaddset, но здесь выполняется проверка, установлен ли разряд. Заметьте, что строка работала бы так же хорошо, имея вид:

return set->sig[0] & (1UL << sig);

Большинство сказанного применимо и к строке . Это нельзя расценивать как усовершенствование, однако можно воспринимать как существенно более согласованый вариант по сравнению с текущей реализацией этих функций.

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


sigismember выбирает реализацию на основе того, является ли передаваемый аргумент константным выражением, подсчитанным на этапе компиляции. Недокументированное чудо __builtin_constant_p компилятора gcc представляет собой оператор этапа компиляции (наподобие sizeof), который выясняет, может ли его аргумент быть вычислен на этапе компиляции.

Если это так, sigismember использует для обсчета значения функцию __const_sigismember (строка ). В противном случае применяется более общая версия __gen_sigismember (строка ). В этой более общей версии задействована команда btl, проверяющая один разряд в передаваемом ей операнде.

Следует отметить, что константа времени компиляции в результирующий код не попадает, а это значит, что вся проверка осуществляется во время компиляции— по сути, sigismember просто заменяется либо __const_sigismember, либо __gen_sigismember, безо всякого намека в объектном кода даже на сам факт подобной замены. Правда, неплохо?



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