/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *rsp, int last_in_rxq, void *cb_user_context) { struct session_data *session_data = (struct session_data *) cb_user_context; int i = rsp->request->sn % QUEUE_DEPTH; session_data->nrecv++; /* process the incoming message */ process_response(session_data, rsp); /* acknowledge xio that response is no longer needed */ xio_release_response(rsp); if (reconnect_flag || reload_flag) return 0; /* resend the message */ xio_send_request(session_data->conn, &session_data->req[i]); session_data->nsent++; return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *rsp, int more_in_batch, void *cb_user_context) { struct session_data *session_data = cb_user_context; int i = rsp->request->sn % QUEUE_DEPTH; session_data->nrecv++; /* process the incoming message */ process_response(session_data, rsp); /* acknowledge xio that response is no longer needed */ xio_release_response(rsp); #if TEST_DISCONNECT if (session_data->nrecv == DISCONNECT_NR) { xio_disconnect(session_data->conn); return 0; } if (session_data->nsent == DISCONNECT_NR) return 0; #endif session_data->req[i].in.header.iov_base = NULL; session_data->req[i].in.header.iov_len = 0; vmsg_sglist_set_nents(&session_data->req[i].in, 0); /* resend the message */ xio_send_request(session_data->conn, &session_data->req[i]); session_data->nsent++; return 0; }
int xio_exec_req(const struct node_id *nid, struct sd_req *hdr, void *data, bool (*need_retry)(uint32_t epoch), uint32_t epoch, uint32_t max_count) { struct xio_context *ctx = xio_context_create(NULL, 0, -1); struct client_data cli = { .ctx = ctx }; struct xio_connection *conn = sd_xio_create_connection(ctx, nid, &cli); struct xio_msg xreq; struct sd_rsp rsp; sd_assert(!is_main_thread()); memset(&rsp, 0, sizeof(rsp)); memset(&xreq, 0, sizeof(xreq)); client_msg_vec_init(&xreq); memset(&rsp, 0, sizeof(rsp)); msg_prep_for_send(hdr, &rsp, data, &xreq); xio_send_request(conn, &xreq); xio_context_run_loop(ctx, XIO_INFINITE); msg_finalize(hdr, data, cli.rsp); xio_connection_destroy(conn); xio_context_destroy(ctx); return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *msg, int last_in_rxq, void *cb_user_context) { /* struct scatterlist *sgl; */ process_response(msg); /* message is no longer needed */ xio_release_response(msg); nrecv++; msg_pool_put(pool, msg); if (test_config.finite_run) { if (nrecv == disconnect_nr) { xio_disconnect(g_connection); return 0; } if (nrecv > disconnect_nr) return 0; } /* reset message */ msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; msg->in.data_tbl.nents = 0; /* sgl = msg->in.data_tbl.sgl; xio_tbl_set_nents(&msg->in.data_tbl, test_config.in_iov_len); sg_set_buf(sgl, NULL, ONE_MB); */ msg->sn = 0; /* recycle the message and fill new request */ msg_build_out_sgl(&msg_params, msg, test_config.hdr_len, 1, test_config.data_len); /* try to send it */ if (xio_send_request(g_connection, msg) == -1) { if (xio_errno() != EAGAIN) pr_err("**** [%p] Error - xio_send_msg " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(pool, msg); /* xio_assert(0); */ } return 0; }
/*---------------------------------------------------------------------------*/ static void on_connection_established(struct xio_connection *connection, struct session_data *session_data) { int i = 0; /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) { xio_send_request(connection, &session_data->req[i]); session_data->nsent++; } }
/*---------------------------------------------------------------------------*/ static int on_new_session(struct xio_session *session, struct xio_new_session_req *session_data, void *cb_prv_data) { struct xio_msg *req; int i = 0; printf("**** [%p] on_new_session :%s:%d\n", session, get_ip((struct sockaddr *)&session_data->src_addr), get_port((struct sockaddr *)&session_data->src_addr)); xio_accept(session, NULL, 0, NULL, 0); msg_pool_reset(pool); conn = xio_get_connection(session, ctx); printf("**** starting ...\n"); while (1) { /* create transaction */ req = msg_pool_get(pool); if (req == NULL) break; /* get pointers to internal buffers */ req->in.header.iov_base = NULL; req->in.header.iov_len = 0; req->in.data_iovlen = 1; req->in.data_iov[0].iov_base = NULL; req->in.data_iov[0].iov_len = ONE_MB; req->in.data_iov[0].mr = NULL; /* recycle the message and fill new request */ msg_set(req, 1, test_config.hdr_len, test_config.data_len); /* try to send it */ if (xio_send_request(conn, req) == -1) { printf("**** sent %d messages\n", i); if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_msg " \ "failed. %s\n", session, xio_strerror(xio_errno())); msg_pool_put(pool, req); return 0; } i++; if (i == 256) break; } 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; }
void xio_gw_send_req(struct xio_connection *conn, struct sd_req *hdr, void *data, bool (*need_retry)(uint32_t epoch), uint32_t epoch, uint32_t max_count) { struct xio_msg *xreq = xzalloc(sizeof(*xreq)); struct sd_rsp *rsp = xzalloc(sizeof(*rsp)); client_msg_vec_init(xreq); msg_prep_for_send(hdr, rsp, data, xreq); xio_send_request(conn, xreq); }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *msg, int last_in_rxq, void *cb_user_context) { struct thread_data *tdata = (struct thread_data *)cb_user_context; cycles_t rtt = (get_cycles()-(cycles_t)msg->user_context); if (tdata->do_stat) { if (rtt > tdata->stat.max_rtt) tdata->stat.max_rtt = rtt; if (rtt < tdata->stat.min_rtt) tdata->stat.min_rtt = rtt; tdata->stat.tot_rtt += rtt; tdata->stat.ccnt++; } tdata->rx_nr++; /* message is no longer needed */ xio_release_response(msg); if (tdata->disconnect) { if (tdata->rx_nr == tdata->tx_nr) xio_disconnect(tdata->conn); else msg_pool_put(tdata->pool, msg); return 0; } /* reset message */ msg->in.header.iov_len = 0; vmsg_sglist_set_nents(&msg->in, 0); msg->user_context = (void *)get_cycles(); if (xio_send_request(tdata->conn, msg) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_request " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(tdata->pool, msg); return 0; } if (tdata->do_stat) tdata->stat.scnt++; tdata->tx_nr++; return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *msg, int more_in_batch, void *cb_user_context) { process_response(msg); if (msg->status) printf("**** message completed with error. [%s]\n", xio_strerror(msg->status)); /* message is no longer needed */ xio_release_response(msg); /* reset message */ msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; msg->in.data_iovlen = 1; msg->in.data_iov[0].iov_base = NULL; msg->in.data_iov[0].iov_len = ONE_MB; msg->in.data_iov[0].mr = NULL; msg->sn = 0; msg->more_in_batch = 0; do { /* recycle the message and fill new request */ msg_write(msg, "hello world request header", test_config.hdr_len, "hello world request data", test_config.data_len); /* try to send it */ if (xio_send_request(conn, msg) == -1) { if (xio_errno() != EAGAIN) printf("**** [%p] Error - xio_send_msg " \ "failed %s\n", session, xio_strerror(xio_errno())); msg_pool_put(pool, msg); return 0; } } while (0); return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *rsp, int last_in_rxq, void *cb_user_context) { struct session_data *session_data = cb_user_context; struct xio_msg *req = rsp; /* process the incoming message */ process_response(rsp); /* acknowledge xio that response is no longer needed */ xio_release_response(rsp); /* resend the message */ xio_send_request(session_data->connection, req); return 0; }
/*---------------------------------------------------------------------------*/ static int on_response(struct xio_session *session, struct xio_msg *rsp, int more_in_batch, void *cb_user_context) { struct hw_session_data *session_data = cb_user_context; int i = rsp->request->sn % QUEUE_DEPTH; /* process the incoming message */ process_response(rsp); /* acknowledge xio that response is no longer needed */ xio_release_response(rsp); /* resend the message */ xio_send_request(session_data->conn, &session_data->req[i]); return 0; }
/*---------------------------------------------------------------------------*/ static int on_connection_established(struct xio_connection *conn) { struct xio_msg *msg; pr_info("**** starting ...\n"); /* create transaction */ msg = msg_pool_get(pool); if (!msg) return 0; /* get pointers to internal buffers */ msg->in.header.iov_base = NULL; msg->in.header.iov_len = 0; msg->in.data_tbl.nents = 0; /* sglist = vmsg_sglist(&msg->in); sglist[0].iov_base = NULL; sglist[0].iov_len = ONE_MB; sglist[0].mr = NULL; vmsg_sglist_set_nents(&msg->in, 1); */ /* recycle the message and fill new request */ msg_build_out_sgl(&msg_params, msg, test_config.hdr_len, 1, test_config.data_len); /* try to send it */ if (xio_send_request(conn, msg) == -1) { pr_info("**** sent %d messages\n", 1); if (xio_errno() != EAGAIN) pr_info("**** [%p] Error - xio_send_msg " \ "failed. %s\n", conn, xio_strerror(xio_errno())); msg_pool_put(pool, msg); xio_assert(0); } return 0; }
/*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { struct xio_session *session; char url[256]; struct session_data session_data; int i = 0; /* client session attributes */ struct xio_session_attr attr = { &ses_ops, /* callbacks structure */ NULL, /* no need to pass the server private data */ 0 }; memset(&session_data, 0, sizeof(session_data)); /* initialize library */ xio_init(); /* create thread context for the client */ session_data.ctx = xio_context_create(NULL, 0); /* create url to connect to */ sprintf(url, "rdma://%s:%s", argv[1], argv[2]); session = xio_session_create(XIO_SESSION_CLIENT, &attr, url, 0, 0, &session_data); /* connect the session */ session_data.conn = xio_connect(session, session_data.ctx, 0, NULL, &session_data); /* create "hello world" message */ for (i = 0; i < QUEUE_DEPTH; i++) { memset(&session_data.req[i], 0, sizeof(session_data.req[i])); session_data.req[i].out.header.iov_base = strdup("hello world header request"); session_data.req[i].out.header.iov_len = strlen(session_data.req[i].out.header.iov_base) + 1; } /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) { xio_send_request(session_data.conn, &session_data.req[i]); session_data.nsent++; } /* event dispatcher is now running */ xio_context_run_loop(session_data.ctx, XIO_INFINITE); /* normal exit phase */ fprintf(stdout, "exit signaled\n"); /* free the message */ for (i = 0; i < QUEUE_DEPTH; i++) free(session_data.req[i].out.header.iov_base); /* free the context */ xio_context_destroy(session_data.ctx); xio_shutdown(); printf("good bye\n"); return 0; }
/*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { struct xio_session *session; char url[256]; struct session_data session_data; int i = 0; struct xio_session_params params; if (argc < 3) { printf("Usage: %s <host> <port> <transport:optional>\n", argv[0]); exit(1); } memset(&session_data, 0, sizeof(session_data)); memset(¶ms, 0, sizeof(params)); /* initialize library */ xio_init(); /* create thread context for the client */ session_data.ctx = xio_context_create(NULL, 0, -1); /* create url to connect to */ if (argc > 3) sprintf(url, "%s://%s:%s", argv[3], argv[1], argv[2]); else sprintf(url, "rdma://%s:%s", argv[1], argv[2]); params.type = XIO_SESSION_CLIENT; params.ses_ops = &ses_ops; params.user_context = &session_data; params.uri = url; session = xio_session_create(¶ms); /* connect the session */ session_data.conn = xio_connect(session, session_data.ctx, 0, NULL, &session_data); /* create "hello world" message */ for (i = 0; i < QUEUE_DEPTH; i++) { memset(&session_data.req[i], 0, sizeof(session_data.req[i])); /* header */ session_data.req[i].out.header.iov_base = strdup("hello world header request"); session_data.req[i].out.header.iov_len = strlen(session_data.req[i].out.header.iov_base) + 1; /* iovec[0]*/ session_data.req[i].in.sgl_type = XIO_SGL_TYPE_IOV; session_data.req[i].in.data_iov.max_nents = XIO_IOVLEN; session_data.req[i].out.sgl_type = XIO_SGL_TYPE_IOV; session_data.req[i].out.data_iov.max_nents = XIO_IOVLEN; session_data.req[i].out.data_iov.sglist[0].iov_base = strdup("hello world data request"); session_data.req[i].out.data_iov.sglist[0].iov_len = strlen(session_data.req[i].out.data_iov.sglist[0].iov_base) + 1; session_data.req[i].out.data_iov.nents = 1; } /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) { xio_send_request(session_data.conn, &session_data.req[i]); session_data.nsent++; } /* event dispatcher is now running */ xio_context_run_loop(session_data.ctx, XIO_INFINITE); /* normal exit phase */ fprintf(stdout, "exit signaled\n"); /* free the message */ for (i = 0; i < QUEUE_DEPTH; i++) { free(session_data.req[i].out.header.iov_base); free(session_data.req[i].out.data_iov.sglist[0].iov_base); } /* free the context */ xio_context_destroy(session_data.ctx); xio_shutdown(); printf("good bye\n"); return 0; }
/*---------------------------------------------------------------------------*/ static int xio_client_main(void *data) { char **argv = (char **) data; struct xio_session *session; char url[256]; struct xio_context *ctx; struct hw_session_data *session_data; int i = 0; /* client session attributes */ struct xio_session_attr attr = { &ses_ops, /* callbacks structure */ NULL, /* no need to pass the server private data */ 0 }; session_data = kzalloc(sizeof(*session_data), GFP_KERNEL); if (!session_data) { printk("session_data alloc failed\n"); return 0; } /* create thread context for the client */ ctx = xio_ctx_open(XIO_LOOP_GIVEN_THREAD, NULL, current, 0, -1); if (!ctx) { kfree(session_data); printk("context open filed\n"); return 0; } session_data->ctx = ctx; /* create url to connect to */ sprintf(url, "rdma://%s:%s", argv[1], argv[2]); session = xio_session_open(XIO_SESSION_REQ, &attr, url, 0, 0, session_data); /* connect the session */ session_data->conn = xio_connect(session, ctx, 0, NULL, session_data); /* create "hello world" message */ for (i = 0; i < QUEUE_DEPTH; i++) { memset(&session_data->req[i], 0, sizeof(session_data->req[i])); session_data->req[i].out.header.iov_base = kstrdup("hello world header request", GFP_KERNEL); session_data->req[i].out.header.iov_len = strlen(session_data->req[i].out.header.iov_base); } /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) xio_send_request(session_data->conn, &session_data->req[i]); /* the default xio supplied main loop */ xio_ev_loop_run(ctx); /* normal exit phase */ printk("exit signaled\n"); /* free the message */ for (i = 0; i < QUEUE_DEPTH; i++) kfree(session_data->req[i].out.header.iov_base); /* free the context */ xio_ctx_close(ctx); kfree(session_data); printk("good bye\n"); return 0; }
/*---------------------------------------------------------------------------*/ static int xio_client_main(void *data) { char **argv = (char **)data; struct xio_session *session; struct xio_session_params params; struct xio_context_params ctx_params; struct xio_connection_params cparams; char url[256]; struct xio_context *ctx; struct session_data *session_data; int i = 0; atomic_add(2, &module_state); session_data = vzalloc(sizeof(*session_data)); if (!session_data) { /*pr_err("session_data alloc failed\n");*/ return 0; } /* create thread context for the client */ memset(&ctx_params, 0, sizeof(ctx_params)); ctx_params.flags = XIO_LOOP_GIVEN_THREAD; ctx_params.worker = current; ctx = xio_context_create(&ctx_params, 0, -1); if (!ctx) { vfree(session_data); pr_err("context open filed\n"); return 0; } session_data->ctx = ctx; /* create url to connect to */ sprintf(url, "rdma://%s:%s", argv[1], argv[2]); memset(¶ms, 0, sizeof(params)); params.type = XIO_SESSION_CLIENT; params.ses_ops = &ses_ops; params.user_context = session_data; params.uri = url; session = xio_session_create(¶ms); memset(&cparams, 0, sizeof(cparams)); cparams.session = session; cparams.ctx = ctx; cparams.conn_user_context = session_data; /* connect the session */ session_data->session = session; session_data->connection = xio_connect(&cparams); /* create "hello world" message */ for (i = 0; i < QUEUE_DEPTH; i++) { struct xio_vmsg *omsg; void *buf; omsg = &session_data->req[i].out; memset(&session_data->req[i], 0, sizeof(session_data->req[i])); /* header */ buf = kstrdup("hello world header request", GFP_KERNEL); session_data->req[i].out.header.iov_base = buf; session_data->req[i].out.header.iov_len = strlen(buf) + 1; /* iovec[0]*/ omsg->sgl_type = XIO_SGL_TYPE_SCATTERLIST; sg_alloc_table(&omsg->data_tbl, SG_TBL_LEN, GFP_KERNEL); /* currently only one entry */ buf = kstrdup("hello world iovec request", GFP_KERNEL); sg_init_one(omsg->data_tbl.sgl, buf, strlen(buf) + 1); /* orig_nents is XIO_IOVLEN */ omsg->data_tbl.nents = 1; } /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) xio_send_request(session_data->connection, &session_data->req[i]); g_session_data = session_data; /* the default xio supplied main loop */ if (atomic_add_unless(&module_state, 4, 0x83)) xio_context_run_loop(ctx); atomic_sub(4, &module_state); /* normal exit phase */ pr_info("exit signaled\n"); /* free the message */ for (i = 0; i < QUEUE_DEPTH; i++) { kfree(session_data->req[i].out.header.iov_base); /* Currently need to release only one entry */ kfree(sg_virt(session_data->req[i].out.data_tbl.sgl)); sg_free_table(&session_data->req[i].out.data_tbl); } /* free the context */ xio_context_destroy(ctx); vfree(session_data); pr_info("good bye\n"); complete_and_exit(&cleanup_complete, 0); return 0; }
/*---------------------------------------------------------------------------*/ static void *worker_thread(void *data) { struct thread_data *tdata = data; cpu_set_t cpuset; struct xio_msg *msg; 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); /* connect the session */ tdata->conn = xio_connect(tdata->session, tdata->ctx, tdata->cid, NULL, tdata); 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; msg->in.data_iovlen = 0; msg->out.header.iov_len = 0; if (tdata->data_len) { msg->out.data_iovlen = 1; msg->out.data_iov[0].iov_base = tdata->xbuf->addr; msg->out.data_iov[0].iov_len = tdata->xbuf->length; msg->out.data_iov[0].mr = tdata->xbuf->mr; } else { msg->out.data_iovlen = 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; }
/*---------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { struct xio_session *session; char url[256]; struct session_data session_data; int i = 0; struct event timeout; struct event xio_event; struct timeval tv; struct xio_poll_params poll_params; struct xio_session_params params; if (argc < 3) { printf("Usage: %s <host> <port> <transport:optional>\n", argv[0]); exit(1); } memset(&session_data, 0, sizeof(session_data)); memset(¶ms, 0, sizeof(params)); /* initialize library */ xio_init(); /* create thread context for the client */ session_data.ctx = xio_context_create(NULL, 0, -1); /* get poll parameters for libevent */ xio_context_get_poll_params(session_data.ctx, &poll_params); /* create url to connect to */ if (argc > 3) sprintf(url, "%s://%s:%s", argv[3], argv[1], argv[2]); else sprintf(url, "rdma://%s:%s", argv[1], argv[2]); params.type = XIO_SESSION_CLIENT; params.ses_ops = &ses_ops; params.user_context = &session_data; params.uri = url; session = xio_session_create(¶ms); /* connect the session */ session_data.conn = xio_connect(session, session_data.ctx, 0, NULL, &session_data); /* create "hello world" message */ for (i = 0; i < QUEUE_DEPTH; i++) { memset(&session_data.req[i], 0, sizeof(session_data.req[i])); /* header */ session_data.req[i].out.header.iov_base = strdup("hello world header request"); session_data.req[i].out.header.iov_len = strlen(session_data.req[i].out.header.iov_base) + 1; /* iovec[0]*/ session_data.req[i].out.sgl_type = XIO_SGL_TYPE_IOV; session_data.req[i].out.data_iov.max_nents = XIO_IOVLEN; session_data.req[i].out.data_iov.sglist[0].iov_base = strdup("hello world iovec request"); session_data.req[i].out.data_iov.sglist[0].iov_len = strlen(session_data.req[i].out.data_iov.sglist[0].iov_base) + 1; session_data.req[i].out.data_iov.nents = 1; } /* send first message */ for (i = 0; i < QUEUE_DEPTH; i++) { xio_send_request(session_data.conn, &session_data.req[i]); session_data.nsent++; } /* Initialize the event library */ session_data.evbase = event_base_new(); /* Initialize one timer event */ event_assign(&timeout, session_data.evbase, -1, EV_PERSIST, timeout_cb, (void *)&timeout); evutil_timerclear(&tv); tv.tv_sec = 2; event_add(&timeout, &tv); event_assign(&xio_event, session_data.evbase, poll_params.fd, EV_READ|EV_PERSIST, xio_event_handler, (void *)&poll_params); /* Add it to the active events, without a timeout */ event_add(&xio_event, NULL); event_base_dispatch(session_data.evbase); fprintf(stdout, "exit signaled\n"); event_base_free(session_data.evbase); /* free the message */ for (i = 0; i < QUEUE_DEPTH; i++) { free(session_data.req[i].out.header.iov_base); free(session_data.req[i].out.data_iov.sglist[0].iov_base); } /* free the context */ xio_context_destroy(session_data.ctx); xio_shutdown(); printf("good bye\n"); return 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; }