/* 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)); }
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; } }
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 }
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)); }
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; }
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; }