static aligned_t consumer(void *arg)
{
    uint64_t me;

    iprintf("consumer locking id(%p)\n", &id);
    qthread_syncvar_readFE(&me, &id);
    iprintf("consumer id's status became: %u\n", qthread_syncvar_status(&id));
    iprintf("consumer unlocking id(%p), result is %lu\n", &id,
            (unsigned long)me);
    me++;
    qthread_syncvar_writeEF(&id, &me);

    for (uint64_t i = 0; i < iterations; ++i) {
        iprintf("consumer readFE on x\n");
        qthread_syncvar_readFE(NULL, &x);
    }

    iprintf("thread %i exiting\n", (int)(uintptr_t)arg);

    return 0;
}
示例#2
0
void chpl_sync_waitEmptyAndLock(chpl_sync_aux_t *s,
                                int32_t          lineno,
                                chpl_string      filename)
{
    PROFILE_INCR(profile_sync_waitEmptyAndLock, 1);

    if (blockreport) { about_to_block(lineno, filename); }
    chpl_sync_lock(s);
    while (s->is_full != 0) {
        chpl_sync_unlock(s);
        qthread_syncvar_readFE(NULL, &(s->signal_empty));
        chpl_sync_lock(s);
    }
}
static aligned_t producer(void *arg)
{
    uint64_t me;

    iprintf("producer locking id(%p)\n", &id);
    qthread_syncvar_readFE(&me, &id);
    iprintf("producer unlocking id(%p), result is %lu\n", &id,
            (unsigned long)me);
    me++;
    qthread_syncvar_writeEF(&id, &me);

    for (uint64_t i = 0; i < iterations; ++i) {
        iprintf("producer x's status is: %s (expect empty)\n",
                qthread_syncvar_status(&x) ? "full" : "empty");
        iprintf("producer filling x(%p)\n", &x);
        qthread_syncvar_writeEF_const(&x, i);
    }
    iprintf("thread %i exiting\n", (int)(uintptr_t)arg);

    return 0;
}
示例#4
0
文件: log.c 项目: DawidvC/chapel
// walk up the barrier -- waits for neighbor lock at each level of the tree
//   when both arrive the lower thread number climbs up the tree and the
//   higher number waits for the down walk to release.  When all of the nodes arrive
//   Thread 0 starts the walk down (after executing functions to resync for loop
//   implementation).  Any node that is waiting release at a level other than the
//   leaves, releases its subtree
static void qtb_internal_up(qt_barrier_t *b,
                            int           myLock,
                            int64_t       val,
                            int           level)
{                                      /*{{{ */
    // compute neighbor node at this level
    int  mask       = 1 << level;
    int  pairedLock = myLock ^ mask;
    char debug      = b->barrierDebug;

    assert(b->activeSize > 1);
    if (debug) {
        printf("on lock %d paired with %d level %d val %ld\n", myLock,
               pairedLock, level, (long int)val);
    }
    if (pairedLock >= b->activeSize) { // my pair is out of range don't wait for it
        qthread_syncvar_writeEF(&b->upLock[myLock], &dummy);
        qthread_syncvar_readFE(NULL, &b->downLock[myLock]);
        if (debug) {
            printf("released (no pair) lock %d level %d val %ld\n", myLock,
                   level, (long int)val);
        }
        if (level != 0) {
            qtb_internal_down(b, myLock, level); // everyone is here and I have people to release
        }
        return;                        // done
    }

    if (pairedLock < myLock) {         // I'm higher -- wait for release
        qthread_syncvar_writeEF(&b->upLock[myLock], &dummy);
        if (debug) {
            printf
                ("about to wait on lock %d paired with %d level %d val %ld\n",
                myLock, pairedLock, level, (long int)val);
        }
        qthread_syncvar_readFE(NULL, &b->downLock[myLock]);

        if (debug) {
            printf("released lock %d level %d val %ld\n", myLock, level,
                   (long int)val);
        }
        if (level != 0) {
            qtb_internal_down(b, myLock, level); // everyone is here and I have people to release
        }
        return;                        // done
    } else {                           // I'm lower -- wait for pair and continue up
        if (debug) {
            printf("wait lock %d for %d level %d val %ld\n", myLock,
                   pairedLock, level, (long int)val);
        }
        qthread_syncvar_readFE(NULL, &b->upLock[pairedLock]);
        if (debug) {
            printf("continue on %d level %d val %ld\n", myLock, level,
                   (long int)val);
        }
    }

    if ((level + 1 < b->doneLevel) || (myLock != 0)) {  // not done?  yes
        qtb_internal_up(b, myLock, val, level + 1);
    } else {                           // done -- start release
        // myLock == 0 here -- don't need to fill either because Zero never waits on them
        // qthread_syncvar_writeEF(&b->upLock[myLock],&dummy);
        // qthread_syncvar_writeEF(&b->downLock[myLock],&dummy);
        if (debug) {
            printf("\t start down lock %d level %d \n", myLock, level);
        }
        qtb_internal_down(b, myLock, level);    // everyone is here
    }
}                                      /*}}} */
int main(int argc,
         char *argv[])
{
    aligned_t *t[2];
    uint64_t x_value;

    uint64_t pairs;

    assert(qthread_initialize() == 0);
    pairs = qthread_num_shepherds() * 6;

    CHECK_VERBOSE();
    NUMARG(iterations, "ITERATIONS");
    NUMARG(pairs, "PAIRS");

    t[0] = calloc(pairs, sizeof(aligned_t));
    t[1] = calloc(pairs, sizeof(aligned_t));

    iprintf("%i threads...\n", qthread_num_shepherds());
    iprintf("Initial value of x: %lu\n", (unsigned long)x.u.w);

    qthread_syncvar_empty(&id);
    qthread_syncvar_writeF_const(&id, 1);
    iprintf("id = 0x%lx\n", (unsigned long)id.u.w);
    {
        uint64_t tmp = 0;
        qthread_syncvar_readFF(&tmp, &id);
        assert(tmp == 1);
    }
    iprintf("x's status is: %s (want full (and nowait))\n",
            qthread_syncvar_status(&x) ? "full" : "empty");
    assert(qthread_syncvar_status(&x) == 1);
    qthread_syncvar_readFE(NULL, &x);
    iprintf("x's status became: %s (want empty (and nowait))\n",
            qthread_syncvar_status(&x) ? "full" : "empty");
    assert(qthread_syncvar_status(&x) == 0);
    for (unsigned int i = 0; i < pairs; ++i) {
        qthread_fork(consumer, (void *)(uintptr_t)i, &(t[0][i]));
    }
    for (unsigned int i = 0; i < pairs; ++i) {
        qthread_fork(producer, (void *)(uintptr_t)(i + pairs), &(t[1][i]));
    }
    for (unsigned int i = 0; i < pairs; ++i) {
        qthread_readFF(NULL, &(t[0][i]));
        qthread_readFF(NULL, &(t[1][i]));
    }
    iprintf("shouldn't be blocking on x (current status: %s)\n",
            qthread_syncvar_status(&x) ? "full" : "empty");
    qthread_syncvar_fill(&x);
    iprintf("shouldn't be blocking on x (current status: %s)\n",
            qthread_syncvar_status(&x) ? "full" : "empty");
    qthread_syncvar_readFF(&x_value, &x);
    assert(qthread_syncvar_status(&x) == 1);

    free(t[0]);
    free(t[1]);

    if (x_value == iterations - 1) {
        iprintf("Success! x==%lu\n", (unsigned long)x_value);
        return 0;
    } else {
        fprintf(stderr, "Final value of x=%lu, expected %lu\n",
                (unsigned long)x_value, (unsigned long)(iterations - 1));
        return -1;
    }
}