这个内核函数可以更具可读性吗? (学术研究所需的想法!)

发布于 2024-07-26 16:13:24 字数 795 浏览 5 评论 0 原文

按照我之前的问题关于极长函数背后的基本原理,我想提出一个关于 一段代码 我正在为我的研究而学习。 它是 Linux 内核中的一个函数,相当长(412 行)且复杂(MCC 索引 133)。 基本上,这是一个又长又嵌套的 switch 语句。

坦率地说,我想不出任何方法来改善这种混乱。 调度表看起来既庞大又低效,任何子例程调用都需要难以想象的参数数量才能覆盖足够大的代码段。

您是否认为可以以更易读的方式重写该函数,而不损失效率? 如果没有,您觉得这段代码可读吗?

不用说,我的研究中出现的任何答案都将得到全额评分——无论是在此处还是在提交的论文中。

在线源中该函数的链接浏览器

Following my previous question regarding the rationale behind extremely long functions, I would like to present a specific question regarding a piece of code I am studying for my research. It's a function from the Linux Kernel which is quite long (412 lines) and complicated (an MCC index of 133). Basically, it's a long and nested switch statement

Frankly, I can't think of any way to improve this mess. A dispatch table seems both huge and inefficient, and any subroutine call would require an inconceivable number of arguments in order to cover a large-enough segment of code.

Do you think of any way this function can be rewritten in a more readable way, without losing efficiency? If not, does the code seem readable to you?

Needless to say, any answer that will appear in my research will be given full credit - both here and in the submitted paper.

Link to the function in an online source browser

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

花伊自在美 2024-08-02 16:13:24

我不认为这个功能是一团糟。 我以前也写过这么乱七八糟的。

该函数是将微处理器制造商提供的表格代码转换为代码。 这是非常低级的东西,为特定的中断或错误原因复制适当的硬件寄存器。 在这种代码中,您通常无法触摸尚未由硬件填充的寄存器 - 这可能会导致总线错误。 这可以防止使用更通用的代码(例如复制所有寄存器)。

我确实看到了一些代码重复。 然而,在这个级别(在中断级别操作),速度更为重要。 我不会在公共代码上使用提取方法,除非我知道提取的方法将被内联。


顺便说一句,当您在那里(内核)时,请务必捕获此代码的更改历史记录。 我怀疑您会发现这里没有太多变化,因为它与硬件相关。 此类代码随时间变化的性质与大多数用户模式代码经历的变化的性质有很大不同。

例如,当实施新的整合 IO 芯片时,这种情况就会发生变化。 在这种情况下,更改很可能是复制粘贴并更改新副本,而不是修改现有代码以适应更改的寄存器。

I don't think that function is a mess. I've had to write such a mess before.

That function is the translation into code of a table from a microprocessor manufacturer. It's very low-level stuff, copying the appropriate hardware registers for the particular interrupt or error reason. In this kind of code, you often can't touch registers which have not been filled in by the hardware - that can cause bus errors. This prevents the use of code that is more general (like copying all registers).

I did see what appeared to be some code duplication. However, at this level (operating at interrupt level), speed is more important. I wouldn't use Extract Method on the common code unless I knew that the extracted method would be inlined.


BTW, while you're in there (the kernel), be sure to capture the change history of this code. I have a suspicion that you'll find there have not been very many changes in here, since it's tied to hardware. The nature of the changes over time of this sort of code will be quite different from the nature of the changes experienced by most user-mode code.

This is the sort of thing that will change, for instance, when a new consolidated IO chip is implemented. In that case, the change is likely to be copy and paste and change the new copy, rather than to modify the existing code to accommodate the changed registers.

清风夜微凉 2024-08-02 16:13:24

非常可怕,恕我直言。 明显的一阶修复是使 switch 中的每个 case 都调用一个函数。 在任何人开始抱怨效率之前,让我先说一个词——“内联”。

编辑:这段代码是否是 Linux FPU 模拟器的一部分? 如果是这样的话,这是非常古老的代码,是一种让 Linux 在没有 FPU 的 Intel 芯片(如 386)上工作的 hack。 如果是的话,那么除了历史学家之外,这可能不适合学术界的研究!

Utterly horrible, IMHO. The obvious first-order fix is to make each case in the switch a call to a function. And before anyone starts mumbling about efficiency, let me just say one word - "inlining".

Edit: Is this code part of the Linux FPU emulator by any chance? If so this is very old code that was a hack to get linux to work on Intel chips like the 386 which didn't have an FPU. If it is, it's probably not a suitable study for academics, except for historians!

傲性难收 2024-08-02 16:13:24

这里有一种规律性,我怀疑对于领域专家来说,这实际上感觉非常连贯。

此外,近距离的变化允许立即进行目视检查。

我认为没有必要重构这段代码。

There's a kind of regularity here, I suspect that for a domain expert this actually feels very coherent.

Also having the variations in close proximty allows immediate visual inspection.

I don't see a need to refactor this code.

愛放△進行李 2024-08-02 16:13:24

我首先为各个类定义常量。 冷冷地看这段代码,切换的目的是一个谜; 如果切换是针对命名常量的,我就有一个起点。

更新:您可以删除案例返回 MAJOR_0C_EXCP 的大约 70 行; 只需让他们完成例程即可。 由于这是内核代码,我会提到可能存在一些性能问题,特别是如果案例顺序已经优化,但它至少会减少您需要处理的代码量。

I'd start by defining constants for the various classes. Coming into this code cold, it's a mystery what the switching is for; if the switching was against named constants, I'd have a starting point.

Update: You can get rid of about 70 lines where the cases return MAJOR_0C_EXCP; simply let them fall through to the end of the routine. Since this is kernel code I'll mention that there might be some performance issues with that, particularly if the case order has already been optimized, but it would at least reduce the amount of code you need to deal with.

囚我心虐我身 2024-08-02 16:13:24

我不太了解内核或重构它们如何工作。

我想到的主要事情是采用该 switch 语句并将每个子步骤分解为一个单独的函数,该函数的名称描述了该部分正在执行的操作。 基本上,更具描述性的名称。

但是,我认为这不再优化该功能。 它只是将其分解为更小的函数,其中可能会有所帮助......我不知道。

那是我的2分钱。

I don't know much about kernels or about how re-factoring them might work.

The main thing that comes to my mind is taking that switch statement and breaking each sub step in to a separate function with a name that describes what the section is doing. Basically, more descriptive names.

But, I don't think this optimizes the function any more. It just breaks it in to smaller functions of which might be helpful... I don't know.

That is my 2 cents.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文