void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
{
unsigned long flags;
wait->flags &= ~WQ_FLAG_EXCLUSIVE;
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, wait);
spin_unlock_irqrestore(&q->lock, flags);
}
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
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;
}
#include <stdio.h>
struct list_head {
struct list_head *next, *prev;
};
typedef struct __wait_queue_head {
int lock;
struct list_head task_list;
}wait_queue_head_t;
typedef struct __wait_queue {
int a;
int b;
struct list_head task_list;
}wait_queue_t;
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define DEFINE_WAIT(name) \
wait_queue_t name = { \
.a = 7, \
.b = 8, \
.task_list = LIST_HEAD_INIT((name).task_list), \
}
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \
.lock = 10, \
.task_list = { &(name).task_list, &(name).task_list } }
#define DECLARE_WAIT_QUEUE_HEAD(name) \
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
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;
}
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
{
list_add(&new->task_list, &head->task_list);
}
void prepare_to_wait (wait_queue_head_t *q, wait_queue_t *wait)
{
if (list_empty(&wait->task_list))
__add_wait_queue(q, wait);
}
int main(void)
{
DECLARE_WAIT_QUEUE_HEAD(wq);
printf ("header task_list address: 0x%x\n", &wq.task_list);
printf ("header prev: 0x%x\n", wq.task_list.prev);
printf ("header next: 0x%x\n", wq.task_list.next);
printf ("------------list_add a new-------------\n\n");
DEFINE_WAIT(__wait);
prepare_to_wait (&wq, &__wait);
printf ("header prev: 0x%x\n", wq.task_list.prev);
printf ("header next: 0x%x\n", wq.task_list.next);
printf ("first node task_list address: 0x%x\n", &__wait.task_list);
printf ("first node prev: 0x%x\n", __wait.task_list.prev);
printf ("first node next: 0x%x\n", __wait.task_list.next);
printf ("------------list_add a new-------------\n");
DEFINE_WAIT(second);
prepare_to_wait (&wq, &second);
printf ("header prev: 0x%x\n", wq.task_list.prev);
printf ("header next: 0x%x\n", wq.task_list.next);
printf ("first node prev: 0x%x\n", __wait.task_list.prev);
printf ("first node next: 0x%x\n", __wait.task_list.next);
printf ("second node task_list address: 0x%x\n", &second.task_list);
printf ("second node prev: 0x%x\n", second.task_list.prev);
printf ("second node next: 0x%x\n", second.task_list.next);
printf ("------------list_add a new-------------\n");
DEFINE_WAIT(third);
prepare_to_wait (&wq, &third);
printf ("header prev: 0x%x\n", wq.task_list.prev);
printf ("header next: 0x%x\n", wq.task_list.next);
printf ("first node prev: 0x%x\n", __wait.task_list.prev);
printf ("first node next: 0x%x\n", __wait.task_list.next);
printf ("second node prev: 0x%x\n", second.task_list.prev);
printf ("second node next: 0x%x\n", second.task_list.next);
printf ("third node task_list address: 0x%x\n", &third.task_list);
printf ("third node prev: 0x%x\n", third.task_list.prev);
printf ("third node next: 0x%x\n", third.task_list.next);
return (0);
}
linux-kd1q:/home/beyes/C/micro # ./micro
header task_list address: 0xbfc6b3b8
header prev: 0xbfc6b3b8
header next: 0xbfc6b3b8
------------list_add a new-------------
header prev: 0xbfc6b3ac
header next: 0xbfc6b3ac
first node task_list address: 0xbfc6b3ac
first node prev: 0xbfc6b3b8
first node next: 0xbfc6b3b8
------------list_add a new-------------
header prev: 0xbfc6b3ac
header next: 0xbfc6b39c
first node prev: 0xbfc6b39c
first node next: 0xbfc6b3b8
second node task_list address: 0xbfc6b39c
second node prev: 0xbfc6b3b8
second node next: 0xbfc6b3ac
------------list_add a new-------------
header prev: 0xbfc6b3ac
header next: 0xbfc6b38c
first node prev: 0xbfc6b39c
first node next: 0xbfc6b3b8
second node prev: 0xbfc6b38c
second node next: 0xbfc6b3ac
third node task_list address: 0xbfc6b38c
third node prev: 0xbfc6b3b8
third node next: 0xbfc6b39c
header task_list address: 0xbfc6b3b8
header prev: 0xbfc6b3b8
header next: 0xbfc6b3b8
header prev: 0xbfc6b3ac
header next: 0xbfc6b3ac
first node task_list address: 0xbfc6b3ac
first node prev: 0xbfc6b3b8
first node next: 0xbfc6b3b8
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
header prev: 0xbfc6b3ac
header next: 0xbfc6b39c
first node prev: 0xbfc6b39c
first node next: 0xbfc6b3b8
second node task_list address: 0xbfc6b39c
second node prev: 0xbfc6b3b8
second node next: 0xbfc6b3ac
0x521:描述的真清晰。我想请教一下你使用什么工具画的图啊?我也想学习学习。 (2012-07-03 23:10)
beyes:也有 Windows 里的画图,还有 Linux 里的 GIMP 。 (2012-07-04 11:48)
欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) | Powered by Discuz! X3.2 |