Example #1
0
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);
		}
	}
}
Example #2
0
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);
		}
	}
}
Example #3
0
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);
		}
	}
}
Example #4
0
static
void shm_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 && shm_cansend(&con->arch.shm)) {
		len = iov[0].iov_len + iov[1].iov_len;
		len = pscom_min(len, SHM_BUFLEN);

		shm_iovsend(&con->arch.shm, iov, len);

		pscom_write_done(con, req, len);
	}
}
Example #5
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;
}
Example #6
0
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;
}