linux无效设备,linux wake_up_interruptible()无效

我正在为操作系统类编写一个“困”设备驱动程序.

它的工作方式是,用户通过read()/ write()访问设备.

当用户像这样写入设备时:写入(fd,& wait,size),设备将以等待值的秒数进入休眠状态.如果等待时间到期,则驱动程序的write方法返回0并且程序结束.但是如果用户在进程在等待队列上休眠时从驱动程序读取,则驱动程序的write方法立即返回休眠进程在其自身发生超时之前等待的秒数.

另一个问题是创建了10个设备实例,并且10个设备中的每个设备必须彼此独立.因此,对设备1的读取必须仅唤醒设备1上的休眠进程.

已经提供了很多代码,我负责主要为驱动程序编写read()和write()方法.

我试图解决保持设备彼此独立的问题的方法是包括两个大小为10的全局静态数组.其中一个类型为wait_head_queue_t,另一个类型为Int(Bool标志).当我通过open()打开设备时,这两个数组都被初始化了一次.问题是,当我调用wake_up_interruptible()时,没有任何反应,程序在超时时终止.这是我的写法:

ssize_t sleepy_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos){

struct sleepy_dev *dev = (struct sleepy_dev *)filp->private_data;

ssize_t retval = 0;

int mem_to_be_copied = 0;

if (mutex_lock_killable(&dev->sleepy_mutex))

{

return -EINTR;

}

// check size

if(count != 4) // user must provide 4 byte Int

{

return EINVAL; // = 22

}

// else if the user provided valid sized input...

else

{

if((mem_to_be_copied = copy_from_user(&long_buff[0], buf, count)))

{

return -EFAULT;

}

// check for negative wait time entered by user

if(long_buff[0] > -1)// "long_buff[]"is global,for now only holds 1 value

{

proc_read_flags[MINOR(dev->cdev.dev)] = 0; //****** flag array

retval = wait_event_interruptible_timeout(wqs[MINOR(dev->cdev.dev)], proc_read_flags[MINOR(dev->cdev.dev)] == 1, long_buff[0] * HZ) / HZ;

proc_read_flags[MINOR(dev->cdev.dev)] = 0; // MINOR numbers for each

// device correspond to array indices

// devices 0 - 9

// "wqs" is array of wait queues

}

else

{

printk(KERN_INFO "user entered negative value for sleep time\n");

}

}

mutex_unlock(&dev->sleepy_mutex);

return retval;}

与本主题的许多示例不同,我在调用wait_event_interruptible_timeout()之前立即将标志切换回零,因为标志值似乎在程序的后续运行之间保持不变.这是我的read方法的代码:

ssize_t sleepy_read(struct file *filp, char __user *buf, size_t count,

loff_t *f_pos){

struct sleepy_dev *dev = (struct sleepy_dev *)filp->private_data;

ssize_t retval = 0;

if (mutex_lock_killable(&dev->sleepy_mutex))

return -EINTR;

// switch the flag

proc_read_flags[MINOR(dev->cdev.dev)] = 1; // again device minor numbers

// correspond to array indices

// TODO: this is not waking up the process in write!

// wake up the queue

wake_up_interruptible(&wqs[MINOR(dev->cdev.dev)]);

mutex_unlock(&dev->sleepy_mutex);

return retval;}

我试图测试程序的方法是有两个main.c,一个用于写入设备,一个用于从设备读取,我只是./a.out它们在我的ubuntu安装在Virtual Box中的单独控制台中.另一件事,它现在的设置方式,写入或读取a.outs直到超时发生.我为代码的格式错误道歉.我不确定这里到底发生了什么,所以任何帮助都会非常感激!谢谢!

解决方法:

您的写入方法在等待事件时保持sleepy_mutex.因此,读取方法等待mutex_lock_killable(& dev-> sleepy_mutex),而互斥锁由编写器解锁.仅当写入器的超时超过时才会发生,并且write方法返回.这是你观察到的行为.

通常,wait_event *在任何关键部分之外执行.这可以通过使用这些宏的_lock-suffixed变体来实现,或者简单地用spinlock获取/释放对包装这些宏的cond参数:

int check_cond()

{

int res;

spin_lock(&lock);

res = ;

spin_unlock(&lock);

return res;

}

...

wait_event_interruptible(&wq, check_cond());

不幸的是,当使用互斥锁保护条件检查时,不能使用wait_event-family宏.在这种情况下,您可以使用wait_woken()函数和手动条件检查代码.或者重写代码而不需要在条件检查时使用互斥锁定/解锁.

作家代码:

//Declare local variable at the beginning of the function

int cflag;

...

// Outside of any critical section(after mutex_unlock())

cflag = proc_read_flags[MINOR(dev->cdev.dev)];

wait_event_interruptible_timeout(&wqs[MINOR(dev->cdev.dev)],

proc_read_flags[MINOR(dev->cdev.dev)] != cflag, long_buff[0]*HZ);

读者代码:

// Mutex holding protects this flag's increment from concurrent one.

proc_read_flags[MINOR(dev->cdev.dev)]++;

wake_up_interruptible_all(&wqs[MINOR(dev->cdev.dev)]);

标签:linux,linux-kernel,device,driver

来源: https://codeday.me/bug/20190702/1360571.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值