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