Пример #1
0
int main(int argc, char *argv[])
{
    int tid;
    pthread_t *th;

    if (argc != 2) {
        printf("*** Incorrect number of arguments.  Skipping test\n");
        return 77;
    }
    nthreads = atoi(argv[1]);


    /* first test single-threaded functionality */

    /* -- cmpset 32-bit tests -- */

    vol32 = 42, old32 = 42, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) == true);
    opal_atomic_rmb();
    assert(vol32 == new32);
    assert(old32 == 42);

    vol32 = 42, old32 = 420, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) ==  false);
    opal_atomic_rmb();
    assert(vol32 == 42);
    assert(old32 == 42);

    vol32 = 42, old32 = 42, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_32 (&vol32, &old32, new32) == true);
    assert(vol32 == new32);
    assert(old32 == 42);

    vol32 = 42, old32 = 420, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_acq_32 (&vol32, &old32, new32) == false);
    assert(vol32 == 42);
    assert(old32 == 42);

    vol32 = 42, old32 = 42, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_rel_32 (&vol32, &old32, new32) ==  true);
    opal_atomic_rmb();
    assert(vol32 == new32);
    assert(old32 == 42);

    vol32 = 42, old32 = 420, new32 = 50;
    assert(opal_atomic_compare_exchange_strong_rel_32 (&vol32, &old32, new32) == false);
    opal_atomic_rmb();
    assert(vol32 == 42);
    assert(old32 == 42);

    /* -- cmpset 64-bit tests -- */

#if OPAL_HAVE_ATOMIC_MATH_64
    vol64 = 42, old64 = 42, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_64 (&vol64, &old64, new64) == true);
    opal_atomic_rmb();
    assert(new64 == vol64);
    assert(old64 == 42);

    vol64 = 42, old64 = 420, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_64 (&vol64, &old64, new64) == false);
    opal_atomic_rmb();
    assert(vol64 == 42);
    assert(old64 == 42);

    vol64 = 42, old64 = 42, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_acq_64 (&vol64, &old64, new64) == true);
    assert(vol64 == new64);
    assert(old64 == 42);

    vol64 = 42, old64 = 420, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_acq_64 (&vol64, &old64, new64) == false);
    assert(vol64 == 42);
    assert(old64 == 42);

    vol64 = 42, old64 = 42, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_rel_64 (&vol64, &old64, new64) == true);
    opal_atomic_rmb();
    assert(vol64 == new64);
    assert(old64 == 42);

    vol64 = 42, old64 = 420, new64 = 50;
    assert(opal_atomic_compare_exchange_strong_rel_64 (&vol64, &old64, new64) == false);
    opal_atomic_rmb();
    assert(vol64 == 42);
    assert(old64 == 42);
#endif

    /* -- cmpset 128-bit tests -- */

#if OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_128
    vol128 = 42, old128 = 42, new128 = 50;
    assert(opal_atomic_compare_exchange_strong_128 (&vol128, &old128, new128) == true);
    opal_atomic_rmb();
    assert(new128 == vol128);
    assert(old128 == 42);

    vol128 = 42, old128 = 420, new128 = 50;
    assert(opal_atomic_compare_exchange_strong_128 (&vol128, &old128, new128) == false);
    opal_atomic_rmb();
    assert(vol128 == 42);
    assert(old128 == 42);
#endif

    /* -- cmpset int tests -- */

    volint = 42, oldint = 42, newint = 50;
    assert(opal_atomic_compare_exchange_strong (&volint, &oldint, newint) == true);
    opal_atomic_rmb();
    assert(volint == newint);
    assert(oldint == 42);

    volint = 42, oldint = 420, newint = 50;
    assert(opal_atomic_compare_exchange_strong (&volint, &oldint, newint) == false);
    opal_atomic_rmb();
    assert(volint == 42);
    assert(oldint == 42);

    volint = 42, oldint = 42, newint = 50;
    assert(opal_atomic_compare_exchange_strong_acq (&volint, &oldint, newint) == true);
    assert(volint == newint);
    assert(oldint == 42);

    volint = 42, oldint = 420, newint = 50;
    assert(opal_atomic_compare_exchange_strong_acq (&volint, &oldint, newint) == false);
    assert(volint == 42);
    assert(oldint == 42);

    volint = 42, oldint = 42, newint = 50;
    assert(opal_atomic_compare_exchange_strong_rel (&volint, &oldint, newint) == true);
    opal_atomic_rmb();
    assert(volint == newint);
    assert(oldint == 42);

    volint = 42, oldint = 420, newint = 50;
    assert(opal_atomic_compare_exchange_strong_rel (&volint, &oldint, newint) == false);
    opal_atomic_rmb();
    assert(volint == 42);
    assert(oldint == 42);


    /* -- cmpset ptr tests -- */

    volptr = 42, oldptr = 42, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_ptr (&volptr, &oldptr, newptr) == true);
    opal_atomic_rmb();
    assert(volptr == newptr);
    assert(oldptr == 42);

    volptr = 42, oldptr = 420, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_ptr (&volptr, &oldptr, newptr) == false);
    opal_atomic_rmb();
    assert(volptr == 42);
    assert(oldptr == 42);

    volptr = 42, oldptr = 42, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_acq_ptr (&volptr, &oldptr, newptr) == true);
    assert(volptr == newptr);
    assert(oldptr == 42);

    volptr = 42, oldptr = 420, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_acq_ptr (&volptr, &oldptr, newptr) == false);
    assert(volptr == 42);
    assert(oldptr == 42);

    volptr = 42, oldptr = 42, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_rel_ptr (&volptr, &oldptr, newptr) == true);
    opal_atomic_rmb();
    assert(volptr == newptr);
    assert(oldptr == 42);

    volptr = 42, oldptr = 420, newptr = 50;
    assert(opal_atomic_compare_exchange_strong_rel_ptr (&volptr, &oldptr, newptr) == false);
    opal_atomic_rmb();
    assert(volptr == 42);
    assert(oldptr == 42);

    /* -- add_32 tests -- */

    val32 = 42;
    assert(opal_atomic_add_fetch_32(&val32, 5) == (42 + 5));
    opal_atomic_rmb();
    assert((42 + 5) == val32);

    /* -- add_64 tests -- */
#if OPAL_HAVE_ATOMIC_MATH_64
    val64 = 42;
    assert(opal_atomic_add_fetch_64(&val64, 5) == (42 + 5));
    opal_atomic_rmb();
    assert((42 + 5) == val64);
#endif
    /* -- add_int tests -- */

    valint = 42;
    opal_atomic_add (&valint, 5);
    opal_atomic_rmb();
    assert((42 + 5) == valint);


    /* threaded tests */

    val32 = 0;
#if OPAL_HAVE_ATOMIC_MATH_64
    val64 = 0ul;
#endif
    valint = 0;

    /* -- create the thread set -- */
    th = (pthread_t *) malloc(nthreads * sizeof(pthread_t));
    if (!th) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    for (tid = 0; tid < nthreads; tid++) {
        if (pthread_create(&th[tid], NULL, thread_main, (void *) (unsigned long) tid) != 0) {
            perror("pthread_create");
            exit(EXIT_FAILURE);
        }
    }

    /* -- wait for the thread set to finish -- */

    for (tid = 0; tid < nthreads; tid++) {
        void *thread_return;

        if (pthread_join(th[tid], &thread_return) != 0) {
            perror("pthread_join");
            exit(EXIT_FAILURE);
        }
    }
    free(th);

    opal_atomic_rmb();
    assert((5 * nthreads * nreps) == val32);
#if OPAL_HAVE_ATOMIC_MATH_64
    opal_atomic_rmb();
    assert((5 * nthreads * nreps) ==  val64);
#endif
    opal_atomic_rmb();
    assert((5 * nthreads * nreps) == valint);

    return 0;
}
Пример #2
0
/* progress */
int mca_btl_ugni_smsg_process (mca_btl_base_endpoint_t *ep)
{
    mca_btl_ugni_module_t *ugni_module = mca_btl_ugni_ep_btl (ep);
    mca_btl_active_message_callback_t *reg;
    mca_btl_ugni_base_frag_t frag;
    mca_btl_base_segment_t seg;
    bool disconnect = false;
    int32_t _tmp_value = 0;
    uintptr_t data_ptr;
    gni_return_t rc;
    uint32_t len;
    int count = 0;

    if (!opal_atomic_compare_exchange_strong_32 (&ep->smsg_progressing, &_tmp_value, 1)) {
        /* already progressing (we can't support reentry here) */
        return 0;
    }

    /* per uGNI documentation we loop until the mailbox is empty */
    do {
        uint8_t tag = GNI_SMSG_ANY_TAG;

        rc = mca_btl_ugni_smsg_get_next_wtag (ep->smsg_ep_handle, &data_ptr, &tag);
        if (GNI_RC_SUCCESS != rc) {
            if (OPAL_LIKELY(GNI_RC_NOT_DONE == rc)) {
                BTL_VERBOSE(("no smsg message waiting. rc = %s", gni_err_str[rc]));

                ep->smsg_progressing = 0;
                return count;
            }

            BTL_ERROR(("unhandled GNI_SmsgGetNextWTag error"));
            return OPAL_ERROR;
        }

        assert (0 != data_ptr);

        count++;

        BTL_VERBOSE(("got smsg fragment. tag = %d\n", tag));

        switch (tag) {
        case MCA_BTL_UGNI_TAG_SEND:
            frag.hdr.send = ((mca_btl_ugni_send_frag_hdr_t *) data_ptr)[0];

            tag = frag.hdr.send.lag >> 24;
            len = frag.hdr.send.lag & 0x00ffffff;

            BTL_VERBOSE(("received smsg fragment. hdr = {len = %u, tag = %d}", len, tag));

            reg = mca_btl_base_active_message_trigger + tag;
            frag.base.des_segments       = &seg;
            frag.base.des_segment_count = 1;

            seg.seg_addr.pval = (void *)((uintptr_t)data_ptr + sizeof (mca_btl_ugni_send_frag_hdr_t));
            seg.seg_len       = len;

            assert (NULL != reg->cbfunc);

            reg->cbfunc(&ugni_module->super, tag, &(frag.base), reg->cbdata);

            break;
        case MCA_BTL_UGNI_TAG_GET_INIT:
            frag.hdr.eager_ex = ((mca_btl_ugni_eager_ex_frag_hdr_t *) data_ptr)[0];

            mca_btl_ugni_start_eager_get (ep, frag.hdr.eager_ex, NULL);
            break;
        case MCA_BTL_UGNI_TAG_RDMA_COMPLETE:
            frag.hdr.rdma = ((mca_btl_ugni_rdma_frag_hdr_t *) data_ptr)[0];

            if (((mca_btl_ugni_base_frag_t *)frag.hdr.rdma.ctx)->flags & MCA_BTL_UGNI_FRAG_SMSG_COMPLETE) {
                mca_btl_ugni_frag_complete (frag.hdr.rdma.ctx, OPAL_SUCCESS);
            } else {
                /* let the local smsg completion finish this frag */
                ((mca_btl_ugni_base_frag_t *)frag.hdr.rdma.ctx)->flags &= ~MCA_BTL_UGNI_FRAG_IGNORE;
            }
            break;
        case MCA_BTL_UGNI_TAG_DISCONNECT:
            /* remote endpoint has disconnected */
            disconnect = true;
            break;
        default:
            BTL_ERROR(("unknown tag %d\n", tag));
            break;
        }

        rc = mca_btl_ugni_smsg_release (ep->smsg_ep_handle);
        if (OPAL_UNLIKELY(GNI_RC_SUCCESS != rc)) {
            BTL_ERROR(("Smsg release failed! rc = %d", rc));
            return OPAL_ERROR;
        }
    } while (!disconnect);

    ep->smsg_progressing = 0;

    /* disconnect if we get here */
    opal_mutex_lock (&ep->lock);

    mca_btl_ugni_ep_disconnect (ep, false);

    opal_mutex_unlock (&ep->lock);

    return count;
}