Может ли эта функция ядра быть более читабельной? (Идеи, необходимые для академического исследования!)
Следуя моему предыдущему вопросу относительно обоснования чрезвычайно длинных функций, я хотел бы задать конкретный вопрос, касающийся фрагмента кода, который я изучаю для своего исследования. Это функция из ядра Linux, которая довольно длинная (412 строк) и сложная ( индекс MCC 133). По сути, это длинный и вложенный оператор switch
Честно говоря, я не могу придумать способ улучшить этот беспорядок. Таблица диспетчеризации кажется огромной и неэффективной, и любой вызов подпрограммы потребует немыслимого количества аргументов, чтобы охватить достаточно большой сегмент кода.
Как вы думаете, каким образом эта функция может быть переписана более читабельным образом, без потери эффективности? Если нет, то кажется ли вам код читабельным?
Само собой разумеется, что любой ответ, который появится в моем исследовании, будет в полной мере оценен - и здесь, и в представленном документе.
5 ответов
Совершенно ужасно, ИМХО. Очевидное исправление первого порядка состоит в том, чтобы сделать каждый случай в переключателе вызовом функции. И прежде чем кто-то начнет бормотать об эффективности, позвольте мне сказать одно слово - "встраивание".
Изменить: Является ли этот код частью эмулятора Linux FPU случайно? Если это так, то это очень старый код, взломанный для того, чтобы заставить Linux работать на чипах Intel, таких как 386, у которых нет FPU. Если это так, то это, вероятно, не подходит для академиков, кроме историков!
Я не думаю, что эта функция беспорядок. Я должен был написать такой беспорядок раньше.
Эта функция - перевод в код таблицы от производителя микропроцессора. Это очень низкоуровневый материал, копирующий соответствующие аппаратные регистры для конкретной причины прерывания или ошибки. В этом коде вы часто не можете коснуться регистров, которые не были заполнены аппаратным обеспечением - это может вызвать ошибки шины. Это предотвращает использование более общего кода (например, копирование всех регистров).
Я видел то, что казалось некоторым дублированием кода. Однако на этом уровне (работа на уровне прерывания) скорость важнее. Я бы не использовал Extract Method в общем коде, если бы не знал, что извлеченный метод будет встроенным.
Кстати, пока вы там (ядро), обязательно запишите историю изменений этого кода. У меня есть подозрение, что вы обнаружите, что здесь не так много изменений, поскольку они связаны с аппаратным обеспечением. Характер изменений во времени такого рода кода будет сильно отличаться от характера изменений, испытываемых большинством кодов пользовательского режима.
Это то, что изменится, например, при внедрении нового консолидированного чипа ввода-вывода. В этом случае изменение, скорее всего, будет копировать, вставлять и изменять новую копию, а не модифицировать существующий код, чтобы приспособить измененные регистры.
Я бы начал с определения констант для разных классов. Приходя в этот код холодным, загадка для чего нужна; если бы переключение было против именованных констант, у меня была бы отправная точка.
Обновление: вы можете избавиться от примерно 70 строк, в которых дела возвращаются MAJOR_0C_EXCP; просто дайте им провалиться до конца рутины. Поскольку это код ядра, я упомяну, что с этим могут быть некоторые проблемы с производительностью, особенно если порядок дел уже оптимизирован, но это по крайней мере уменьшит объем кода, с которым вам нужно иметь дело.
Здесь есть какая-то закономерность, я подозреваю, что для эксперта в области это на самом деле кажется очень логичным.
Также наличие изменений в непосредственной близости позволяет немедленно визуальный осмотр.
Я не вижу необходимости в рефакторинге этого кода.
Я не знаю много о ядрах или о том, как рефакторинг их может работать.
Главное, что приходит мне в голову, - взять этот оператор switch и разбить каждый подшаг на отдельную функцию с именем, которое описывает, что делает этот раздел. В основном, более описательные имена.
Но я не думаю, что это оптимизирует функцию больше. Это просто разбивает его на более мелкие функции, которые могут быть полезны... Я не знаю.
Это мои 2 цента.