ptst_t *critical_enter(gc_global_t *gc_global) { ptst_t *ptst, *next, *new_next; #ifdef NEED_ID unsigned int id, oid; #endif ptst = (ptst_t *)pthread_getspecific(gc_global->ptst_key); if ( ptst == NULL ) { for ( ptst = _ptst_first(gc_global); ptst != NULL; ptst = ptst_next(ptst) ) { if ( (ptst->count == 0) && (CASIO(&ptst->count, 0, 1) == 0) ) { break; } } if ( ptst == NULL ) { ptst = ALIGNED_ALLOC(sizeof(*ptst)); if ( ptst == NULL ) exit(1); memset(ptst, 0, sizeof(*ptst)); ptst->gc = gc_init(gc_global); rand_init(ptst); ptst->count = 1; #ifdef NEED_ID id = gc_global->next_id; while ( (oid = CASIO(&gc_global->next_id, id, id+1)) != id ) id = oid; ptst->id = id; #endif new_next = gc_global->ptst_list; do { ptst->next = next = new_next; WMB_NEAR_CAS(); } while ( (new_next = CASPO(&gc_global->ptst_list, next, ptst)) != next ); } pthread_setspecific(gc_global->ptst_key, ptst); } gc_enter(ptst); return(ptst); }
static otag_t * tag_opaque(otype_t type, otagtype_t tag_type) { otag_t *tag; oobject_t object; oobject_t *pointer; gc_enter(); gc_ref(pointer); onew_word(pointer, type); object = *pointer; gc_ref(pointer); onew(pointer, tag); tag = *pointer; tag->name = object; tag->type = tag_type; tag->size = sizeof(oobject_t); oput_hash(tag_table, (oentry_t *)tag); gc_leave(); return (tag); }