日期:2014-05-16  浏览次数:20694 次

谁帮我看下宏定义 这个宏定义我看不懂 关于等待队列的
#define   DECLARE_WAITQUEUE(name,   tsk)       \
wait_queue_t   name     =__WAITQUEUE_INITIALIZER(name,   tsk)
#define   __WAITQUEUE_INITIALIZER(name,   tsk)   {         task:     tsk,             task_list:   {   NULL,   NULL   },       __WAITQUEUE_DEBUG_INI(name)}

它的解释是:
通过DECLARE_WAITQUEUE宏将等待队列项初始化成对应的任务结构,并且用于连接的相关指针均设置为空。其中加入了调试相关代码。


还是不懂   大家帮忙!!!


------解决方案--------------------
详细的用法可以参见LKD2e Chapter 4 process scheduling
Page52 ~ 53 (english edition)
Page41 ~ 41 (chinese edition)
讲得很清楚,下面列了一些内容出来。仔细看看就知道用法了。不用急。

----------------------


Sleeping is handled via wait queues. A wait queue is a simple list of processes waiting for an event to occur. Wait queues are represented in the kernel by wake_queue_head_t. Wait queues are created statically via DECLARE_WAITQUEUE() or dynamically via init_waitqueue_head(). Processes put themselves on a wait queue and mark themselves not runnable. When the event associated with the wait queue occurs, the processes on the queue are awakened. It is important to implement sleeping and waking correctly, to avoid race conditions.

Some simple interfaces for sleeping used to be in wide use. These interfaces, however, have races: It is possible to go to sleep after the condition becomes true. In that case, the task might sleep indefinitely. Therefore, the recommended method for sleeping in the kernel is a bit more complicated:

/* 'q ' is the wait queue we wish to sleep on */
DECLARE_WAITQUEUE(wait, current);

add_wait_queue(q, &wait);
while (!condition) { /* condition is the event that we are waiting for */
set_current_state(TASK_INTERRUPTIBLE); /* or TASK_UNINTERRUPTIBLE */
if (signal_pending(current))
/* handle signal */
schedule();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(q, &wait);


The task performs the following steps to add itself to a wait queue:

1 Creates a wait queue entry via DECLARE_WAITQUEUE().

2 Adds itself to a wait queue via add_wait_queue(). This wait queue awakens the process when the condition for which it is waiting occurs. Of course, there needs to be code elsewhere that calls wake_up() on the queue when the event actually does occur.

3 Changes the process state to TASK_INTERRUPTIBLE or TASK_UNINTERRUPTIBLE.

4 If the state is set to TASK_INTERRUPTIBLE, a signal wakes the process up. This is called a spurious wake up (a wake-up not caused by the occurrence of the event). So check and handle signals.

5 Tests whether the condition is true. If it is, there is no need to sleep. If it is not true, the task calls schedule().

6 When the task awakens, it again checks whether the condition is true. If it is, it exits the loop. Otherwise, it again calls schedule() and repeats.

7 Now that the condition is true, the task can set itself to TASK_RUNNING and remove itself from the wait queue via remove_wait_queue().