schedule(); //调剂其他过程履行 if (signal_pending(current)) //如不雅是因为旌旗灯号唤醒 { ret = - ERESTARTSYS; goto out2; } down(&dev->sem); } /* 拷贝到用户空间 */ if (count > dev->current_len) count = dev->current_len; if (copy_to_user(buf, dev->mem, count)) { ret = - EFAULT; goto out; } else { memcpy(dev->mem, dev->mem + count, dev->current_len - count); //fifo数据前移 dev->current_len -= count; //有效数据长度削减 printk(KERN_INFO "read %d bytes(s),current_len:%d\n", count, dev->current_len); wake_up_interruptible(&dev->w_wait); //唤醒写等待队列 ret = count; } out: up(&dev->sem); //释放旌旗灯号量 out2:remove_wait_queue(&dev->w_wait, &wait); //大年夜从属的等待队列头移除 set_current_state(TASK_RUNNING); return ret; }/*globalfifo写操作*/static ssize_t globalfifo_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { struct globalfifo_dev *dev = filp->private_data; //获得设备构造体指针 int ret; DECLARE_WAITQUEUE(wait, current); //定义等待队列 down(&dev->sem); //获守旌旗灯号量 add_wait_queue(&dev->w_wait, &wait); //进入写等待队列头 /* 等待FIFO非满 */ if (dev->current_len == GLOBALFIFO_SIZE) { if (filp->f_flags &O_NONBLOCK) //如不雅长短浊宣拜访 { ret = - EAGAIN; goto out; } __set_current_state(TASK_INTERRUPTIBLE); //改变过程状况为睡眠 up(&dev->sem);
推荐阅读
看看60万码农怎么评论:这世界上还有没有月薪低于3万的程序员?
IT界一位大年夜神早已下过定论:“对于那些月薪三万以下,自称法度榜样员的码农们,其实我们大年夜来没有把他们归为我们法度榜样员的部队。他们固然老是以法度榜样员自居,但只是他们>>>详细阅读
本文标题:Linux设备驱动中的并发控制
地址:http://www.17bianji.com/lsqh/38523.html
1/2 1