您的位置:首页 > 运维架构 > Linux

linux 内核-信号-队列

2012-05-30 10:24 274 查看


linux 内核-信号-队列

分类: linux2011-01-27
20:05 337人阅读 评论(0) 收藏 举报

static ssize_t mxc_v4l_read(struct file *file, char *buf, size_t count,

loff_t *ppos)

{

int err = 0;

u8 *v_address[2];

struct video_device *dev = video_devdata(file);

cam_data *cam = video_get_drvdata(dev);

if (down_interruptible(&cam->busy_lock))

return -EINTR;

/* Stop the viewfinder */

if (cam->overlay_on == true)

stop_preview(cam);

v_address[0] = dma_alloc_coherent(0,

PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),

&cam->still_buf[0],

GFP_DMA | GFP_KERNEL);

v_address[1] = dma_alloc_coherent(0,

PAGE_ALIGN(cam->v2f.fmt.pix.sizeimage),

&cam->still_buf[1],

GFP_DMA | GFP_KERNEL);

if (!v_address[0] || !v_address[1]) {

err = -ENOBUFS;

goto exit0;

}

err = prp_still_select(cam);

if (err != 0) {

err = -EIO;

goto exit0;

}

cam->still_counter = 0;

err = cam->csi_start(cam);

if (err != 0) {

err = -EIO;

goto exit1;

}

if (!wait_event_interruptible_timeout(cam->still_queue,

cam->still_counter != 0,

10 * HZ)) {

pr_err("ERROR: v4l2 capture: mxc_v4l_read timeout counter %x/n",

cam->still_counter);

err = -ETIME;

goto exit1;

}

err = copy_to_user(buf, v_address[1], cam->v2f.fmt.pix.sizeimage);

exit1:

prp_still_deselect(cam);

exit0:

if (v_address[0] != 0)

dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[0],

cam->still_buf[0]);

if (v_address[1] != 0)

dma_free_coherent(0, cam->v2f.fmt.pix.sizeimage, v_address[1],

cam->still_buf[1]);

cam->still_buf[0] = cam->still_buf[1] = 0;

if (cam->overlay_on == true) {

start_preview(cam);

}

up(&cam->busy_lock);

if (err < 0)

return err;

return (cam->v2f.fmt.pix.sizeimage - err);

}





kernel/include/semaphore.h



#define init_MUTEX(sem) sema_init(sem, 1)

#define init_MUTEX_LOCKED(sem) sema_init(sem, 0)



kernel/semaphore.c

int down_interruptible(struct semaphore *sem)



/**

* down_interruptible - acquire the semaphore unless interrupted

* @sem: the semaphore to be acquired

*

* Attempts to acquire the semaphore. If no more tasks are allowed to

* acquire the semaphore, calling this function will put the task to sleep.

* If the sleep is interrupted by a signal, this function will return -EINTR.

* If the semaphore is successfully acquired, this function returns 0.

*/





调用down_interruptible()的进程在调用down_interruptible()之后,如果sem<0,那么就进入到可中断的睡眠状态并调度其它进程运行, 但是一旦该进程获得信号,那么就会从down_interruptible函数中返回。如果是被别的信号中断则返回错误号-EINTR。







/**

* up - release the semaphore

* @sem: the semaphore to release

*

* Release the semaphore. Unlike mutexes, up() may be called from any

* context and even by tasks which have never called down().

*/

void up(struct semaphore *sem)



***************************************队列



wait_event_interruptible_timeout和schedule_timeout的
一、适用情况

wait_event_interruptible_timeout和schedule_timeout的区别

当在某个硬件驱动程序中使用wait_event_interruptible_timeout时,执行的继续可以通过以下两种方式获得:

1.其他人在等待队列上调用了wake_up(并且condition满足)

2.超时到期。

而调用schedule_timeout的进程始终会在超时到期时被唤醒。

二、函数原型

wait_event_interruptible_timeout(queue, condition, timeout)

返回值:

大于零:剩余时间(以jiffy计)

零:给定的时间到期。

signed long schedule_timeout(signed long timeout);

返回值:

零:正常返回值

大于零:函数提前返回(比如响应某个信号),返回值为剩余时间

三、使用实例

1.wait_event_interrruptible_timeout

(1)初始化等待队列

int flags = 0;

wait_queue_head_t select_wait;

init_waitqueue_head(&select_wait);

(2)等待事件的发生(条件满足)

{

...

wait_event_interruptible_timeout(select_wait, flags != 0, HZ/10);

...

}

(3)唤醒等待队列

{

...

if(waitqueue_active(&select_wait))

{

flags = 1;

wake_up_interruptible( &nd->select_in_wait );

}

...

}
分享到:

上一篇:[OpenCore] Android的多媒体框架OpenCore介绍
下一篇:Android中LocationManager的简单使用,获取当前位置
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: