Example #1
0
/*
 * the producer loops over the requested number of items, writing them to the
 * buffer starting at location 0 and wrapping around when it hits the end of
 * the buffer. It then writes the value -1 as a sentinel to the next position.
 */
static aligned_t producer(void *arg)
{
    for (unsigned int i = 0; i < numItems; ++i) {
        const unsigned int buffInd = i % bufferSize;
        qthread_writeEF_const(&buff[buffInd], i);
        iprintf("producer wrote value #%u\n", i);
    }
    qthread_writeEF_const(&buff[numItems % bufferSize], -1);
    iprintf("producer wrote terminus value #%"PRIu64"\n", -1);

    return 0;
}
// Test that writeFF waits for empty var to be filled, writes, and leaves full.
// Requires that only one worker is running. Basically does:
//     1: empty var
//     1: fork(writeFF)
//     1: yields
//     2: starts runnning
//     2: hits writeFF, and yields since var is empty
//     1: writeEF
//     1: hits readFF on forked task and yield
//     2: running again, finishes writeFF, task returns
//     1: readFF competes, finishes
static void testWriteFFWaits(void)
{
    aligned_t ret;
    concurrent_t=45;
    qthread_empty(&concurrent_t);
    assert(qthread_num_workers() == 1);

    iprintf("1: Forking writeFF wrapper\n");
    qthread_fork_to(writeFF_wrapper, NULL, &ret, qthread_shep());
    iprintf("1: Forked, now yielding to 2\n");
    qthread_yield();
    iprintf("1: Back from yield\n");

    // verify that writeFF has not completed
    assert(qthread_feb_status(&concurrent_t) == 0);
    assert(concurrent_t != 55);

    iprintf("1: Writing EF\n");
    qthread_writeEF_const(&concurrent_t, 35);

    // wait for writeFF wrapper to complete
    qthread_readFF(NULL, &ret);

    // veify that writeFF completed and that FEB is full
    iprintf("1: concurrent_t=%d\n", concurrent_t);
    assert(qthread_feb_status(&concurrent_t) == 1);
    assert(concurrent_t == 55);
}
Example #3
0
static aligned_t update(void *arg)
{
    stencil_t *points = ((update_args_t *)arg)->points;
    size_t i = ((update_args_t *)arg)->i;
    size_t j = ((update_args_t *)arg)->j;
    size_t this_stage = ((update_args_t *)arg)->stage;
    size_t step = ((update_args_t *)arg)->step;

    size_t next_stage_id = next_stage(this_stage);

    // Perform local work
    perform_local_work();
    aligned_t **prev = points->stage[prev_stage(this_stage)];
    aligned_t sum = *(NORTH(prev, i, j)) 
                  + *(WEST(prev, i, j)) 
                  + *(HERE(prev, i, j)) 
                  + *(EAST(prev, i, j)) 
                  + *(SOUTH(prev, i, j));

    // Empty the next stage for this index
    qthread_empty(&points->stage[next_stage_id][i][j]);

    // Update this point
    qthread_writeEF_const(&points->stage[this_stage][i][j], sum/NUM_NEIGHBORS);
    
    if (step < num_timesteps) {
        // Spawn next stage
        update_args_t args = {points, i, j, next_stage_id, step+1};
#ifdef BOUNDARY_SYNC 
        qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, NUM_NEIGHBORS, NEIGHBORS(points->stage[this_stage],i,j));
#else
        if (i == 1) {                   // North edge
            if (j == 1)                     // West edge: EAST & SOUTH
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
            else if (j == points->M-2)      // East edge: WEST & SOUTH
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
            else                            // Interior: WEST & EAST & SOUTH
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, WEST(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
        } else if (i == points->N-2) {  // South edge
            if (j == 1)                     // West edge: NORTH & EAST
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j));
            else if (j == points->M-2)      // East edge: NORTH & WEST
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 2, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j));
            else                            // Interior: NORTH & WEST & EAST
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j));
        } else {                        // Interior
            if (j == 1)                     // West edge: NORTH & EAST & SOUTH
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3 , NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
            else if (j == points->M-2)      // East edge: NORTH & WEST & SOUTH
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 3, NORTH(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
            else                            // Interior: ALL
                qthread_fork_copyargs_precond(update, &args, sizeof(update_args_t), NULL, 4, NORTH(points->stage[this_stage],i,j), EAST(points->stage[this_stage],i,j), WEST(points->stage[this_stage],i,j), SOUTH(points->stage[this_stage],i,j));
        }
#endif
    }
    else
        qt_feb_barrier_enter(points->barrier);

    return 0;
}
Example #4
0
template < typename T > inline int qthread_writeEF(T *const dest,
                                                   const T  src)
{
    QTHREAD_CHECKSIZE(T);
    return qthread_writeEF_const((aligned_t *)dest,
                                 (aligned_t)src);
}
Example #5
0
void mt_write(T& target, T2 val)
{
#ifdef __MTA__
  writeef(&target, val);
#elif USING_QTHREADS
  qthread_writeEF_const((aligned_t*) &target, (aligned_t) val);
#else
  target = val;
#endif
}