1、asmlinkage与FASTCALL
asmlinkage告诉编译器将参数存入局部栈
FASTCALL通知(与体系结构相关的)编译器将参数传给通用寄存器
include/asm/linkage.h
#define asmlinkage CPP_ASMLINKAGE __attribute__ ((regparm(0)))
#define FASTCALL(x) x __attribute__ ((regparm(3)))
#define fastcall __attribute__ ((regparm(3)))
2、UL
表明无符号长整型,保证特定体系结构内的数据不会溢出其数据所规定的范围,涉及很大的数时,有助于编写出与结构体无关的代码
include/linux/kernel.h
#define ULONG_MAX (~0UL)
3、const和volatile
const int *x 表示一个指向const整数的指针,可以修改指针,但不能通过该指针修改整数的值
int const *x 表示一个指向整数的const指针,因而这个整数可以改变,但指针x不可以改变
volatile表明变量无需警告就可以被修改,它通知编译器每次使用这个标记的变量时都要重新加载其值,而不是存储或访问一个副本
volatile unsigned int lock;
4、__init
编译器将标有__init的所有代码存到特殊的内存段中,初始化后释放这段代码。
__initdata、__init
__exitdata、__exit
5、likely()和unlikely()
现代众多CPU具有众多的启发式分支预测法,它尝试预测即将到来的命令,以便达到最快的速度。宏likely()和unlikely()允许开发者通过编译器告诉CPU,某一段代码很可能执行,因而应该被预测到,某一段代码很可能不被执行,不必预测
6、IS_ERR和PTR_ERR
宏IS_ERR将负的错误号编码成指针,而宏PTR_ERR则将该指针恢复成错误号
7、current
尼玛current是个宏,老子还以为全局变量呢
static inline struct task_struct * get_current(void)
{
struct task_struct *current;
__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
return current;
}
实际上,这段代码相当于如下一组汇编指令(设p是指向当前进程task_struc结构的指针):
movl $0xffffe000, %ecx
andl %esp, %ecx
movl %ecx, p
换句话说,仅仅只需检查栈指针的值,而根本无需存取内存,内核就可以导出task_struct结构的地址。
8、prefetch
prefetch的含义是告诉CPU那些元素有可能马上用到,预取一下,可以提高效率