Esempio n. 1
0
static
void pscom_mxm_read_start(pscom_con_t *con)
{
	if (!con->arch.mxm.reading) {
		con->arch.mxm.reading = 1;
		poll_user_inc();
	}
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
/* 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;
}