Linux:为啥内核有的变量没有初始化就敢直接使用?
3)宏展开
将对宏的调用展开成相对应的宏定义
关于宏定义还有很多其他的知识点,本文暂不深入展开。
四、如何快速展开复杂的宏定义?
linux内核中通常有很多宏定义,非常的复杂,对于初学者来说,经常会一头雾水,那如何快速理解宏定义呢?
一口君教你一个非常方便的方法,让你直接看透宏定义,我们以上述代码为例:
第一步将要展开的宏先拷贝到c文件中,然后把所有用到的宏定义都拷贝到该文件中;内核中很多的宏都是嵌套的,把嵌套的宏定义都一起拷贝到文件中;此外内核很多的宏会由条件编译决定,从而导致有多种定义方式,如果不确定,就把条件编译一起拷贝过来,
如该例所示,MAX_NUMNODES 就被嵌套了多级,最终宏CONFIG_NODES_SHIFT在内核中没有检索到,所以该宏没有定义。
文件如下:123.c
1
2
3 #ifdef CONFIG_NODES_SHIFT
4 #define NODES_SHIFT CONFIG_NODES_SHIFT
5 #else
6 #define NODES_SHIFT 0
7 #endif
8
9
10
11 #define MAX_NUMNODES (1 << NODES_SHIFT)
12
13
14
15
16 #if MAX_NUMNODES > 1
17 #define for_each_node_state(__node, __state)
18 for_each_node_mask((__node), node_states[__state])
19 #else
20 #define for_each_node_state(node, __state)
21 for ( (node) = 0; (node) == 0; (node) = 1)
22 #endif
23
24
25
26
27 #define for_each_online_node(node) for_each_node_state(node, N_ONLINE)
28
29
30 static int __build_all_zonelists(void *data)
31 {
32 int nid;
33 int cpu;
34 pg_data_t *self = data;
35
36
37
38 for_each_online_node(nid) {
39 pg_data_t *pgdat = NODE_DATA(nid);
40
41 build_zonelists(pgdat);
42 build_zonelist_cache(pgdat);
43 }
44 }
第二步
使用以下命令,展开宏定义,
gcc -E
-E的含义是,编译预处理该文件,但是不去生成汇编代码,只把文件中的宏定义以及包含的头文件替代,并不会去检查语法正确与否。
结果如下:
peng@ubuntu:~/test$ gcc 123.c -E
# 1 "123.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "123.c"
# 28 "123.c"
static int __build_all_zonelists(void *data)
{
int nid;
int cpu;
pg_data_t *self = data;
for ( (nid) = 0; (nid) == 0; (nid) = 1) {
pg_data_t *pgdat = NODE_DATA(nid);
build_zonelists(pgdat);
build_zonelist_cache(pgdat);
}
}
由结果可知,nid是被赋值为0的。
五、练习
我们来做一个练习,展开一下内核的waite_event()这个宏
拷贝用到所有宏定义到c文件中。
wait.c
1
2 #define ___wait_event(wq, condition, state, exclusive, ret, cmd)
3 ({
4 __label__ __out;
5 wait_queue_t __wait;
6 long __ret = ret;
7
8 INIT_LIST_HEAD(&__wait.task_list);
9 if (exclusive)
10 __wait.flags = WQ_FLAG_EXCLUSIVE;
11 else
12 {
13 code
14 __wait.flags = 0;
15
16 for (;;) {
17 long __int = prepare_to_wait_event(&wq, &__wait, state);
18
19 if (condition)
20 break;
21
22 if (___wait_is_interruptible(state) && __int) {
23 __ret = __int;
24 if (exclusive) {
25 abort_exclusive_wait(&wq, &__wait,
26 state, NULL);
27 goto __out;
28 }
29 break;
30 }
31
32 cmd;
33 }
34 finish_wait(&wq, &__wait);
35 __out: __ret;
36 })
37 }
38
39
40
41
42 #define TASK_UNINTERRUPTIBLE 2
43
44
45 #define __wait_event(wq, condition)
46 (void)___wait_event(wq, condition, TASK_UNINTERRUPTIBLE, 0, 0,
47 schedule())
48
49
图片新闻
最新活动更多
-
即日-1.20限时下载>>> 爱德克(IDEC)设备及工业现场安全解决方案
-
即日-1.31立即参与>>> 【限时免费下载】村田白皮书
-
2月28日火热报名中>> 【免费试用】东集技术年终福利——免费试用活动
-
4日10日立即报名>> OFweek 2025(第十四届)中国机器人产业大会
-
限时免费下载立即下载 >>> 2024“机器人+”行业应用创新发展蓝皮书
-
7.30-8.1火热报名中>> 全数会2025(第六届)机器人及智能工厂展
推荐专题
发表评论
请输入评论内容...
请输入评论/评论长度6~500个字
暂无评论
暂无评论