linux 内核-信号-队列




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) 
***************************************队列

 

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)

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