Get correct iodepth
[archipelago] / xseg / peers / user / bench-xseg.c
index f81f22a..b7c8e9b 100644 (file)
@@ -64,7 +64,7 @@ void custom_peer_usage()
        fprintf(stderr, "Custom peer options: \n"
                        "  --------------------------------------------\n"
                        "    -op       | None    | XSEG operation [read|write|info|delete]\n"
-                       "    --pattern | None    | I/O pattern [sync|rand]\n"
+                       "    --pattern | None    | I/O pattern [seq|rand]\n"
                        "    -to       | None    | Total objects (not for read/write)\n"
                        "    -ts       | None    | Total I/O size\n"
                        "    -os       | 4M      | Object size\n"
@@ -90,6 +90,7 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
        char insanity[MAX_ARG_LEN + 1];
        struct xseg *xseg = peer->xseg;
        unsigned int xseg_page_size = 1 << xseg->config.page_shift;
+       long iodepth = -1;
        long dst_port = -1;
        int r;
 
@@ -126,9 +127,9 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
        READ_ARG_STRING("-ts", total_size, MAX_ARG_LEN);
        READ_ARG_STRING("-os", object_size, MAX_ARG_LEN);
        READ_ARG_STRING("-bs", block_size, MAX_ARG_LEN);
-       READ_ARG_ULONG("--iodepth", prefs->iodepth);
+       READ_ARG_ULONG("--iodepth", iodepth);
        READ_ARG_ULONG("-dp", dst_port);
-       READ_ARG_STRING("--insanity", block_size, MAX_ARG_LEN);
+       READ_ARG_STRING("--insanity", insanity, MAX_ARG_LEN);
        END_READ_ARGS();
 
        /*****************************\
@@ -158,7 +159,13 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
                XSEGLOG2(&lc, E, "Invalid syntax: --pattern %s\n", pattern);
                goto arg_fail;
        }
-       prefs->flags |= (uint8_t)r << PATTERN_FLAG;
+       prefs->flags |= (uint8_t)r;
+
+       //Defailt iodepth value is 1
+       if (iodepth < -1)
+               prefs->iodepth = 1;
+       else
+               prefs->iodepth = iodepth;
 
        /**************************\
         * Check timer parameters *
@@ -215,9 +222,6 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
                if (!block_size[0])
                        strcpy(block_size,"4k");
 
-               if (!prefs->iodepth)
-                       prefs->iodepth = 1;
-
                prefs->bs = str2num(block_size);
                if (!prefs->bs) {
                        XSEGLOG2(&lc, E, "Invalid syntax: -bs %s\n", block_size);
@@ -268,9 +272,9 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
                prefs->max_requests = prefs->ts / prefs->bs;
        }
 
-       /*************************
+       /*************************\
         * Check port parameters *
-        *************************/
+       \*************************/
 
        if (dst_port < 0){
                XSEGLOG2(&lc, E, "Destination port needs to be supplied\n");
@@ -280,9 +284,9 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
        prefs->src_port = peer->portno_start; //TODO: allow user to change this
        prefs->dst_port = (xport) dst_port;
 
-       /*********************************
+       /*********************************\
         * Create timers for all metrics *
-        *********************************/
+       \*********************************/
 
        if (init_timer(&prefs->total_tm, TM_SANE))
                goto tm_fail;
@@ -295,7 +299,7 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
 
        /********************************\
         * Customize struct peerd/prefs *
-        \********************************/
+       \********************************/
 
        prefs->peer = peer;
 
@@ -303,7 +307,7 @@ int custom_peer_init(struct peerd *peer, int argc, char *argv[])
        //variables.
        create_id();
 
-       if ((prefs->flags & PATTERN_FLAG) == IO_RAND) {
+       if ((prefs->flags & (1 <<PATTERN_FLAG)) == IO_RAND) {
                prefs->lfsr = malloc(sizeof(struct lfsr));
                if (!prefs->lfsr) {
                        perror("malloc");
@@ -350,7 +354,7 @@ static int send_request(struct peerd *peer, struct bench *prefs)
 
        //srcport and dstport must already be provided by the user.
        //returns struct xseg_request with basic initializations
-       XSEGLOG2(&lc, D, "Get new request\n");
+       //XSEGLOG2(&lc, D, "Get new request\n");
        timer_start(prefs, prefs->get_tm);
        req = xseg_get_request(xseg, srcport, dstport, X_ALLOC);
        if (!req) {
@@ -360,7 +364,7 @@ static int send_request(struct peerd *peer, struct bench *prefs)
        timer_stop(prefs, prefs->get_tm, NULL);
 
        //Allocate enough space for the data and the target's name
-       XSEGLOG2(&lc, D, "Prepare new request\n");
+       //XSEGLOG2(&lc, D, "Prepare new request\n");
        r = xseg_prep_request(xseg, req, TARGETLEN, size);
        if (r < 0) {
                XSEGLOG2(&lc, W, "Cannot prepare request! (%lu, %llu)\n",
@@ -370,22 +374,24 @@ static int send_request(struct peerd *peer, struct bench *prefs)
 
        //Determine what the next target/chunk will be, based on I/O pattern
        new = determine_next(prefs);
+       XSEGLOG2(&lc, I, "Our new request is %lu\n", new);
        //Create a target of this format: "bench-<obj_no>"
        create_target(prefs, req, new);
 
-       if(prefs->op == X_WRITE || prefs->op == X_READ) {
+       if (prefs->op == X_WRITE || prefs->op == X_READ) {
                req->size = size;
                //Calculate the chunk offset inside the object
                req->offset = (new * prefs->bs) % prefs->os;
+               XSEGLOG2(&lc, D, "Offset of request %lu is %lu\n", new, req->offset);
 
-               if(prefs->op == X_WRITE)
+               if (prefs->op == X_WRITE)
                        create_chunk(prefs, req, new);
        }
 
        req->op = prefs->op;
 
        //Measure this?
-       XSEGLOG2(&lc, D, "Allocate peer request\n");
+       //XSEGLOG2(&lc, D, "Allocate peer request\n");
        pr = alloc_peer_req(peer);
        if (!pr) {
                XSEGLOG2(&lc, W, "Cannot allocate peer request (%ld remaining)\n",
@@ -396,12 +402,12 @@ static int send_request(struct peerd *peer, struct bench *prefs)
        pr->portno = srcport;
        pr->req = req;
        pr->priv = malloc(sizeof(struct timespec));
-       if(!pr->priv) {
+       if (!pr->priv) {
                perror("malloc");
                goto put_peer_request;
        }
 
-       XSEGLOG2(&lc, D, "Set request data\n");
+       //XSEGLOG2(&lc, D, "Set request data\n");
        r = xseg_set_req_data(xseg, req, pr);
        if (r < 0) {
                XSEGLOG2(&lc, W, "Cannot set request data\n");
@@ -415,11 +421,11 @@ static int send_request(struct peerd *peer, struct bench *prefs)
         * QUESTION: Is this the fastest way?
         */
        timer_start(prefs, prefs->rec_tm);
-       memcpy(pr->priv, &prefs->rec_tm->start_time, sizeof(struct timespec));
+       if (prefs->rec_tm->insanity <= prefs->insanity)
+               memcpy(pr->priv, &prefs->rec_tm->start_time, sizeof(struct timespec));
 
        //Submit the request from the source port to the target port
-       XSEGLOG2(&lc, D, "Submit request %lu\n", new);
-       //QUESTION: Can't we just use the submision time calculated previously?
+       //XSEGLOG2(&lc, D, "Submit request %lu\n", new);
        timer_start(prefs, prefs->sub_tm);
        p = xseg_submit(xseg, req, srcport, X_ALLOC);
        if (p == NoPort) {
@@ -428,9 +434,11 @@ static int send_request(struct peerd *peer, struct bench *prefs)
        }
        timer_stop(prefs, prefs->sub_tm, NULL);
 
-       //Send SIGIO to the process that has binded this port to inform that
+       //Send SIGIO to the process that has bound this port to inform that
        //IO is possible
-       xseg_signal(xseg, p);
+       r = xseg_signal(xseg, p);
+       if (r < 0)
+               XSEGLOG2(&lc, W, "Cannot signal destination peer (reason %d)\n", r);
 
        return 0;
 
@@ -462,15 +470,15 @@ int custom_peerd_loop(void *arg)
        xport portno_start = peer->portno_start;
        xport portno_end = peer->portno_end;
        uint64_t threshold=1000/(1 + portno_end - portno_start);
-       pid_t pid =syscall(SYS_gettid);
+       pid_t pid = syscall(SYS_gettid);
        int r;
-
+       uint64_t loops;
 
        XSEGLOG2(&lc, I, "%s has tid %u.\n",id, pid);
        xseg_init_local_signal(xseg, peer->portno_start);
-       uint64_t loops;
 
        timer_start(prefs, prefs->total_tm);
+send_request:
        while (!isTerminate()) {
 #ifdef MT
                if (t->func) {
@@ -482,13 +490,12 @@ int custom_peerd_loop(void *arg)
                        continue;
                }
 #endif
-send_request:
                while (CAN_SEND_REQUEST(prefs)) {
-                       XSEGLOG2(&lc, D, "Because %lu < %lu && %lu < %lu\n",
+                       xseg_cancel_wait(xseg, peer->portno_start);
+                       XSEGLOG2(&lc, D, "...because %lu < %lu && %lu < %lu\n",
                                        prefs->sub_tm->completed - prefs->rec_tm->completed,
                                        prefs->iodepth, prefs->sub_tm->completed,
                                        prefs->max_requests);
-                       xseg_cancel_wait(xseg, peer->portno_start);
                        XSEGLOG2(&lc, D, "Start sending new request\n");
                        r = send_request(peer, prefs);
                        if (r < 0)
@@ -496,17 +503,24 @@ send_request:
                }
                //Heart of peerd_loop. This loop is common for everyone.
                for (loops = threshold; loops > 0; loops--) {
+                       if (loops == 1)
+                               xseg_prepare_wait(xseg, peer->portno_start);
+
                        if (check_ports(peer)) {
-                               if (prefs->max_requests == prefs->rec_tm->completed)
-                                       return 0;
-                               else
-                                       //If an old request has just been acked, the most sensible
-                                       //thing to do is to immediately send a new one
+                               //If an old request has just been acked, the most sensible
+                               //thing to do is to immediately send a new one
+                               if (prefs->rec_tm->completed < prefs->max_requests)
                                        goto send_request;
+                               else
+                                       return 0;
                        }
                }
-               XSEGLOG2(&lc, I, "%s goes to sleep\n",id);
-               xseg_prepare_wait(xseg, peer->portno_start);
+               //struct xseg_port *port = xseg_get_port(xseg, portno_start);
+               //struct xq *q;
+               //q = XPTR_TAKE(port->request_queue, xseg->segment);
+               //XSEGLOG2(&lc, I, "%s goes to sleep with %u requests pending\n",
+               //              id, xq_count(q));
+               XSEGLOG2(&lc, I, "%s goes to sleep\n", id);
 #ifdef ST_THREADS
                if (ta){
                        st_sleep(0);
@@ -527,13 +541,12 @@ void custom_peer_finalize(struct peerd *peer)
 {
        struct bench *prefs = peer->priv;
        //TODO: Measure mean time, standard variation
-       struct tm_result total; //mean, std;
 
        if (!prefs->total_tm->completed)
                timer_stop(prefs, prefs->total_tm, NULL);
 
-       separate_by_order(prefs->total_tm->sum, &total);
-       print_res(total, "Total Time");
+       print_stats(prefs);
+       print_res(prefs, prefs->total_tm, "Total Requests");
        return;
 }