void print_class(const struct tesla_class *c) { static const char *DEBUG_NAME = "libtesla.class.state"; if (!tesla_debugging(DEBUG_NAME)) return; print("----\n"); print("struct tesla_class @ 0x%tx {\n", (intptr_t) c); print(" name: '%s',\n", c->tc_automaton->ta_name); print(" description: '[...]',\n"); // TL;DR print(" scope: "); switch (c->tc_context) { case TESLA_CONTEXT_THREAD: print("thread-local\n"); break; case TESLA_CONTEXT_GLOBAL: print("global\n"); break; default: print("UNKNOWN (0x%x)\n", c->tc_context); } print(" limit: %d\n", c->tc_limit); print(" %d/%d instances\n", c->tc_limit - c->tc_free, c->tc_limit); for (uint32_t i = 0; i < c->tc_limit; i++) { const struct tesla_instance *inst = c->tc_instances + i; if (!tesla_instance_active(inst)) continue; print(" %2u: state %d, ", i, inst->ti_state); print_key(DEBUG_NAME, &inst->ti_key); print("\n"); } print("}\n"); print("----\n"); }
static void no_instance(struct tesla_class *tcp, uint32_t symbol, const struct tesla_key *tkp) { char instbuf[200]; char *c = instbuf; const char *end = instbuf + sizeof(instbuf); SAFE_SPRINTF(c, end, "%d/%d instances\n", tcp->tc_limit - tcp->tc_free, tcp->tc_limit); for (uint32_t i = 0; i < tcp->tc_limit; i++) { const struct tesla_instance *inst = tcp->tc_instances + i; if (!tesla_instance_active(inst)) continue; SAFE_SPRINTF(c, end, " %2u: state %d, ", i, inst->ti_state); c = key_string(c, end, &inst->ti_key); SAFE_SPRINTF(c, end, "\n"); } char keybuf[20]; key_string(keybuf, keybuf + sizeof(keybuf), tkp); SDT_PROBE(tesla, automata, fail, no_instance, tcp, instbuf, symbol, keybuf, 0); }
static void check_store(struct tesla_store *store) { assert(store != NULL); struct tesla_class *classes[CLASSES]; for (unsigned int i = 0; i < CLASSES; i++) { check(tesla_class_get(store, i, classes + i, name(i), desc(i))); struct tesla_instance *instance; struct tesla_key key; key.tk_mask = 1; key.tk_keys[0] = 42 + i; register_t state = 2 * i + 42; check(tesla_instance_new(classes[i], &key, state, &instance)); assert(instance != NULL); assert(tesla_instance_active(instance)); assert(instance->ti_state == 2 * i + 42); assert(instance->ti_key.tk_mask == 1); assert(instance->ti_key.tk_keys[0] == 42 + i); tesla_class_put(classes[i]); } void *JUNK = (void*) 0xF00BA5; struct tesla_class *junk = JUNK; int err = tesla_class_get(store, CLASSES, &junk, "foo", "bar"); if (err != TESLA_ERROR_EINVAL) errx(1, "tesla_class_get() did not report EINVAL: %s", tesla_strerror(err)); if (junk != JUNK) errx(1, "tesla_class_get() clobbered output variable when" " returning an error"); }