PERFORCE change 229662 for review
Jonathan Anderson
jonathan at FreeBSD.org
Thu Jun 13 15:38:21 UTC 2013
http://p4web.freebsd.org/@@229662?ac=10
Change 229662 by jonathan at 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 <stdint.h> /* 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 <b>valid</b> @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 <b>valid</b> @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:
More information about the p4-projects
mailing list