コード例 #1
0
ファイル: pscom_psm.c プロジェクト: carsten-clauss/pscom
/* Process a mq_status. return 1, if a read made progress. 0 else */
static
int pscom_psm_process(psm_mq_status_t *status)
{
	uintptr_t c = (uintptr_t)status->context & 7;
	pspsm_con_info_t *ci = (pspsm_con_info_t *)((uintptr_t)status->context & ~(uintptr_t)7);
	pscom_con_t *con = ci->con;

	assert(ci->magic == UINTMAX_C(0xdeadbeefcafebabe));

	switch (c) {
	case 0:
		/* first send request */
		assert(ci->sreqs[0] != PSM_MQ_REQINVALID);
		poll_user_dec();
		ci->sreqs[0] = PSM_MQ_REQINVALID;
		/* pspsm_dprint(0, "Send0 done %p len %d con %s\n", ci->iov[0].iov_base,
		   (int)ci->iov[0].iov_len, ci->con->pub.remote_con_info.name); */
		if (ci->sreqs[1] == PSM_MQ_REQINVALID){
			pscom_write_done(con, ci->req, ci->iov[0].iov_len + ci->iov[1].iov_len);
			ci->req = NULL;
		}
		break;
	case 1:
		/* second send request */
		assert(ci->sreqs[1] != PSM_MQ_REQINVALID);
		poll_user_dec();
		ci->sreqs[1] = PSM_MQ_REQINVALID;
		/* pspsm_dprint(0, "Send1 done %p len %d con %s\n", ci->iov[1].iov_base,
		   (int)ci->iov[1].iov_len, ci->con->pub.remote_con_info.name); */
		if (ci->sreqs[0] == PSM_MQ_REQINVALID){
			pscom_write_done(con, ci->req, ci->iov[0].iov_len + ci->iov[1].iov_len);
			ci->req = NULL;
		}
		break;
	case 2:
		/* receive request */
		assert(ci->rbuf);
		assert(status->msg_length == status->nbytes);
		ci->rreq = PSM_MQ_REQINVALID;
		/* pspsm_dprint(0, "read done %p len %d con %s\n", ci->rbuf,
		   (int)status->msg_length, ci->con->pub.remote_con_info.name); */
		pscom_read_done_unlock(con, ci->rbuf, status->msg_length);
		ci->rbuf = NULL;
		if (con->arch.psm.reading) {
			/* There is more to read. Post the next receive request */
			pscom_psm_do_read(con);
		}
		return 1;
		break;
	default:
		/* this shouldn't happen */
		assert(0);
	}
	return 0;
}
コード例 #2
0
ファイル: pscom_psm.c プロジェクト: carsten-clauss/pscom
static
void pscom_psm_read_stop(pscom_con_t *con)
{
	if (con->arch.psm.reading) {
		con->arch.psm.reading = 0;
		poll_user_dec();
	}
}
コード例 #3
0
ファイル: pscom_mxm.c プロジェクト: RWTH-OS/pscom
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;
}