天天看點

核心compiler.h的學習

版權聲明:您好,轉載請留下本人部落格的位址,謝謝 https://blog.csdn.net/hongbochen1223/article/details/44962633

直接上代碼就可以了,是以的學習都在注釋當中呢!

#ifndef __LINUX_COMPILER_H
#define __LINUX_COMPILER_H

#ifndef __ASSEMBLY__

//如果宏定義了__CHECKER__
//詳細學習一個Sparse
#ifdef __CHECKER__

/**
 * 這個使用來修飾一個變量的,這個變量必須是非解除參考的,no 
 * dereference的,即這個變量必須是有效的,而且變量所在的
 * 位址空間必須是1,即使用者程式所使用的。
 * 程式空間分成3部分,0表示normal space,即普通位址空間,
 * 對于核心代碼講,就是核心空間,1表示使用者位址空間
 * 2表示裝置位址映射空間,如硬體裝置的寄存器在核心
 * 裡所映射的位址空間
 *
 */
# define __user     __attribute__((noderef, address_space(1)))

//預設的是核心位址空間
# define __kernel   /* default address space */

//變量可以為空
# define __safe     __attribute__((safe))

//變量可以進行強制轉換
# define __force    __attribute__((force))

//參數類型必須與實際參數類型一緻
# define __nocast   __attribute__((nocast))

//指針位址在裝置位址空間
# define __iomem    __attribute__((noderef, address_space(2)))

//參數x,在執行前引用計數必須為0,執行後,引用計數必須為1
# define __acquires(x)  __attribute__((context(0,1)))

//參數x,在執行前引用計數必須為1,執行後,必須為0
# define __releases(x)  __attribute__((context(1,0)))

//參數x的引用計數在執行後+1
# define __acquire(x)   __context__(1)

//參數x的引用計數在執行後-1
# define __release(x)   __context__(-1)

//參數x為0,則傳回0;如果參數x不為0,的引用計數+1,并且傳回1
# define __cond_lock(x) ((x) ? ({ __context__(1); 1; }) : 0)

//檢查使用者位址空間指針
extern void __chk_user_ptr(void __user *);

//檢查裝置位址空間指針
extern void __chk_io_ptr(void __iomem *);

#else

# define __user
# define __kernel
# define __safe
# define __force
# define __nocast
# define __iomem
# define __chk_user_ptr(x) (void)0
# define __chk_io_ptr(x) (void)0
# define __builtin_warning(x, y...) (1)
# define __acquires(x)
# define __releases(x)
# define __acquire(x) (void)0
# define __release(x) (void)0
# define __cond_lock(x) (x)
#endif

#ifdef __KERNEL__

//__GNUC__ 該宏表示GCC的版本
//可以使用該宏針對不同版本的gcc進行條件編譯
#if __GNUC__ > 4
//錯誤,沒有對應版本的compiler-gcc.h檔案 
#error no compiler-gcc.h file for this gcc version
#elif __GNUC__ == 4
# include <linux/compiler-gcc4.h>
#elif __GNUC__ == 3
# include <linux/compiler-gcc3.h>
#else
//對不起,錯誤。你的編譯器版本太老了或者是不被識别。
# error Sorry, your compiler is too old/not recognized.
#endif

/* Intel compiler defines __GNUC__. So weabove header files here will overwrite implementations
 * coming from above header files here
 * Intel編譯器定義了__GNUC__.是以在這裡也包含compiler-intel.h頭檔案。
 */
#ifdef __INTEL_COMPILER
# include <linux/compiler-intel.h>
#endif

/*
 * Generic compiler-dependent macros required for kernel
 * build go below this comment. Actual compiler/compiler version
 * specific implementations come from the above header files
 * 定義likely和unlikely宏
 *
 * 在核心編譯的時候,所需要的宏定義在該注釋下面。真正的編譯器或者是
 * 編譯器版本實作在上面的頭檔案中。
 */

/*
 * __builtin_expect()是有GCC或者是intel編譯器提供的實作
 * 提供該實作的目的是為了優化代碼,避免過度跳轉帶來的性能
 * 上的下降。
 * __builtin(!!(x),1)表示x的值為1的可能性比較大
 * __builtin(!!(x),0)表示x的值為0的可能性比較大
 * 
 * 例如:
 * int x;
 * if(unlikely(x))
 * {
 *   x += 1;
 * }else{
 *  x -= 1;
 * }
 * 這段代碼表示,x為0的可能性較大,也就是說
 * 程式執行else中的代碼的可能性比較大,是以在
 * 編譯的時候else裡面的内容緊跟着上面的代碼
 */

#define likely(x)   __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

//優化屏障
//詳細了解請看我的部落格[《核心Memory Barrier學習》](http://blog.csdn.net/hongbochen1223/article/details/44961487)
/* Optimization barrier */
#ifndef barrier
# define barrier() __memory_barrier()
#endif

#ifndef RELOC_HIDE
# define RELOC_HIDE(ptr, off)                   \
  ({ unsigned long __ptr;                   \
     __ptr = (unsigned long) (ptr);             \
    (typeof(ptr)) (__ptr + (off)); })
#endif

#endif /* __KERNEL__ */

#endif /* __ASSEMBLY__ */

#ifdef __KERNEL__
/*
 * Allow us to mark functions as 'deprecated' and have gcc emit a nice
 * warning for each use, in hopes of speeding the functions removal.
 * Usage is:
 *      int __deprecated foo(void)
 * 
 *
 * 允許我們标志一個函數為'過時的',并且會使gcc對沒一個使用發出合理的警告,
 * 希望能夠加快函數的移除。
 * 使用方式:
 *      int __deprecated foo(void)
 */
#ifndef __deprecated
# define __deprecated       /* unimplemented */ //未實作
#endif

#ifdef MODULE
#define __deprecated_for_modules __deprecated
#else
#define __deprecated_for_modules
#endif

#ifndef __must_check
#define __must_check
#endif

/*
 * Allow us to avoid 'defined but not used' warnings on functions and data,
 * as well as force them to be emitted to the assembly file.
 *
 * As of gcc 3.3, static functions that are not marked with attribute((used))
 * may be elided from the assembly file.  As of gcc 3.3, static data not so
 * marked will not be elided, but this may change in a future gcc version.
 *
 * In prior versions of gcc, such functions and data would be emitted, but
 * would be warned about except with attribute((unused)).
 *
 * 允許我們避免在函數和資料中‘定義了但是沒有使用’的警告,同時強制他們發送給
 * 彙編檔案。
 * 對于編譯器gcc 3.3,未被标記上已用屬性的靜态函數将會被彙編檔案忽略。但是對于
 * 編譯器gcc 3.3,沒有這樣标記靜态資料将不會被忽略,但是在後續的gcc版本中将會
 * 發生改變。
 * 在更進階的gcc版本中,這樣的函數和資料雖然會被傳送,但是将會用‘未使用的屬性’
 * 來發出異常警告。
 */
#ifndef __attribute_used__
# define __attribute_used__ /* unimplemented */  //未實作
#endif

/*
 * From the GCC manual:
 * 來自GCC手冊
 *
 * Many functions have no effects except the return value and their
 * return value depends only on the parameters and/or global
 * variables.  Such a function can be subject to common subexpression
 * elimination and loop optimization just as an arithmetic operator
 * would be.
 * [...]
 * 很多函數除了他們的傳回值都是沒有影響的,并且他們的傳回值僅僅依賴于參數
 * 或者是全局變量。這樣的函數将受公共子表達式消除和循環優化支配作為一個算數
 * 運算符。
 */
#ifndef __attribute_pure__
# define __attribute_pure__ /* unimplemented */
#endif

#ifndef noinline
#define noinline
#endif

#ifndef __always_inline
#define __always_inline inline
#endif

#endif /* __KERNEL__ */

/*
 * From the GCC manual:
 * 定義const函數
 * Many functions do not examine any values except their arguments,
 * and have no effects except the return value.  Basically this is
 * just slightly more strict class than the `pure' attribute above,
 * since function is not allowed to read global memory.
 *
 * Note that a function that has pointer arguments and examines the
 * data pointed to must _not_ be declared `const'.  Likewise, a
 * function that calls a non-`const' function usually must not be
 * `const'.  It does not make sense for a `const' function to return
 * `void'.
 */
#ifndef __attribute_const__
# define __attribute_const__    /* unimplemented */
#endif

#endif /* __LINUX_COMPILER_H */           

繼續閱讀