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




Sys_msgctl - часть 3


Во втором из оставшихся трех случаях, IPC_STAT, просто выполняется проверка допустимости: настоящая работа для этой команды предусмотрена далее в этой функции. Для последнего из этих трех случаев, IPC_RMID, в этом переключателе работы нет; вся его работа отложена в этой функции на дальнейшее.

Этот код является общим для всех оставшихся случаев и теперь он должен выглядеть для вас знакомым: в нем происходит извлечение индекса массива из msqid, проверка того, что по указанному индексу существует действительная очередь сообщений и сверка порядкового номера.

Выполнение оставшейся части команды IPC_STAT. Если пользователь имеет разрешение читать из очереди, функция sys_msgctl копирует статистическую информацию в буфер вызывающей программы. Если вам кажется, что это в значительной степени напоминает основную часть описанного раннее случая MSG_STAT, то вы правы. Единственным различием между этими двумя случаями является то, что MSG_STAT ожидает «неполный» msqid, как было показано выше, a IPC_STAT ожидает «полный» (то есть включающий порядковый номер).

Копирует статистические данные в пространство пользователя. Эти три строки выполнялись бы чуть быстрее, если бы были перезаписаны следующим образом:

err = 0 ; if (copy_to_user(buf, &tbuf, sizeof(*buf))) err = -EFAULT;

В конце концов, запись в пространство пользователя, безусловно, чаще оканчивается успехом, чем неудачей. По той же причине, соответствующий код в случае MSG_STAT (начиная со строки ) работал бы быстрее, если его перезаписать следующим образом:

if (copy_to_user(buf, &tbuf, sizeof(*buf))) { err = -EFAULT; goto out; } err = id;

Или даже могли бы работать быстрее два следующих варианта, поскольку в них не выполняется ненужное присваивание:

if (copy_to_user (buf, &tbuf, sizeof(*buf))) err = -EFAULT; else err = 0;

или

err = copy_to_user (buf, &buf, sizeof(*buf)) ? -EFAULT : 0 ;

Вопреки очевидному, проведенные автором проверки всех этих изменений показывают, что версия ядра работает быстрее. Причина этого заключается в том, как gcc вырабатывает объектный код: по-видимому, стоимость дополнительного присваивания в версии ядра не идет в сравнение со стоимостью дополнительного перехода в версии автора. (Дополнительный переход нельзя сразу обнаружить, рассматривая исходный код С: необходимо просматривать ассемблерный вывод gcc.) Напомним, что в предыдущих главах мы уже говорили о том, что переходы связаны со значительными потерями, поскольку они заставляют процессор терять преимущества некоторых внутренних алгоритмов параллельного выполнения. Разработчики процессора сделали очень многое по предотвращению влияния потерь, связанных с ветвлениями, но, очевидно, не смогли устранить все проблемы.




Содержание  Назад  Вперед