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


Wait_event


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

    Если условие истино, процесс не должен ожидать.

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

Код wait_event заключен в несколько необычную конструкцию:

do { /* . . . */ } while (0)

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

#define FREE1(p) if (p) free(p)

Все хорошо до тех пор, пока FREE1 не будет задействован в ситуации наподобие:

if (expression) FREE1(p); else printf ("expression ложно.\n");

После разворачивания макроса FREE1 конструкция else ассоциируется не с тем if (т.е. с if относящимся к FREE1).

Я наблюдал, как некоторые программисты так решали подобную проблему:

#define FREE2(p) if (p) { free(p); } #define FREE3(p) { if (p) { free(p); } }

Ни одно из вышеприведенных решений нельзя считать удовлетворительным— точка с запятой, которую программист естественно ставит после вызова макроса, портит разворачиваемый текст. Возьмите, к примеру, FREE2. После разворачивания макроса и добавления отступов для лучшего чтения компилятор получит такой текст:

if (expression) if (p) { free(p); } ; else printf("expression ложно.\n");

Результат — синтаксическая ошибка, поскольку else не связан ни с одним if. Аналогичная проблема имеет место и с FREE3. После некоторых размышлений становится ясно, что абсолютно неважно, есть ли if внутри тела макроса. Ту же проблему можно получить и в результате заключения тела макроса в скобки, причем неважно, что находится внутри макроса.




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



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