arm linux 等待队列简单分析

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")

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值