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; } }
/*---------------------------------------------------------------------------*/ 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(); } }
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; }
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; }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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, ®_mem); sglist[0].iov_base = reg_mem.addr; sglist[0].mr = reg_mem.mr; sglist[0].iov_len = XIO_READ_BUF_LEN; return 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; }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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; } }
/*---------------------------------------------------------------------------*/ 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(); } }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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); }
/*---------------------------------------------------------------------------*/ 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; } }
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; } }
/*---------------------------------------------------------------------------*/ 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; } }
/*---------------------------------------------------------------------------*/ 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; } }
/*---------------------------------------------------------------------------*/ 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; }
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); }
/*---------------------------------------------------------------------------*/ 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(); } }
/*---------------------------------------------------------------------------*/ 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; } }
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); }
/*---------------------------------------------------------------------------*/ 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; }
/*---------------------------------------------------------------------------*/ 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; }