EN JA
CONDVAR(9)
CONDVAR(9) FreeBSD Kernel Developer's Manual CONDVAR(9)

名称

condvar, cv_init, cv_destroy, cv_wait, cv_wait_sig, cv_wait_unlock, cv_timedwait, cv_timedwait_sbt, cv_timedwait_sig, cv_timedwait_sig_sbt, cv_signal, cv_broadcast, cv_broadcastpri, cv_wmesgカーネル状態変数

書式

#include < sys/param.h>
#include < sys/proc.h>
#include < sys/condvar.h>

void
cv_init( struct cv *cvp, const char *desc);

void
cv_destroy( struct cv *cvp);

void
cv_wait( struct cv *cvp, lock);

int
cv_wait_sig( struct cv *cvp, lock);

void
cv_wait_unlock( struct cv *cvp, lock);

int
cv_timedwait( struct cv *cvp, lock, int timo);

int
cv_timedwait_sbt( struct cv *cvp, lock, sbintime_t sbt, sbintime_t pr, int flags);

int
cv_timedwait_sig( struct cv *cvp, lock, int timo);

int
cv_timedwait_sig_sbt( struct cv *cvp, lock, sbintime_t sbt, sbintime_t pr, int flags);

void
cv_signal( struct cv *cvp);

void
cv_broadcast( struct cv *cvp);

void
cv_broadcastpri( struct cv *cvp, int pri);

const char *
cv_wmesg( struct cv *cvp);

解説

状態変数は、状態が起こるのを待つために mutex (ミューテックス) とともに使用されます。状態変数は、 cv_init() で作成され、ここで cvp は、 struct cv のための空間を指し、 desc は、状態変数を記述するヌル文字で終了する文字列へのポインタです。状態変数は、 cv_destroy() で破壊されます。スレッドは、 cv_wait(), cv_wait_sig(), cv_wait_unlock(), cv_timedwait() または cv_timedwait_sig() を呼び出すことによって、状態変数でウェートします。スレッドは、1 つのウェイタ (waiter) のブロックを解除するために cv_signal() を呼び出すことによってウェイタのブロックを解除するか、またはすべてのウェイタのブロックを解除するために cv_broadcast() または cv_broadcastpri() を呼び出すことによってウェイタ (waiter) のブロックを解除します。ウェイタ (waiter) を起こすことに加えて、 cv_broadcastpri() は、あらゆるスレッドの優先度を上げることによって、すべてのウェイタが少なくとも pri の優先度があることを保証します。 cv_wmesg() は、 cv_init() への最初の呼び出しによって設定されるように、 cvp の記述文字列を返します。

lock 引数は、 mutex(9), rwlock(9) または sx(9) ロックのいずれかへのポインタです。 mutex(9) 引数は、 MTX_SPIN ではなく、 MTX_DEF で初期化されなければなりません。スレッドは、 cv_wait(), cv_wait_sig(), cv_wait_unlock(), cv_timedwait() または cv_timedwait_sig() を呼び出す前に lock を保持しなければなりません。スレッドがある状態でウェートするときに、 lock は、そのスレッドがブロックされる前に不可分に開放され、それからその関数呼び出しが戻る前に再獲得されます。さらに、スレッドは、サスペンド (一時停止) している間に、 (たとえ、繰り返されても) Giant mutex を完全に落とし、関数が返る前に、 Giant mutex を再獲得します。 cv_wait_unlock() 関数は、返る前に、ロックを再獲得しません。 Giant mutex が、 lock として指定されるかもしれないことに注意してください。しかしながら、 Giant は、 cv_wait_unlock() 関数のために lock として使用されません。すべてのウェイタ (waiter) は、 cvp と関連する同じ lock を渡さなければなりません。

cv_wait(), cv_wait_sig(), cv_wait_unlock(), cv_timedwait() と cv_timedwait_sig() がブロックを解除するとき、それらの呼び出しているスレッドは、実行可能とされます。 cv_timedwait() と cv_timedwait_sig() は、ブロックを解除して、 EWOULDBLOCK を返す前に、多くても timo / HZ 秒待ちます。そうでなければ、それらは、0 を返します。 cv_wait_sig() と cv_timedwait_sig() は、シグナルが捕獲されるか、または cv_signal() または cv_broadcast() によってシグナルが送られるなら、 EINTR または ERESTART の値で時期を早めて返ります。

cv_timedwait_sbt() と cv_timedwait_sig_sbt() 関数は、 timo の代わりに sbt 引数を取ります。それは、 sbintime_t の形式でより高い解像度がある、相対的か、または絶対的なブロック解除 (unblock) 時間を指定することができます。パラメータ pr によって、必要とされる絶対的なイベントの正確さを指定することができます。パラメータ flags によって、追加の callout_reset_sbt() フラグを渡すことができます。

戻り値

成功するなら、 cv_wait_sig(), cv_timedwait() と cv_timedwait_sig() は、0 を返します。そうでなければ、0 以外のエラーコードが返されます。

cv_wmesg() は、 cv_init() に渡された記述文字列を返します。

エラー

cv_wait_sig() と cv_timedwait_sig() は、次の場合に失敗します:
[ EINTR]
シグナルが捕獲され、システムコールが、割り込まれるべきです。
[ ERESTART]
シグナルが捕獲され、システムコールが、再開されるべきです。

cv_timedwait() と cv_timedwait_sig() は、次の場合に失敗します:

[ EWOULDBLOCK]
タイムアウトが満了しました。
February 19, 2013 FreeBSD