static void pscom_mxm_read_start(pscom_con_t *con) { if (!con->arch.mxm.reading) { con->arch.mxm.reading = 1; poll_user_inc(); } }
static void pscom_psm_read_start(pscom_con_t *con) { if (!con->arch.psm.reading) { con->arch.psm.reading = 1; poll_user_inc(); } /* post a receive */ pscom_psm_do_read(con); }
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; }
/* sends an iov. FIXME: returns 0 if the send is complete, -EAGAIN if it created one or more requests for it, and -EPIPE in case of an error. */ static int _pspsm_sendv(pspsm_con_info_t *con_info, uint64_t magic) { uint64_t tag = con_info->send_id | magic; unsigned int i=0; psm_error_t ret; size_t len = con_info->iov[0].iov_len + con_info->iov[1].iov_len; if (len <= pscom.env.readahead){ pscom_memcpy_from_iov(sendbuf, con_info->iov, len); /* we hope that doesn't block - it shouldn't, as the * message is sufficiently small */ ret = psm_mq_send(pspsm_mq, con_info->epaddr, /* flags*/ 0, tag, sendbuf, len); if (ret != PSM_OK) goto err; return 0; } for (i=0; i<2; i++){ if (con_info->iov[i].iov_len){ /* pspsm_dprint(0, "Send part[%d], %p len %d to con %s\n", i, con_info->iov[i].iov_base, (int)con_info->iov[i].iov_len, con_info->con->pub.remote_con_info.name); */ if (_pspsm_send_buf(con_info, con_info->iov[i].iov_base, con_info->iov[i].iov_len, tag, &con_info->sreqs[i], i)){ return -EPIPE; } /* inc for each outstanding send request */ poll_user_inc(); } } return -EAGAIN; err: pspsm_err(psm_error_get_string(ret)); pspsm_dprint(1, "_pspsm_send_buf: %s", pspsm_err_str); return -EPIPE; }