読み書きを消費する実装の単純なcharドライバを書きたいと思っています。読み込みと書き込みのオフセット用のバッファと2つのグローバルポインタを保持しています。すべてのプロセスは排他的に読み取りまたは書き込みを行う必要があります。また、読み取りには少なくとも512バイトがあるまで待機する必要があります。演習のために、私はmutexの代わりにwait_event_interruptible_exclusive
としたいと思います。私の読み書きは次の通りです:カーネルのミューテックスとwait_event_interruptible_exclusiveとの比較
static ssize_t
my_read(struct file *file, char __user *buf, size_t lbuf, loff_t *ppos)
{
int nbytes;
wait_event_interruptible_exclusive(wq, atomic_read(&data_sz) >=512 && (atomic_xchg(&data_sz,-1) || 1));
nbytes = simple_read_from_buffer(buf, lbuf, &read_pos, my_buff, my_buff_size);
*ppos = read_pos;
atomic_set(&data_sz,write_pos-read_pos);
wake_up_interruptible(&wq);
return nbytes;
}
static ssize_t
my_write(struct file *file, const char __user *buf, size_t lbuf,
loff_t *ppos)
{
int nbytes;
wait_event_interruptible_exclusive(wq, atomic_read(&data_sz) != -1 && (atomic_xchg(&data_sz,-1) || 1));
nbytes = simple_write_to_buffer(my_buff, my_buff_size, &write_pos, buf, lbuf);
*ppos = write_pos;
atomic_set(&data_sz,write_pos-read_pos);
wake_up_interruptible(&wq);
return nbytes;
}
そういうのは大丈夫ですか? mutexのあらゆる使用法をそのようなものに置き換えることは可能ですか? また、バッファの私のオフセットはグローバルなので、読み書きのpposパラメータはドライバによって無視され、行*ppos=read_pos
と*ppos=write_pos
が必要かどうか疑問に思っていますか?
「すべてのプロセスは排他的に読み取りまたは書き込みする必要があります」 - 排他性を保証するものではありません。たとえば、2人の読者の条件が同時にチェックされると、両方の読者は「atomic_read(&data_sz)> = 512」が真であると判読して読書に進むことができる。排他性がなければ、 'write_pos'と' read_pos'へのアクセスに関する競争条件があります。 – Tsyvarev
これは、atomic_read(&data_sz)> = 512 &&(atomic_xchg(&data_sz、-1)|| 1) 'であり、' atomic_read(&data_sz)> = 512'だけでなく、 = 512'とすると、data_szを-1に設定します – dafnahaktana