예제 #1
0
파일: xio.c 프로젝트: smallsmallc/sheepdog2
static void msg_prep_for_send(struct sd_req *hdr, struct sd_rsp *rsp,
			      void *data, struct xio_msg *msg)
{
	struct xio_vmsg *pomsg = &msg->out;
	struct xio_iovec_ex *osglist = vmsg_sglist(pomsg);
	struct xio_vmsg *pimsg = &msg->in;
	struct xio_iovec_ex *isglist = vmsg_sglist(pimsg);

	vmsg_sglist_set_nents(pomsg, 0);
	pomsg->header.iov_len = sizeof(*hdr);
	pomsg->header.iov_base = hdr;

	if (hdr->flags & SD_FLAG_CMD_WRITE) {
		vmsg_sglist_set_nents(pomsg, 1);

		osglist[0].iov_base = data;
		osglist[0].iov_len = hdr->data_length;
		osglist[0].mr = NULL;
	}

	vmsg_sglist_set_nents(pimsg, 1);
	isglist[0].iov_base = rsp;
	isglist[0].iov_len = sizeof(*rsp);
	isglist[0].mr = NULL;

	if (hdr->data_length) {
		vmsg_sglist_set_nents(pimsg, 2);
		isglist[1].iov_base = xzalloc(hdr->data_length);
		isglist[1].iov_len = hdr->data_length;
		isglist[1].mr = NULL;
	}
}
예제 #2
0
/*---------------------------------------------------------------------------*/
static void process_response(struct test_params *test_params,
			     struct xio_msg *rsp)
{
	struct xio_iovec_ex	*isglist = vmsg_sglist(&rsp->in);
	int			inents = vmsg_sglist_nents(&rsp->in);

	if (test_params->stat.first_time) {
		struct xio_iovec_ex	*osglist = vmsg_sglist(&rsp->out);
		int			onents = vmsg_sglist_nents(&rsp->out);
		size_t			data_len = 0;
		int			i;

		for (i = 0; i < onents; i++)
			data_len += osglist[i].iov_len;

		test_params->stat.txlen = rsp->out.header.iov_len + data_len;

		data_len = 0;
		for (i = 0; i < inents; i++)
			data_len += isglist[i].iov_len;

		test_params->stat.rxlen = rsp->in.header.iov_len + data_len;

		test_params->stat.start_time = get_cpu_usecs();
		test_params->stat.first_time = 0;

		data_len = test_params->stat.txlen > test_params->stat.rxlen ?
			   test_params->stat.txlen : test_params->stat.rxlen;
		data_len = data_len/1024;
		test_params->stat.print_counter = (data_len ?
				 PRINT_COUNTER/data_len : PRINT_COUNTER);
		if (test_params->stat.print_counter < 1000)
			test_params->stat.print_counter = 1000;
		test_params->disconnect_nr =
			test_params->stat.print_counter * DISCONNECT_FACTOR;
	}
	if (++test_params->stat.cnt == test_params->stat.print_counter) {
		char		timeb[40];

		uint64_t delta = get_cpu_usecs() - test_params->stat.start_time;
		uint64_t pps = (test_params->stat.cnt*USECS_IN_SEC)/delta;

		double txbw = (1.0*pps*test_params->stat.txlen/ONE_MB);
		double rxbw = (1.0*pps*test_params->stat.rxlen/ONE_MB);
		printf("transactions per second: %lu, bandwidth: " \
		       "TX %.2f MB/s, RX: %.2f MB/s, length: TX: %zd B, RX: %zd B\n",
		       pps, txbw, rxbw,
		       test_params->stat.txlen, test_params->stat.rxlen);
		get_time(timeb, 40);

		printf("**** [%s] - message [%zd] %s - %s\n",
		       timeb, (rsp->request->sn + 1),
		       (char *)rsp->in.header.iov_base,
		       (char *)(inents > 0 ? isglist[0].iov_base : NULL));

		test_params->stat.cnt = 0;
		test_params->stat.start_time = get_cpu_usecs();
	}
}
예제 #3
0
파일: xio.c 프로젝트: smallsmallc/sheepdog2
static int gw_client_on_response(struct xio_session *session,
				 struct xio_msg *rsp,
				 int last_in_rxq,
				 void *cb_user_context)
{
	struct xio_forward_info_entry *fi_entry =
		(struct xio_forward_info_entry *)cb_user_context;
	struct xio_forward_info *fi = fi_entry->fi;

	struct xio_vmsg *pimsg = &rsp->in;
	struct xio_iovec_ex *isglist = vmsg_sglist(pimsg);

	int nents = vmsg_sglist_nents(pimsg), total = 0;

	sd_debug("response on fi_entry %p", fi_entry);

	for (int i = 0; i < nents; i++) {
		memcpy((char *)fi_entry->buf + total,
		       isglist[i].iov_base, isglist[i].iov_len);

		total += isglist[i].iov_len;
	}

	fi->nr_done++;
	if (fi->nr_done == fi->nr_send)
		xio_context_stop_loop(fi->ctx);

	return 0;
}
예제 #4
0
static int server_on_request(struct xio_session *session,
			     struct xio_msg *xio_req,
			     int last_in_rxq,
			     void *cb_user_conext)
{
	struct client_info *ci = (struct client_info *)cb_user_conext;
	struct sd_req *hdr;
	struct request *req;

	struct xio_iovec_ex *sglist = vmsg_sglist(&xio_req->in);
	int nents = vmsg_sglist_nents(&xio_req->in);

	sd_debug("on request: %p, %p, nents: %d", session, xio_req, nents);
	hdr = xio_req->in.header.iov_base;

	req = alloc_request(ci, hdr->data_length);
	memcpy(&req->rq, hdr, sizeof(req->rq));

	if (hdr->data_length && hdr->flags & SD_FLAG_CMD_WRITE) {
		sd_assert(nents == 1);
		req->data = sglist[0].iov_base;
	}

	xio_req->in.header.iov_base  = NULL;
	xio_req->in.header.iov_len  = 0;
	vmsg_sglist_set_nents(&xio_req->in, 0);

	ci->xio_req = xio_req;

	queue_request(req);

	xio_context_stop_loop(xio_get_main_ctx());
	return 0;
}
예제 #5
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session, struct xio_msg *rsp,
		       int more_in_batch, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist;

	process_response(rsp);

	/* message is no longer needed */
	xio_release_response(rsp);

	nrecv++;
	if (test_config.finite_run) {
		if (nrecv == disconnect_nr) {
			xio_disconnect(conn);
			return 0;
		}

		if (nrecv > disconnect_nr || nsent == disconnect_nr)
			return 0;
	}

	/* reset message */
	rsp->in.header.iov_base = NULL;
	rsp->in.header.iov_len = 0;
	sglist = vmsg_sglist(&rsp->in);
	vmsg_sglist_set_nents(&rsp->in, 1);

	sglist[0].iov_base = NULL;
	sglist[0].iov_len  = ONE_MB;
	sglist[0].mr = NULL;

	rsp->sn = 0;
	rsp->more_in_batch = 0;
	do {
		/* recycle the message and fill new request */
		msg_write(&msg_params, rsp,
			  test_config.hdr_len,
			  1, test_config.data_len);

		/* try to send it */
		if (xio_send_request(conn, rsp) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_msg " \
				       "failed %s\n",
				       session,
				       xio_strerror(xio_errno()));
			msg_pool_put(pool, rsp);
			xio_assert(0);
		}
		nsent++;
	} while (0);

	return 0;
}
예제 #6
0
/*---------------------------------------------------------------------------*/
int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	vmsg_sglist_set_nents(&msg->in, 1);
	if (reg_mem.addr == NULL)
		xio_mem_alloc(XIO_READ_BUF_LEN, &reg_mem);

	sglist[0].iov_base = reg_mem.addr;
	sglist[0].mr =	reg_mem.mr;
	sglist[0].iov_len = XIO_READ_BUF_LEN;

	return 0;
}
예제 #7
0
static int server_assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);
	struct xio_reg_mem	in_xbuf;

	sd_debug("assign buffer, msg vec len: %lu", sglist[0].iov_len);

	xio_mem_alloc(sglist[0].iov_len, &in_xbuf);

	sglist[0].iov_base = in_xbuf.addr;
	sglist[0].mr = in_xbuf.mr;

	return 0;
}
예제 #8
0
/*---------------------------------------------------------------------------*/
static int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	vmsg_sglist_set_nents(&msg->in, 1);
	if (xbuf == NULL)
		xbuf = xio_alloc(XIO_READ_BUF_LEN);

	sglist[0].iov_base = xbuf->addr;
	sglist[0].mr = xbuf->mr;
	sglist[0].iov_len = XIO_READ_BUF_LEN;

	return 0;
}
예제 #9
0
/*---------------------------------------------------------------------------*/
static void process_response(struct session_data *session_data,
			     struct xio_msg *rsp)
{
	if (++session_data->cnt == PRINT_COUNTER) {
		struct xio_iovec_ex	*isglist = vmsg_sglist(&rsp->in);
		int			inents = vmsg_sglist_nents(&rsp->in);

		printf("message: [%lu] - %s\n",
		       (rsp->request->sn + 1),
		       (char *)rsp->in.header.iov_base);
		printf("message: [%lu] - %s\n",
		       (rsp->request->sn + 1),
		       (char *)(inents > 0 ? isglist[0].iov_base : NULL));
		session_data->cnt = 0;
	}
}
예제 #10
0
/*---------------------------------------------------------------------------*/
static void process_tx_message(struct ow_test_params *ow_params,
			       struct xio_msg *msg)
{
	struct xio_iovec_ex	*osglist = vmsg_sglist(&msg->out);
	int			onents = vmsg_sglist_nents(&msg->out);

	if (ow_params->tx_stat.first_time) {
		size_t	data_len = 0;
		int	i;

		for (i = 0; i < onents; i++)
			data_len += osglist[i].iov_len;

		ow_params->tx_stat.xlen = msg->out.header.iov_len + data_len;

		ow_params->tx_stat.start_time = get_cpu_usecs();
		ow_params->tx_stat.first_time = 0;

		data_len = ow_params->tx_stat.xlen/1024;
		ow_params->tx_stat.print_counter = data_len ?
			PRINT_COUNTER/data_len : PRINT_COUNTER;
		if (ow_params->tx_stat.print_counter < 1000)
			ow_params->tx_stat.print_counter = 1000;
		ow_params->disconnect_nr =
			ow_params->tx_stat.print_counter * DISCONNECT_FACTOR;
	}
	if (++ow_params->tx_stat.cnt == ow_params->tx_stat.print_counter) {
		char		timeb[40];

		uint64_t delta =
			get_cpu_usecs() - ow_params->tx_stat.start_time;
		uint64_t pps = (ow_params->tx_stat.cnt*USECS_IN_SEC)/delta;

		double txbw = (1.0*pps*ow_params->tx_stat.xlen/ONE_MB);

		printf("transactions per second: %lu, bandwidth: " \
		       "TX %.2f MB/s,length: TX: %zd B\n",
		       pps, txbw, ow_params->tx_stat.xlen);
		get_time(timeb, 40);
		printf("**** [%s] - message [%lu] %s - %s\n",
		       timeb, (msg->sn + 1),
		       (char *)msg->out.header.iov_base,
		       (char *)(onents > 0 ? osglist[0].iov_base : NULL));
		ow_params->tx_stat.cnt = 0;
		ow_params->tx_stat.start_time = get_cpu_usecs();
	}
}
예제 #11
0
/*---------------------------------------------------------------------------*/
static int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct test_params *test_params = (struct test_params *)cb_user_context;
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);
	int			nents = vmsg_sglist_nents(&msg->in);
	int i;

	if (test_params->reg_mem.addr == NULL)
		xio_mem_alloc(XIO_READ_BUF_LEN, &test_params->reg_mem);

	for (i = 0; i < nents; i++) {
		sglist[i].iov_base = test_params->reg_mem.addr;
		sglist[i].mr = test_params->reg_mem.mr;
	}

	return 0;
}
예제 #12
0
파일: xiosrvd.c 프로젝트: SUSE/accelio
/*---------------------------------------------------------------------------*/
static void process_request(struct server_data *server_data,
			    struct xio_msg *req)
{
	struct xio_iovec_ex	*sglist = vmsg_sglist(&req->in);
	char			*str;
	int			nents = vmsg_sglist_nents(&req->in);
	int			len, i;
	char			tmp;

	/* note all data is packed together so in order to print each
	 * part on its own NULL character is temporarily stuffed
	 * before the print and the original character is restored after
	 * the printf
	 */
	if (++server_data->cnt == PRINT_COUNTER) {
		str = (char *)req->in.header.iov_base;
		len = req->in.header.iov_len;
		if (str) {
			if (((unsigned) len) > 64)
				len = 64;
			tmp = str[len];
			str[len] = '\0';
			logit(LOG_INFO, "message header : [%lu] - %s",
			      (req->sn + 1), str);
			str[len] = tmp;
		}
		for (i = 0; i < nents; i++) {
			str = (char *)sglist[i].iov_base;
			len = sglist[i].iov_len;
			if (str) {
				if (((unsigned)len) > 64)
					len = 64;
				tmp = str[len];
				str[len] = '\0';
				logit(LOG_INFO, "message data: " \
				      "[%lu][%d][%d] - %s",
				      (req->sn + 1), i, len, str);
				str[len] = tmp;
			}
		}
		server_data->cnt = 0;
	}
	req->in.header.iov_base	  = NULL;
	req->in.header.iov_len	  = 0;
	vmsg_sglist_set_nents(&req->in, 0);
}
예제 #13
0
/*---------------------------------------------------------------------------*/
static void process_request(struct xio_msg *msg)
{
	static int cnt;

	if (msg == NULL) {
		cnt = 0;
		return;
	}
	if (++cnt == PRINT_COUNTER) {
		struct xio_iovec_ex *sglist = vmsg_sglist(&msg->in);

		printf("**** message [%lu] %s - %s\n",
		       (msg->sn+1),
		       (char *)msg->in.header.iov_base,
		       (char *)sglist[0].iov_base);
		cnt = 0;
	}
}
예제 #14
0
static void msg_prep_for_reply(struct sd_rsp *rsp,
			       void *data, struct xio_msg *msg)
{
	struct xio_vmsg *pomsg = &msg->out;
	struct xio_iovec_ex *sglist = vmsg_sglist(pomsg);

	vmsg_sglist_set_nents(pomsg, 0);
	pomsg->header.iov_len = sizeof(*rsp);
	pomsg->header.iov_base = rsp;

	if (rsp->data_length != 0) {
		vmsg_sglist_set_nents(pomsg, 1);

		sglist[0].iov_base = data;
		sglist[0].iov_len = rsp->data_length;
		sglist[0].mr = NULL;
	}
}
예제 #15
0
/*---------------------------------------------------------------------------*/
static void process_request(struct thread_data *tdata, struct xio_msg *msg)
{
    if (msg == NULL) {
        tdata->stat.cnt = 0;
        return;
    }

    if (++tdata->stat.cnt == PRINT_COUNTER) {
        struct xio_iovec_ex *sglist = vmsg_sglist(&msg->in);

        printf("thread [%d] - message [%lu] %s - %s\n",
               tdata->affinity,
               (msg->sn+1),
               (char *)msg->in.header.iov_base,
               (char *)sglist[0].iov_base);
        tdata->stat.cnt = 0;
    }
}
예제 #16
0
/*---------------------------------------------------------------------------*/
static void process_request(struct xio_msg *req)
{
	static int cnt;

	if (req == NULL) {
		cnt = 0;
		return;
	}

	if (++cnt == print_counter) {
		struct xio_iovec_ex *sglist = vmsg_sglist(&req->in);

		printf("**** request [%lu] %s - %s\n",
		       (req->sn+1),
		       (char *)req->in.header.iov_base,
		       (char *)sglist[0].iov_base);
		cnt = 0;
	}
}
예제 #17
0
/*---------------------------------------------------------------------------*/
static int assign_data_in_buf(struct xio_msg *msg, void *cb_user_context)
{
	struct thread_data	*tdata = cb_user_context;
	struct xio_iovec_ex	*sglist = vmsg_sglist(&msg->in);

	if (!tdata->in_xbuf) {
		tdata->in_xbuf = xio_alloc(sglist[0].iov_len);
	} else if (tdata->in_xbuf->length < sglist[0].iov_len) {
		xio_free(&tdata->in_xbuf);
		tdata->in_xbuf = xio_alloc(sglist[0].iov_len);
	}

	vmsg_sglist_set_nents(&msg->in, 1);

	sglist[0].iov_base	= tdata->in_xbuf->addr;
	sglist[0].iov_len	= tdata->in_xbuf->length;
	sglist[0].mr		= tdata->in_xbuf->mr;

	return 0;
}
예제 #18
0
파일: xio.c 프로젝트: smallsmallc/sheepdog2
static void msg_finalize(struct sd_req *hdr, void *data, struct xio_msg *xrsp)
{
	struct xio_vmsg *pimsg = &xrsp->in;
	struct xio_iovec_ex *isglist = vmsg_sglist(pimsg);
	int nents = vmsg_sglist_nents(pimsg);

	sd_assert(xrsp->in.header.iov_len == sizeof(struct sd_rsp));
	memcpy(hdr, xrsp->in.header.iov_base, sizeof(*hdr));
	if (data) {
		int total = 0;

		for (int i = 0; i < nents; i++) {
			memcpy((char *)data + total, isglist[i].iov_base,
			       isglist[i].iov_len);
			total += isglist[i].iov_len;
		}
	}

	xio_release_response(xrsp);
}
예제 #19
0
/*---------------------------------------------------------------------------*/
static void process_message(struct test_params *test_params,
			    struct xio_msg *msg)
{
	struct xio_iovec_ex	*osglist = vmsg_sglist(&msg->out);
	int			onents = vmsg_sglist_nents(&msg->out);

	if (test_params->stat.first_time) {
		size_t	data_len = 0;
		int	i;

		for (i = 0; i < onents; i++)
			data_len += osglist[i].iov_len;

		test_params->stat.txlen = msg->out.header.iov_len + data_len;

		test_params->stat.start_time = get_cpu_usecs();
		test_params->stat.first_time = 0;

		data_len = test_params->stat.txlen/1024;
		test_params->stat.print_counter = (data_len ?
				 PRINT_COUNTER/data_len : PRINT_COUNTER);
		if (test_params->stat.print_counter < 1000)
			test_params->stat.print_counter = 1000;
		test_params->disconnect_nr =
			test_params->stat.print_counter * DISCONNECT_FACTOR;
	}
	if (++test_params->stat.cnt == test_params->stat.print_counter) {
		uint64_t delta = get_cpu_usecs() - test_params->stat.start_time;
		uint64_t pps = (test_params->stat.cnt*USECS_IN_SEC)/delta;

		double txbw = (1.0*pps*test_params->stat.txlen/ONE_MB);

		printf("transactions per second: %lu, bandwidth: " \
		       "TX %.2f MB/s, length: TX: %zd B\n",
		       pps, txbw,
		       test_params->stat.txlen);

		test_params->stat.cnt = 0;
		test_params->stat.start_time = get_cpu_usecs();
	}
}
예제 #20
0
/*---------------------------------------------------------------------------*/
void msg_write(struct msg_params *msg_params,
	       struct xio_msg *msg,
	       size_t hdrlen,
	       size_t data_iovlen, size_t datalen)
{
	struct xio_vmsg		*pmsg = &msg->out;
	struct xio_iovec_ex	*sglist = vmsg_sglist(pmsg);
	int			nents;
	int			i;

	/* don't do the memcpy */
	pmsg->header.iov_len		= hdrlen;
	pmsg->header.iov_base		= msg_params->g_hdr;
	nents				= datalen ? data_iovlen : 0;

	vmsg_sglist_set_nents(pmsg, nents);

	for (i = 0; i < nents; i++) {
		sglist[i].iov_base	= msg_params->g_data;
		sglist[i].iov_len	= datalen;
		sglist[i].mr		= msg_params->g_data_mr;
	}
}
예제 #21
0
static int on_request(struct xio_session *session,
            struct xio_msg *req,
            int last_in_rxq,
            void *cb_user_context)
{
    struct xio_msg *rsp;
    struct io_worker_data *wdata;
    struct xio_iovec_ex *in_sglist;
    struct xio_iovec_ex *out_sglist;
    struct rdb_req_hdr *req_hdr;
    void *ptr;
    int *status;
    char *value;
    size_t key_size, value_size;
//    int len;

    wdata = cb_user_context;
    rsp = &wdata->rsp;

    in_sglist = vmsg_sglist(&req->in);
    req_hdr = in_sglist[0].iov_base;
    ptr = in_sglist[0].iov_base;
    ptr += sizeof (*req_hdr);

    switch (req_hdr->rdb_command) {
        case RDB_CMD_PUT:
            {
                struct rdb_put_req_hdr *put_hdr;

                put_hdr = ptr;

                struct __attribute__((__packed__)) rdb_put_req {
                    struct rdb_key {
                        struct  rdb_key_hdr     key_hdr;
                        char                    key_data[put_hdr->key_size];
                    } key;
                    struct rdb_value {
                        struct  rdb_value_hdr   value_hdr;
                        char                    value_data[put_hdr->value_size];
                    } value;
                } *put_req;

                ptr += sizeof (*put_hdr);
                put_req = ptr;
                key_size = sizeof (struct rdb_key);
                value_size = sizeof (struct rdb_value);
                if (!null_mode)
                    if (!rocksdb_server_put(wdata->rdb, (char *)&put_req->key, &key_size,
                            (char *)&put_req->value, &value_size)) {
                        fprintf(stderr, "rocksdb put failed\n");
                    }
//                len = (int) in_sglist[0].iov_len;

                break;
            }
        case RDB_CMD_MPUT:
            {
                struct rdb_mput_req_hdr *mput_hdr;
                char *records;

                mput_hdr = ptr;

                struct __attribute__((__packed__)) rdb_mput_req {
                    struct multi_kv_pairs {
                        struct rdb_key {
                            struct  rdb_key_hdr     key_hdr;
                            char                    key_data[mput_hdr->key_size];
                        } key;
                        struct rdb_value {
                            struct  rdb_value_hdr   value_hdr;
                            char                    value_data[mput_hdr->value_size];
                        } value;
                    } m_kv_pairs[mput_hdr->num_records];
                } *mput_req;

                ptr += sizeof (*mput_hdr);
                mput_req = ptr;
                key_size = sizeof (struct rdb_key);
                value_size = sizeof (struct rdb_value);
                records = (char *)mput_req->m_kv_pairs;

                if (!null_mode)
                    if (!rocksdb_server_mput(wdata->rdb, records, &key_size,
                            &value_size, &mput_hdr->num_records)) {
                        fprintf(stderr, "rocksdb mput failed\n");
                    }
//                len = (int) in_sglist[0].iov_len;

                break;
            }
        case RDB_CMD_GET:
            {
                struct rdb_get_req_hdr *get_hdr;

                get_hdr = ptr;

                struct __attribute__((__packed__)) rdb_get_req {
                    struct rdb_key {
                        struct  rdb_key_hdr     key_hdr;
                        char                    key_data[get_hdr->key_size];
                    } key;
                } *get_req;

                ptr += sizeof (*get_hdr);
                get_req = ptr;
                key_size = sizeof (get_req->key);

                out_sglist = vmsg_sglist(&rsp->out);
                out_sglist[0].iov_base = wdata->reg_mem.addr;
                out_sglist[0].mr = wdata->reg_mem.mr;

                if (!null_mode) {
                    status = wdata->reg_mem.addr;
                    value = wdata->reg_mem.addr + sizeof (*status);
                    *status = rocksdb_server_get(wdata->rdb, (char *)&get_req->key, &key_size,
                                    value, &value_size);
                    if (*status)
                        out_sglist[0].iov_len = value_size + sizeof (*status);
                    else
                        out_sglist[0].iov_len = sizeof (*status);
                } else {
                    status = wdata->reg_mem.addr;
                    *status = 1;
                    out_sglist[0].iov_len = sizeof (*status);
                }
//                len = (int) out_sglist[0].iov_len;

                vmsg_sglist_set_nents(&rsp->out, 1);

                break;
            }
        case RDB_CMD_MGET:
            {
                struct rdb_mget_req_hdr *mget_hdr;
                char *records;

                mget_hdr = ptr;

                struct __attribute__((__packed__)) rdb_mget_req {
                    struct multi_k_pairs {
                        struct rdb_key {
                            struct  rdb_key_hdr     key_hdr;
                            char                    key_data[mget_hdr->key_size];
                        } key;
                    } m_k_pairs[mget_hdr->num_records];
                } *mget_req;

                ptr += sizeof (*mget_hdr);
                mget_req = ptr;
                key_size = sizeof (struct rdb_key);
                records = (char *) mget_req->m_k_pairs;

                out_sglist = vmsg_sglist(&rsp->out);
                out_sglist[0].iov_base = wdata->reg_mem.addr;
                out_sglist[0].mr = wdata->reg_mem.mr;

                if (!null_mode) {
                    status = wdata->reg_mem.addr;
                    value = wdata->reg_mem.addr + sizeof (*status);
                    *status = rocksdb_server_mget(wdata->rdb, records, &key_size,
                                    value, &value_size, &mget_hdr->num_records);
                    if (*status)
                        out_sglist[0].iov_len = value_size + sizeof (*status);
                    else
                        out_sglist[0].iov_len = sizeof (*status);
                } else {
                    status = wdata->reg_mem.addr;
                    *status = 1;
                    out_sglist[0].iov_len = sizeof (*status);
                }
//                len = (int) out_sglist[0].iov_len;

                vmsg_sglist_set_nents(&rsp->out, 1);

                break;
            }
        default:
            break;
    };

    /*printf("thread : portal : %s, command : %d, version : %d, key : %s, value : %s, len : %d\n",
            wdata->portal,
            *payload_cmd,
            *payload_version,
            key,
            value,
            len);*/

    in_sglist[0].iov_base = NULL;
    in_sglist[0].iov_len = 0;
    vmsg_sglist_set_nents(&req->in, 0);

    rsp->request = req;
    if (xio_send_response(rsp) == -1) {
        fprintf(stderr, "failed to send response for thread %s. reason %d - (%s)\n",
                wdata->portal, xio_errno(), xio_strerror(xio_errno()));
    }

    return (0);
}
예제 #22
0
/*---------------------------------------------------------------------------*/
static void *worker_thread(void *data)
{
	struct thread_data		*tdata = (struct thread_data *)data;
	struct xio_connection_params	cparams;
	struct xio_iovec_ex		*sglist;
	cpu_set_t			cpuset;
	struct xio_msg			*msg;
	unsigned int			i;

	/* set affinity to thread */

	CPU_ZERO(&cpuset);
	CPU_SET(tdata->affinity, &cpuset);

	pthread_setaffinity_np(tdata->thread_id, sizeof(cpu_set_t), &cpuset);

	/* prepare data for the cuurent thread */
	tdata->pool = msg_pool_alloc(tdata->user_param->queue_depth);

	/* create thread context for the client */
	tdata->ctx = xio_context_create(NULL, tdata->user_param->poll_timeout,
					tdata->affinity);

	memset(&cparams, 0, sizeof(cparams));
	cparams.session			= tdata->session;
	cparams.ctx			= tdata->ctx;
	cparams.conn_idx		= tdata->cid;
	cparams.conn_user_context	= tdata;

	/* connect the session  */
	tdata->conn = xio_connect(&cparams);

	if (tdata->data_len)
		tdata->xbuf = xio_alloc(tdata->data_len);

	for (i = 0;  i < tdata->user_param->queue_depth; i++) {
		/* create transaction */
		msg = msg_pool_get(tdata->pool);
		if (msg == NULL)
			break;

		/* get pointers to internal buffers */
		msg->in.header.iov_len = 0;

		sglist = vmsg_sglist(&msg->in);
		vmsg_sglist_set_nents(&msg->in, 0);

		msg->out.header.iov_len = 0;
		sglist = vmsg_sglist(&msg->out);
		if (tdata->data_len) {
			vmsg_sglist_set_nents(&msg->out, 1);
			sglist[0].iov_base	= tdata->xbuf->addr;
			sglist[0].iov_len	= tdata->xbuf->length;
			sglist[0].mr		= tdata->xbuf->mr;
		} else {
			vmsg_sglist_set_nents(&msg->out, 0);
		}
		msg->user_context = (void *)get_cycles();
		/* send first message */
		if (xio_send_request(tdata->conn, msg) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_request " \
				       "failed. %s\n",
					tdata->session,
					xio_strerror(xio_errno()));
			msg_pool_put(tdata->pool, msg);
			return 0;
		}
		if (tdata->do_stat)
			tdata->stat.scnt++;
		tdata->tx_nr++;
	}

	/* the default xio supplied main loop */
	xio_context_run_loop(tdata->ctx, XIO_INFINITE);

	/* normal exit phase */

	if (tdata->pool)
		msg_pool_free(tdata->pool);

	if (tdata->xbuf)
		xio_free(&tdata->xbuf);


	/* free the context */
	xio_context_destroy(tdata->ctx);

	return NULL;
}
예제 #23
0
/*---------------------------------------------------------------------------*/
static int on_response(struct xio_session *session,
		       struct xio_msg *msg,
		       int last_in_rxq,
		       void *cb_user_context)
{
	struct test_params *test_params = (struct test_params *)cb_user_context;
	struct xio_iovec_ex	*sglist;
	static int		chain_messages = CHAIN_MESSAGES;
	size_t			j;

	test_params->nrecv++;

	process_response(test_params, msg);

	/* message is no longer needed */
	xio_release_response(msg);

	msg_pool_put(test_params->pool, msg);

	if (test_params->finite_run) {
		if (test_params->nrecv ==  test_params->disconnect_nr) {
			xio_disconnect(test_params->connection);
			return 0;
		}

		if (test_params->nsent == test_params->disconnect_nr)
			return 0;
	}

	/* peek message from the pool */
	msg = msg_pool_get(test_params->pool);
	if (msg == NULL) {
		printf("pool is empty\n");
		return 0;
	}
	msg->in.header.iov_base = NULL;
	msg->in.header.iov_len = 0;

	sglist = vmsg_sglist(&msg->in);
	vmsg_sglist_set_nents(&msg->in, test_config.in_iov_len);

	/* tell accelio to use 1MB buffer from its internal pool */
	for (j = 0; j < test_config.in_iov_len; j++) {
		sglist[j].iov_base = NULL;
		sglist[j].iov_len  = ONE_MB;
		sglist[j].mr = NULL;
	}

	msg->sn = 0;

	/* assign buffers to the message */
	msg_build_out_sgl(&test_params->msg_params, msg,
		  test_config.hdr_len,
		  test_config.out_iov_len, test_config.data_len);



	if (chain_messages) {
		msg->next = NULL;
		if (test_params->chain.head  == NULL) {
			test_params->chain.head = msg;
			test_params->chain.tail = test_params->chain.head;
		} else {
			test_params->chain.tail->next = msg;
			test_params->chain.tail = test_params->chain.tail->next;
		}
		if (++test_params->chain.sz == MAX_OUTSTANDING_REQS) {
			if (xio_send_request(test_params->connection,
					     test_params->chain.head) == -1) {
				if (xio_errno() != EAGAIN)
					printf("**** [%p] Error - xio_send_request " \
							"failed %s\n",
							session,
							xio_strerror(xio_errno()));
				msg_pool_put(test_params->pool, msg);
				xio_assert(xio_errno() == EAGAIN);
			}
			test_params->nsent += test_params->chain.sz;
			test_params->chain.head = NULL;
			test_params->chain.sz = 0;
		}
	} else {
		/* try to send it */
		/*msg->flags = XIO_MSG_FLAG_REQUEST_READ_RECEIPT; */
		/*msg->flags = XIO_MSG_FLAG_PEER_READ_REQ;*/
		if (xio_send_request(test_params->connection, msg) == -1) {
			if (xio_errno() != EAGAIN)
				printf("**** [%p] Error - xio_send_request " \
						"failed %s\n",
						session,
						xio_strerror(xio_errno()));
			msg_pool_put(test_params->pool, msg);
			xio_assert(xio_errno() == EAGAIN);
		}
		test_params->nsent++;
	}

	return 0;
}