コード例 #1
0
ファイル: feb_barrier.c プロジェクト: deniskin82/chapel
int main(int   argc,
         char *argv[])
{
    size_t       threads = 1000, i;
    aligned_t   *rets;
    qtimer_t     t;
    unsigned int iter, iterations = 10;

    assert(qthread_initialize() == 0);
    t = qtimer_create();

    CHECK_VERBOSE();
    NUMARG(threads, "THREADS");
    NUMARG(iterations, "ITERATIONS");

    initme = (aligned_t *)calloc(threads, sizeof(aligned_t));
    assert(initme);

    rets = (aligned_t *)malloc(iterations * threads * sizeof(aligned_t));
    assert(rets);

    iprintf("creating the barrier for %zu threads\n", threads + 1);
    wait_on_me = qt_feb_barrier_create(threads + 1);    // all my spawnees plus me
    assert(wait_on_me);

    for (iter = 0; iter < iterations; iter++) {
        iprintf("%i: forking the threads\n", iter);
        for (i = 0; i < threads; i++) {
            qthread_fork(barrier_thread, wait_on_me, rets + (iter * threads) + i);
        }
        iprintf("%i: done forking the threads, entering the barrier\n", iter);
        qtimer_start(t);
        qt_feb_barrier_enter(wait_on_me);
        qtimer_stop(t);
        iprintf("%i: main thread exited barrier in %f seconds\n", iter, qtimer_secs(t));

        initme_idx = 0;

        for (i = 0; i < threads; i++) {
            if (initme[i] != iter + 1) {
                iprintf("initme[%i] = %i (should be %i)\n", (int)i,
                        (int)initme[i], iter + 1);
            }
            assert(initme[i] == iter + 1);
        }
    }

    iprintf("Destroying barrier...\n");
    qt_feb_barrier_destroy(wait_on_me);

    iprintf("Success!\n");

    /* this loop shouldn't be necessary... but seems to avoid crashes in rare
     * cases (in other words there must a race condition in qthread_finalize()
     * if there are outstanding threads out there) */
    for (i = 0; i < threads * 2; i++) {
        aligned_t tmp = 1;
        qthread_readFF(&tmp, rets + i);
        assert(tmp == 0);
    }
    return 0;
}
コード例 #2
0
ファイル: sinc_null.c プロジェクト: Agobin/chapel
// //////////////////////////////////////////////////////////////////////////////
int main(int   argc,
         char *argv[])
{
    size_t depth = 3;

    assert(qthread_initialize() == 0);

    CHECK_VERBOSE();
    NUMARG(depth, "TEST_DEPTH");

    // Test creating an empty sinc
    {
        qt_sinc_t zero_sinc;
	qt_sinc_init(&zero_sinc, 0, NULL, NULL, 0);
        qt_sinc_wait(&zero_sinc, NULL);
        qt_sinc_fini(&zero_sinc);

        qt_sinc_t *three_sinc = qt_sinc_create(0, NULL, NULL, 0);
        qt_sinc_expect(three_sinc, 3);
        qthread_fork(submit_to_sinc, three_sinc, NULL);
        qthread_fork(submit_to_sinc, three_sinc, NULL);
        qthread_fork(submit_to_sinc, three_sinc, NULL);
        qt_sinc_wait(three_sinc, NULL);
        qt_sinc_destroy(three_sinc);
    }

    qt_sinc_t *sinc = qt_sinc_create(0, NULL, NULL, 2);

    // Spawn additional waits
    aligned_t rets[3];
    {
        qthread_fork(wait_on_sinc, sinc, &rets[0]);
        qthread_fork(wait_on_sinc, sinc, &rets[1]);
        qthread_fork(wait_on_sinc, sinc, &rets[2]);
    }

    {
        v_args_t args = { depth, sinc };

        // These two spawns covered by qt_sinc_create(...,2)
        qthread_fork_syncvar_copyargs(visit, &args, sizeof(v_args_t), NULL);
        qthread_fork_syncvar_copyargs(visit, &args, sizeof(v_args_t), NULL);
    }

    qt_sinc_wait(sinc, NULL);
    for (int i = 0; i < 3; i++)
        qthread_readFF(NULL, &rets[i]);

    // Reset the sinc
    qt_sinc_reset(sinc, 2);

    // Second use
    {
        v_args_t args = { depth, sinc };

        // These two spawns covered by qt_sinc_reset(...,2)
        qthread_fork_syncvar_copyargs(visit, &args, sizeof(v_args_t), NULL);
        qthread_fork_syncvar_copyargs(visit, &args, sizeof(v_args_t), NULL);
    }

    qt_sinc_wait(sinc, NULL);
    qt_sinc_destroy(sinc);

    return 0;
}
コード例 #3
0
ファイル: qutil.c プロジェクト: Agobin/chapel
void API_FUNC qutil_mergesort(double *array,
                              size_t  length)
{   /*{{{*/
    /* first, decide how much of the array each thread gets */
    size_t chunksize = MT_LOOP_CHUNK;

    /* second, decide how many threads to use... */
    size_t                       numthreads;
    aligned_t                   *rets;
    size_t                       i;
    struct qutil_mergesort_args *args;

    assert(qthread_library_initialized);

    chunksize = 10;
    /* third, an initial qsort() */
    numthreads = length / chunksize;
    if (length - (numthreads * chunksize)) {
        numthreads++;
    }
    rets = MALLOC(sizeof(aligned_t) * numthreads);
    args = MALLOC(sizeof(struct qutil_mergesort_args) * numthreads);
    for (i = 0; i < numthreads; i++) {
        args[i].array       = array;
        args[i].first_start = i * chunksize;
        args[i].first_stop  = (i + 1) * chunksize - 1;
        if (args[i].first_stop >= length) {
            args[i].first_stop = length - 1;
        }

        qthread_fork((qthread_f)qutil_mergesort_presort, args + i, rets + i);
    }
    for (i = 0; i < numthreads; i++) {
        qthread_readFF(NULL, rets + i);
    }
    FREE(rets, sizeof(aligned_t) * numthreads);
    FREE(args, sizeof(struct qutil_mergesort_args) * numthreads);
    /* prepare scratch memory */
    if (chunksize <= length) {
        numthreads = (length - chunksize) / (2 * chunksize);
        if ((length - chunksize) - (2 * chunksize * numthreads)) {
            numthreads++;
        }
        rets = MALLOC(sizeof(aligned_t) * numthreads);
        assert(rets);
        args = MALLOC(sizeof(struct qutil_mergesort_args) * numthreads);
        assert(args);
        numthreads = 0;
    }
    /* now, commence with the merging */
    while (chunksize <= length) {
        i          = 0;
        numthreads = 0;
        while (i < length - chunksize) {
            args[numthreads].array        = array;
            args[numthreads].first_start  = i;
            args[numthreads].first_stop   = i + chunksize - 1;
            args[numthreads].second_start = i + chunksize;
            args[numthreads].second_stop  =
                ((i + 2 * chunksize - 1) <
                 (length - 1)) ? (i + 2 * chunksize - 1) : (length - 1);
            qthread_fork((qthread_f)qutil_mergesort_inner, args + numthreads,
                         rets + numthreads);
            i += 2 * chunksize;
            numthreads++;
        }
        for (i = 0; i < numthreads; i++) {
            qthread_readFF(NULL, rets + i);
        }
        chunksize *= 2;
    }
    if (rets) {
        FREE(rets, sizeof(aligned_t) * numthreads);
        FREE(args, sizeof(struct qutil_mergesort_args) * numthreads);
    }
} /*}}}*/