您的位置:首页 > 编程语言

代码碎片

2013-05-24 21:15 120 查看
(1)DEVICE_ATTR

例如,定义一个device属性,名为foo,读写该文件的方法分别为show_foo和store_foo:

static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);

将宏展开为:

static struct device_attribute dev_attr_foo = {

.attr = {

.name = "foo",

.mode = S_IWUSR | S_IRUGO,

},

.show = show_foo,

.store = store_foo,

};

mode_t 是文件权限值。定义在src/include/stat.h

这里的 S_IRUGO=(S_IRUSR|S_IRGRP|S_IROTH)
S_IRUSR:用户读 00400
S_IRGRP:用户组读 00040
S_IROTH: 其他读 00004

(2) container_of

kernel.h

/**

* 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 struct this is embedded in.

* @member: the name of the member within the struct.

*

*/

#define container_of(ptr, type, member) ({ /

const typeof( ((type *)0)->member ) *__mptr = (ptr); /

(type *)( (char *)__mptr - offsetof(type,member) );})

container_of在Linux Kernel中的应用非常广泛,它用于获得某结构中某成员的入口地址.

关于offsetof见stddef.h中:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

TYPE是某struct的类型 0是一个假想TYPE类型struct,MEMBER是该struct中的一个成员. 由于该struct的基地址为0, MEMBER的地址就是该成员相对与struct头地址的偏移量.

关于typeof,这是gcc的C语言扩展保留字,用于声明变量类型.

const typeof( ((type *)0->member ) *__mptr = (ptr);意思是声明一个与member同一个类型的指针常量 *__mptr,并初始化为ptr.

(type *)( (char *)__mptr - offsetof(type,member) );意思是__mptr的地址减去member在该struct中的偏移量得到的地址, 再转换成type型指针. 该指针就是member的入口地址了.

通过某一struct成员变量获取整个struct结构体的指针。

(3) int down_interruptible(struct semaphore *sem)

/**

* down_interruptible - acquire the semaphore unless interrupted

* @sem: the semaphore to be acquired

*

* Attempts to acquire the semaphore. If no more tasks are allowed to

* acquire the semaphore, calling this function will put the task to sleep.

* If the sleep is interrupted by a signal, this function will return -EINTR.

* If the semaphore is successfully acquired, this function returns 0.

*/
一个进程在调用down_interruptible()之后,如果sem<0,那么就进入到可中断的睡眠状态并调度其它进程运行, 但是一旦该进程收到信号,那么就会从down_interruptible函数中返回。并标记错误号为:-EINTR。一个形象的比喻:传入的信号量为1好比天亮,如果当前信号量为0,进程睡眠,直到(信号量为1)天亮才醒,但是可能中途有个闹铃(信号)把你闹醒。

万一出现了semaphore的死锁,还有机会用ctrl+c发出软中断,让等待这个内核驱动返回的用户态进程退出。而不是把整个系统都锁住了。在休眠时,能被中断信号终止,这个进程是可以接受中断信号的!比如你在命令行中输入# sleep 10000,按下ctrl + c,就给上面的进程发送了进程终止信号。信号发送给用户空间,然后通过系统调用,会把这个信号传给递给驱动。信号只能发送给用户空间,无权直接发送给内核的,那1G的内核空间,我们是无法直接去操作的。

-ERESTARTSYS表示信号函数处理完毕后重新执行信号函数前的某个系统调用。

也就是说,如果信号函数前有发生系统调用,在调度用户信号函数之前,内核会检查系统调用的返回值,看看是不是因为这个信号而中断了系统调用.如果返回值-ERESTARTSYS,并且当前调度的信号具备-ERESTARTSYS属性,系统就会在用户信号函数返回之后再执行该系统调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: