void load_pedigree_leaf_into_user_worker(__cilkrts_worker *w) { __cilkrts_pedigree *pedigree_leaf; CILK_ASSERT(w->l->type == WORKER_USER); pedigree_leaf = __cilkrts_get_tls_pedigree_leaf(1); w->pedigree = *pedigree_leaf; // Save a pointer to the old leaf. // We'll need to restore it later. CILK_ASSERT(w->l->original_pedigree_leaf == NULL); w->l->original_pedigree_leaf = pedigree_leaf; __cilkrts_set_tls_pedigree_leaf(&w->pedigree); // Check that this new pedigree root has at least two values. CILK_ASSERT(w->pedigree.parent); CILK_ASSERT(w->pedigree.parent->parent == NULL); }
COMMON_SYSDEP __cilkrts_pedigree *__cilkrts_get_tls_pedigree_leaf(int create_new) { __cilkrts_pedigree *pedigree_tls; if (__builtin_expect(cilk_keys_defined, 1)) { pedigree_tls = (struct __cilkrts_pedigree *)pthread_getspecific(pedigree_leaf_key); } else { return 0; } if (!pedigree_tls && create_new) { // This call creates two nodes, X and Y. // X == pedigree_tls[0] is the leaf node, which gets copied // in and out of a user worker w when w binds and unbinds. // Y == pedigree_tls[1] is the root node, // which is a constant node that represents the user worker // thread w. pedigree_tls = (__cilkrts_pedigree*) __cilkrts_malloc(2 * sizeof(__cilkrts_pedigree)); // This call sets the TLS pointer to the new node. __cilkrts_set_tls_pedigree_leaf(pedigree_tls); pedigree_tls[0].rank = 0; pedigree_tls[0].parent = &pedigree_tls[1]; // Create Y, whose rank begins as the global counter value. pedigree_tls[1].rank = __sync_add_and_fetch(&__cilkrts_global_pedigree_tls_counter, 1); pedigree_tls[1].parent = NULL; CILK_ASSERT(pedigree_tls[1].rank != -1); } return pedigree_tls; }
void save_pedigree_leaf_from_user_worker(__cilkrts_worker *w) { CILK_ASSERT(w->l->type == WORKER_USER); // Existing leaf in tls should be for the current worker. // This assert is expensive to check though. // CILK_ASSERT(&w->pedigree == __cilkrts_get_tls_pedigree_leaf(0)); CILK_ASSERT(w->l->original_pedigree_leaf); // w should finish with a pedigree node that points to // the same root that we just looked up. // TODO: This assert should be valid. // But we are removing it now to make exceptions (without pedigrees) work. // Currently, reading the pedigree after an exception is caught // fails because the pedigree chain not restored correctly. // CILK_ASSERT(w->l->original_pedigree_leaf->next == w->pedigree.parent); w->l->original_pedigree_leaf->rank = w->pedigree.rank; // Save that leaf pointer back into tls. __cilkrts_set_tls_pedigree_leaf(w->l->original_pedigree_leaf); // Null out worker's leaf for paranoia. w->l->original_pedigree_leaf = NULL; }
void __cilkrts_set_pedigree_leaf(__cilkrts_pedigree *leaf) { __cilkrts_set_tls_pedigree_leaf(leaf); }