예제 #1
0
파일: pselan.c 프로젝트: JonBau/pscom
/* 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;
}
예제 #2
0
파일: psextoll.c 프로젝트: JonBau/pscom
/* 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;
}
예제 #3
0
파일: psdapl.c 프로젝트: ParaStation/pscom
/* 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;
}