/* * fi_cq_err_entry can be cast to any CQ entry format. */ static int ft_fdwait_for_comp(struct fid_cq *cq, uint64_t *cur, uint64_t total, int timeout) { struct fi_cq_err_entry comp; struct fid *fids[1]; int fd, ret; fd = cq == txcq ? tx_fd : rx_fd; fids[0] = &cq->fid; while (total - *cur > 0) { ret = fi_trywait(fabric, fids, 1); if (ret == FI_SUCCESS) { ret = ft_poll_fd(fd, timeout); if (ret) return ret; } ret = fi_cq_read(cq, &comp, 1); if (ret > 0) { (*cur)++; } else if (ret < 0 && ret != -FI_EAGAIN) { return ret; } } return 0; }
static int rxd_ep_trywait(void *arg) { struct rxd_fabric *rxd_fabric; struct rxd_ep *rxd_ep = (struct rxd_ep *) arg; struct fid *fids[1] = {&rxd_ep->dg_cq->fid}; rxd_fabric = container_of(rxd_ep->util_ep.domain->fabric, struct rxd_fabric, util_fabric); return fi_trywait(rxd_fabric->dg_fabric, fids, 1); }
static int send_recv() { struct fi_cq_entry comp; struct epoll_event event; struct fid *fids[1]; int ret; const char *message = "Hello from Client!"; size_t message_len = strlen(message) + 1; if (opts.dst_addr) { fprintf(stdout, "Posting a send...\n"); if (snprintf(tx_buf, tx_size, "%s", message) >= tx_size) { fprintf(stderr, "Transmit buffer too small.\n"); return -FI_ETOOSMALL; } ret = ft_post_tx(ep, remote_fi_addr, message_len, NO_CQ_DATA, &tx_ctx); if (ret) return ret; memset(&event, 0, sizeof event); fids[0] = &txcq->fid; do { if (fi_trywait(fabric, fids, 1) == FI_SUCCESS) { ret = TEMP_FAILURE_RETRY(epoll_wait(epfd, &event, 1, -1)); if (ret < 0) { ret = -errno; FT_PRINTERR("epoll_wait", ret); return ret; } if (event.data.ptr != &txcq->fid) fprintf(stdout, "unexpected event!\n"); } ret = fi_cq_read(txcq, &comp, 1); } while (ret == -FI_EAGAIN); if (ret < 0) { if (ret == -FI_EAVAIL) ret = ft_cq_readerr(txcq); return ret; } fprintf(stdout, "Send completion received\n"); } else { fprintf(stdout, "Waiting for client...\n"); memset(&event, 0, sizeof event); fids[0] = &rxcq->fid; do { if (fi_trywait(fabric, fids, 1) == FI_SUCCESS) { ret = TEMP_FAILURE_RETRY(epoll_wait(epfd, &event, 1, -1)); if (ret < 0) { ret = -errno; FT_PRINTERR("epoll_wait", ret); return ret; } if (event.data.ptr != &rxcq->fid) { fprintf(stdout, "unexpected event!\n"); } } ret = fi_cq_read(rxcq, &comp, 1); } while (ret == -FI_EAGAIN); if (ret < 0) { if (ret == -FI_EAVAIL) ret = ft_cq_readerr(rxcq); return ret; } ret = check_recv_msg(message); if (ret) return ret; fprintf(stdout, "Received data from client: %s\n", (char *) rx_buf); } return 0; }
/* * Tests: * - extracting FD from EQ with FI_WAIT_FD * - wait on fd with nothing pending * - wait on fd with event pending */ static int eq_wait_fd_poll() { int fd; struct fi_eq_entry entry; struct pollfd pfd; struct fid *fids[1]; int testret; int ret; testret = FAIL; ret = create_eq(32, FI_WRITE, FI_WAIT_FD); if (ret != 0) { sprintf(err_buf, "fi_eq_open ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } ret = fi_control(&eq->fid, FI_GETWAIT, &fd); if (ret != 0) { sprintf(err_buf, "fi_control ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } fids[0] = &eq->fid; if (fi_trywait(fabric, fids, 1) != FI_SUCCESS) { sprintf(err_buf, "fi_trywait ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } pfd.fd = fd; pfd.events = POLLIN; ret = poll(&pfd, 1, 0); if (ret < 0) { sprintf(err_buf, "poll errno=%d, %s", errno, fi_strerror(-errno)); goto fail; } if (ret > 0) { sprintf(err_buf, "poll returned %d, should be 0", ret); goto fail; } /* write an event */ entry.fid = &eq->fid; entry.context = eq; ret = fi_eq_write(eq, FI_NOTIFY, &entry, sizeof(entry), 0); if (ret != sizeof(entry)) { sprintf(err_buf, "fi_eq_write ret=%d, %s", ret, fi_strerror(-ret)); goto fail; } pfd.fd = fd; pfd.events = POLLIN; ret = poll(&pfd, 1, 0); if (ret < 0) { sprintf(err_buf, "poll errno=%d, %s", errno, fi_strerror(-errno)); goto fail; } if (ret != 1) { sprintf(err_buf, "poll returned %d, should be 1", ret); goto fail; } testret = PASS; fail: FT_CLOSE_FID(eq); return TEST_RET_VAL(ret, testret); }