arm linux 等待隊列簡單分析

來源:互聯網
上載者:User

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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.