Читаем Разработка ядра Linux полностью

Статически условная переменная может быть создана с помощью макроса

DECLARE_COMPLETION(mr_comp);

Динамически созданная условная переменная может быть инициализирована с помощью функции init_completion().

Задание, которое должно ожидать на условной переменной, вызывает функцию wait_for_completion(). После того как наступило ожидаемое событие, вызов функции complete() посылает сигнал заданию, которое ожидает на условной переменной, и это задание возвращается к выполнению. В табл. 9.7 приведены методы работы с условными переменными.

Таблица. 9.7. Методы работы с условными переменными

МетодОписание
init_completion(struct completion*)Инициализация динамически созданной условной переменной в заданной области памяти
wait_for_completion(struct completion*)Ожидание сигнала на указанной условной переменной
complete(struct completion*)Отправка сигнала всем ожидающим заданиям и возвращение их к выполнению

Для примеров использования условных переменных смотрите файлы kernel/sched.c и kernel/fork.с. Наиболее часто используются условные переменные, которые создаются динамически, как часть структур данных. Код ядра, который ожидает на инициализацию структуры данных, вызывает функцию wait_for_completion(). Когда инициализация закончена, ожидающие задания возвращаются к выполнению с помощью вызова функции complete().

<p>BKL: Большая блокировка ядра</p>

Добро пожаловать к "рыжему пасынку" ядра. Большая блокировка ядра (Big Kernel Lock, BKL) — это глобальная спин-блокировка, которая была создана специально для того, чтобы облегчить переход от первоначальной реализации SMP в операционной системе Linux к мелкоструктурным блокировкам. Блокировка BKL имеет следующие интересные свойства.

• Во время удержания BKL можно переходить в состояние ожидания. Блокировка автоматически освобождается, когда задание переходит в состояние ожидания, и снова захватывается, когда задание планируется на выполнение. Конечно, это не означает, что безопасно переходить в состояние ожидания при удержании BKL, просто это можно делать и это не приведет к взаимоблокировке.

• Блокировка BKL рекурсивна. Один процесс может захватывать эту блокировку несколько раз подряд, и это не приведет к самоблокировке, как в случае обычных спин-блокировок.

• Блокировка BKL может использоваться только в контексте процесса.

• Блокировка BKL — это от лукавого.

Рассмотренные свойства дали возможность упростить переход от ядер серии 2.0 к серии 2.2. Когда в ядро 2.0 была введена поддержка SMP, только одно задание могло выполняться в режиме ядра в любой момент времени (конечно, сейчас ядро распараллелено очень хорошо — пройден огромный путь). Целью создания ядра серии 2.2 было обеспечение возможности параллельного выполнения кода ядра на нескольких процессорах. Блокировка BKL была введена для того, чтобы упростить переход к мелкоструктурным блокировкам. В те времена она оказала большую помощь, а сегодня она приводит к ухудшению масштабируемости[51].

Использовать блокировку BKL не рекомендуется. На самом деле, новый код никогда не должен использовать BKL. Однако эта блокировка все еще достаточно интенсивно используется в некоторых частях ядра. Поэтому важно понимать особенности большой блокировки ядра и интерфейса к ней. Блокировка BKL ведет себя, как обычная спин-блокировка, за исключением тех особенностей, которые были рассмотрены выше. Функция lock_kernel() позволяет захватить блокировку, а функция unlock_kernel() — освободить блокировку. Каждый поток выполнения может рекурсивно захватывать эту блокировку, но после этого необходимо столько же раз вызвать функцию unlock_kernel(). При последнем вызове функции освобождения блокировки блокировка будет освобождена. Функция kernel_locked() возвращает ненулевое значение, если блокировка в данный момент захвачена, в противном случае возвращается нуль. Эти интерфейсы определены в файле . Рассмотрим простой пример использования этой блокировки.

lock_kernel();

/*

* Критический раздел, который синхронизирован со всеми пользователями

* блокировки BKL...

* Заметим, что здесь можно безопасно переходить в состояние ожидания

* и блокировка будет прозрачным образом освобождаться.

* После перепланирования блокировка будет прозрачным образом снова

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных