Macでデバイスドライバーを開発しています。私の質問は、デバイス要求を非同期から同期にするにはどうすればよいかということです。カプセル化されたコマンドをデバイスに送信し、割り込みパイプで通知を受け取った後、カプセル化されたコマンドを使用して応答を取得します。上記のすべてのリクエストが完了するまでスレッドを待機させるにはどうすればよいですか(送信と取得の両方)。
1 に答える
0
おそらく、それよりももう少し具体的にする必要があります。しかし、一般的に、自分の関数が別のスレッドで呼び出されるまでスレッドをスリープ状態にする必要がある場合は、xnu のイベント システムを使用できます。これはデバイス ドライバーであるため、I/O キットを使用していると仮定します。その場合、IO LocksまたはIOCommandGateが最も適切です。
ドライバー インスタンスで明示的なロックを使用すると、次のようになります。
IOLock* lock;
bool cleared;
これらをどこかで初期化します:
lock = IOLockAlloc();
cleared = false;
次に、スレッドが I/O を開始すると、次のようになります。
IOLockLock(lock);
cleared = false;
startYourIO(yourCallbackFunction);
while (!cleared)
{
IOLockSleep(
lock,
&cleared, // using address of status variable as event
THREAD_UNINT);
}
IOLockUnlock(lock);
あなたのCallbackFunctionで:
IOLockLock(lock);
cleared = true;
IOLockWakeup(
lock,
&cleared, // this must match the event pointer used in sleep
true); // flip to false to wake up all waiting threads, not just 1
IOLockUnlock(lock);
明らかに、複数の同時 I/O が進行している場合、ステータス変数はコンテキストごとにする必要があります。また、カーネルでは、同期よりも非同期の設計の方が優れていることがよくあります。しかし、この種の一般的なドライバーの設計についてはすべて知っていて、長所と短所を比較検討したと思います。
IOCommandGate
スリープ/ウェイク API は非常によく似ており、IOWorkLoop
. I/O Kit を使用していない場合は、IOLock が実装されている BSD レベルのロック/ミューテックス API を使用することをお勧めします。
于 2013-12-23T20:23:52.063 に答える