Tramp data In Kernel
表象
內(nèi)核中經(jīng)常見到某些函數(shù)有很多的參數(shù),而且這些參數(shù)會一級一級往下面?zhèn)鬟f,部分參數(shù)可能只有最深一級函數(shù)才會用到,但卻被傳遞了很多級,其中不乏一些bool型的參數(shù),比如如下的代碼流程,6個參數(shù)傳遞了很多級。
kvm_mips_map_page() -> gfn_to_pfn_prot() -> __gfn_to_pfn_memslot() ->hva_to_pfn() -> hva_to_pfn_slow()
對于這樣的代碼,大家覺得如何?這樣的代碼是否有毛病?
這叫什么?
對于逐級傳遞的參數(shù),業(yè)界有專門的術(shù)語對應(yīng),叫Tramp data,其標(biāo)準(zhǔn)定義為:
(programming) Data which is passed via one function to another, and not otherwise used by the first.有問題么?
Tramp data是一種典型的代碼壞味道,其表示:
一些代碼需要了解相隔遙遠(yuǎn)的另一些代碼提供的信息,需要通過中間媒介來傳遞這些信息。其帶來典型的問題如:
另外,內(nèi)核中經(jīng)常使用bool類型的tramp data作為參數(shù)。bool類型的參數(shù)本身也是一種壞味道,會使代碼的可讀性變差。 再者,參數(shù)過多也是一種壞味道,問題很多,比如使函數(shù)變得復(fù)雜、職責(zé)不單一、難以測試等。不專門討論~
為什么出現(xiàn)?
Tramp data出現(xiàn)的一個典型場景是用于代替全局變量,我們知道不合適的全局變量也是一種壞味道,對于全局變量的重構(gòu),最簡單的方法就是使用tramp data了,這個很容易理解。
另一些場景,比如內(nèi)核中,一些功能實(shí)現(xiàn)復(fù)雜,有很長的調(diào)用鏈,在底層的函數(shù)中需要了解的信息,通常都使用這樣的tramp data來傳遞。
如果解決?
最基本的處理方式是:
至少需要保證每一級函數(shù)傳遞的參數(shù)名稱是相同的,保證可讀性。還有一些建議,比如使用單例來重構(gòu),但單例本質(zhì)上還是全局?jǐn)?shù)據(jù),又走回去了,但是一些情況下,全局變量可能比tramp data更好一些~
進(jìn)一步的處理,可能就涉及代碼自身設(shè)計(jì)的問題了,出現(xiàn)tramp data可能說明代碼在設(shè)計(jì)上出了問題,理論上,整潔代碼要求
- 函數(shù)職責(zé)單一。單一職責(zé)的函數(shù),應(yīng)該不會有太多的參數(shù),tramp data出現(xiàn)的幾率也小。
- 低耦合。距離遙遠(yuǎn)的代碼間的依賴,說明其耦合不低。
- 數(shù)據(jù)聲明和數(shù)據(jù)使用的距離盡量短。
- 抽象層次一致。個人理解,可能隱含的意思包括函數(shù)依賴的數(shù)據(jù)應(yīng)當(dāng)最好在同一抽象層次中。
重構(gòu)理論中,建議用:去除中間人和提取類的方法來重構(gòu),具體操作需要針對具體的情況處理了,實(shí)際操作比理論可能復(fù)雜得多。
內(nèi)核中的困惑
內(nèi)核中類似這樣的比比皆是,好像已經(jīng)形成了一種習(xí)慣和風(fēng)格,編寫新代碼時往往會參考已有代碼方式,導(dǎo)致新代碼中仍然有很多這樣的情況。
將那前面的代碼流程看,6個參數(shù)中,幾乎所有的數(shù)據(jù)都可以從vcpu中獲取,按整潔代碼和重構(gòu)理論中的建議,對于過多參數(shù)的重構(gòu),典型的處理方式就是抽象,如將相關(guān)的參數(shù)抽象成對象傳遞,對應(yīng)內(nèi)核中的這種情況,理論上,看似僅傳遞一個vcpu參數(shù)應(yīng)該是更佳的選擇,但代碼中偏偏提取了vcpu中的各種數(shù)據(jù),然后將其逐級傳遞。
這是內(nèi)核中的普遍現(xiàn)象,可能原因是:為了更好性能。 這可能也是內(nèi)核代碼跟用戶態(tài)程序相比,能不做clean code的最好的借口了~
內(nèi)核社區(qū)中曾經(jīng)也發(fā)起過關(guān)于內(nèi)核代碼clean code的爭論,但最終沒有結(jié)果,至今,內(nèi)核中包含上千萬行代碼,早已形成了自己的code style了,不能說其代碼不clean,可能需要你換個角度來看~
原文地址:?https://happyseeker.github.io/kernel/2017/01/20/tramp-data-in-kernel.html
總結(jié)
以上是生活随笔為你收集整理的Tramp data In Kernel的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 彻底弄懂dalvik字节码【三】
- 下一篇: 内核中的page fault copy