Вопрос по switch-statement, linux-kernel, mcc – Может ли эта функция ядра быть более читабельной? (Идеи, необходимые для академического исследования!)

2

После моего предыдущего вопроса Что касается обоснования чрезвычайно длинных функций, я хотел бы представить конкретный вопрос, касающийсякусок кода Я учусь для своего исследования. Это функция из ядра Linux, которая довольно длинная (412 строк) и сложная (Индекс MCC из 133). По сути, это длинный и вложенный оператор switch

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

Как вы думаете, каким образом эта функция может быть переписана более читабельным образом, без потери эффективности? Если нет, то кажется ли вам код читабельным?

Само собой разумеется, что любой ответ, который появится в моем исследовании, будет в полной мере оценен - и здесь, и в представленном документе.

Ссылка на функцию в браузере исходного кода

Почему это так? Adam Matan
Это и любые другие сообщения, которые вы делаете по этой теме, должны быть вики-сообществом, ИМХО. anon
У вас есть очень интересные исследования ... Frank V
Я считаю, что код ядра очень сильно отличается от нормального кода приложения. И особенно код, который реализует очень четко определенную и понятную концепцию, которую не нужно изменять или развивать. nos

Ваш Ответ

5   ответов
1

Совершенно ужасно, ИМХО. Очевидное исправление первого порядка состоит в том, чтобы сделать каждый случай в переключателе вызовом функции. И прежде чем кто-то начнет бормотать об эффективности, позвольте мне сказать одно слово - "встраивание".

Edit: Является ли этот код частью эмулятора Linux FPU случайно? Если это так, то это очень старый код, который был взломан для того, чтобы заставить Linux работать на чипах Intel, таких как 386, у которых не было FPU. Если это так, то это, вероятно, неподходящее исследование для академиков, за исключением историков!

@Udi Как кажется, что-то связано с FPU, кажется, что нужно обойти какую-то структуру FPU.
Единственный минус, о котором я могу подумать, - это необоснованно большое количество аргументов, которые необходимо передать. Adam Matan
@ Джон, я согласен - см. Мое редактирование.
Нил: больше слов: это Linux. Вероятно, он должен основываться на различных компиляторах. Также очень вероятно, что никто не смотрит на этот код, за исключением людей, проводящих исследования.
0

Я мало знаю о ядрах или о том, как может сработать их повторный факторинг.

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

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

Это мои 2 цента.

Затраты на вызов функции были бы чрезмерными. Это похоже на часть обработчика прерываний - нужно войти и выйти.
4

Я не думаю, что эта функция - беспорядок. Я должен был написать такой беспорядок прежде.

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

Я видел то, что казалось некоторым дублированием кода. Однако на этом уровне (работа на уровне прерывания) скорость важнее. Я бы не использовал метод извлечения в общем коде, если бы не знал, что извлеченный метод будет встроенным.


Кстати, пока вы там (ядро), обязательно запишите историю изменений этого кода. У меня есть подозрение, что вы обнаружите, что изменений здесь не так уж и много, поскольку оно связано с аппаратным обеспечением. Характер изменений во времени такого рода кода будет сильно отличаться от характера изменений, испытываемых большинством кода пользовательского режима.

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

Спасибо, это было информативно и полезно. Adam Matan
1

Здесь есть какая-то закономерность, я подозреваю, что для эксперта в области это действительно очень логично.

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

Я не вижу необходимости в рефакторинге этого кода.

1

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

Обновление: вы можете избавиться от примерно 70 строк, в которых дела возвращаются MAJOR_0C_EXCP; просто дайте им провалиться до конца рутины. Поскольку это код ядра, я упомяну, что с этим могут быть некоторые проблемы с производительностью, особенно если порядок дел уже оптимизирован, но это, по крайней мере, уменьшит объем кода, с которым вам нужно иметь дело.

Похожие вопросы