LDD3では、そのようなコードを見ました
static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
struct scull_pipe *dev = filp->private_data;
unsigned int mask = 0;
/*
* The buffer is circular; it is considered full
* if "wp" is right behind "rp" and empty if the
* two are equal.
*/
down(&dev->sem);
poll_wait(filp, &dev->inq, wait);
poll_wait(filp, &dev->outq, wait);
if (dev->rp != dev->wp)
mask |= POLLIN | POLLRDNORM; /* readable */
if (spacefree(dev))
mask |= POLLOUT | POLLWRNORM; /* writable */
up(&dev->sem);
return mask;
}
しかし、poll_waitは待機せず、すぐに戻ると書かれています。では、なぜそれを呼び出す必要があるのでしょうか。なぜマスクを返せないのですか?
poll_waitは、プロセスをウェイクアップできるデバイスのリストにデバイス(「構造体ファイル」で表される)を追加します。
プロセスは、poll(またはselectまたはepollなど)を使用して、待機したいリストに一連のファイル記述子を追加できるという考え方です。各ドライバーのポーリングエントリが呼び出されます。それぞれが(poll_waitを介して)ウェイターリストに追加されます。
次に、コアカーネルがプロセスを1か所でブロックします。そうすれば、どのデバイスでもプロセスをウェイクアップできます。ゼロ以外のマスクビットを返す場合、それはそれらの「準備完了」属性(読み取り可能/書き込み可能など)が適用されることを意味します今。
したがって、擬似コードでは、大まかに次のようになります。
foreach fd:
find device corresponding to fd
call device poll function to setup wait queues (with poll_wait) and to collect its "ready-now" mask
while time remaining in timeout and no devices are ready:
sleep
return from system call (either due to timeout or to ready devices)
file_operation
を返すと、poll
0
はスリープします
これが私を混乱させたものです。
ゼロ以外を返すと、何らかのイベントが発生し、ウェイクアップしたことを意味します。
これを見ると、何かがプロセスを待機キューに結び付けている必要があることは明らかであり、それはpoll_wait
です。
また、struct file
は、ファイルシステムファイルだけでなく、「プロセスと開いているファイル間の接続」を表すため、プロセスを識別するために使用されるpidが含まれていることにも注意してください。
最小限の実行可能な例で遊ぶことも、物事を明確にするのに役立つかもしれません: https://stackoverflow.com/a/44645336/895245