Битый час искал функцию pci_read_config_word(). Нету нигде ее реализации. Однако, заметив, что в drivers/pci.c она все-таки экспортируется, внимательно просмотрел файл. Нашел нижеуказанный текст.
Даже коментировать не хочется. Бить за такое надо.
int pci_##rw##_config_##size (struct pci_dev *dev, int pos, type value) \
{ \
int res; \
unsigned long flags; \
if (PCI_##size##_BAD) return PCIBIOS_BAD_REGISTER_NUMBER; \
spin_lock_irqsave(&pci_lock, flags); \
res = dev->bus->ops->rw##_##size(dev, pos, value); \
spin_unlock_irqrestore(&pci_lock, flags); \
return res; \
}
Угумс. Я кажется еще с yenta_socket когда возился, тоже видел подобные макросы и обалдевал. Раньше как-то не сталкивался с подобными приколами. Неужели девелоперы кернела сменились настолько?
Лучше сгенерировать несколько десятков однотипных функций с помощью макроса, чем писать их руками, а потом, при необходимости, вносить в них во все синхронные изменения.
Смотря чем "лучше". Во-первых, сложно выловить ее определение. Во-вторых, использование макросов и inline функций(+ оперирование ядерными структурами напрямую с учетом того, что в разных версиях ядра структуры нередко меняются) - одна из причин, почему модули Linux просто офигенно непереносимы.
Давайте еще карать за применение функций и переменных. А то недоноски пионеры не могут запомнить, что делает та или иная функция. Читать им видите ли трудно... Это тебе что, роман Марининой, чтоб его в сортире читать?
Почитай книгу TAOCP, раздел о том, что надо писать программы, пишущие програмы, а не писать самому.
Пионер никогда не станет комсомольцем если будет полдня разбираться в трехэтадных макросах, вместо того, чтобы разбираться в сути действия. Комсомолец никогда не станет комунистом, если вместо отладки и ловли багов будет тратить по пол дня на разбор кода запутаный до неузнаваемости. Любой код, а тем более ядра системы, которую позиционируют как свободную, должен быть читабельным. Человек должен смотреть на смелые инженерные решения, а не на умение извратиться с маркосами.
Хорошо, я вот предлагаю отказаться и от функций. Зачем, если можно все писать в main'е? Проходишь курс обучения скоропечатанию -- и вперед. Мозги отключаешь и кодишь. Пофиг, что кода выйдет в n раз больше -- главное, что при чтении програмы не отвлекаешься на вспоминание, что делает та или иная функция.
Ну а если убрать сарказм, то надо просто убивать за фанатизм типа "макросы надо запретить". Макросы -- хороший инструмент, который в нормальных руках творить чудеса может, а если у человека мозгов нет, то он все равно читабедбную програму не напишет, какой бы язык не использовал.
Вижу, что ты вообще плохо понял о чем я написал.
Могу только порекомендовать кроме чтения книг иногда практиковаться.
Например, в качестве примера разобрать, почему драйвер WinNT, собранный на UP будет прекрасно работать на SMP, а драйвер Linux, собранный на UP, преобразует spin-блокировку в ничего и посему на SMP работать не будет.
Грубо говоря, логика работы ядра должна быть собрана в ядре, а не в клиентском модуле. Тогда это будет работать.
В теории макросы можно использовать со смыслом, но в ядре они, к сожалению, в большой степени используются довольно неудачно.
>А это чем тебе не автоматическая генерация?
Так генерируется не функция, а код в месте вставки. В итоге нужной экспортируемой функции нет, зато за счет использования макросов подобных приведенному код разбухает. Это, кстати, осложняет не только поиск определения, но и отладку.
Например, нельзя поставить breakpoint на подобный код. Да и понять из дизассемблированного кода, если собрано без исходного кода, не всегда просто, только засоряет код основной функции.
> Битый час искал функцию pci_read_config_word().
да, помню, я тоже grep до одурения набирал :)
хватит ругаться, это уже давно исправлено:
include/linux/pci.h:
static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val)
{
return pci_bus_read_config_word (dev->bus, dev->devfn, where, val);
}
по поводу того, что spin_lock() раскрывается в модуле, и не
переносится c UP на SMP. это сознательно сделано, binary код
не _хотят_ поддерживать, и все тут.
А ты, небось, жабофил, да? Макры - рулят нипадеццки! А если использование макр или темплейтов в C, Лиспе или C++ мешает тебе найти нужное определение - то у тебя убогая IDE и кривые руки, и не тебе этот код читать.
Слышу голоса виндузятников. :)
А как еще отлаживать ядро на другой архитектуре? :) Только отладчиком(не программным ;) ) и наплюдать с примитивной комконсоли что пишеться. :)
Это не ты часом GTK+ писал (хотя по стилю понятно - не ты). Там assert в библиотеке пришибает приложение. И все от того, что пейсателям лень было подумать о том, как же отреагировать на ситуёвину ПРАВИЛЬНО.
Кто ж тебя, глупого, просит пользоваться стандартным сишным ассертом? Нормальный ассерт - та же аннотация. Только, боюсь, ты и слова такого, как "аннотация", не знаешь (это общая черта всех пользователей дебаггеров).
Ну так разъясни мне, дураку, как способ отличить штатную ситуацию от нештатной, помогает справлятся с уже случившимися непредусмотренными ситуациями. Или может мое понимание настолько неправильное, что мне стоит в детский сад сходить, схемку подучить?
Согласен с Murr. Один раз день потерял по причине почему дома
работает, а на работе Segmentation faults. Дома UP, а на работе SMP,
и всего-то блокировку инициализировал после использования... :-)
Стоит в детский садик, определённо стоит. Ещё раз приказываю - выучи, наконец, что такое аннотации. Тогда дурацких вопросов не будет. Заодно узнай про контракты, как про жалкий частный случай аннотаций.
Сцылку, сестра, сцылку. Настоящий сами-знаете-кто отличался обилием сцылок по теме. Приказываю привести сцылку, где сжато и правильно разъясняется вся ссуть аннотаций, а так же их применение в народном хозяйстве. Литератепрограмминг не предлагать.