一、向量定義
在某些情況下,資料結構的末端定義一個可選的區塊,增加其靈活性: struct abc{ int age; char *name[20]; …… char placeholder[0]; } 可選地區從placeholder開始,定義為大小為0的數組。因此當abc被分配帶有可選區塊時,就指向此區塊的起始處,否則指向此結構的尾端。從而可以靈活分配負載的長度。
二、編譯條件指令(#ifdef及其系列指令) #ifdef 或 #if defined用於指示C預先處理程式完成檢查的功能 如:struct sk_buff { …… #ifdef CONFIG_NTFLITER_DEBUG unsigned int nf_debug; #endif …… } 還可以用於選擇編譯語句,屏蔽另一些語句。或者選擇函數原型
三、編譯期間的條件檢查最佳化 多數情況下,當核心用某些外部值比較一個變數以瞭解是否滿足給定條件時,其結果極有可能是可預測的。核心分別使用likely和unlikely宏,進行返回真或假的比較。這些宏會利用gcc編譯器的功能依據該項資訊使代碼的編譯最佳化。 如,假設需要調用do_something函數,在調用失敗時,必須使用handle_error函數進行處理: err = do_something(x, y, z); if(err) handle_error(err); 假設do_something很少失敗,則可以按下列方式重寫代碼: err = do_something(x, y, z); if(unlikely(err)) handle_error(err); linkly和unikely宏其實是用gcc的內建__builtin_expect功能來做程式的最佳化。likely是指為真的機會更大,而unlikely是指為假的機會更大。這樣編譯器可以將機會更大機器碼直接緊跟其後,減少跳轉的次數。
四、互斥
在網路代碼中廣泛使用上鎖,對眾多程式設計類型而言,尤其是針對核心的程式設計,互斥、上鎖機制以及同步都是一般性主題相當複雜而有趣。在網路代碼豬常見的可選互斥方法有:自旋鎖:在某一時刻只能由一個執行的縣城所持有的鎖。自旋鎖只用於多處理器系統中,且應該在預期該鎖只會被短期持有的時候。讀寫鎖:當給定的使用可以明確分為唯讀和讀寫時,應該先使用讀寫鎖。多個讀者可以同時持有該鎖,而同一時刻的持有人只有一個可以寫入,當該鎖被一個寫者持有時,其他讀者和寫者都不能獲得該鎖。讀者的優先順序高於寫者,因此當讀者的數目遠遠大於寫者時,這種類型的鎖可以很好地工作。 但該鎖在唯讀模式下時,不能直接提升為讀寫入模式,需要先釋放該鎖,在以讀寫入模式擷取。RCU(Read-Copy-Update) RCU是Linux 2.6中一個最新的互斥機制,在下列特定條件下工作非常好: 1.與唯讀鎖的請求相比,讀寫鎖的請求很少見 2.持有該鎖的代碼以原子的形式執行,而且不能休眠 3.由該鎖保護的資料結構是通過指標訪問的五、主機和網路位元組序直接的轉化 超過一個位元組的資料結構可以以大端和小端兩種方式存放在記憶體中。小端是將最低位元組存放在最低記憶體位址中,大端恰好相反。Intel處理器遵循小端模式,TCP/IP網路位元組序是大端模式。所以,所有的網路通訊協定都會明確定義位元組的位元組序。 為了代碼的可移植性,都會定義主機和網路位元組序之間的轉換函式,只是若主機和網路為同一位元組序,則為空白操作。否則,將位元組序進行轉換。 htons\ntohs、htonl\ntohl分別為2位元組和四位元組轉換函式。
六、捕獲BUG 核心使用BUG_ON和BUG_TRAP來捕獲條件不滿足的情況。當傳給BUG_TRAP的輸入條件為假時,核心會列印警告資訊。對於BUG_ON的則列印出錯誤訊息,然後系統崩潰。
七、核心程式的時間 核心空間中時間用嘀嗒(tick)來計算。一個嘀嗒是連續到期的定時器中斷之間的時間長度。定時器會負責各種不同任務,而且每秒會固定到期HZ次。HZ是一個變數,由系統體系依賴的代碼進行初始化。如在i386機器上,它被初始化為每秒1000次,所以i386機器上,定時器每秒中斷1000次。 每次定時器到期,就是一個名為jiffies的全域變數遞增。因此,任何時刻,jiffies代表從系統引導後所經過的嘀嗒次數,通用值n*HZ代表的就是n秒。