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

Spin_lock_string


Эта макрокоманда имеет код, общий для всех макрокоманд блокировки примитива блокировки в цикле. Она также используется в предназначенных для архитектуры х86 версиях функций lock_kernel и unlock_kernel (которые не включены в эту книгу, хотя их универсальные версии — включены; см. строки и ).

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

При успешном завершении этой операции управление передается дальше; в ином случае, в макрокоманде spin_lock_string выполняется переход вперед к строке (команда btsl помещает старое значение бита во флажок Carry процессора, и поэтому здесь применяется команда jc). Это тот же прием, с которым мы уже встречались три раза: цель перехода находится в отдельной секции ядра.

Команда стоит в жестком цикле, повторно проверяя младший бит блокировки в цикле. Обратите внимание, что команды btsl и testb интерпретируют свой первый операнд по-разному: для btsl это — битовая позиция, а для testb — битовая маска. Следовательно, в строке происходит проверка того же бита, который макрокоманда spin_lock_string пыталась (и не смогла) установить в строке , даже несмотря на то, что в первом случае используется операнд $0, а во втором — операнд $1.

Бит был очищен, поэтому макрокоманда spin_lock_string должна выполнить еще одну попытку его захватить. Она переходит назад к строке . Этот код можно было бы упростить только до двух команд и префикса lock:

1: lock ; btsl $0, %0 jc 1b

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



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