Date: Tue, 4 Jun 2013 15:48:19 GMT From: Jonathan Anderson <jonathan@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 229368 for review Message-ID: <201306041548.r54FmJw9086252@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@229368?ac=10 Change 229368 by jonathan@jonathan-on-joe on 2013/06/04 15:47:30 Incorporate latest libtesla parts into /lib/libtesla. Affected files ... .. //depot/projects/ctsrd/tesla/src/lib/libtesla/libtesla.h#6 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla.h#6 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_class.c#2 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_debug.c#2 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_dtrace.c#3 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_internal.h#7 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_notification.c#5 edit .. //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_update.c#2 edit Differences ... ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/libtesla.h#6 (text+ko) ==== @@ -34,6 +34,12 @@ #ifndef _TESLA_STATE #define _TESLA_STATE +/** + * Support library for TESLA instrumentation. + * @addtogroup libtesla + * @{ + */ + #ifdef _KERNEL #include <sys/types.h> #else @@ -180,7 +186,7 @@ /** * Check to see if a key matches a pattern. * - * @returns 1 if @ref #k matches @ref pattern, 0 otherwise + * @returns 1 if @a k matches @a pattern, 0 otherwise */ int32_t tesla_key_matches( const struct tesla_key *pattern, const struct tesla_key *k); @@ -236,4 +242,48 @@ void tesla_instance_destroy(struct tesla_class *tsp, struct tesla_instance *tip); + +/* + * Event notification: + */ +/** A new @ref tesla_instance has been created. */ +typedef void (*tesla_ev_new_instance)(struct tesla_class *, + struct tesla_instance *); + +/** A @ref tesla_instance has taken a transition. */ +typedef void (*tesla_ev_transition)(struct tesla_class *, + struct tesla_instance *, const struct tesla_transition*); + +/** An exisiting @ref tesla_instance has been cloned because of an event. */ +typedef void (*tesla_ev_clone)(struct tesla_class *, + struct tesla_instance *orig, struct tesla_instance *copy, + const struct tesla_transition*); + +/** No @ref tesla_class instance was found to match a @ref tesla_key. */ +typedef void (*tesla_ev_no_instance)(struct tesla_class *, + const struct tesla_key *, const struct tesla_transitions *); + +/** A @ref tesla_instance is not in the right state to take a transition. */ +typedef void (*tesla_ev_bad_transition)(struct tesla_class *, + struct tesla_instance *, const struct tesla_transitions *); + +/** A @ref tesla_instance has accepted a sequence of events. */ +typedef void (*tesla_ev_accept)(struct tesla_class *, + struct tesla_instance *); + +/** A vector of event handlers. */ +struct tesla_event_handlers { + tesla_ev_new_instance teh_init; + tesla_ev_transition teh_transition; + tesla_ev_clone teh_clone; + tesla_ev_no_instance teh_fail_no_instance; + tesla_ev_bad_transition teh_bad_transition; + tesla_ev_accept teh_accept; +}; + +/** Register a set of event handlers. */ +int tesla_set_event_handlers(struct tesla_event_handlers *); + +/** @} */ + #endif /* _TESLA_STATE */ ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla.h#6 (text+ko) ==== @@ -28,10 +28,25 @@ * SUCH DAMAGE. */ +/** + * @mainpage TESLA API documentation + * + * This is the API documentation for TESLA's programmer interface + * (@ref ConsumerAPI), runtime support library (@ref libtesla) and + * analysis/instrumentation implementation. + */ + #ifndef TESLA_H #define TESLA_H -/** Basic TESLA types (magic for the compiler to munge). */ +/** + * API for programmers who want to use TESLA in their code. + * + * @addtogroup ConsumerAPI + * @{ + */ + +/** The basic TESLA type is a pointer to a TESLA Basic TESLA types (magic for the compiler to munge). */ typedef struct __tesla_event {} __tesla_event; typedef struct __tesla_locality {} __tesla_locality; @@ -144,7 +159,7 @@ /** * Declare that a struct's behaviour is described by an automaton. * - * @param struct_name name of the struct that uses the automaton + * @param subject name of the struct that uses the automaton * @param automaton reference to the automaton description * @param loc a TESLA locality (global, per-thread...) * @param start event that kicks off the automaton @@ -198,5 +213,6 @@ #endif /* __TESLA_ANALYSER__ */ +/** @} */ + #endif /* TESLA_H */ - ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_class.c#2 (text+ko) ==== @@ -53,12 +53,6 @@ tclass->tc_limit = instances; -#ifdef _KERNEL - tclass->tc_action = TESLA_ACTION_PRINTF; -#else - tclass->tc_action = TESLA_ACTION_FAILSTOP; -#endif - tclass->tc_scope = context; tclass->tc_limit = instances; tclass->tc_free = instances; ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_debug.c#2 (text+ko) ==== @@ -1,4 +1,4 @@ -/** @file debug.c Debugging helpers for TESLA state. */ +/** @file tesla_debug.c Debugging helpers for TESLA state. */ /*- * Copyright (c) 2012-2013 Jonathan Anderson * All rights reserved. @@ -194,14 +194,6 @@ default: print("UNKNOWN (0x%x)\n", c->tc_scope); } print(" limit: %d\n", c->tc_limit); - print(" fail action: "); - switch (c->tc_action) { - case TESLA_ACTION_FAILSTOP: print("fail-stop\n"); break; - case TESLA_ACTION_DTRACE: print("DTrace probe\n"); break; - case TESLA_ACTION_PRINTF: print("printf()\n"); break; - default: print("UNKNOWN (0x%x)\n", c->tc_action); - } - 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; ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_dtrace.c#3 (text+ko) ==== @@ -37,70 +37,77 @@ #include <sys/sdt.h> SDT_PROVIDER_DEFINE(tesla); -SDT_PROBE_DEFINE2(tesla, kernel, , state_transition, state-transition, + +SDT_PROBE_DEFINE2(tesla, kernel, notify, new_instance, new-instance, + "struct tesla_class *", "struct tesla_instance *"); +SDT_PROBE_DEFINE3(tesla, kernel, notify, transition, transition, + "struct tesla_class *", "struct tesla_instance *", + "struct tesla_transition *"); +SDT_PROBE_DEFINE4(tesla, kernel, notify, clone, clone, + "struct tesla_class *", "struct tesla_instance *", + "struct tesla_instance *", "struct tesla_transition *"); +SDT_PROBE_DEFINE3(tesla, kernel, notify, no_instance, no-instance-match, + "struct tesla_class *", "struct tesla_key *", + "struct tesla_transitions *"); +SDT_PROBE_DEFINE3(tesla, kernel, notify, bad_transition, bad-transition, + "struct tesla_class *", "struct tesla_instance *", + "struct tesla_transitions *"); +SDT_PROBE_DEFINE2(tesla, kernel, notify, accept, accept, "struct tesla_class *", "struct tesla_instance *"); -SDT_PROBE_DEFINE2(tesla, kernel, assert, fail, fail, "struct tesla_class *", - "struct tesla_instance *"); -SDT_PROBE_DEFINE2(tesla, kernel, assert, pass, pass, "struct tesla_class *", - "struct tesla_instance *"); -void -tesla_state_transition_dtrace(struct tesla_class *tcp, - struct tesla_instance *tip, - __unused const struct tesla_transition *transp) +static void +new_instance(struct tesla_class *tcp, struct tesla_instance *tip) { - SDT_PROBE(tesla, kernel, , state_transition, tcp, tip, 0, 0, 0); + SDT_PROBE(tesla, kernel, assert, new_instance, tcp, tip, 0, 0, 0); } -void -tesla_assert_fail_dtrace(struct tesla_class *tcp, struct tesla_instance *tip, - __unused const struct tesla_transitions *transp) +static void +transition(struct tesla_class *tcp, struct tesla_instance *tip, + const struct tesla_transition *ttp) { - if (tip) - SDT_PROBE(tesla, kernel, assert, fail, tcp, tip, 0, 0, 0); - - /* XXXRW: - * 'tip' could be NULL if we failed to match any automaton instances - * to go with a supplied key; perhaps a separate probe? - */ + SDT_PROBE(tesla, kernel, notify, transition, tcp, tip, ttp, 0, 0); } -void -tesla_assert_pass_dtrace(struct tesla_class *tcp, struct tesla_instance *tip) +static void +clone(struct tesla_class *tcp, struct tesla_instance *origp, + struct tesla_instance *copyp, const struct tesla_transition *ttp) { - SDT_PROBE(tesla, kernel, assert, pass, tcp, tip, 0, 0, 0); + SDT_PROBE(tesla, kernel, notify, clone, tcp, origp, copyp, ttp, 0); } -#else /* !_KERNEL */ - -void -tesla_state_transition_dtrace(__unused struct tesla_class *tcp, - __unused struct tesla_instance *tip, - __unused const struct tesla_transition *transp) +static void +no_instance(struct tesla_class *tcp, const struct tesla_key *tkp, + const struct tesla_transitions *) { - assert(0 && "DTrace not implemented in userspace"); + SDT_PROBE(tesla, kernel, notify, no_instance, tcp, tkp, ttp, 0, 0); } -void -tesla_assert_fail_dtrace(__unused struct tesla_class *tcp, - __unused struct tesla_instance *tip, - __unused const struct tesla_transitions *transp) +static void +bad_transition(struct tesla_class *tcp, struct tesla_instance *tip, + const struct tesla_transitions *ttp) { - assert(0 && "DTrace not implemented in userspace"); + SDT_PROBE(tesla, kernel, notify, bad_transition, tcp, tip, ttp, 0, 0); } -void -tesla_assert_pass_dtrace(__unused struct tesla_class *tcp, - __unused struct tesla_instance *tip) +static void +accept(struct tesla_class *tcp, struct tesla_instance *tip) { - assert(0 && "DTrace not implemented in userspace"); + SDT_PROBE(tesla, kernel, notify, accept, tcp, tip, 0, 0, 0); } +struct tesla_event_handlers dtrace_handler = { + .teh_init = new_instance, + .teh_transition = transition, + .teh_clone = clone, + .teh_fail_no_instance = no_instance, + .teh_fail_bad_transition = bad_transition, + .teh_accept = accept +}; + #endif /* _KERNEL */ - ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_internal.h#7 (text+ko) ==== @@ -33,6 +33,11 @@ #ifndef TESLA_INTERNAL_H #define TESLA_INTERNAL_H +/** + * @addtogroup libtesla + * @{ + */ + #include "config.h" #ifdef _KERNEL @@ -61,7 +66,7 @@ #include <libtesla.h> #endif -//! Is @ref x a subset of @ref y? +/** Is @a x a subset of @a y? */ #define SUBSET(x,y) ((x & y) == x) /** @@ -129,7 +134,7 @@ const struct tesla_key*, const struct tesla_transitions*, const struct tesla_transition** trigger); -/** Copy new entries from @ref source into @ref dest. */ +/** Copy new entries from @a source into @a dest. */ int32_t tesla_key_union(struct tesla_key *dest, const struct tesla_key *source); @@ -161,10 +166,10 @@ #else /* !_KERNEL */ -/** @ref errx() is the userspace equivalent of panic(). */ +/** @a errx() is the userspace equivalent of panic(). */ #define tesla_panic(...) errx(1, __VA_ARGS__) -/** POSIX @ref assert() doesn't let us provide an error message. */ +/** POSIX @a assert() doesn't let us provide an error message. */ #define tesla_assert(condition, ...) assert(condition) #define tesla_malloc(len) calloc(1, len) @@ -188,7 +193,6 @@ const char *tc_description;/* Description of the assertion. */ uint32_t tc_scope; /* Per-thread or global. */ uint32_t tc_limit; /* Simultaneous automata limit. */ - uint32_t tc_action; /* What to do on failure. */ struct tesla_instance *tc_instances; /* Instances of this class. */ uint32_t tc_free; /* Unused instances. */ @@ -233,12 +237,6 @@ int tesla_class_init(struct tesla_class*, uint32_t context, uint32_t instances); -#if 0 -//! We have failed to find an instance that matches a @ref tesla_key. -void tesla_match_fail(struct tesla_class*, const struct tesla_key*, - const struct tesla_transitions*); -#endif - /* * XXXRW: temporarily, maximum number of classes and instances are hard-coded * constants. In the future, this should somehow be more dynamic. @@ -268,7 +266,7 @@ void tesla_class_global_release(struct tesla_class*); void tesla_class_global_destroy(struct tesla_class*); -int32_t tesla_class_perthread_postinit(struct tesla_class*c); +int32_t tesla_class_perthread_postinit(struct tesla_class*); void tesla_class_perthread_acquire(struct tesla_class*); void tesla_class_perthread_release(struct tesla_class*); void tesla_class_perthread_destroy(struct tesla_class*); @@ -276,44 +274,19 @@ /* * Event notification: */ -/** A new @ref tesla_instance has been created. */ -void tesla_notify_new_instance(struct tesla_class *, - struct tesla_instance *); +extern struct tesla_event_handlers *ev_handlers; +extern struct tesla_event_handlers failstop_handlers; +extern struct tesla_event_handlers printf_handlers; -/** A @ref tesla_instance has taken an expected transition. */ -void tesla_notify_transition(struct tesla_class *, struct tesla_instance *, - const struct tesla_transition*); +#ifdef _KERNEL +extern struct tesla_event_handlers dtrace_handlers; +#endif -/** An exisiting @ref tesla_instance has been cloned because of an event. */ -void tesla_notify_clone(struct tesla_class *, - struct tesla_instance *old_instance, struct tesla_instance *new_instance, - const struct tesla_transition*); - -/** A @ref tesla_instance was unable to take any of a set of transitions. */ -void tesla_notify_assert_fail(struct tesla_class *, struct tesla_instance *, - const struct tesla_transitions *); - -/** No @ref tesla_class instance was found to match a @ref tesla_key. */ -void tesla_notify_match_fail(struct tesla_class *, const struct tesla_key *, - const struct tesla_transitions *); - -/** A @ref tesla_instance has "passed" (worked through the automaton). */ -void tesla_notify_pass(struct tesla_class *, struct tesla_instance *); - -/* - * DTrace notifications of various events. - */ -void tesla_state_transition_dtrace(struct tesla_class *, - struct tesla_instance *, const struct tesla_transition *); -void tesla_assert_fail_dtrace(struct tesla_class *, - struct tesla_instance *, const struct tesla_transitions *); -void tesla_assert_pass_dtrace(struct tesla_class *, - struct tesla_instance *); - /* * Debug helpers. */ +/** Do a @a sprintf() into a buffer, checking bounds appropriately. */ #define SAFE_SPRINTF(current, end, ...) do { \ int written = snprintf(current, end - current, __VA_ARGS__); \ if ((written > 0) && (current + written < end)) \ @@ -341,6 +314,7 @@ /** Are we in (verbose) debug mode? */ int32_t tesla_debugging(const char*); +/** Emit debugging information with a debug name (e.g., libtesla.event). */ #define DEBUG(dclass, ...) \ if (tesla_debugging(#dclass)) printf(__VA_ARGS__) @@ -358,10 +332,10 @@ * Assert that a @ref tesla_instance is an instance of a @ref tesla_class. * * This could be expensive (a linear walk over all @ref tesla_instance in - * @ref #tclass), so it should only be called from debug code. + * @a tclass), so it should only be called from debug code. * * @param i the instance to test - * @param tclass the expected class of @ref #i + * @param tclass the expected class of @a i */ void assert_instanceof(struct tesla_instance *i, struct tesla_class *tclass); @@ -388,4 +362,6 @@ char* sprint_transitions(char *buffer, const char *end, const struct tesla_transitions *); +/** @} */ + #endif /* TESLA_INTERNAL_H */ ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_notification.c#5 (text+ko) ==== @@ -34,97 +34,166 @@ #define ERROR_BUFFER_LENGTH 1024 +int +tesla_set_event_handlers(struct tesla_event_handlers *tehp) +{ + + if (!tehp || !tehp->teh_init || !tehp->teh_transition + || !tehp->teh_clone || !tehp->teh_fail_no_instance + || !tehp->teh_bad_transition + || !tehp->teh_accept) + return (TESLA_ERROR_EINVAL); + + ev_handlers = tehp; + return (TESLA_SUCCESS); +} + +/* + * printf()-based event handlers: + */ +static void print_new_instance(struct tesla_class *, + struct tesla_instance *); + +static void print_transition_taken(struct tesla_class *, + struct tesla_instance *, const struct tesla_transition*); + +static void print_clone(struct tesla_class *, + struct tesla_instance *orig, struct tesla_instance *copy, + const struct tesla_transition*); + +static void print_no_instance(struct tesla_class *, + const struct tesla_key *, const struct tesla_transitions *); + +static void print_bad_transition(struct tesla_class *, + struct tesla_instance *, const struct tesla_transitions *); + +static void print_accept(struct tesla_class *, struct tesla_instance *); + +struct tesla_event_handlers printf_handlers = { + .teh_init = print_new_instance, + .teh_transition = print_transition_taken, + .teh_clone = print_clone, + .teh_fail_no_instance = print_no_instance, + .teh_bad_transition = print_bad_transition, + .teh_accept = print_accept +}; + + +/* + * Wrappers that panic on failure: + */ +static void panic_no_instance(struct tesla_class *, + const struct tesla_key *, const struct tesla_transitions *); + +static void panic_bad_transition(struct tesla_class *, + struct tesla_instance *, const struct tesla_transitions *); + +struct tesla_event_handlers failstop_handlers = { + .teh_init = print_new_instance, + .teh_transition = print_transition_taken, + .teh_clone = print_clone, + .teh_fail_no_instance = panic_no_instance, + .teh_bad_transition = panic_bad_transition, + .teh_accept = print_accept +}; + + +/** Default to print-with-failstop in userspace, DTrace in the kernel. */ +struct tesla_event_handlers *ev_handlers = +#ifdef _KERNEL + &dtrace_handlers +#else + &failstop_handlers +#endif + ; + static void print_failure_header(const struct tesla_class *); + void -tesla_notify_new_instance(struct tesla_class *tcp, - struct tesla_instance *tip) +print_new_instance(struct tesla_class *tcp, struct tesla_instance *tip) { - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - /* XXXRW: more fine-grained DTrace probes? */ - tesla_state_transition_dtrace(tcp, tip, NULL); - return; + DEBUG(libtesla.instance.new, "new %td: %tx\n", + tip - tcp->tc_instances, tip->ti_state); +} - default: - /* for the PRINTF action, should this be a non-verbose print? */ - DEBUG(libtesla.instance.new, "new %td: %tx\n", - tip - tcp->tc_instances, tip->ti_state); +void +print_transition_taken(struct tesla_class *tcp, + struct tesla_instance *tip, const struct tesla_transition *transp) +{ - /* - * XXXJA: convince self that we can never "pass" an assertion - * with an event that creates a new instance - */ - - break; - } + DEBUG(libtesla.state.transition, "update %td: %tx->%tx\n", + tip - tcp->tc_instances, transp->from, transp->to); } void -tesla_notify_clone(struct tesla_class *tcp, +print_clone(struct tesla_class *tcp, struct tesla_instance *old_instance, struct tesla_instance *new_instance, const struct tesla_transition *transp) { - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - /* XXXRW: more fine-grained DTrace probes? */ - tesla_state_transition_dtrace(tcp, new_instance, transp); - return; + DEBUG(libtesla.instance.clone, "clone %td:%tx -> %td:%tx\n", + old_instance - tcp->tc_instances, transp->from, + new_instance - tcp->tc_instances, transp->to); +} + +static void +no_instance_message(char *buffer, const char *end, + struct tesla_class *tcp, const struct tesla_key *tkp, + const struct tesla_transitions *transp) +{ + + assert(tcp != NULL); + assert(tkp != NULL); - default: { - DEBUG(libtesla.instance.clone, "clone %td:%tx -> %td:%tx\n", - old_instance - tcp->tc_instances, transp->from, - new_instance - tcp->tc_instances, transp->to); + print_failure_header(tcp); - if (transp->flags & TESLA_TRANS_CLEANUP) - tesla_notify_pass(tcp, new_instance); + char *next = buffer; - break; - } - } + SAFE_SPRINTF(next, end, "No instance matched key '"); + next = key_string(next, end, tkp); + SAFE_SPRINTF(next, end, "' for transition(s) "); + next = sprint_transitions(next, end, transp); + assert(next > buffer); } void -tesla_notify_transition(struct tesla_class *tcp, - struct tesla_instance *tip, const struct tesla_transition *transp) +print_no_instance(struct tesla_class *tcp, const struct tesla_key *tkp, + const struct tesla_transitions *transp) { - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - tesla_state_transition_dtrace(tcp, tip, transp); - return; + char buffer[ERROR_BUFFER_LENGTH]; + const char *end = buffer + sizeof(buffer); + + no_instance_message(buffer, end, tcp, tkp, transp); + error("%s", buffer); +} - default: { - DEBUG(libtesla.state.transition, "update %td: %tx->%tx\n", - tip - tcp->tc_instances, transp->from, transp->to); +void +panic_no_instance(struct tesla_class *tcp, const struct tesla_key *tkp, + const struct tesla_transitions *transp) +{ - if (transp->flags & TESLA_TRANS_CLEANUP) - tesla_notify_pass(tcp, tip); + char buffer[ERROR_BUFFER_LENGTH]; + const char *end = buffer + sizeof(buffer); - break; - } - } + no_instance_message(buffer, end, tcp, tkp, transp); + tesla_panic("%s", buffer); } -void -tesla_notify_assert_fail(struct tesla_class *tcp, struct tesla_instance *tip, +static void +bad_transition_message(char *buffer, const char *end, + struct tesla_class *tcp, struct tesla_instance *tip, const struct tesla_transitions *transp) { + assert(tcp != NULL); assert(tip != NULL); - if (tcp->tc_action == TESLA_ACTION_DTRACE) { - tesla_assert_fail_dtrace(tcp, tip, transp); - return; - } - print_failure_header(tcp); - char buffer[ERROR_BUFFER_LENGTH]; char *next = buffer; - const char *end = buffer + sizeof(buffer); SAFE_SPRINTF(next, end, "Instance %td is in state %d\n" @@ -134,76 +203,39 @@ next = sprint_transitions(next, end, transp); assert(next > buffer); +} - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - assert(0 && "handled above"); - return; +void +print_bad_transition(struct tesla_class *tcp, struct tesla_instance *tip, + const struct tesla_transitions *transp) +{ - case TESLA_ACTION_FAILSTOP: - tesla_panic("%s", buffer); - break; + char buffer[ERROR_BUFFER_LENGTH]; + const char *end = buffer + sizeof(buffer); - case TESLA_ACTION_PRINTF: - error("%s", buffer); - break; - } + bad_transition_message(buffer, end, tcp, tip, transp); + error("%s", buffer); } void -tesla_notify_match_fail(struct tesla_class *tcp, const struct tesla_key *tkp, +panic_bad_transition(struct tesla_class *tcp, struct tesla_instance *tip, const struct tesla_transitions *transp) { - assert(tcp != NULL); - assert(tkp != NULL); - if (tcp->tc_action == TESLA_ACTION_DTRACE) { - tesla_assert_fail_dtrace(tcp, NULL, NULL); - return; - } - - print_failure_header(tcp); - char buffer[ERROR_BUFFER_LENGTH]; - char *next = buffer; const char *end = buffer + sizeof(buffer); - SAFE_SPRINTF(next, end, "No instance matched key '"); - next = key_string(next, end, tkp); - SAFE_SPRINTF(next, end, "' for transition(s) "); - next = sprint_transitions(next, end, transp); - assert(next > buffer); - - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - assert(0 && "handled above"); - break; - - case TESLA_ACTION_FAILSTOP: - tesla_panic("%s", buffer); - break; - - case TESLA_ACTION_PRINTF: - error("%s", buffer); - break; - } + bad_transition_message(buffer, end, tcp, tip, transp); + tesla_panic("%s", buffer); } void -tesla_notify_pass(struct tesla_class *tcp, struct tesla_instance *tip) +print_accept(struct tesla_class *tcp, struct tesla_instance *tip) { - switch (tcp->tc_action) { - case TESLA_ACTION_DTRACE: - tesla_assert_pass_dtrace(tcp, tip); - return; - - default: - DEBUG(libtesla.instance.success, - "pass '%s': %td\n", tcp->tc_name, - tip - tcp->tc_instances); - break; - } + DEBUG(libtesla.instance.success, + "pass '%s': %td\n", tcp->tc_name, + tip - tcp->tc_instances); } @@ -218,4 +250,3 @@ error("In automaton '%s':\n%s\n", tcp->tc_name, tcp->tc_description); } - ==== //depot/projects/ctsrd/tesla/src/lib/libtesla/tesla_update.c#2 (text+ko) ==== @@ -54,6 +54,9 @@ const char *name, const char *description, const struct tesla_transitions *trans) { + + assert(ev_handlers != NULL); + if (tesla_debugging(DEBUG_NAME)) { /* We should never see with multiple <<init>> transitions. */ int init_count = 0; @@ -111,16 +114,20 @@ switch (action) { case FAIL: - tesla_notify_assert_fail(class, inst, trans); + ev_handlers->teh_bad_transition(class, inst, trans); break; case IGNORE: break; case UPDATE: - tesla_notify_transition(class, inst, trigger); + ev_handlers->teh_transition(class, inst, trigger); inst->ti_state = trigger->to; matched_something = true; + + if (trigger->flags & TESLA_TRANS_CLEANUP) + ev_handlers->teh_accept(class, inst); + break; case FORK: { @@ -148,7 +155,10 @@ clone->ti_state = c->transition->to; - tesla_notify_clone(class, c->old, clone, c->transition); + ev_handlers->teh_clone(class, c->old, clone, c->transition); + + if (c->transition->flags & TESLA_TRANS_CLEANUP) + ev_handlers->teh_accept(class, clone); } @@ -161,7 +171,7 @@ assert(tesla_instance_active(inst)); matched_something = true; - tesla_notify_new_instance(class, inst); + ev_handlers->teh_init(class, inst); } } @@ -173,7 +183,7 @@ PRINT("\n====\n\n"); if (!matched_something) - tesla_notify_match_fail(class, pattern, trans); + ev_handlers->teh_fail_no_instance(class, pattern, trans); tesla_class_put(class);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306041548.r54FmJw9086252>
