核心中常見的符號
[THIS_MODULE]
模組是一種可以在核心運行過程中動態載入、卸載的核心功能組件。2.6核心中模組在被使用時,是不允許被卸載的。編程是需要用”使用計數”來描述模組是否在被使用。THIS_MODULE就充當了這個功能。
[likely& unlikely]
在2.6的核心中經常看到這兩個符號,表面上看if(likely(value))和if(unlikely(value))其實都等同於if(value),但是在實際上執行是不同,加likely的意識著value為真的可能性要大;unlikely與之相反;加上這兩個宏編譯器會對其進行最佳化,提高程式效率。
[BUG_ON]
#define BUG_ON(condition) do { \
if(unlikely(condition)) BUG(); \
} while(0)
一些核心調用可以用來方便標記bug,提供斷言並輸出資訊。最常用的兩個是BUG()和BUG_ON()。當被調用的時候,它們會引發oops,導致棧的回溯和錯誤資訊的列印。為什麼這些聲明會導致 oops跟硬體的體繫結構是相關的。大部分體繫結構把BUG()和BUG_ON()定義成某種非法操作,這樣自然會產生需要的oops。
[IS_ERR& PTR_ERR & ERR_PTR]
static inline long __must_check IS_ERR(const void *ptr)
{
return IS_ERR_VALUE((unsigned long)ptr);
}
#define IS_ERR_VALUE(x) unlikely((x) >=(unsigned long)-MAX_ERRNO)
IS_ERR宏用來檢測x地址是否有效;
static inline void *ERR_PTR(long error)
{
return(void *) error;
}
static inline long PTR_ERR(const void *ptr)
{
return(long) ptr;
}
[container_of]
/**
*container_of - cast a member of a structure out to the containing structure
*@ptr: the pointer to the member.
*@type: the type of the container structthis is embedded in.
*@member: the name of the member within the struct.
*
*/
#define container_of(ptr, type, member)({ \
consttypeof(((type *)0)->member)*__mptr = (ptr); \
(type *)((char *)__mptr - offsetof(type,member)); })
這可能是核心裡面最長見的宏,替開發人員解決了不少問題。通過指向成員(成員可以是一個結構體)member的指標ptr,來擷取包含該成員的結構體type的指標。
EXAMPLE:
struct example_1 {
struct example_2 s;
int a;
int b;
};
struct example_2 *doo;
struct example_1 *poo = container_of(doo, struct example_1, s);
[__init& __initdata & __exit & __exitdata]
這些宏定義的作用是告訴編譯器將這些函數或者資料放入相應的section中,而在模組載入的階段,.ko檔案中的代碼和資料的載入地區是根據section來載入的
比如:如果函數的定義中帶有__init,那麼這個函數的所有代碼被放入.init.text的section中;
如果函數的定義中帶有__initdata,那麼這個函數的所有代碼被放入.init.data的section中
之所以要使用這個宏定義,其中一個原因是標記為初始化的函數和資料,表明該函數和資料僅在初始化期間使用,在模組裝載之後,模組就會將初始化函數扔掉。這樣可以將該函數佔用的記憶體釋放出來。
如果想詳細瞭解,請參考:http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=2985620
[ARRAY_SIZE]
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
用於計算數組x成員個數