Exemplo n.º 1
0
static aligned_t barrier_thread(void *arg)
{
    qt_feb_barrier_t *b   = (qt_feb_barrier_t *)arg;
    aligned_t         idx = qthread_incr(&initme_idx, 1);

    qthread_incr(&(initme[idx]), 1);
    qt_feb_barrier_enter(b);
    return 0;
}
Exemplo n.º 2
0
static aligned_t tobequeued(void *arg)
{
    qthread_incr(&threads_in, 1);
    //iprintf("\tOne thread about to join the queue...\n");
    qthread_queue_join(the_queue);
    //iprintf("\tAwoke from the queue! %p\n", qthread_retloc());
    qthread_incr(&awoke, 1);

    return 1;
}
Exemplo n.º 3
0
static aligned_t barrier_thread(void *arg)
{
    void **args = (void**)arg;
    qt_barrier_t *b   = (qt_barrier_t *)args[0];
    uintptr_t     id = (uintptr_t)args[1];
    aligned_t     idx = qthread_incr(&initme_idx, 1);
    qthread_shepherd_id_t shep;
    qthread_worker_id_t wkr;

    wkr = qthread_worker(&shep);
    //iprintf("I woke up on shep %u worker %u, barrier %p, using ID number %u, idx %u\n", shep, wkr, b, id, idx);
    qthread_incr(&(initme[idx]), 1);
    qt_barrier_enter(b, id);
    return 0;
}
Exemplo n.º 4
0
// Sync variables
void chpl_sync_lock(chpl_sync_aux_t *s)
{
    aligned_t l;
    chpl_bool uncontested_lock = true;

    PROFILE_INCR(profile_sync_lock, 1);

    //
    // To prevent starvation due to never switching away from a task that is
    // spinning while doing readXX() on a sync variable, yield if this sync var
    // has a "lot" of uncontested locks. Note that the uncontested locks do not
    // have to be consecutive. Also note that the number of uncontested locks
    // is a lossy counter. Currently a "lot" is defined as ~100 uncontested
    // locks, with care taken to not yield on the first uncontested lock.
    //
    // If real qthreads sync vars were used, it's possible this wouldn't be
    // needed.
    //

    l = qthread_incr(&s->lockers_in, 1);

    while (l != s->lockers_out) {
        uncontested_lock = false;
        qthread_yield();
    }

    if (uncontested_lock) {
        if ((++s->uncontested_locks & 0x5F) == 0) {
            qthread_yield();
        }
    }
}
Exemplo n.º 5
0
void INTERNAL hazardous_ptr(unsigned int which,
                            void        *ptr)
{/*{{{*/
    uintptr_t *hzptrs = TLS_GET(ts_hazard_ptrs);

    if (hzptrs == NULL) {
        {
            qthread_worker_t *wkr = qthread_internal_getworker();
            if (wkr == NULL) {
                hzptrs = calloc(sizeof(uintptr_t), HAZARD_PTRS_PER_SHEP + 1);
                assert(hzptrs);
                do {
                    hzptrs[HAZARD_PTRS_PER_SHEP] = (uintptr_t)QTHREAD_CASLOCK_READ(hzptr_list);
                } while (QT_CAS(hzptr_list, hzptrs[HAZARD_PTRS_PER_SHEP], hzptrs)
                         != (void *)hzptrs[HAZARD_PTRS_PER_SHEP]);
                (void)qthread_incr(&hzptr_list_len, 1);
            } else {
                hzptrs = wkr->hazard_ptrs;
            }
        }
        TLS_SET(ts_hazard_ptrs, hzptrs);
    }

    assert(hzptrs);
    assert(which < HAZARD_PTRS_PER_SHEP);
    hzptrs[which] = (uintptr_t)ptr;
}/*}}}*/
Exemplo n.º 6
0
aligned_t incr_in_degree(void * args_)
{
    vertex_id_t src = *((vertex_id_t *)args_);

    printf("[%03d] incrementing in-degree at %p\n", here, &(indices[src]));
    qthread_incr(&(in_degrees[src]), 1);

    return 0;
}
Exemplo n.º 7
0
// Sync variables
void chpl_sync_lock(chpl_sync_aux_t *s)
{
    aligned_t l;

    PROFILE_INCR(profile_sync_lock, 1);

    l = qthread_incr(&s->lockers_in, 1);
    while (l != s->lockers_out) SPINLOCK_BODY();
}
Exemplo n.º 8
0
static void assignoff1(const size_t startat,
                       const size_t stopat,
                       qarray * q,
                       void *arg)
{
    for (size_t i = startat; i < stopat; i++) {
        void *ptr = qarray_elem_nomigrate(q, i);

        memset(ptr, 1, sizeof(offsize));
    }
    qthread_incr(&count, stopat - startat);
}
Exemplo n.º 9
0
static qthread_t *qt_threadqueue_dequeue(qt_threadqueue_t *q)
{                                      /*{{{ */
    qt_threadqueue_node_t *node = qt_internal_NEMESIS_dequeue(&q->q);

    if (node) {
        qthread_t *retval = node->thread;
        assert(node->next == NULL);
        (void)qthread_incr(&(q->advisory_queuelen), -1);
        FREE_TQNODE(node);
        return retval;
    } else {
        return NULL;
    }
}                                      /*}}} */
Exemplo n.º 10
0
// Notes:
// -    Each task receives distinct copy of parent
// -    Copy of child is shallow, be careful with `state` member
static aligned_t visit(void *args_)
{
    node_t  *parent          = (node_t *)args_;
    int      parent_height   = parent->height;
    int      num_children    = parent->num_children;
    aligned_t expect         = parent->expect;
    aligned_t num_descendants[num_children];
    aligned_t sum_descendants = 1;

    if (num_children != 0) {
        node_t     child __attribute__((aligned(8)));
        aligned_t  donec = 0;

        // Spawn children, if any
        child.height = parent_height + 1;
        child.dc     = &donec;
        child.expect = num_children;

        qthread_empty(&donec);

        for (int i = 0; i < num_children; i++) {
            child.acc    = &num_descendants[i];

            for (int j = 0; j < num_samples; j++) {
                rng_spawn(parent->state.state, child.state.state, i);
            }

            child.num_children = calc_num_children(&child);

            qthread_fork_syncvar_copyargs(visit, &child, sizeof(node_t), NULL);
        }

        // Wait for children to finish up, accumulate descendants counts
        if (donec != expect) qthread_readFF(NULL, &donec);

        for (int i = 0; i < num_children; i++) {
            sum_descendants += num_descendants[i];
        }
    }

    *parent->acc = sum_descendants;
    if (qthread_incr(parent->dc, 1) + 1 == expect) {
        qthread_fill(parent->dc);
    }

    return 0;
}
Exemplo n.º 11
0
// old public method
static inline int qt_hash_remove(qt_hash        h,
                                 const qt_key_t key)
{
    size_t   bucket;
    uint64_t lkey = (uint64_t)(uintptr_t)(h->op_hash(key));

    HASH_KEY(lkey);
    bucket = lkey % h->size;

    if (h->B[bucket] == UNINITIALIZED) {
        initialize_bucket(h, bucket);
    }
    if (!qt_lf_list_delete(&(h->B[bucket]), so_regularkey(lkey), key, h->op_equals, h->op_cleanup)) {
        return 0;
    }
    qthread_incr(&h->count, -1);
    return 1;
}
Exemplo n.º 12
0
void INTERNAL qt_threadqueue_free(qt_threadqueue_t *q)
{                                      /*{{{ */
    assert(q);
    while (1) {
        qt_threadqueue_node_t *node = qt_internal_NEMESIS_dequeue_st(&q->q);
        if (node) {
            qthread_t *retval = node->thread;
            assert(node->next == NULL);
            (void)qthread_incr(&(q->advisory_queuelen), -1);
            FREE_TQNODE(node);
            qthread_thread_free(retval);
        } else {
            break;
        }
    }
#ifdef QTHREAD_CONDWAIT_BLOCKING_QUEUE
    QTHREAD_COND_DESTROY(q->trigger);
#endif
    FREE_THREADQUEUE(q);
}                                      /*}}} */
Exemplo n.º 13
0
// old public method; added last param to distinguish between put and put if absent
static inline hash_entry *qt_hash_put(qt_hash  h,
                                      qt_key_t key,
                                      void    *value,
                                      int      put_choice)
{
    hash_entry *node = qpool_alloc(hash_entry_pool);
    hash_entry *ret  = node;
    size_t      bucket;
    uint64_t    lkey = (uint64_t)(uintptr_t)(h->op_hash(key));

    HASH_KEY(lkey);
    bucket = lkey % h->size;

    assert(node);
    assert((lkey & MSB) == 0);
    node->hashed_key = so_regularkey(lkey);
    node->key        = key; // Also store original key!
    node->value      = value;
    node->next       = (hash_entry*)UNINITIALIZED;

    if (h->B[bucket] == UNINITIALIZED) {
        initialize_bucket(h, bucket);
    }

    if(put_choice == PUT_IF_ABSENT) {
        if (!qt_lf_list_insert(&(h->B[bucket]), node, NULL, &ret, h->op_equals)) {
            qpool_free(hash_entry_pool, node);
            return ret->value;
        }
    } else {
        qt_lf_force_list_insert(&(h->B[bucket]), node, h->op_equals);
    }

    size_t csize = h->size;
    if (qthread_incr(&h->count, 1) / csize > MAX_LOAD) {
        if (2 * csize <= hard_max_buckets) { // this caps the size of the hash
            qthread_cas(&h->size, csize, 2 * csize);
        }
    }
    return ret->value;
}
Exemplo n.º 14
0
T mt_incr(T& target, T2 inc)
{
#ifdef __MTA__
  T res = int_fetch_add((int*) &target, inc);
#elif _OPENMP
#ifdef MTGL_ATOMIC_INCR
  T res = __sync_fetch_and_add(&target, inc);
#else
  T res;
  #pragma omp critical
  {
    res = target;
    target += inc;
  }
#endif
#elif USING_QTHREADS
  T res = qthread_incr(&target, inc);
#else
  T res = target;
  target += inc;
#endif

  return res;
}
Exemplo n.º 15
0
void chpl_sync_unlock(chpl_sync_aux_t *s)
{
    PROFILE_INCR(profile_sync_unlock, 1);

    qthread_incr(&s->lockers_out, 1);
}
Exemplo n.º 16
0
static void sum(const size_t startat,
                const size_t stopat,
                void        *arg_)
{
    qthread_incr(&threads, stopat - startat);
}
Exemplo n.º 17
0
static aligned_t assign1(void *arg)
{
    *(double *)arg = 1.0;
    qthread_incr(&count, 1);
    return 0;
}
Exemplo n.º 18
0
static aligned_t assignall1(void *arg)
{
    memset(arg, 1, sizeof(bigobj));
    qthread_incr(&count, 1);
    return 0;
}