NAME
ibv_get_async_event, ibv_ack_async_event - 非同期イベント(asynchronous events)を取得・承認(acknowledge)する。
SYNOPSIS
#include <infiniband/verbs.h> int ibv_get_async_event(struct ibv_context *context, struct ibv_async_event *event); void ibv_ack_async_event(struct ibv_async_event *event);
DESCRIPTION
ibv_get_async_event()
は context で指定される RDMA デバイスから非同期イベントが到着するまで待機する。
ibv_get_async_event()
の呼び出しに成功した場合、1 イベントだけ取得し event の領域へコピーする。
失敗した場合は、イベントの取得なしで ibv_get_async_event()
の呼び出しから復帰する。
context は ibv_open_device(3) でオープンした RDMA デバイスを指定する。
ibv_ack_async_event()
は非同期イベント event を承認する。
非同期イベントの詳細は 「InfiniBand のエラーハンドリングのモデルを理解する」を参照のこと。
RETURN VALUE
ibv_get_async_event()
は成功すれば 0 を返す。
失敗すれば -1 を返す。
ibv_ack_async_event()
には戻り値はない。
ERRORS
ibv_get_async_event()
は仕様に明記されていないが、-1 で返ってきた場合 errno にエラー原因が登録されている。
EINTR | シグナルによる割り込みが入った。 |
EAGAIN | (context->async_fd をノンブロッキングモードに設定している場合) 取り出し可能な非同期イベントがない。 |
errno の利用は仕様外なので、自己責任になる。
NOTES
ibv_get_async_event()
で取り出した非同期イベントは、ibv_ack_async_event()
を使って承認する必要がある。
ibv_get_async_event()
で取り出した非同期イベントに紐付けられたオブジェクト(CQ、SRQ、QP) を破壊する操作(ibv_destroy_cq()、ibv_destroy_srq()、ibv_destroy_qp())を実行すると、ibv_ack_async_event()
が呼ばれるまで待機することになる。
これは InfiniBand Verbs 内での競合を避けるためのガード機構である。
逆に event が指す非同期イベントのデータに触ってよいのは、ibv_get_async_evnet()
で取得した後、ibv_ack_async_event()
を呼び出す前までである。
ibv_ack_async_event()
が呼ばれた後は、非同期イベントのデータの先にある CQ/QP/SRQ は破壊されメモリ領域が回収されている可能性がある。
ibv_get_async_event()
は待機関数である。
もしマルチスレッドがこの関数を同時に呼び出した状態で、1 つだけ非同期イベントが発生すると、どちらか 1 つのスレッドだけが非同期イベントを受信する。
ただしどちらのスレッドが受け取るかは予測できない。
EXAMPLES
context->async_fd をノンブロッキングモードに設定するには以下のコードのように fcntl()
を設定する。
#include <stdlib.h> /* for exit */ #include <unistd.h> #include <fcntl.h> #include <infiniband/verbs.h> static void async_change_blocking_mode(struct ibv_context *context) { int ret, flags; flags = fcntl(context->async_fd, F_GETFL); if (flags < 0) { perror("fcntl(context->async_fd, F_GETFL)"); exit(EXIT_FAILURE); } ret = fcntl(context->async_fd, F_SETFL, flags | O_NONBLOCK); if (ret < 0) { perror("fcntl(context->async_fd, F_SETFL, flags | O_NONBLOCK)"); exit(EXIT_FAILURE); } }
ノンブロッキングモードに設定以降は ibv_get_async_event()
もブロックせず、取り出し可能な非同期イベントがない場合は -1 で復帰し、errno に EAGAIN が設定されるようになる。
非同期イベントの到着は context->async_fd が ready-to-input になるタイミングを select()
や epoll()
で待ち合わせることができる。
context->async_fd が "ready" になった後は、ibv_get_async_event()
を呼び出すと最低 1 つは完了イベントを取り出すことができる。
SEE ALSO
InfiniBand Verbs API Reference、ibv_open_device(3)
AUTHORS