static void bhv_setTag(struct Behavior *bhv) { if (bhv->Object.Any._id) { // generics case struct Generic *gen = CAST(struct Generic*, bhv); if (bhv->id) cos_abort("generic '%s' at (%s,%d) has already an id", gen_name(gen), gen_file(gen), gen_line(gen)); if ( (bhv->Object.Any._id & COS_ID_TAGMSK) ) cos_abort("generic '%s' at (%s,%d) has invalid initialization", gen_name(gen), gen_file(gen), gen_line(gen)); bhv->id = bhv->Object.Any._id | bhv_tag(); bhv->Object.Any._id = 0; } else { // classes case
struct cos_method_cache2* cos_method_cache2_init(void) { struct cos_method_cache2 *cache; pthread_once(&cos_method_cache2_key_once, make_key); cos_method_cache2_key_init = 1; if (!(cache = malloc(sizeof *cache))) cos_abort("out of memory while creating dispatcher cache2"); cache->slot = &cache_empty; cache->msk = 0; cache->mis = 0; cache->mis2 = 0; if ( pthread_setspecific(cos_method_cache2_key, cache) ) cos_abort("unable to initialize dispatcher cache2"); return cache; }
static inline U32 bhv_tag(void) { static U32 x = 1; x = x * 2621124293u + 1; // group generator for any \frac{\setN}{2^k\setN}, k=1..32 if (x == COS_ID_TENMEGA) // keep the rest for dynamic behaviors (dynamic classes) cos_abort("too many static behaviors (>10000000)"); return x & COS_ID_TAGMSK; // use only the 27 lower bits (134217727 ids) }
static void enlarge_cache(void) { struct cos_method_cache2 *cache = cos_method_cache2(); U32 i, n; n = cache->msk ? (cache->msk+1)*2 : 512; cos_method_clearCache2(); cache->slot = malloc(n * sizeof *cache->slot); if (!cache->slot) cos_abort("method2_lookup: out of memory"); for (i = 0; i < n; i++) cache->slot[i] = &sentinel; cache->msk = n-1; }
static void enlarge_slot(struct cos_method_slot1 **slot) { U32 i, n = first_cell(slot); *slot = realloc(n ? *slot : 0, (n+1) * sizeof **slot); if (!*slot) cos_abort("method1_lookup: out of memory"); for (i = 0; i < (n+1); i++) { (*slot)[i].nxt = *slot+i+1; // Ok: see C99 6.5.6-8 (*slot)[i].fct = init; (*slot)[i].idg = 0; (*slot)[i].id1 = 0; } (*slot)[n].nxt = &sentinel; }
static void make_key(void) { if ( pthread_key_create(&cos_method_cache2_key, free) ) cos_abort("unable to initialize dispatcher cache2"); }