init_waitqueue_head 定义在哪个文件
时间: 2023-08-16 15:09:45 浏览: 52
`init_waitqueue_head` 函数定义在内核源码的 `include/linux/wait.h` 头文件中。
该函数用于初始化等待队列头 `wait_queue_head_t` 结构体,以便于在内核中使用等待队列实现进程之间的同步。在内核中,等待队列头通常与某个共享资源相关联,等待队列项 `wait_queue_t` 则表示等待这个资源的进程。
`init_waitqueue_head` 函数的定义如下:
```
static inline void init_waitqueue_head(wait_queue_head_t *q)
{
q->lock = __RAW_SPIN_LOCK_UNLOCKED(q->lock);
q->task_list.next = &q->task_list;
q->task_list.prev = &q->task_list;
}
```
该函数使用内联函数的方式定义,将等待队列头的三个成员变量初始化为默认值:
- `lock` 初始化为未加锁的自旋锁。
- `task_list` 的 `next` 和 `prev` 指针都指向等待队列头本身,表示该等待队列目前没有任何等待进程。
在使用等待队列头之前,通常需要先调用 `init_waitqueue_head` 函数进行初始化。
相关问题
__init_waitqueue_head
`__init_waitqueue_head` 函数是 `init_waitqueue_head` 函数的一个宏定义,定义在内核源码的 `include/linux/wait.h` 头文件中。
该宏定义的作用是将等待队列头 `wait_queue_head_t` 结构体初始化为默认值,并标记为只能在初始化时被调用。在内核编译时,带有 `__init` 宏定义的函数和数据结构都会被编译到内核的只读数据段(rodata)中,并在内核启动时被映射到只读内存中。这样可以避免在内核运行时修改这些数据结构,提高内核的安全性和稳定性。
`__init_waitqueue_head` 宏定义的代码如下:
```
#define __init_waitqueue_head(q, name) \
do { \
static wait_queue_head_t __init_waitqueue_head_##name = \
__WAIT_QUEUE_HEAD_INITIALIZER(__init_waitqueue_head_##name); \
*(q) = __init_waitqueue_head_##name; \
} while (0)
```
该宏定义中使用了另外一个宏定义 `__WAIT_QUEUE_HEAD_INITIALIZER`,用于初始化 `wait_queue_head_t` 结构体的成员变量。`__init_waitqueue_head` 宏定义的作用是将初始化后的等待队列头赋值给参数 `q` 所指向的变量,以便于在内核中使用等待队列实现进程之间的同步。
需要注意的是,`__init_waitqueue_head` 宏定义只能在初始化时被调用,否则编译器会给出警告或错误提示。
start_kernel 怎么调到INIT_WAITQUEUE_HEAD
start_kernel() 函数并没有直接调用 INIT_WAITQUEUE_HEAD() 宏来初始化等待队列。实际上,等待队列的初始化是在宏定义 DECLARE_WAIT_QUEUE_HEAD(name) 中完成的。
DECLARE_WAIT_QUEUE_HEAD(name) 宏定义了一个等待队列头部的结构体变量,并使用 __WAIT_QUEUE_HEAD_INITIALIZER 宏对该结构体进行初始化。__WAIT_QUEUE_HEAD_INITIALIZER 宏是一个内部宏,用于初始化等待队列头部的双向链表。
在内核源代码中,INIT_WAITQUEUE_HEAD() 宏是由 DECLARE_WAIT_QUEUE_HEAD() 宏调用的。例如,在某个模块中定义了一个等待队列 my_waitqueue,可以使用以下代码来对这个队列进行初始化:
```c
DECLARE_WAIT_QUEUE_HEAD(my_waitqueue);
```
这个宏定义会生成以下代码:
```c
wait_queue_head_t my_waitqueue = __WAIT_QUEUE_HEAD_INITIALIZER(my_waitqueue);
```
这个代码会定义一个名为 my_waitqueue 的等待队列,并初始化它的头部节点。等待队列的头部节点是一个 wait_queue_head_t 结构体,它包含了一个双向链表,用于存储等待这个事件的任务。
因此,虽然 INIT_WAITQUEUE_HEAD() 宏也可以用于初始化等待队列,但在实际使用中,更常见的是使用 DECLARE_WAIT_QUEUE_HEAD() 宏来定义和初始化等待队列。