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


Идиомы кода ядра


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

Я дал идиомам имена, поэтому мне теперь проще о них говорить. Однако имена эти мои, и даны они только в интересах обсуждения. На практике мало кто явно ссылается на идиомы. Они — суть способ, в соответствии с которым ядро выполняет свою работу.

Одна общая идиома — это та, которую я называю идиома накопления ресурсов (resource acquisition idiom). В соответствии с этой идиомой, некоторая функция должна получать последовательность ресурсов — память, блокировки и т.д. Функция перейдет к получению следующего ресурса только после того, как будет успешно получен текущий ресурс. В конечном итоге, функция должна освободить все накопленные ресурсы и не предпринимать попытки освобождать те, при получении которых возникшли ошибки.

Идиома накопления ресурсов была показана в композиции с идиомой переменной ошибки (error variable idiom), которая предполагает использование временной переменной для записи возвращаемого из функции значения. Разумеется, множество функций делают это — тем-то и известна идиома переменной ошибки, когда некая переменная ошибки приеняется для того, чтобы справиться с управлением потоком, усложненным ради достижения высокой скорости. Значение переменной ошибки — либо 0 (успешное выполнение), либо отрицательная величина (ошибка). Рассмотренные две идиомы переходят из рук в руки, естественно приводя к коду, шаблон которого показан ниже:

int f(void) { int err; resource * r1, * r2; err = -ERR1; /* Предположить ошибку */ r1 = acquire_resource1(); if (!r1) /* Ресурс не получен */ goto out; /* Вернуть -ERR1 */ /* Получили ресурс r1; запрашиваем r2 */ err = -ERR2; /* Предположить ошибку */ if (!r2) /* Ресурс не получен */ goto out1; /* Вернуть -ERR2 */ /* Получили ресурсы r1 и r2 */ err = 0; /* Ошибок нет */




- Начало -  - Назад -  - Вперед -



Книжный магазин