Chinaunix首页 | 论坛 | 博客
  • 博客访问: 427795
  • 博文数量: 123
  • 博客积分: 2686
  • 博客等级: 少校
  • 技术积分: 1349
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-23 22:11
文章分类
文章存档

2012年(3)

2011年(10)

2010年(100)

2009年(10)

我的朋友

分类: LINUX

2010-06-21 21:54:26

阻塞操作是指在执行设备操作时若不能获得资源则挂起进程,直到满足可操作的条件后再进行操作。被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件被满足。非阻塞的进程在不能进行设备时并不挂起,它或者放弃,或者不停地查询,直到可以操作为至。

驱动程序需要提供这样的能力:当应用程序进行read(),write等系统调用的时候,若设备的资源不能获取,而用户又希望以阻塞的方式访问设备,驱动程序应在设备驱动的xxx_read,xxx_write等操作中将进程阻塞直到资源可以获取。

等待队列:
在linux驱动程序中,可以使用等待队列来实现阻塞进程的唤醒。

STEP 1: linux 2.6提供如下关于等待队列的操作:

1.定义 等待队列头

wait_queue_head_t my_queue;


2.初始化 等待队列头

init_wait_queue_head(&my_queue);

定义并初始化等待队列头

DECLEAR_WAIT_QUEUE_HEAD(name);


3.定义等待队列

DECLEAR_WAITQUEUE(name,tsk);//定义并初始化一个名为name的等待队列


4.添加/移除等待队列

void fastcall add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);

void fastcall remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);


5.等待事件

wait_event(queue,condition);

wait_event_inerruptible(queue,condition);

wait_event_timeout(queue,condition,timeout);

wait_event_inerruptible_timeout(queue,condition,timeout);


6.唤醒队列

void wake_up(wait_queue_head_t *queue);

void wake_up_inerruptible(wait_queue_head_t *queue);


7.在等待队列上睡眠

sleep_on(wait_queue_head_t *q);

interrupt_sleep_on(wait_queue_head_t *q);




STEP 2: wait_event()代码

#define DEFINE_WAIT_FUNC(name, function) \

wait_queue_t name = { \

.private = current, \

.func = function, \

.task_list = LIST_HEAD_INIT((name).task_list), \

}

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

#define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function)

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

#define __wait_event(wq, condition) \

do { \

DEFINE_WAIT(__wait); \

\

for (;;) { \

prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \

if (condition) \

break; \

schedule(); \

} \

finish_wait(&wq, &__wait); \

} while (0)

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

/**
 * wait_event - sleep until a condition gets true
 * @wq: the waitqueue to wait on
 * @condition: a C expression for the event to wait for
 *
 * The process is put to sleep (TASK_UNINTERRUPTIBLE) until the
 * @condition evaluates to true. The @condition is checked each time
 * the waitqueue @wq is woken up.
 *
 * wake_up() has to be called after changing any variable that could
 * change the result of the wait condition.
 */

#define wait_event(wq, condition)                     \
do {                                    \
    if (condition)                             \
        break;                            \
    __wait_event(wq, condition);                    \
} while (0)

#define __wait_event_timeout(wq, condition, ret)            \
do {                                    \
    DEFINE_WAIT(__wait);                        \
                                    \
    for (;;) {                            \
        prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);    \
        if (condition)                        \
            break;                        \
        ret = schedule_timeout(ret);                \
        if (!ret)                        \
            break;                        \
    }                                \
    finish_wait(&wq, &__wait);                    \
} while (0)


typedef struct __wait_queue wait_queue_t;

struct __wait_queue {

unsigned int flags;

#define WQ_FLAG_EXCLUSIVE 0x01

void *private;

wait_queue_func_t func;

struct list_head task_list;

};


阅读(581) | 评论(0) | 转发(0) |
0

上一篇:task_struct

下一篇:Linus对微内核的看法

给主人留下些什么吧!~~