/* returnvalue like write(), except on error errno is negative return */ static int _pselan_sendv(pselan_con_info_t *ci, struct iovec *iov, int size, unsigned int magic) { int len; int pselanlen; pselan_msg_t *msg; if (ci->con_broken) goto err_broken; /* Its allowed to send, if At least 2 tokens left or (1 token left AND n_tosend > 0) */ if ((ci->n_send_toks < 2) && ((ci->n_send_toks < 1) || (ci->n_tosend_toks == 0))) goto err_busy; len = (size <= (int)ELAN_BUFSIZE_PAYLOAD) ? size : (int)ELAN_BUFSIZE_PAYLOAD; pselanlen = PSELAN_LEN(len); msg = ci->send_bufs + ci->send_pos; msg->tail.token = ci->n_tosend_toks; msg->tail.payload = len; msg->tail.magic = magic; char *buf = msg->data - pselanlen; /* copy to registerd send buffer */ pscom_memcpy_from_iov(buf, iov, len); pselan_flush_sendbuf(ci, buf, ci->remote_r_buf[ci->send_pos].data - pselanlen, pselanlen + sizeof(pselan_msgheader_t)); pscom_forward_iov(iov, len); ci->n_tosend_toks = 0; ci->send_pos = (ci->send_pos + 1) % SIZE_SR_QUEUE; ci->n_send_toks--; pselan_flush_event(ci); return len; err_busy: pselan_get_fresh_tokens(ci); pselan_flush_event(ci); return -EAGAIN; err_broken: return -EPIPE; }
/* returnvalue like write(), except on error errno is negative return */ static int _psex_sendv(psex_con_info_t *con_info, struct iovec *iov, int size, unsigned int magic) { int len; int psex_len; psex_msg_t *_msg; int rc; psex_msgheader_t *tail; hca_info_t *hca_info = con_info->hca_info; if (con_info->con_broken) goto err_broken; /* Its allowed to send, if At least 2 tokens left or (1 token left AND n_tosend > 0) */ if ((con_info->n_send_toks < 2) && ((con_info->n_send_toks < 1) || (con_info->n_tosend_toks == 0))) { psex_stat.busy_notokens++; goto err_busy; } if (psex_global_sendq && psex_pending_global_sends >= psex_sendq_size && psex_event_count) { // printf("Busy global\n"); usleep(10*1000); psex_stat.busy_global_cq++; goto err_busy; } len = (size <= (int)PSEX_RMA2_PAYLOAD) ? size : (int)PSEX_RMA2_PAYLOAD; psex_len = PSEX_LEN(len); ringbuf_t *send = (con_info->send.bufs.mr) ? &con_info->send : &hca_info->send; _msg = ((psex_msg_t *)send->bufs.ptr) + send->pos; tail = (psex_msgheader_t *)((char*)_msg + psex_len - sizeof(psex_msgheader_t)); tail->token = con_info->n_tosend_toks; tail->payload = len; tail->magic = magic; /* copy to registerd send buffer */ pscom_memcpy_from_iov((void *)_msg, iov, len); rc = rma2_post_put_bt(con_info->rma2_port, con_info->rma2_handle, send->bufs.mr, ((char*)_msg - (char *)send->bufs.ptr), psex_len, PSEX_DATA(con_info->remote_rbuf_nla + con_info->remote_recv_pos * sizeof(psex_msg_t), psex_len), 0, 0); if (rc != 0) goto err_rma2_post_cl; psex_pending_global_sends++; // ToDo: Decrease the counter somewhere! pscom_forward_iov(iov, len); con_info->n_tosend_toks = 0; con_info->remote_recv_pos = (con_info->remote_recv_pos + 1) % psex_recvq_size; send->pos = (send->pos + 1) % psex_sendq_size; con_info->n_send_toks--; return len; /* --- */ err_busy: return -EAGAIN; /* --- */ err_rma2_post_cl: if (0 /*rc == ???EAGAIN Too many posted work requests ? */) { psex_stat.post_send_eagain++; return -EAGAIN; } else { psex_stat.post_send_error++; psex_err_rma2_error("rma2_post_put_cl()", rc); con_info->con_broken = 1; return -EPIPE; } /* --- */ err_broken: return -EPIPE; }
/* returnvalue like write(), except on error errno is negative return */ static int _psdapl_sendv(psdapl_con_info_t *ci, struct iovec *iov, int size, unsigned int magic) { int len; int psdapllen; psdapl_msg_t *msg; int rc; psdapl_msgheader_t *tail; if (ci->con_broken) goto err_broken; /* Its allowed to send, if At least 2 tokens left or (1 token left AND n_tosend > 0) */ if ((ci->n_send_toks < 2) && ((ci->n_send_toks < 1) || (ci->n_tosend_toks == 0))) { psdapl_stat.busy_notokens++; goto err_busy; } if (ci->outstanding_cq_entries >= EVD_MIN_QLEN) { psdapl_stat.busy_local_cq++; goto err_busy; } /* if (psdapl_outstanding_cq_entries >= ???) { psdapl_stat.busy_global_cq++; goto err_busy; } */ len = (size <= (int)DAPL_BUFSIZE_PAYLOAD) ? size : (int)DAPL_BUFSIZE_PAYLOAD; psdapllen = PSDAPL_LEN(len); msg = ((psdapl_msg_t *)ci->send_bufs.lmr_mem) + ci->send_pos; tail = (psdapl_msgheader_t *)((char*)msg + psdapllen); tail->token = ci->n_tosend_toks; tail->payload = len; tail->magic = magic; /* copy to registerd send buffer */ pscom_memcpy_from_iov((void *)msg, iov, len); rc = psdapl_flush_sendbuf(ci, (char *)msg, PSDAPL_DATA_OFFSET(ci->send_pos, psdapllen), psdapllen + sizeof(psdapl_msgheader_t)); if (rc != 0) goto err_send; ci->outstanding_cq_entries++; pscom_forward_iov(iov, len); ci->n_tosend_toks = 0; ci->send_pos = (ci->send_pos + 1) % SIZE_SR_QUEUE; ci->n_send_toks--; psdapl_flush_evd(ci); return len; err_busy: psdapl_get_fresh_tokens(ci); psdapl_flush_evd(ci); return -EAGAIN; err_send: psdapl_stat.post_send_error++; /* ToDo: Check for EAGAIN ? */ ci->con_broken = 1; return -EPIPE; err_broken: return -EPIPE; }