static void pscom_psm_do_write(pscom_con_t *con) { pspsm_con_info_t *ci = con->arch.psm.ci; if (ci->req) { /* send in progress. wait for completion before transmiting the next message. */ return; } /* FIXME: we might want to send more than one message at a time. */ /* get and post a new write request */ pscom_req_t *req = pscom_write_get_iov(con, ci->iov); if (req) { int ret = pspsm_sendv(ci); if (ret == 0){ /* was a direct send */ size_t size = ci->iov[0].iov_len + ci->iov[1].iov_len; pscom_write_done(con, req, size); } else if (ret == -EAGAIN){ /* pspsm_sendv was successful */ ci->req = req; } else if (ret == -EPIPE){ errno = -ret; pscom_con_error(con, PSCOM_OP_WRITE, PSCOM_ERR_STDERROR); } } }
static void pscom_openib_do_write(pscom_con_t *con) { size_t len; struct iovec iov[2]; pscom_req_t *req; req = pscom_write_get_iov(con, iov); if (req) { psoib_con_info_t *mcon = con->arch.openib.mcon; len = iov[0].iov_len + iov[1].iov_len; perf_add("openib_sendv"); ssize_t rlen = psoib_sendv(mcon, iov, len); if (rlen >= 0) { pscom_write_done(con, req, rlen); pscom_check_cq_poll(); } else if ((rlen == -EINTR) || (rlen == -EAGAIN)) { // Busy: Maybe out of tokens? try to read more tokens: _pscom_openib_do_read(con, mcon); } else { // Error pscom_con_error(con, PSCOM_OP_WRITE, PSCOM_ERR_STDERROR); } } }
static void pscom_extoll_rma2_do_write(pscom_con_t *con) { unsigned int len; struct iovec iov[2]; pscom_req_t *req; req = pscom_write_get_iov(con, iov); if (req) { psex_con_info_t *ci = con->arch.extoll.ci; len = iov[0].iov_len + iov[1].iov_len; int rlen = psex_sendv(ci, iov, len); if (rlen >= 0) { pscom_write_done(con, req, rlen); } else if ((rlen == -EINTR) || (rlen == -EAGAIN)) { // Busy: Maybe out of tokens? try to read more tokens: _pscom_extoll_rma2_do_read(con, ci); } else { // Error pscom_con_error(con, PSCOM_OP_WRITE, PSCOM_ERR_STDERROR); } } }
static void pscom_mxm_do_write(pscom_con_t *con) { struct iovec iov[2]; psmxm_con_info_t *ci = con->arch.mxm.ci; pscom_req_t *req = con->arch.mxm.sreq; int polling = 0; if (req) { // proceed with the send from the last iteration. polling = 1; unsigned sent = psmxm_send_progress(ci); if (sent) { pscom_write_done(con, req, sent); } else { /* FIXME: we might want to send more than one message at a time. */ /* send in progress. wait for completion before transmitting the next message. */ return; } } /* get and post a new write request */ req = pscom_write_get_iov(con, iov); if (req) { int ret = psmxm_sendv(ci, iov, iov[0].iov_len + iov[1].iov_len); if (ret > 0){ /* sending ret bytes. Complete this request in the next iteration. */ if (!polling) poll_user_inc(); } else if (ret == -EAGAIN){ /* Try again later. */ req = NULL; } else { assert(ret == -EPIPE); errno = -ret; pscom_con_error(con, PSCOM_OP_WRITE, PSCOM_ERR_STDERROR); req = NULL; } } if (!req && polling) poll_user_dec(); // Remember the current request or NULL in the case of EAGAIN. con->arch.mxm.sreq = req; }
static int pscom_psm_do_read(pscom_con_t *con) { pspsm_con_info_t *ci = con->arch.psm.ci; /* old request outstanding? */ if (ci->rbuf) return 0; /* post a new request */ pscom_read_get_buf_locked(con, &ci->rbuf, &ci->rbuflen); int ret = pspsm_recvlook(ci); if (ret == -EPIPE) goto err; assert(ret == -EAGAIN); return 0; err: errno = -ret; pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR); return 1; }
static int pscom_psm_do_read(pscom_con_t *con) { pspsm_con_info_t *ci = con->arch.psm.ci; char *rbuf; /**< buffer to be used for next receive */ size_t rbuflen; /**< size of buffer */ /* old request outstanding? */ if (pspsm_recv_pending(ci)) return 0; /* post a new request */ pscom_read_get_buf_locked(con, &rbuf, &rbuflen); int ret = pspsm_recv_start(ci, rbuf, rbuflen); if (ret) goto err; return 0; err: errno = -ret; pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR); return 1; }
static int _pscom_extoll_rma2_do_read(pscom_con_t *con, psex_con_info_t *ci) { void *buf; int size; size = psex_recvlook(ci, &buf); if (size >= 0) { pscom_read_done(con, buf, size); psex_recvdone(ci); return 1; } else if ((size == -EINTR) || (size == -EAGAIN)) { // Nothing received return 0; } else { // Error errno = -size; pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR); return 1; } }
static void _tcp_do_write(pscom_con_t *con) { struct iovec iov[2]; struct msghdr msg; pscom_req_t *req; req = pscom_write_get_iov(con, iov); if (req) { assert(req->magic == MAGIC_REQUEST); ssize_t len; // len = writev(con->arch.tcp.con_fd, // con->out.iov, con->out.count); msg.msg_iov = iov; msg.msg_iovlen = 2; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT; len = sendmsg(con->arch.tcp.ufd_info.fd, &msg, MSG_NOSIGNAL | MSG_DONTWAIT); if (len >= 0) { pscom_write_done(con, req, len); } else if ((errno != EINTR) && (errno != EAGAIN)) { goto err_con_broken; } } return; /* error code */ err_con_broken: pscom_con_error(con, PSCOM_OP_WRITE, PSCOM_ERR_STDERROR); return; }
static void tcp_do_read(ufd_t *ufd, ufd_funcinfo_t *ufd_info) { pscom_con_t *con = (pscom_con_t *) ufd_info->priv; char *buf; size_t len; ssize_t rlen; pscom_read_get_buf(con, &buf, &len); rlen = recv(con->arch.tcp.ufd_info.fd, buf, len, MSG_NOSIGNAL | MSG_DONTWAIT); if (rlen >= 0) { pscom_read_done(con, buf, rlen); } else if ((errno != EINTR) && (errno != EAGAIN)) { goto err_con_broken; } return; /* --- */ err_con_broken: pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR); return; }
static int _pscom_openib_do_read(pscom_con_t *con, psoib_con_info_t *mcon) { void *buf; ssize_t size; size = psoib_recvlook(mcon, &buf); if (size >= 0) { perf_add("openib_do_read"); pscom_read_done(con, buf, size); psoib_recvdone(mcon); return 1; } else if ((size == -EINTR) || (size == -EAGAIN)) { // Nothing received return 0; } else { // Error errno = -size; pscom_con_error(con, PSCOM_OP_READ, PSCOM_ERR_STDERROR); return 1; } }