Пример #1
0
/* See POSIX 2008 Volume 3 Shell and Utilities, Issue 7
 * Section 2.8.2 Exit status for shell commands (page 2315)
 */
static void completion_cb (flux_subprocess_t *p)
{
    runlevel_t *r = flux_subprocess_aux_get (p, "runlevel");
    const char *exit_string = NULL;
    int rc;

    if ((rc = flux_subprocess_exit_code (p)) < 0) {
        /* bash standard, signals + 128 */
        if ((rc = flux_subprocess_signaled (p)) >= 0) {
            rc += 128;
            exit_string = strsignal (rc);
        }
    }
    else {
        if (rc)
            exit_string = "Exited with non-zero status";
        else
            exit_string = "Exited";
    }

    assert (r->rc[r->level].p == p);
    r->rc[r->level].p = NULL;

    flux_watcher_stop (r->rc[r->level].timer);

    if (r->cb) {
        double elapsed = monotime_since (r->rc[r->level].start) / 1000;
        r->cb (r, r->level, rc, elapsed, exit_string, r->cb_arg);
    }
    flux_subprocess_destroy (p);
}
Пример #2
0
/* Handle responses
 */
void ping_continuation (flux_rpc_t *rpc, void *arg)
{
    struct ping_ctx *ctx = arg;
    const char *json_str, *route, *pad;
    int64_t sec, nsec;
    struct timespec t0;
    int seq;
    json_object *out = NULL;
    struct ping_data *pdata = flux_rpc_aux_get (rpc);
    tstat_t *tstat = pdata->tstat;

    if (flux_rpc_get (rpc, &json_str) < 0) {
        log_err ("flux_rpc_get");
        goto done;
    }
    if (!(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq)
            || !Jget_int64 (out, "time.tv_sec", &sec)
            || !Jget_int64 (out, "time.tv_nsec", &nsec)
            || !Jget_str (out, "pad", &pad)
            || !Jget_str (out, "route", &route)
            || strcmp (ctx->pad, pad) != 0) {
        log_err ("error decoding ping response");
        goto done;
    }
    t0.tv_sec = sec;
    t0.tv_nsec = nsec;
    tstat_push (tstat, monotime_since (t0));

    pdata->seq = seq;
    if (pdata->route)
        free (pdata->route);
    pdata->route = xstrdup (route);
    pdata->rpc_count++;

done:
    if (flux_rpc_next (rpc) < 0 && pdata->rpc_count) {
        if (ctx->rank != NULL) {
            printf ("%s!%s pad=%lu seq=%d time=(%0.3f:%0.3f:%0.3f) ms stddev %0.3f\n",
                    ctx->rank,
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_min (tstat), tstat_mean (tstat), tstat_max (tstat),
                    tstat_stddev (tstat));
        } else {
            char s[16];
            snprintf (s, sizeof (s), "%u", ctx->nodeid);
            printf ("%s%s%s pad=%lu seq=%d time=%0.3f ms (%s)\n",
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : s,
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : "!",
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_mean (tstat),
                    pdata->route);
        }
        flux_rpc_destroy (rpc);
    }
    Jput (out);
}
Пример #3
0
void *thread (void *arg)
{
    thd_t *t = arg;
    char *key, *fence_name = NULL;
    int i, flags = 0;
    struct timespec t0;
    uint32_t rank;
    flux_future_t *f;
    flux_kvs_txn_t *txn;

    if (!(t->h = flux_open (NULL, 0))) {
        log_err ("%d: flux_open", t->n);
        goto done;
    }
    if (flux_get_rank (t->h, &rank) < 0) {
        log_err ("%d: flux_get_rank", t->n);
        goto done;
    }
    for (i = 0; i < count; i++) {
        if (!(txn = flux_kvs_txn_create ()))
            log_err_exit ("flux_kvs_txn_create");
        key = xasprintf ("%s.%"PRIu32".%d.%d", prefix, rank, t->n, i);
        if (fopt)
            fence_name = xasprintf ("%s-%d", prefix, i);
        if (sopt)
            monotime (&t0);
        if (flux_kvs_txn_pack (txn, 0, key, "i", 42) < 0)
            log_err_exit ("%s", key);
        if (nopt && (i % nopt_divisor) == 0)
            flags |= FLUX_KVS_NO_MERGE;
        else
            flags = 0;
        if (fopt) {
            if (!(f = flux_kvs_fence (t->h, flags, fence_name,
                                                   fence_nprocs, txn))
                    || flux_future_get (f, NULL) < 0)
                log_err_exit ("flux_kvs_fence");
            flux_future_destroy (f);
        } else {
            if (!(f = flux_kvs_commit (t->h, flags, txn))
                    || flux_future_get (f, NULL) < 0)
                log_err_exit ("flux_kvs_commit");
            flux_future_destroy (f);
        }
        if (sopt && zlist_append (t->perf, ddup (monotime_since (t0))) < 0)
            oom ();
        free (key);
        free (fence_name);
        flux_kvs_txn_destroy (txn);
    }
done:
    if (t->h)
        flux_close (t->h);
    return NULL;
}
Пример #4
0
void wait_destroy (wait_t *w, double *msec)
{
    assert (w->magic == WAIT_MAGIC);
    assert (w->usecount == 0);
    if (msec)
        *msec = monotime_since (w->t0);
    flux_msg_destroy (w->hand.msg);
    if (w->id)
        free (w->id);
    w->magic = ~WAIT_MAGIC;
    free (w);
}
Пример #5
0
int main (int argc, char *argv[])
{
    nodeset_t *n, *n2;
    nodeset_iterator_t *itr;
    int i;
    struct timespec ts;
    uint32_t bigset = 1E6;
    char *tmp;

    plan (NO_PLAN);

    n = nodeset_create ();
    ok (n != NULL);
    nodeset_config_brackets (n, false);

    /* obtain constants used in other tests */
    uint32_t maxrank = nodeset_getattr (n, NODESET_ATTR_MAXRANK);
    uint32_t minsize = nodeset_getattr (n, NODESET_ATTR_MINSIZE);
    uint32_t maxsize = nodeset_getattr (n, NODESET_ATTR_MAXSIZE);

    nodeset_add_rank (n, 8);
    nodeset_add_rank (n, 7);
    nodeset_add_rank (n, 9);
    like (nodeset_string (n), "7-9", "consecutive adds become range");
    ok (nodeset_count (n) == 3);

    nodeset_add_rank (n, 1);
    like (nodeset_string (n), "1,7-9", "singleton prepended to range");
    ok (nodeset_count (n) == 4);

    nodeset_add_rank (n, 16);
    like (nodeset_string (n), "1,7-9,16", "singleton appended to range");
    ok (nodeset_count (n) == 5);

    nodeset_add_rank (n, 14);
    like (nodeset_string (n), "1,7-9,14,16", "singleton embedded in range");
    ok (nodeset_count (n) == 6);

    nodeset_add_rank (n, 3);
    like (nodeset_string (n), "1,3,7-9,14,16", "singleton embedded in range 2");
    ok (nodeset_count (n) == 7);

    nodeset_add_range (n, 1, 3);
    like (nodeset_string (n), "1-3,7-9,14,16", "overlapping range");
    ok (nodeset_count (n) == 8);

    nodeset_add_range (n, 5, 8);
    like (nodeset_string (n), "1-3,5-9,14,16", "overlapping range 2");
    ok (nodeset_count (n) == 10);

    nodeset_add_range (n, 8, 11);
    like (nodeset_string (n), "1-3,5-11,14,16", "overlapping range 3");
    ok (nodeset_count (n) == 12);

    nodeset_add_range (n, 1, 16);
    like (nodeset_string (n), "1-16", "add range that contains existing");
    ok (nodeset_count (n) == 16);

    nodeset_add_range (n, 4, 8);
    like (nodeset_string (n), "1-16", "add range contained by existing");
    ok (nodeset_count (n) == 16);

    nodeset_destroy (n);

/********************************************/

    n = nodeset_create ();
    ok (n != NULL);
    nodeset_add_rank (n, 0);
    nodeset_add_rank (n, 1);
    nodeset_add_rank (n, 2);
    like (nodeset_string (n), "\\[0-2\\]", "edge case 1 merges with 0");
    ok (nodeset_count (n) == 3);
    nodeset_config_ranges (n, false);
    like (nodeset_string (n), "\\[0,1,2\\]");
    nodeset_destroy (n);

/********************************************/

    n = nodeset_create ();
    ok (n != NULL);
    nodeset_add_rank (n, 2);
    nodeset_add_rank (n, 1);
    nodeset_add_rank (n, 0);
    like (nodeset_string (n), "\\[0-2\\]", "reverse merge works");
    ok (nodeset_count (n) == 3);
    nodeset_destroy (n);

/********************************************/

    n = nodeset_create_string ("[1,3,5,6-100]");
    ok (n != NULL);
    like (nodeset_string (n), "\\[1,3,5-100\\]", "mundane range string works");
    ok (nodeset_count (n) == 98);
    nodeset_destroy (n);

    n = nodeset_create_string ("2-1");
    ok (n != NULL);
    like (nodeset_string (n), "\\[1-2\\]", "numerically reversed range handled");
    ok (nodeset_count (n) == 2);
    nodeset_destroy (n);

    n = nodeset_create_string ("");
    ok (n != NULL);
    ok (nodeset_count (n) == 0);
    like (nodeset_string (n), "", "empty string produces empty range");
    nodeset_destroy (n);

    n = nodeset_create_string (",");
    ok (n == NULL, "comma by itself produces error");

    n = nodeset_create_string ("-1");
    ok (n == NULL, "range missing start produces error");

    n = nodeset_create_string ("1-");
    ok (n == NULL, "range missing end produces error");

    n = nodeset_create_string ("foo1");
    ok (n == NULL, "alpha with numerical suffix produces error");

    n = nodeset_create_string ("[1-2]");
    ok (n != NULL);
    like (nodeset_string (n), "\\[1-2\\]", "bracketed range works");
    ok (nodeset_count (n) == 2);
    nodeset_destroy (n);

    n = nodeset_create_string ("xyz");
    ok (n == NULL, "alpha by itself produces error");

/********************************************/

    n = nodeset_create_string ("0-2");
    ok (n != NULL);
    ok (nodeset_test_rank (n, 0));
    ok (nodeset_test_rank (n, 1));
    ok (nodeset_test_rank (n, 2));
    ok (!nodeset_test_rank (n, 3));

    ok (!nodeset_test_rank (n, nodeset_getattr (n, NODESET_ATTR_SIZE) - 1),
        "nodeset_test_rank (internal size - 1) fails");
    ok (!nodeset_test_rank (n, nodeset_getattr (n, NODESET_ATTR_SIZE)),
        "nodeset_test_rank (internal size) fails");
    ok (!nodeset_test_rank (n, nodeset_getattr (n, NODESET_ATTR_SIZE) + 1),
        "nodeset_test_rank (internal size + 1) fails");

    ok (!nodeset_test_range (n, 2, nodeset_getattr (n, NODESET_ATTR_SIZE) - 1),
        "nodeset_test_range (2, internal size - 1) fails");
    ok (!nodeset_test_range (n, 2, nodeset_getattr (n, NODESET_ATTR_SIZE)),
        "nodeset_test_range (2, internal size) fails");
    ok (!nodeset_test_range (n, 2, nodeset_getattr (n, NODESET_ATTR_SIZE) + 1),
        "nodeset_test_range (2, internal size + 1) fails");

    ok (!nodeset_test_range (n, nodeset_getattr (n, NODESET_ATTR_SIZE) - 1, 2),
        "nodeset_test_range (internal size - 1, 2) fails");
    ok (!nodeset_test_range (n, nodeset_getattr (n, NODESET_ATTR_SIZE), 2),
        "nodeset_test_range (internal size, 2) fails");
    ok (!nodeset_test_range (n, nodeset_getattr (n, NODESET_ATTR_SIZE) + 1, 2),
        "nodeset_test_range (internal size + 1, 2) fails");

    nodeset_config_brackets (n, false);
    like (nodeset_string (n), "0-2");
    ok (nodeset_test_range (n, 0, 2), "nodeset_test_range works");
    nodeset_delete_rank (n, 0);
    like (nodeset_string (n), "1-2", "nodeset_delete_rank works");
    ok (!nodeset_test_rank (n, 0), "nodeset_test_rank works");
    ok (nodeset_test_range (n, 1, 2));
    nodeset_delete_rank (n, 1);
    ok (!nodeset_test_rank (n, 0));
    ok (!nodeset_test_rank (n, 1));
    ok (nodeset_test_rank (n, 2));
    ok (!strcmp (nodeset_string (n), "2"));
    nodeset_delete_rank (n, 2);
    ok (!nodeset_test_rank (n, 0));
    ok (!nodeset_test_rank (n, 1));
    ok (!nodeset_test_rank (n, 2));
    like (nodeset_string (n), "");
    nodeset_destroy (n);

/********************************************/

    /* Exercise iteration
     */
    n = nodeset_create_string ("0-2");
    ok (n != NULL);
    itr = nodeset_iterator_create (n);
    ok (nodeset_next (itr) == 0, "iterator_next works on first element");
    ok (nodeset_next (itr) == 1, "iterator_next works on next element");
    ok (nodeset_next (itr) == 2, "iterator_next works on last element");
    ok (nodeset_next (itr) == NODESET_EOF, "iterator_next returns EOF");
    nodeset_iterator_rewind (itr);
    ok (nodeset_next (itr) == 0, "iterator rewind works");
    nodeset_iterator_destroy (itr);
    nodeset_destroy (n);

/********************************************/
    /* Exercise iteration with nodeset_next_rank
     */
    n = nodeset_create_string ("0,2-3,7");
    ok (n != NULL);
    int r = nodeset_min (n);
    ok (r == 0, "nodeset_min");
    ok ((r = nodeset_next_rank (n, r)) == 2,
        "nodeset_next_rank (n, min) returns second element");
    ok ((r = nodeset_next_rank (n, r)) == 3,
        "nodeset_next_rank works on third element");
    ok ((r = nodeset_next_rank (n, r)) == 7,
        "nodeset_next_rank works on fourth element");
    ok ((r = nodeset_next_rank (n, r)) == NODESET_EOF,
        "nodeset_next_rank detects end of nodeset");

    ok ((r = nodeset_next_rank (n, 1)) == 2,
        "nodeset_next_rank returns next rank even if arg not in set");


/********************************************/

    /* Exercise nodeset_dup
     */
    n = nodeset_create_string ("0-2");
    ok (n != NULL);
    nodeset_config_brackets (n, false);
    like (nodeset_string (n), "0-2");
    n2 = nodeset_dup (n);
    ok (n2 != NULL, "nodeset_dup says it worked");
    like (nodeset_string (n2), "0-2", "nodeset_dup returned identical nodeset");
    nodeset_add_rank (n, 4);
    nodeset_add_rank (n2, 5);
    like (nodeset_string (n), "0-2,4", "orig unaffected by changes in dup");
    like (nodeset_string (n2), "0-2,5", "dup unaffected by changes in orig");
    nodeset_destroy (n);
    nodeset_destroy (n2);

/********************************************/

    /* Try zero padding.
     */
    n = nodeset_create_string ("[1,3,5,6-100]");
    ok (n != NULL);
    nodeset_config_brackets (n, false);
    like (nodeset_string (n), "1,3,5-100", "results not zero padded by default");
    //nodeset_config_padding (n, log10 (nodeset_max (n)) + 1);
    nodeset_config_padding (n, 3);
    like (nodeset_string (n), "001,003,005-100", "padding 3 on all all works");
    nodeset_config_padding (n, 2);
    like (nodeset_string (n), "01,03,05-100", "padding 2 on subset works");
    nodeset_config_padding (n, 4);
    like (nodeset_string (n), "0001,0003,0005-0100", "padding 4 on all works");
    nodeset_destroy (n);

/********************************************/

    /* Add 'bigset' consecutive singletons.
     */
    n = nodeset_create ();
    ok (n != NULL);
    nodeset_config_brackets (n, false);

    ok (nodeset_resize (n, bigset), "explicitly resize to %u", bigset);

    monotime (&ts);
    for (i = 0; i < bigset; i++)
        if (!nodeset_add_rank (n, i))
            break;
    ok (i == bigset, "added %u consecutive ranks [%.2fs %u Mbytes]", bigset,
        monotime_since (ts)/1000, nodeset_getattr (n, NODESET_ATTR_BYTES)/1024);

    monotime (&ts);
    tmp = xasprintf ("0-%u", bigset - 1);
    like (nodeset_string (n), tmp, "string conversion %s [%.2fs %u Mbytes]", tmp,
        monotime_since (ts)/1000, nodeset_getattr (n, NODESET_ATTR_BYTES)/1024);
    free (tmp);

    ok (nodeset_count (n) == bigset, "large nodeset count is sane");

    nodeset_destroy (n);

/********************************************/

    /* Add 'bigset'/2 non-consecutive singletons.
     */
    n = nodeset_create ();
    ok (n != NULL);
    nodeset_config_brackets (n, false);

    ok (nodeset_resize (n, bigset), "explicitly resize to %u", bigset);

    monotime (&ts);
    for (i = 0; i < bigset; i += 2)
        if (!nodeset_add_rank (n, i))
            break;
    ok (i == bigset,
        "added %u non-consecutive ranks [%.2fs %u Mbytes]", bigset/2,
        monotime_since (ts)/1000, nodeset_getattr (n, NODESET_ATTR_BYTES)/1024);

    monotime (&ts);
    ok (nodeset_string (n) != NULL, "string conversion [%.2fs %u Mbytes]",
        monotime_since (ts)/1000, nodeset_getattr (n, NODESET_ATTR_BYTES)/1024);

    ok (nodeset_count (n)  == bigset/2, "large nodeset count is sane");

    nodeset_destroy (n);

/********************************************/

    /* Check edge cases with very big ranks and resize.
     */
    bool skip_huge = true;


    n = nodeset_create ();
    nodeset_config_brackets (n, false);
    ok (nodeset_getattr (n, NODESET_ATTR_SIZE) == minsize,
        "veb size is the minimum %u", minsize);

    monotime (&ts);
    ok (!nodeset_add_rank (n, maxrank + 1),
        "adding max+1 %u rank fails [%.2fs %u Mbytes]", maxrank + 1,
        monotime_since (ts)/1000,
        nodeset_getattr (n, NODESET_ATTR_BYTES)/(1024*1024));
    ok (nodeset_getattr (n, NODESET_ATTR_SIZE) == minsize,
        "veb size is the minimum %u", minsize);

    skip (skip_huge, 16, "too slow");

    monotime (&ts);
    ok (nodeset_add_rank (n, maxrank),
        "add max rank %u [%.2fs %u Mbytes]", maxrank,
        monotime_since (ts)/1000,
        nodeset_getattr (n, NODESET_ATTR_BYTES)/(1024*1024));
    ok (nodeset_getattr (n, NODESET_ATTR_SIZE) == maxsize,
        "veb size is the maximum %u", maxsize);
    /* 2 */

    monotime (&ts);
    ok (nodeset_add_rank (n, maxrank - 1),
        "add max-1 %u [%.2fs %u Mbytes]", maxrank - 1,
        monotime_since (ts)/1000,
        nodeset_getattr (n, NODESET_ATTR_BYTES)/(1024*1024));

    ok (nodeset_test_rank (n, maxrank - 1), "test rank max - 1");
    ok (nodeset_test_rank (n, maxrank), "test rank max");
    ok (!nodeset_test_rank (n, maxrank + 1), "test rank max + 1");
    ok (nodeset_count (n) == 2, "nodeset count is sane");
    /* 7 */

    tmp = xasprintf ("%u-%u", maxrank-1, maxrank);
    monotime (&ts);
    like (nodeset_string (n), tmp, "convert to string %s [%.2fs %u Mbytes]", tmp,
        monotime_since (ts)/1000,
        nodeset_getattr (n, NODESET_ATTR_BYTES)/(1024*1024));
    free (tmp);
    /* 8 */

    ok (nodeset_resize (n, 0), "resize to 0 returns success");
    ok (nodeset_getattr (n, NODESET_ATTR_SIZE) == maxsize,
        "nodeset size remains max %u", maxsize);
    /* 10 */

    nodeset_delete_rank (n, maxrank - 1);
    ok (!nodeset_test_rank (n, maxrank - 1), "nodeset_del max - 1 works");
    ok (nodeset_test_rank (n, maxrank));
    ok (!nodeset_test_rank (n, maxrank + 1));
    /* 13 */

    nodeset_delete_rank (n, maxrank + 1);
    ok (!nodeset_test_rank (n, maxrank - 1), "nodeset_del max + 1 has no effect");
    ok (nodeset_test_rank (n, maxrank));
    ok (!nodeset_test_rank (n, maxrank + 1));
    /* 16 */

    end_skip;

    nodeset_delete_rank (n, maxrank);
    ok (!nodeset_test_rank (n, maxrank - 1), "nodeset_del max works");
    ok (!nodeset_test_rank (n, maxrank));
    ok (!nodeset_test_rank (n, maxrank + 1));
    /* 19 */

    ok (nodeset_resize (n, 0), "resize to zero returns success");
    ok (nodeset_getattr (n, NODESET_ATTR_SIZE) == minsize,
        "nodeset size is the minimum %u", minsize);

    nodeset_destroy (n);

    done_testing ();
}
Пример #6
0
int main (int argc, char *argv[])
{
    flux_t h;
    int ch;
    struct timespec t0;
    char *name = NULL;
    int quiet = 0;
    int nprocs = 1;
    int iter = 1;
    int i;

    log_init ("tbarrier");

    while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) {
        switch (ch) {
            case 'h': /* --help */
                usage ();
                break;
            case 'q': /* --quiet */
                quiet = 1;
                break;
            case 'n': /* --nprocs N */
                nprocs = strtoul (optarg, NULL, 10);
                break;
            case 't': /* --test-iterations N */
                iter = strtoul (optarg, NULL, 10);
                break;
            default:
                usage ();
                break;
        }
    }
    if (optind < argc - 1)
        usage ();
    if (optind < argc)
        name = argv[optind++];

    if (!(h = flux_open (NULL, 0)))
        err_exit ("flux_open");

    for (i = 0; i < iter; i++) {
        char *tname = NULL;
        monotime (&t0);
        if (name)
            tname = xasprintf ("%s.%d", name, i);
        if (flux_barrier (h, tname, nprocs) < 0) {
            if (errno == EINVAL && tname == NULL)
                msg_exit ("%s", "provide barrier name if not running as LWJ");
            else
                err_exit ("flux_barrier");
        }
        if (!quiet)
            printf ("barrier name=%s nprocs=%d time=%0.3f ms\n",
                    tname ? tname : "NULL", nprocs, monotime_since (t0));
        if (tname)
            free (tname);
    }

    flux_close (h);
    log_fini ();
    return 0;
}
Пример #7
0
int main (int argc, char *argv[])
{
    thd_t *thd;
    int i, rc;
    int ch;
    tstat_t ts;
    struct timespec t0;

    log_init (basename (argv[0]));

    while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) {
        switch (ch) {
            case 'f':
                fopt = true;
                fence_nprocs = strtoul (optarg, NULL, 10);
                if (!fence_nprocs)
                    log_msg_exit ("fence value must be > 0");
                break;
            case 's':
                sopt = true;
                break;
            case 'n':
                nopt = true;
                nopt_divisor = strtoul (optarg, NULL, 10);
                if (!nopt_divisor)
                    log_msg_exit ("nopt value must be > 0");
                break;
            default:
                usage ();
        }
    }
    if (argc - optind != 3)
        usage ();

    nthreads = strtoul (argv[optind++], NULL, 10);
    if (!nthreads)
        log_msg_exit ("thread count must be > 0");
    count = strtoul (argv[optind++], NULL, 10);
    if (!count)
        log_msg_exit ("commit count must be > 0");
    prefix = argv[optind++];

    memset (&ts, 0, sizeof (ts));

    thd = xzmalloc (sizeof (*thd) * nthreads);

    if (sopt)
        monotime (&t0);

    for (i = 0; i < nthreads; i++) {
        thd[i].n = i;
        if (!(thd[i].perf = zlist_new ()))
            oom ();
        if ((rc = pthread_attr_init (&thd[i].attr)))
            log_errn (rc, "pthread_attr_init");
        if ((rc = pthread_create (&thd[i].t, &thd[i].attr, thread, &thd[i])))
            log_errn (rc, "pthread_create");
    }

    for (i = 0; i < nthreads; i++) {
        if ((rc = pthread_join (thd[i].t, NULL)))
            log_errn (rc, "pthread_join");
        if (sopt) {
            double *e;
            while ((e = zlist_pop (thd[i].perf))) {
                tstat_push (&ts, *e);
                free (e);
            }
        }
        zlist_destroy (&thd[i].perf);
    }

    if (sopt) {
        json_t *o;
        char *s;

        if (!(o = json_pack ("{s:{s:i s:f s:f s:f s:f} s:f}",
                             "put+commit times (sec)",
                                 "count", tstat_count (&ts),
                                 "min", tstat_min (&ts)*1E-3,
                                 "mean", tstat_mean (&ts)*1E-3,
                                 "stddev", tstat_stddev (&ts)*1E-3,
                                 "max", tstat_max (&ts)*1E-3,
                             "put+commit throughput (#/sec)",
                             (double)(count*nthreads)
                                    / (monotime_since (t0)*1E-3))))
            log_err_exit ("json_pack");
        if (!(s = json_dumps (o, JSON_INDENT(2))))
            log_err_exit ("json_dumps");
        printf ("%s\n", s);
        json_decref (o);
        free (s);
    }

    free (thd);

    log_fini ();

    return 0;
}
Пример #8
0
double hello_get_time (hello_t *hello)
{
    if (!monotime_isset (hello->start))
        return 0;
    return monotime_since (hello->start) / 1000;
}