Ejemplo n.º 1
0
/* Destroy a reducer map.  The map must have been allocated
   from the worker's global context and should have been
   allocated from the same worker. */
void __cilkrts_destroy_reducer_map(__cilkrts_worker *w, cilkred_map *h)
{
    CILK_ASSERT((w == 0 && h->g == 0) || w->g == h->g);
    verify_current_wkr(w);

    /* the reducer map is allowed to contain el->val == NULL here (and
       only here).  We set el->val == NULL only when we know that the
       map will be destroyed immediately afterwards. */
    DBG h->check(/*allow_null_val=*/true);

    bucket *b;
    size_t i;

    for (i = 0; i < h->nbuckets; ++i) {
        b = h->buckets[i];
        if (b) {
            elem *el;
            for (el = b->el; el->key; ++el) {
                if (el->val)
                    el->destroy();
            }
        }
    }

    free_buckets(w, h->buckets, h->nbuckets);

#if REDPAR_DEBUG >= 1
    fprintf(stderr, "W=%d, destroy_red_map, freeing map h=%p, size=%zd\n",
	    w->self, h, sizeof(*h));
#endif
    
    __cilkrts_frame_free(w, h, sizeof(*h));
}
Ejemplo n.º 2
0
static void free_bucket(__cilkrts_worker *w, bucket **bp)
{
    bucket *b = *bp;
    if (b) {
        __cilkrts_frame_free(w, b, sizeof_bucket(b->nmax));
        *bp = 0;
    }
}
Ejemplo n.º 3
0
void __cilkrts_setup_for_execution_sysdep(__cilkrts_worker *w, full_frame *ff)
{
    // ASSERT: We own w->lock and ff->lock || P == 1

    __cxa_eh_globals *state = __cxa_get_globals ();
    struct pending_exception_info *info = w->l->pending_exception;

    if (info == NULL)
        return;

    w->l->pending_exception = 0;

#if DEBUG_EXCEPTIONS
    _Unwind_Exception *exc = info->active;
    if (exc) {
        fflush(stdout);
        fprintf(stderr, "__cilkrts_resume_except W%u %p->%p [%u %p]\n",
                w->self, exc,
                to_cxx(exc)->nextException,
                info->runtime_state.uncaughtExceptions,
                info->runtime_state.caughtExceptions);
        /*CILK_ASSERT(info->runtime_state.uncaughtExceptions > 0);*/
    }
#endif

    if (state->uncaughtExceptions || state->caughtExceptions)
        __cilkrts_bug("W%u: resuming with non-empty prior exception state %u %p\n", state->uncaughtExceptions, state->caughtExceptions);

    *state = info->runtime_state;
    info->runtime_state.caughtExceptions = 0;
    info->runtime_state.uncaughtExceptions = 0;

    if (info->rethrow) {
        info->rethrow = false;
        /* Resuming function will rethrow.  Runtime calls
           std::terminate if there is no caught exception. */
        ff->call_stack->flags |= CILK_FRAME_EXCEPTING;
    }
    if (info->active) {
        ff->call_stack->flags |= CILK_FRAME_EXCEPTING;
        ff->call_stack->except_data = info->active;
        info->active = 0;
    }

    if (info->empty()) {
        info->destruct();
        __cilkrts_frame_free(w, info, sizeof *info);
        w->l->pending_exception = NULL;
    }

#if CILK_LIB_DEBUG
    if (ff->call_stack->except_data)
        CILK_ASSERT(std::uncaught_exception());
#endif
}
Ejemplo n.º 4
0
static void free_buckets(__cilkrts_worker  *w, 
                         bucket           **buckets,
                         size_t             nbuckets)
{
    size_t i;

#if REDPAR_DEBUG >= 1
    verify_current_wkr(w);
    fprintf(stderr, "W=%d, desc=free_buckets, buckets=%p, size=%zd\n",
	    w->self, buckets,
	    nbuckets * sizeof(*buckets));
#endif

    for (i = 0; i < nbuckets; ++i)
        free_bucket(w, buckets + i);

    __cilkrts_frame_free(w, buckets, nbuckets * sizeof(*buckets));
}
Ejemplo n.º 5
0
struct pending_exception_info *__cilkrts_get_exception(__cilkrts_worker *w,
                                                       __cilkrts_stack_frame *sf)
{
    struct pending_exception_info *info = w->l->pending_exception;

    if (info == NULL) {
        sf->flags &= ~CILK_FRAME_EXCEPTING;
        return 0;
    }

    w->l->pending_exception = NULL;

    /* This exception goes into the frame. */

    _Unwind_Exception *exc = info->active;
    info->active = NULL;
    info->destruct();
    __cilkrts_frame_free(w, info, sizeof *info);
    info = 0;
    sf->flags |= CILK_FRAME_EXCEPTING;
    sf->exception = exc;
    return 0;
}
Ejemplo n.º 6
0
struct pending_exception_info *
__cilkrts_merge_pending_exceptions (
    __cilkrts_worker *w,
    struct pending_exception_info *left,
    struct pending_exception_info *right)
{
    /* If we've only got one exception, return it */

    if (NULL == left) {
#if DEBUG_EXCEPTIONS
        if (right) {
            char buf[40];
            decode_exceptions(buf, sizeof buf, right);
            fprintf(stderr, "__cilkrts merge W%u nil %p -> %p %s\n",
                    w->self, right, right, buf);
        }
#endif
        return right;
    }

    if (NULL == right) {
#if DEBUG_EXCEPTIONS
        if (left) {
            char buf[40];
            decode_exceptions(buf, sizeof buf, left);
            fprintf(stderr, "__cilkrts merge W%u %p nil -> %p %s\n",
                    w->self, left, left, buf);
        }
#endif
        return left;
    }

#if CILK_LIB_DEBUG
    /*volatile struct pending_exception_info left_in = *left, right_in = *right;*/
    left->check();
    right->check();
#endif

#if DEBUG_EXCEPTIONS
    {
        char buf1[40], buf2[40];
        decode_exceptions(buf1, sizeof buf1, left);
        decode_exceptions(buf2, sizeof buf2, right);
        fprintf(stderr, "__cilkrts merge W%u %p %s %p %s\n",
                w->self, left, buf1, right, buf2);
    }
#endif

    /* It should not be possible for both left and right to
       have accumulated catch blocks.

       The left exception record may always have a catch
       chain it kept when its parent was stolen.

       If they are siblings, the right sibling should not
       have accumulated any net catches.  (Catch is lexically
       scoped.)

       If the right frame is a parent, it should not have entered
       a catch block without syncing first.  If it spawned in a
       catch block, the child got its catch. */
    __cxa_exception *caught = left->runtime_state.caughtExceptions;
    if (caught)
        CILK_ASSERT(!right->runtime_state.caughtExceptions);
    else {
        CILK_ASSERT(!left->rethrow);
        left->rethrow = right->rethrow;
        left->runtime_state.caughtExceptions = caught = right->runtime_state.caughtExceptions;
        right->runtime_state.caughtExceptions = NULL;
    }

    /* Merge the uncaught exception and count of uncaught exceptions. */
    const unsigned int right_uncaught = right->runtime_state.uncaughtExceptions;
    if (!left->active){
        left->active = right->active; /* could be NULL */
        right->active = 0;
        left->runtime_state.uncaughtExceptions += right_uncaught;
        if (left->active)
            /* assert is C++ exception */
            /*CILK_ASSERT(__cxxabiv1::__is_gxx_exception_class(left->active->exception_class))*/;
    } else {
        /* Subtract 1 if the right exception is being destructed. */
        left->runtime_state.uncaughtExceptions += right_uncaught - (right->active != 0);
    }

    right->destruct();
    __cilkrts_frame_free(w, right, sizeof *right);

    /* If there is no state left, return NULL. */
    if (left->empty()) {
        left->destruct();
        __cilkrts_frame_free(w, left, sizeof *left);
        left = NULL;
    }

#if CILK_LIB_DEBUG
    if (left)
        left->check();
#endif

    return left;
}