From owner-p4-projects@FreeBSD.ORG Thu Jun 13 15:38:21 2013 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 527C28B1; Thu, 13 Jun 2013 15:38:21 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 0E1928AF for ; Thu, 13 Jun 2013 15:38:21 +0000 (UTC) (envelope-from jonathan@freebsd.org) Received: from skunkworks.freebsd.org (skunkworks6.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) by mx1.freebsd.org (Postfix) with ESMTP id E333912BF for ; Thu, 13 Jun 2013 15:38:20 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.7/8.14.7) with ESMTP id r5DFcKqC030200 for ; Thu, 13 Jun 2013 15:38:20 GMT (envelope-from jonathan@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.7/8.14.6/Submit) id r5DFcKG6030197 for perforce@freebsd.org; Thu, 13 Jun 2013 15:38:20 GMT (envelope-from jonathan@freebsd.org) Date: Thu, 13 Jun 2013 15:38:20 GMT Message-Id: <201306131538.r5DFcKG6030197@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jonathan@freebsd.org using -f From: Jonathan Anderson Subject: PERFORCE change 229662 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.14 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 13 Jun 2013 15:38:21 -0000 http://p4web.freebsd.org/@@229662?ac=10 Change 229662 by jonathan@jonathan-on-joe on 2013/06/13 15:37:38 Update libtesla, taking care not to step on _KERNEL panic() calls. This changeset shouldn't cause any functional changes, but it is a bit of a messy diff because I have renamed some things in libtesla. Affected files ... .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/include/libtesla.h#5 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_class.c#3 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_class_global.c#2 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_debug.c#3 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_internal.h#5 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_key.c#3 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_notification.c#5 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_store.c#3 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_update.c#3 edit .. //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_util.c#3 edit Differences ... ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/include/libtesla.h#5 (text+ko) ==== @@ -46,65 +46,26 @@ #include /* int32_t, uint32_t */ #endif -/* +/** + * Error values that can be returned by libtesla functions. + * * libtesla functions mostly return error values, and therefore return - * pointers, etc, via call-by-reference arguments. These errors are modeled - * on errno(2), but a separate namespace. + * pointers, etc, via call-by-reference arguments. */ -#define TESLA_SUCCESS 0 /* Success. */ -#define TESLA_ERROR_ENOENT 1 /* Entry not found. */ -#define TESLA_ERROR_EEXIST 2 /* Entry already present. */ -#define TESLA_ERROR_ENOMEM 3 /* Insufficient memory. */ -#define TESLA_ERROR_EINVAL 4 /* Invalid parameters. */ -#define TESLA_ERROR_UNKNOWN 5 /* An unknown (e.g. platform) error. */ - -struct tesla_key; - -/** A single allowable transition in a TESLA automaton. */ -struct tesla_transition { - /** The state we are moving from. */ - uint32_t from; - - /** The mask of the state we're moving from. */ - uint32_t from_mask; - - /** The state we are moving to. */ - uint32_t to; - - /** A mask of the keys that the 'to' state should have set. */ - uint32_t to_mask; - - /** Things we may need to do on this transition. */ - int flags; +enum tesla_err_t { + TESLA_SUCCESS, /* Success. */ + TESLA_ERROR_ENOENT, /* Entry not found. */ + TESLA_ERROR_ENOMEM, /* Insufficient memory. */ + TESLA_ERROR_EINVAL, /* Invalid parameters. */ + TESLA_ERROR_UNKNOWN, /* An unknown (e.g. platform) error. */ }; -#define TESLA_TRANS_INIT 0x02 /* May need to initialise the class. */ -#define TESLA_TRANS_CLEANUP 0x04 /* Clean up the class now. */ - - /** - * A set of permissible state transitions for an automata instance. - * - * An automaton must take exactly one of these transitions. - */ -struct tesla_transitions { - /** The number of possible transitions in @ref #transitions. */ - uint32_t length; - - /** Possible transitions: exactly one must be taken. */ - struct tesla_transition *transitions; -}; - -/** Update all automata instances that match a given key to a new state. */ -int32_t tesla_update_state(uint32_t context, uint32_t class_id, - const struct tesla_key *key, const char *name, const char *description, - const struct tesla_transitions*); - -/* * Provide string versions of TESLA errors. */ const char *tesla_strerror(int32_t error); + /** * A storage container for one or more @ref tesla_class objects. * @@ -114,25 +75,35 @@ struct tesla_store; /** + * A context where TESLA data is stored. + * + * TESLA data can be stored in a number of places that imply different + * synchronisation requirements. For instance, thread-local storage does not + * require synchronisation on access, whereas global storage does. + * On the other hand, thread-local storage cannot be used to track events + * across multiple threads. + */ +enum tesla_context { + TESLA_CONTEXT_GLOBAL, + TESLA_CONTEXT_THREAD, +}; + +/** * Retrieve the @ref tesla_store for a context (e.g., a thread). * * If the @ref tesla_store does not exist yet, it will be created. * - * @param[in] context @ref TESLA_SCOPE_PERTHREAD or @ref TESLA_SCOPE_GLOBAL + * @param[in] context @ref TESLA_CONTEXT_THREAD or + * @ref TESLA_CONTEXT_GLOBAL * @param[in] classes number of @ref tesla_class'es to expect * @param[in] instances @ref tesla_instance count per @ref tesla_class * @param[out] store return parameter for @ref tesla_store pointer */ -int32_t tesla_store_get(uint32_t context, uint32_t classes, uint32_t instances, +int32_t tesla_store_get(enum tesla_context context, + uint32_t classes, uint32_t instances, struct tesla_store* *store); -/** Reset all automata in a store to the inactive state. */ -int32_t tesla_store_reset(struct tesla_store *store); - -/** Clean up a @ref tesla_store. */ -void tesla_store_free(struct tesla_store*); - /** * A description of a TESLA automaton, which may be instantiated a number of * times with different names and current states. @@ -161,8 +132,44 @@ const char *name, const char *description); +/** Release resources (e.g., locks) associated with a @ref tesla_class. */ +void tesla_class_put(struct tesla_class*); +/** A single allowable transition in a TESLA automaton. */ +struct tesla_transition { + /** The state we are moving from. */ + uint32_t from; + + /** The mask of the state we're moving from. */ + uint32_t from_mask; + + /** The state we are moving to. */ + uint32_t to; + + /** A mask of the keys that the 'to' state should have set. */ + uint32_t to_mask; + + /** Things we may need to do on this transition. */ + int flags; +}; + +#define TESLA_TRANS_INIT 0x02 /* May need to initialise the class. */ +#define TESLA_TRANS_CLEANUP 0x04 /* Clean up the class now. */ + +/** + * A set of permissible state transitions for an automata instance. + * + * An automaton must take exactly one of these transitions. + */ +struct tesla_transitions { + /** The number of possible transitions in @ref #transitions. */ + uint32_t length; + + /** Possible transitions: exactly one must be taken. */ + struct tesla_transition *transitions; +}; + #define TESLA_KEY_SIZE 4 /** @@ -183,13 +190,13 @@ uint32_t tk_mask; }; + /** - * Check to see if a key matches a pattern. - * - * @returns 1 if @a k matches @a pattern, 0 otherwise + * Update all automata instances that match a given key to a new state. */ -int32_t tesla_key_matches( - const struct tesla_key *pattern, const struct tesla_key *k); +int32_t tesla_update_state(enum tesla_context context, uint32_t class_id, + const struct tesla_key *key, const char *name, const char *description, + const struct tesla_transitions*); /** A single instance of an automaton: a name (@ref ti_key) and a state. */ @@ -198,50 +205,6 @@ uint32_t ti_state; }; -/** - * Instances of tesla_class each have a "scope", used to determine where data - * should be stored, and how it should be synchronised. - * - * Two scopes are currently supported: thread-local and global. Thread-local - * storage does not require explicit synchronisation, as accesses are - * serialised by the executing thread, whereas global storage does. On the - * other hand, thread-local storage is accessible only to the thread itself, - * so cannot be used to track events across multiple threads. Global storage - * is globally visible, but requires explicit (and potentially expensive) - * synchronisation. - */ -#define TESLA_SCOPE_PERTHREAD 1 -#define TESLA_SCOPE_GLOBAL 2 - - -/** - * Checks whether or not a TESLA automata instance is active (in use). - * - * @param i pointer to a valid @ref tesla_instance - * - * @returns 1 if active, 0 if inactive - */ -int32_t tesla_instance_active(const struct tesla_instance *i); - - -/** Clone an existing instance into a new instance. */ -int32_t tesla_instance_clone(struct tesla_class *tclass, - struct tesla_instance *original, struct tesla_instance **copy); - -/** Release resources (e.g., locks) associated with a @ref tesla_class. */ -void tesla_class_put(struct tesla_class*); - -/** Reset a @ref tesla_class for re-use from a clean state. */ -void tesla_class_reset(struct tesla_class*); - -/** - * This interface releases an instance for reuse; some types of automata will - * prefer tesla_class_reset(), which clears all instances associated with a - * particular tesla_class. - */ -void tesla_instance_destroy(struct tesla_class *tsp, - struct tesla_instance *tip); - /* * Event notification: ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_class.c#3 (text+ko) ==== @@ -43,27 +43,27 @@ int -tesla_class_init(struct tesla_class *tclass, - uint32_t context, uint32_t instances) +tesla_class_init(struct tesla_class *tclass, enum tesla_context context, + uint32_t instances) { assert(tclass != NULL); - assert(context > 0); + assert(context >= 0); assert(instances > 0); // TODO: write a TESLA assertion about locking here. tclass->tc_limit = instances; - tclass->tc_scope = context; + tclass->tc_context = context; tclass->tc_limit = instances; tclass->tc_free = instances; tclass->tc_instances = tesla_malloc(instances * sizeof(tclass->tc_instances[0])); switch (context) { - case TESLA_SCOPE_GLOBAL: + case TESLA_CONTEXT_GLOBAL: return tesla_class_global_postinit(tclass); - case TESLA_SCOPE_PERTHREAD: + case TESLA_CONTEXT_THREAD: return tesla_class_perthread_postinit(tclass); default: @@ -77,12 +77,12 @@ tesla_class_destroy(struct tesla_class *class) { tesla_free(class->tc_instances); - switch (class->tc_scope) { - case TESLA_SCOPE_GLOBAL: + switch (class->tc_context) { + case TESLA_CONTEXT_GLOBAL: tesla_class_global_destroy(class); break; - case TESLA_SCOPE_PERTHREAD: + case TESLA_CONTEXT_THREAD: tesla_class_perthread_destroy(class); break; } @@ -168,8 +168,8 @@ } int -tesla_clone(struct tesla_class *tclass, const struct tesla_instance *orig, - struct tesla_instance **copy) +tesla_instance_clone(struct tesla_class *tclass, + const struct tesla_instance *orig, struct tesla_instance **copy) { return tesla_instance_new(tclass, &orig->ti_key, orig->ti_state, copy); } @@ -177,11 +177,11 @@ void tesla_class_put(struct tesla_class *tsp) { - switch (tsp->tc_scope) { - case TESLA_SCOPE_GLOBAL: + switch (tsp->tc_context) { + case TESLA_CONTEXT_GLOBAL: return tesla_class_global_release(tsp); - case TESLA_SCOPE_PERTHREAD: + case TESLA_CONTEXT_THREAD: return tesla_class_perthread_release(tsp); default: @@ -198,11 +198,11 @@ bzero(c->tc_instances, sizeof(c->tc_instances[0]) * c->tc_limit); c->tc_free = c->tc_limit; - switch (c->tc_scope) { - case TESLA_SCOPE_GLOBAL: + switch (c->tc_context) { + case TESLA_CONTEXT_GLOBAL: return tesla_class_global_release(c); - case TESLA_SCOPE_PERTHREAD: + case TESLA_CONTEXT_THREAD: return tesla_class_perthread_release(c); default: ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_class_global.c#2 (text+ko) ==== @@ -40,7 +40,7 @@ tesla_class_global_postinit(struct tesla_class *tsp) { - assert(tsp->tc_scope == TESLA_SCOPE_GLOBAL); + assert(tsp->tc_context == TESLA_CONTEXT_GLOBAL); tesla_class_global_lock_init(tsp); return (TESLA_SUCCESS); } @@ -49,7 +49,7 @@ tesla_class_global_acquire(struct tesla_class *tsp) { - assert(tsp->tc_scope == TESLA_SCOPE_GLOBAL); + assert(tsp->tc_context == TESLA_CONTEXT_GLOBAL); tesla_lock(&tsp->tc_lock); } @@ -57,7 +57,7 @@ tesla_class_global_release(struct tesla_class *tsp) { - assert(tsp->tc_scope == TESLA_SCOPE_GLOBAL); + assert(tsp->tc_context == TESLA_CONTEXT_GLOBAL); tesla_unlock(&tsp->tc_lock); } ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_debug.c#3 (text+ko) ==== @@ -191,10 +191,11 @@ print(" name: '%s',\n", c->tc_name); print(" description: '[...]',\n"); // TL;DR print(" scope: "); - switch (c->tc_scope) { - case TESLA_SCOPE_PERTHREAD: print("thread-local\n"); break; - case TESLA_SCOPE_GLOBAL: print("global\n"); break; - default: print("UNKNOWN (0x%x)\n", c->tc_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); ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_internal.h#5 (text+ko) ==== @@ -76,10 +76,27 @@ void tesla_die(int32_t errno, const char *event) __attribute__((noreturn)); /** + * Reset all automata in a store to the inactive state. + */ +int32_t tesla_store_reset(struct tesla_store *store); + +/** + * Clean up a @ref tesla_store. + */ +void tesla_store_free(struct tesla_store*); + + +/** + * Reset a @ref tesla_class for re-use from a clean state. + */ +void tesla_class_reset(struct tesla_class*); + +/** * Clean up a @ref tesla_class. */ void tesla_class_destroy(struct tesla_class*); + /** * Create a new @ref tesla_instance. * @@ -90,10 +107,27 @@ struct tesla_instance **out); /** - * Clone an existing @ref tesla_instance within a @ref tesla_class. + * Checks whether or not a TESLA automata instance is active (in use). + * + * @param i pointer to a valid @ref tesla_instance + * + * @returns 1 if active, 0 if inactive + */ +int32_t tesla_instance_active(const struct tesla_instance *i); + + +/** Clone an existing instance into a new instance. */ +int32_t tesla_instance_clone(struct tesla_class *tclass, + const struct tesla_instance *orig, struct tesla_instance **copy); + +/** + * This interface releases an instance for reuse; some types of automata will + * prefer tesla_class_reset(), which clears all instances associated with a + * particular tesla_class. */ -int32_t tesla_clone(struct tesla_class*, const struct tesla_instance *orig, - struct tesla_instance **copy); +void tesla_instance_destroy(struct tesla_class *tsp, + struct tesla_instance *tip); + /** * Find all automata instances in a class that match a particular key. @@ -110,6 +144,15 @@ int32_t tesla_match(struct tesla_class *tclass, const struct tesla_key *key, struct tesla_instance **array, uint32_t *size); +/** + * Check to see if a key matches a pattern. + * + * @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); + + /** Actions that can be taken by @ref tesla_update_state. */ enum tesla_action_t { /** The instance's state should be updated. */ @@ -190,10 +233,10 @@ * we need to. */ struct tesla_class { - const char *tc_name; /* Name of the assertion. */ - const char *tc_description;/* Description of the assertion. */ - uint32_t tc_scope; /* Per-thread or global. */ - uint32_t tc_limit; /* Simultaneous automata limit. */ + const char *tc_name; /* Name of the assertion. */ + const char *tc_description;/* Automaton representation. */ + enum tesla_context tc_context; /* Global, thread... */ + uint32_t tc_limit; /* Maximum instances. */ struct tesla_instance *tc_instances; /* Instances of this class. */ uint32_t tc_free; /* Unused instances. */ @@ -228,32 +271,23 @@ * Initialise @ref tesla_store internals. * Locking is the responsibility of the caller. */ -int tesla_store_init(tesla_store*, uint32_t context, uint32_t classes, - uint32_t instances); +int tesla_store_init(tesla_store*, enum tesla_context context, + uint32_t classes, uint32_t instances); /** * Initialize @ref tesla_class internals. * Locking is the responsibility of the caller. */ -int tesla_class_init(struct tesla_class*, uint32_t context, +int tesla_class_init(struct tesla_class*, enum tesla_context context, uint32_t instances); /* * XXXRW: temporarily, maximum number of classes and instances are hard-coded * constants. In the future, this should somehow be more dynamic. - * - * XXXRW: this is still true. */ #define TESLA_MAX_CLASSES 128 #define TESLA_MAX_INSTANCES 128 -/* - * When the assertion fails, what to do? - */ -#define TESLA_ACTION_FAILSTOP 1 /* Stop on failure. */ -#define TESLA_ACTION_DTRACE 2 /* Fire DTrace probe on failure. */ -#define TESLA_ACTION_PRINTF 3 /* Console/stdio printf. */ - #if defined(_KERNEL) && defined(MALLOC_DECLARE) /* * Memory type for TESLA allocations in the kernel. ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_key.c#3 (text+ko) ==== @@ -75,8 +75,6 @@ #ifdef _KERNEL tesla_panic("dest key %d (0x%x) != source (0x%x)", i, dest->tk_keys[i], source->tk_keys[i]); -#else - return (TESLA_ERROR_EINVAL); #endif return (TESLA_ERROR_EINVAL); } else { ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_notification.c#5 (text+ko) ==== ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_store.c#3 (text+ko) ==== @@ -53,7 +53,7 @@ { uint32_t error; - error = tesla_store_init(&global_store, TESLA_SCOPE_GLOBAL, + error = tesla_store_init(&global_store, TESLA_CONTEXT_GLOBAL, TESLA_MAX_CLASSES, TESLA_MAX_INSTANCES); tesla_assert(error == TESLA_SUCCESS, ("tesla_store_init failed")); } @@ -62,19 +62,19 @@ #endif int32_t -tesla_store_get(uint32_t context, uint32_t classes, uint32_t instances, - tesla_store* *storep) +tesla_store_get(enum tesla_context context, uint32_t classes, + uint32_t instances, tesla_store* *storep) { assert(storep); tesla_store *store; switch (context) { - case TESLA_SCOPE_GLOBAL: + case TESLA_CONTEXT_GLOBAL: store = &global_store; break; - case TESLA_SCOPE_PERTHREAD: { + case TESLA_CONTEXT_THREAD: { #ifdef _KERNEL store = curthread->td_tesla; #else @@ -97,7 +97,7 @@ default: #ifdef _KERNEL - tesla_panic("invalid TESLA_SCOPE %d", context); + tesla_panic("invliad TESLA_CONTEXT %d", context); #else return (TESLA_ERROR_EINVAL); #endif @@ -118,7 +118,7 @@ int32_t -tesla_store_init(tesla_store *store, uint32_t context, +tesla_store_init(tesla_store *store, enum tesla_context context, uint32_t classes, uint32_t instances) { assert(classes > 0); @@ -136,7 +136,7 @@ if (error != TESLA_SUCCESS) break; - assert(store->classes[i].tc_scope > 0); + assert(store->classes[i].tc_context >= 0); } return (error); @@ -172,7 +172,7 @@ tesla_class *tclass = &store->classes[id]; assert(tclass != NULL); assert(tclass->tc_instances != NULL); - assert(tclass->tc_scope > 0); + assert(tclass->tc_context >= 0); if (tclass->tc_name == NULL) tclass->tc_name = name; if (tclass->tc_description == NULL) @@ -186,11 +186,11 @@ void tesla_class_acquire(tesla_class *class) { - switch (class->tc_scope) { - case TESLA_SCOPE_GLOBAL: + switch (class->tc_context) { + case TESLA_CONTEXT_GLOBAL: return tesla_class_global_acquire(class); - case TESLA_SCOPE_PERTHREAD: + case TESLA_CONTEXT_THREAD: return tesla_class_perthread_acquire(class); default: ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_update.c#3 (text+ko) ==== @@ -49,7 +49,7 @@ #define PRINT(...) DEBUG(libtesla.state.update, __VA_ARGS__) int32_t -tesla_update_state(uint32_t tesla_context, uint32_t class_id, +tesla_update_state(enum tesla_context tesla_context, uint32_t class_id, const struct tesla_key *pattern, const char *name, const char *description, const struct tesla_transitions *trans) @@ -69,7 +69,7 @@ PRINT("\n====\n%s()\n", __func__); PRINT(" context: %s\n", - (tesla_context == TESLA_SCOPE_GLOBAL + (tesla_context == TESLA_CONTEXT_GLOBAL ? "global" : "per-thread")); PRINT(" class: %d ('%s')\n", class_id, name); @@ -147,7 +147,7 @@ for (size_t i = 0; i < cloned; i++) { struct clone_info *c = clones + i; struct tesla_instance *clone; - CHECK(tesla_clone, class, c->old, &clone); + CHECK(tesla_instance_clone, class, c->old, &clone); tesla_key new_name = *pattern; new_name.tk_mask &= c->transition->to_mask; ==== //depot/projects/ctsrd/tesla/src/sys/contrib/tesla/libtesla/tesla_util.c#3 (text+ko) ==== @@ -51,8 +51,6 @@ return ("Success"); case TESLA_ERROR_ENOENT: return ("Entry not found"); - case TESLA_ERROR_EEXIST: - return ("Entry already present"); case TESLA_ERROR_ENOMEM: return ("Insufficient memory"); case TESLA_ERROR_EINVAL: