Author-------Dansen-----xzd2734@163.com
wait_queue_head_t wait_q;
首先看看wait_queue_head_t这个等待队列的结构
在wait.h中定义了这个结构
typedef struct __wait_queue_head wait_queue_head_t;
struct __wait_queue_head {
wq_lock_t lock;
struct list_head task_list;
};
# define wq_lock_t spinlock_t
typedef struct {
volatile unsigned int lock;
} spinlock_t;
struct list_head {
struct list_head *next, *prev;
};
这样其实总共有了3个变量
wait_q.lock.lock volatile unsigned int
wait_q.task_list.next struct list_head *
wait_q.task_list.prev struct list_head *
定义了等待队列后需要进行初始化
init_waitqueue_head(&wait_q);
static inline void init_waitqueue_head(wait_queue_head_t *q)
{
q->lock = WAITQUEUE_RW_LOCK_UNLOCKED;
INIT_LIST_HEAD(&q->task_list);
}
#define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 }
#define INIT_LIST_HEAD(ptr) do { /
(ptr)->next = (ptr); (ptr)->prev = (ptr); /
} while (0)
这样在初始化等待队列wait_q后,
wait_q.lock.lock=0;
wait_q.task_list.next=&(wait_q.task_list)
wait_q.task_list.prev=&(wait_q.task_list)
当然系统还给了另外一种在编译时初始化的定义方法
#define DECLARE_WAIT_QUEUE_HEAD(name) /
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { /
lock: WAITQUEUE_RW_LOCK_UNLOCKED, /
task_list: { &(name).task_list, &(name).task_list }
}
结果显然和上一种方法相同,不过这个ms比较简单.
下面说的是要加入等待队列中的等待项
DECLARE_WAITQUEUE(wait, current);
一种简单的定义方法
#define DECLARE_WAITQUEUE(name, tsk) /
wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk)
#define __WAITQUEUE_INITIALIZER(name, tsk) { /
task: tsk, /
task_list: { NULL, NULL }, }
typedef struct __wait_queue wait_queue_t;
struct __wait_queue {
unsigned int flags;
struct task_struct * task;
struct list_head task_list;
};
这就定义了一个wait_queue_t的结构体并初始化了
wait.flags
wait.task = current
wait.task_list 中两个指针都是空
另一种定义和初始化的方法是
wait_queue_t wait;
init_waitqueue_entry(&wait,current);
static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
{
q->flags = 0;
q->task = p;
}
下面要把wait添加到wait_q中去
add_wait_queue(&wait_q, &wait);
在fork.c中找到了add_wait_queue的定义
void add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)
{
unsigned long flags;
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
wq_write_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait);
wq_write_unlock_irqrestore(&q->lock, flags);
}
#define WQ_FLAG_EXCLUSIVE 0x01
# define wq_write_lock_irqsave spin_lock_irqsave
#define spin_lock_irqsave(lock, flags) /
do { local_irq_save(flags); spin_lock(lock); } while (0)
#define local_irq_save(x) __save_flags_cli(x) //这是与平台相关的,不同cpu是不同的
#define spin_lock(x) do { (x)->lock = 1; } while (0)
/*
* Save the current interrupt enable state & disable IRQs
*/
#define __save_flags_cli(x) /
({ /
unsigned long temp; /
__asm__ __volatile__( /
"mrs %0, cpsr @ save_flags_cli/n" /
" orr %1, %0, #128/n" /
" msr cpsr_c, %1" /
: "=r" (x), "=r" (temp) /
: /
: "memory"); /
})
这是32位ARM平台的代码
意思是把cpsr状态寄存器的值存到flags中,然后通过一个临时变量temp
把中断控制位置1,回写到cpsr中去。
具体可参见《ARM体系结构与编程》
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
static __inline__ void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static __inline__ void __list_add(struct list_head * new,
struct list_head * prev,
struct list_head * next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
#define wq_write_unlock_irqrestore spin_unlock_irqrestore
#define spin_unlock_irqrestore(lock, flags) /
do { spin_unlock(lock); local_irq_restore(flags); } while (0)
#define local_irq_restore(x) __restore_flags(x)
#define spin_unlock(x) do { (x)->lock = 0; } while (0)
/*
* restore saved IRQ & FIQ state
*/
#define __restore_flags(x) /
__asm__ __volatile__( /
"msr cpsr_c, %0 @ restore_flags/n" /
: /
: "r" (x) /
: "memory")