[PVFS2-CVS]
commit by slang in pvfs2/src/common/misc: pint-textlog.c
pint-textlog.h pint-event.c pint-event.h state-machine-fns.h
state-machine.h
CVS commit program
cvs at parl.clemson.edu
Fri Jun 3 12:19:03 EDT 2005
Update of /anoncvs/pvfs2/src/common/misc
In directory parlweb:/tmp/cvs-serv12358/src/common/misc
Modified Files:
Tag: slang-event-changes-branch
pint-event.c pint-event.h state-machine-fns.h state-machine.h
Added Files:
Tag: slang-event-changes-branch
pint-textlog.c pint-textlog.h
Log Message:
* added event logging for states
* moved state debug code to state-machine so all state start/end
points get debug messages automatically
* added textlog stuff. This allows us to write the default event
queue out to a text file that can be converted to slog2 later.
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ pint-textlog.c 2005-06-03 11:19:03.000000000 -0400
@@ -0,0 +1,542 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+/* This code generates a textlog in the text log format
+ * defined by the slog2sdk package. This allows us to write
+ * events out easily and later convert them to slog2 using
+ * textlogTOslog2. Although slog2 is primarily used to show
+ * event traces of different *nodes* in an MPI program, we're
+ * using it to show event traces of states, functions, and async
+ * I/0 calls for different *requests* within the same server
+ * process.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include "id-generator.h"
+#include "pvfs2-event.h"
+#include "pvfs2-mgmt.h"
+#include "gossip.h"
+#include "quickhash.h"
+#include "pint-event.h"
+
+#define STATE_TABLE_SIZE 503
+
+static char * PINT_event_operation_names[29] =
+{
+ "INVALID",
+ "CREATE",
+ "REMOVE",
+ "IO",
+ "GETATTR",
+ "SETATTR",
+ "LOOKUP_PATH",
+ "CRDIRENT",
+ "RMDIRENT",
+ "CHDIRENT",
+ "TRUNCATE",
+ "MKDIR",
+ "READDIR",
+ "GETCONFIG",
+ "WRITE_COMPLETION",
+ "FLUSH",
+ "MGMT_SETPARAM",
+ "MGMT_NOOP",
+ "STATFS",
+ "PERF_UPDATE",
+ "MGMT_PERF_MON",
+ "MGMT_ITERATE_HANDLES",
+ "MGMT_DSPACE_INFO_LIST",
+ "MGMT_EVENT_MON",
+ "MGMT_REMOVE_OBJECT",
+ "MGMT_REMOVE_DIRENT",
+ "MGMT_GET_DIRDATA_HANDLE",
+ "JOB_TIMER",
+ "PROTO_ERROR",
+};
+
+static char * PINT_event_api_names[10] =
+{
+ "JOB",
+ "BMI",
+ "TROVE",
+ "ENCODE_REQ",
+ "ENCODE_RESP",
+ "DECODE_REQ",
+ "DECODE_RESP",
+ "SM",
+ "STATES"
+};
+
+static int PINT_event_log2(int _val)
+{
+ int res = 0;
+ while(!(_val & (1 << res)))
+ {
+ ++res;
+ }
+ return res;
+}
+
+#define PINT_event_api_get_name(_api) PINT_event_api_names[PINT_event_log2(_api)]
+
+static char * PINT_event_op_names[25] =
+{
+ "INVALID",
+ "BMI_SEND",
+ "BMI_RECV",
+ "FLOW",
+ "TROVE_READ_AT",
+ "TROVE_WRITE_AT",
+ "TROVE_BSTREAM_FLUSH",
+ "TROVE_KEYVAL_FLUSH",
+ "TROVE_READ_LIST",
+ "TROVE_WRITE_LIST",
+ "TROVE_KEYVAL_READ",
+ "TROVE_KEYVAL_READ_LIST",
+ "TROVE_KEYVAL_WRITE",
+ "TROVE_DSPACE_GETATTR",
+ "TROVE_DSPACE_SETATTR",
+ "TROVE_BSTREAM_RESIZE",
+ "TROVE_KEYVAL_REMOVE",
+ "TROVE_KEYVAL_ITERATE",
+ "TROVE_KEYVAL_ITERATE_KEYS",
+ "TROVE_DSPACE_ITERATE_HANDLES",
+ "TROVE_DSPACE_CREATE",
+ "TROVE_DSPACE_REMOVE",
+ "TROVE_DSPACE_VERIFY",
+ "TROVE_BSTREAM_VALIDATE",
+ "TROVE_KEYVAL_VALIDATE"
+};
+
+#define PINT_event_op_get_name(_op) PINT_event_op_names[_op]
+
+/* We need to keep track of the start events
+ * so that we can match them up with the end events
+ * when they occur
+ */
+typedef struct
+{
+ struct PVFS_mgmt_event * event;
+
+ struct qlist_head link;
+} PINT_textlog_start_event_entry;
+
+/* Each state gets a unique index number
+ * in the log, so we keep a state hashtable
+ * that maps references of states to their
+ * unique index numbers for the log.
+ */
+typedef struct
+{
+ uint32_t id;
+ int index; /* this is the category number in the textlog */
+
+ struct qhash_head link;
+} PINT_textlog_entry;
+
+static inline int PINT_textlog_id_compare(
+ void * key,
+ struct qhash_head * link)
+{
+ uint32_t k = (uint32_t)key;
+ PINT_textlog_entry * link_entry;
+ link_entry = (qhash_entry(link,
+ PINT_textlog_entry, link));
+
+ if(k == link_entry->id)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+static inline int PINT_textlog_id_hash(
+ void * key,
+ int table_size)
+{
+ uint32_t k = (uint32_t) key;
+
+ return (k << ((sizeof(uint32_t) * 4)) ^
+ (k >> (sizeof(uint32_t) * 4))) % table_size;
+}
+
+#define PINT_textlog_make_state_key(_event) \
+ ((0xFFFF0000 & ((uint32_t)_event->operation)) | \
+ (0x0000FFFF & (((uint32_t)_event->state_id) << 4)))
+
+#define PINT_textlog_make_apiop_key(_event) \
+ ((0x0000FFFF & ((uint32_t)_event->api)) | \
+ (0xFFFF0000 & ((uint32_t)_event->operation)))
+
+#define PINT_textlog_make_key(_event) \
+ ((_event->api & PVFS_EVENT_API_STATES) ? \
+ PINT_textlog_make_state_key(_event) : \
+ PINT_textlog_make_apiop_key(_event))
+
+static inline int PINT_textlog_id_table_lookup(
+ struct qhash_table * id_map,
+ struct PVFS_mgmt_event * event)
+{
+ void * key;
+ PINT_textlog_entry * entry;
+ struct qhash_head * qres;
+
+ key = (void *)PINT_textlog_make_key(event);
+
+ qres = qhash_search(id_map, key);
+ if(qres)
+ {
+ entry = qhash_entry(qres, PINT_textlog_entry, link);
+ return entry->index;
+ }
+
+ return -1;
+}
+
+static inline int PINT_textlog_state_table_add(
+ struct qhash_table * state_table,
+ struct PVFS_mgmt_event * event,
+ int index)
+{
+ PINT_textlog_entry * entry;
+
+ entry = qhash_malloc(sizeof(PINT_textlog_entry));
+ if(!entry)
+ {
+ gossip_err("PINT_textlog_state_table_add: Out of Memory Error: "
+ "malloc(%d)\n", sizeof(PINT_textlog_entry));
+ return -1;
+ }
+ memset(entry, 0, sizeof(PINT_textlog_entry));
+
+ entry->id = PINT_textlog_make_key(event);
+
+ entry->index = index;
+ INIT_QHASH_HEAD(&entry->link);
+ qhash_add(state_table, (void *)entry->id, &entry->link);
+
+
+ return 0;
+}
+
+static inline void PINT_textlog_state_table_finalize(
+ struct qhash_table * table)
+{
+ PINT_textlog_entry * entry;
+ struct qhash_head * tmp_link = NULL;
+
+ qhash_for_each(tmp_link, &(table->array[0]))
+ {
+ entry = qhash_entry(tmp_link, PINT_textlog_entry, link);
+ qhash_free(entry);
+ }
+ qhash_finalize(table);
+}
+
+/* writes the state as a category in the textlog format
+ */
+static inline int PINT_textlog_write_statename(
+ FILE * fp,
+ struct PVFS_mgmt_event * event,
+ struct qhash_table * state_table)
+{
+ int res;
+ int index = PINT_textlog_id_table_lookup(
+ state_table, event);
+
+ res = fprintf(fp,
+ "Category[ index=%d name=", index);
+ if(res < 0)
+ {
+ return res;
+ }
+
+ if(event->api & PVFS_EVENT_API_STATES)
+ {
+ int res;
+
+ res = fprintf(fp, "%s:%s",
+ (event->operation < 26) ?
+ PINT_event_operation_names[event->operation] :
+ "NULL",
+ (char *)id_gen_fast_lookup(event->state_id));
+ if(res < 0)
+ {
+ return res;
+ }
+
+ res = fprintf(fp,
+ " topo=State "
+ "color=(%d,%d,%d,127,true) width=1 ]\n",
+ rand() % 255,
+ rand() % 255,
+ rand() % 255);
+ if(res < 0)
+ {
+ return res;
+ }
+ }
+ else
+ {
+ res = fprintf(fp,
+ "%s:%s topo=State "
+ "color=(%d,%d,%d,127,true) width=1 ]\n",
+ PINT_event_api_get_name(event->api),
+ PINT_event_op_get_name(event->operation),
+ rand() % 255,
+ rand() % 255,
+ rand() % 255);
+ if(res < 0)
+ {
+ return res;
+ }
+ }
+
+ return 0;
+}
+
+#define PINT_textlog_timeval_to_secs(_epoc, _event) \
+ (((float)(_event->tv_sec - _epoc->tv_sec)) + \
+ (((float)(_event->tv_usec - _epoc->tv_usec))*1e-6))
+
+static int PINT_textlog_write_event(
+ FILE * fp,
+ struct timeval * epoc,
+ struct PVFS_mgmt_event * estart,
+ struct PVFS_mgmt_event * eend,
+ struct qhash_table * state_table)
+{
+ float starttime, endtime;
+ int req_index;
+
+ req_index = (int)id_gen_fast_lookup(estart->req_id);
+
+ starttime = PINT_textlog_timeval_to_secs(epoc, estart);
+ endtime = PINT_textlog_timeval_to_secs(epoc, eend);
+
+ return fprintf(
+ fp,
+ "Primitive[ TimeBBox(%.10f,%.10f) "
+ "Category=%d (%.10f, %d) (%.10f, %d) ]\n",
+ starttime, endtime,
+ PINT_textlog_id_table_lookup(state_table, estart),
+ starttime,
+ req_index,
+ endtime,
+ req_index);
+}
+
+static inline int PINT_textlog_start_events_insert(
+ struct qlist_head * events_list,
+ struct PVFS_mgmt_event * event)
+{
+ PINT_textlog_start_event_entry * entry;
+
+ entry = malloc(sizeof(PINT_textlog_start_event_entry));
+ if(!entry)
+ {
+ gossip_err("PINT_textlog_start_events_insert: Out of Memory\n");
+ return -1;
+ }
+ memset(entry, 0, sizeof(PINT_textlog_start_event_entry));
+
+ entry->event = event;
+ INIT_QLIST_HEAD(&entry->link);
+ qlist_add(&entry->link, events_list);
+
+ return 0;
+}
+
+static inline
+struct PVFS_mgmt_event * PINT_textlog_find_matching_start_event(
+ struct qlist_head * events_list,
+ struct PVFS_mgmt_event * end_event)
+{
+ struct PVFS_mgmt_event * event_entry;
+ PINT_textlog_start_event_entry * entry;
+ struct qlist_head * iter;
+ uint32_t end_key;
+ uint32_t iter_key;
+
+ end_key = PINT_textlog_make_key(end_event);
+
+ qlist_for_each(iter, events_list)
+ {
+ entry = (qlist_entry(
+ iter, PINT_textlog_start_event_entry, link));
+ iter_key = PINT_textlog_make_key(entry->event);
+
+ if(entry->event->req_id == end_event->req_id &&
+ end_key == iter_key)
+ {
+ event_entry = entry->event;
+ qlist_del(&entry->link);
+ free(entry);
+ return event_entry;
+ }
+ }
+
+ return NULL;
+}
+
+static inline void PINT_textlog_start_events_list_finalize(
+ struct qlist_head * events)
+{
+ PINT_textlog_start_event_entry * se_entry;
+ struct qlist_head * entry;
+
+ for(entry = events->next; entry != events;)
+ {
+ se_entry = qlist_entry(
+ entry, PINT_textlog_start_event_entry, link);
+ entry = entry->next;
+ free(se_entry);
+ }
+}
+
+void PINT_textlog_generate(
+ struct PVFS_mgmt_event * events,
+ int count,
+ const char * filename)
+{
+ FILE * outfp;
+ struct timeval epoc;
+ int tr_index;
+ struct qhash_table * id_map;
+ QLIST_HEAD(start_events_list);
+ int textlog_state_index = 0;
+
+ outfp = fopen(filename, "w");
+ if(!outfp)
+ {
+ gossip_err("PINT_generate_textlog: Failed to open file %s: %s\n",
+ filename, strerror(errno));
+ return;
+ }
+
+ id_map = qhash_init(PINT_textlog_id_compare,
+ PINT_textlog_id_hash,
+ STATE_TABLE_SIZE);
+ if(!id_map)
+ {
+ gossip_err("PINT_generate_textlog: qhash_init failed for state map "
+ "with table size of %d\n", STATE_TABLE_SIZE);
+ goto close_fp;
+ }
+
+ for(tr_index = 0; tr_index < count; ++tr_index)
+ {
+ if(events[tr_index].flags != PVFS_EVENT_FLAG_INVALID)
+ {
+ /* find all the possible unique state values
+ * and create indexes, colors and
+ * write out the categories for each
+ */
+
+ /* lookup this state name to see if its already defined */
+ if(PINT_textlog_id_table_lookup(
+ id_map, &events[tr_index]) == -1)
+ {
+ if(PINT_textlog_state_table_add(
+ id_map,
+ &events[tr_index],
+ ++textlog_state_index) < 0)
+ {
+ goto finalize_id_map;
+ }
+
+ if(PINT_textlog_write_statename(
+ outfp,
+ &events[tr_index],
+ id_map) < 0)
+ {
+ goto finalize_id_map;
+ }
+ }
+ }
+ }
+
+ /* get first timestamp - we assume all timestamps occur
+ * after the first event in the array.
+ * */
+ if(events[0].flags != PVFS_EVENT_FLAG_INVALID)
+ {
+ epoc.tv_sec = events[0].tv_sec;
+ epoc.tv_usec = events[0].tv_usec;
+ }
+ else
+ {
+ gossip_err("PINT_textlog_generate: invalid event in array[0]\n");
+ goto finalize_start_events_list;
+ }
+
+ /* now that the categories (state definitions) are written
+ * we can write the actual events with the appropriate request id
+ * mapped to node number
+ */
+ for(tr_index = 0; tr_index < count; tr_index++)
+ {
+ if(events[tr_index].flags == PVFS_EVENT_FLAG_START)
+ {
+ /* added started event to the event list */
+ if(PINT_textlog_start_events_insert(
+ &start_events_list,
+ &events[tr_index]) < 0)
+ {
+ goto finalize_start_events_list;
+ }
+ }
+ else if(events[tr_index].flags == PVFS_EVENT_FLAG_END)
+ {
+ struct PVFS_mgmt_event * start_event =
+ PINT_textlog_find_matching_start_event(
+ &start_events_list,
+ &events[tr_index]);
+ if(!start_event)
+ {
+ /* hmmm - no matching start event. Just skip
+ * and go to the next one
+ */
+ continue;
+ }
+
+ if(PINT_textlog_write_event(
+ outfp,
+ &epoc,
+ start_event,
+ &events[tr_index],
+ id_map) < 0)
+ {
+ goto finalize_start_events_list;
+ }
+ }
+ }
+
+finalize_start_events_list:
+ PINT_textlog_start_events_list_finalize(&start_events_list);
+finalize_id_map:
+ PINT_textlog_state_table_finalize(id_map);
+close_fp:
+ fclose(outfp);
+}
+
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
--- /dev/null 2003-01-30 05:24:37.000000000 -0500
+++ pint-textlog.h 2005-06-03 11:19:03.000000000 -0400
@@ -0,0 +1,30 @@
+/*
+ * (C) 2001 Clemson University and The University of Chicago
+ *
+ * See COPYING in top-level directory.
+ */
+
+#ifndef __PINT_TEXTLOG_H
+#define __PINT_TEXTLOG_H
+
+#include "pvfs2-types.h"
+#include "pvfs2-mgmt.h"
+#include "pvfs2-event.h"
+
+/* writes the events in the queue to a textlog */
+void PINT_textlog_generate(
+ struct PVFS_mgmt_event * events,
+ int count,
+ const char * filename);
+
+#endif /* __PINT_TEXTLOG_H */
+
+/*
+ * Local variables:
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * End:
+ *
+ * vim: ts=8 sts=4 sw=4 expandtab
+ */
+
Index: pint-event.c
===================================================================
RCS file: /anoncvs/pvfs2/src/common/misc/pint-event.c,v
diff -p -u -r1.10 -r1.10.6.1
--- pint-event.c 28 Jul 2004 14:32:36 -0000 1.10
+++ pint-event.c 3 Jun 2005 15:19:03 -0000 1.10.6.1
@@ -9,11 +9,15 @@
#include <sys/time.h>
#include <stdio.h>
-
+#include <stdarg.h>
#include "pint-event.h"
+#include "pint-textlog.h"
#include "pvfs2-types.h"
#include "pvfs2-mgmt.h"
#include "gossip.h"
+#include "id-generator.h"
+
+#define PINT_EVENT_DEFAULT_TEXTLOG_FILENAME "/tmp/pvfs2-events-log.txt"
/* variables that provide runtime control over which events are recorded */
int PINT_event_on = 0;
@@ -35,30 +39,6 @@ int PINT_event_bmi_start, PINT_event_bmi
int PINT_event_flow_start, PINT_event_flow_stop;
#endif
-
-/* PINT_event_initialize()
- *
- * starts up the event logging interface
- *
- * returns 0 on success, -PVFS_error on failure
- */
-int PINT_event_initialize(int ring_size)
-{
- gen_mutex_lock(&event_mutex);
-
-#if defined(HAVE_PABLO)
- PINT_event_pablo_init();
-#endif
-#if defined(HAVE_MPE)
- PINT_event_mpe_init();
-#endif
-
- PINT_event_default_init(ring_size);
-
- gen_mutex_unlock(&event_mutex);
- return(0);
-}
-
#if defined(HAVE_MPE)
/*
* PINT_event_mpe_init
@@ -123,7 +103,6 @@ void PINT_event_pablo_finalize(void)
#endif
-
int PINT_event_default_init(int ring_size)
{
if(ts_ring != NULL)
@@ -172,6 +151,29 @@ void PINT_event_default_finalize(void)
}
+/* PINT_event_initialize()
+ *
+ * starts up the event logging interface
+ *
+ * returns 0 on success, -PVFS_error on failure
+ */
+int PINT_event_initialize(int ring_size)
+{
+ gen_mutex_lock(&event_mutex);
+
+#if defined(HAVE_PABLO)
+ PINT_event_pablo_init();
+#endif
+#if defined(HAVE_MPE)
+ PINT_event_mpe_init();
+#endif
+
+ PINT_event_default_init(ring_size);
+
+ gen_mutex_unlock(&event_mutex);
+ return(0);
+}
+
/* PINT_event_finalize()
*
@@ -189,6 +191,7 @@ void PINT_event_finalize(void)
#if defined(HAVE_MPE)
PINT_event_mpe_finalize();
#endif
+
PINT_event_default_finalize();
gen_mutex_unlock(&event_mutex);
@@ -234,41 +237,15 @@ void PINT_event_get_masks(int* event_on,
return;
}
-/* PINT_event_timestamp()
- *
- * records a timestamp in the ring buffer
- *
- * returns 0 on success, -PVFS_error on failure
- */
-void __PINT_event_timestamp(enum PVFS_event_api api,
- int32_t operation,
- int64_t value,
- PVFS_id_gen_t id,
- int8_t flags)
-{
- gen_mutex_lock(&event_mutex);
-
-#if defined(HAVE_PABLO)
- __PINT_event_pablo(api, operation, value, id, flags);
-#endif
-
-#if defined (HAVE_MPE)
- __PINT_event_mpe(api, operation, value, id, flags);
-#endif
-
- __PINT_event_default(api, operation, value, id, flags);
-
- gen_mutex_unlock(&event_mutex);
-
- return;
-}
-
void __PINT_event_default(enum PVFS_event_api api,
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags)
+ int8_t flags,
+ const char * state_name,
+ PVFS_id_gen_t req_id)
{
+ PVFS_id_gen_t state_id;
struct timeval tv;
/* immediately grab timestamp */
@@ -282,7 +259,10 @@ void __PINT_event_default(enum PVFS_even
ts_ring[ts_head].flags = flags;
ts_ring[ts_head].tv_sec = tv.tv_sec;
ts_ring[ts_head].tv_usec = tv.tv_usec;
-
+ id_gen_fast_register(&state_id, (void *)state_name);
+ ts_ring[ts_head].state_id = state_id;
+ ts_ring[ts_head].req_id = req_id;
+
/* update ring buffer positions */
ts_head = (ts_head+1)%ts_ring_size;
if(ts_head == ts_tail)
@@ -297,7 +277,9 @@ void __PINT_event_pablo(enum PVFS_event_
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags)
+ int8_t flags,
+ const char * sn,
+ PVFS_id_gen_t req_id)
{
/* TODO: this can all go once there is a nice "enum to string" function */
char description[100];
@@ -339,7 +321,9 @@ void __PINT_event_mpe(enum PVFS_event_ap
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags)
+ int8_t flags,
+ const char * sn,
+ PVFS_id_gen_t req_id)
{
switch(api) {
case PVFS_EVENT_API_BMI:
@@ -352,19 +336,50 @@ void __PINT_event_mpe(enum PVFS_event_ap
if (flags & PVFS_EVENT_FLAG_START) {
MPE_Log_event(PINT_event_job_start, 0, NULL);
} else if (flags & PVFS_EVENT_FLAG_END) {
- MPE_Log_event(PINT_event_bmi_stop, value, NULL);
+ MPE_Log_event(PINT_event_job_stop, value, NULL);
}
case PVFS_EVENT_API_TROVE:
if (flags & PVFS_EVENT_FLAG_START) {
- MPE_Log_event(PINT_event_job_start, 0, NULL);
+ MPE_Log_event(PINT_event_trove_start, 0, NULL);
} else if (flags & PVFS_EVENT_FLAG_END) {
- MPE_Log_event(PINT_event_bmi_stop, value, NULL);
+ MPE_Log_event(PINT_event_trove_stop, value, NULL);
}
}
}
#endif
+/* PINT_event_timestamp()
+ *
+ * records a timestamp in the ring buffer
+ *
+ * returns 0 on success, -PVFS_error on failure
+ */
+void __PINT_event_timestamp(enum PVFS_event_api api,
+ int32_t operation,
+ int64_t value,
+ PVFS_id_gen_t id,
+ int8_t flags,
+ const char * state_name,
+ PVFS_id_gen_t req_id)
+{
+ gen_mutex_lock(&event_mutex);
+
+#if defined(HAVE_PABLO)
+ __PINT_event_pablo(api, operation, value, id, flags, state_name, req_id);
+#endif
+
+#if defined (HAVE_MPE)
+ __PINT_event_mpe(api, operation, value, id, flags, state_name, req_id);
+#endif
+
+ __PINT_event_default(api, operation, value, id, flags, state_name, req_id);
+
+ gen_mutex_unlock(&event_mutex);
+
+ return;
+}
+
/* PINT_event_retrieve()
*
* fills in an array with current snapshot of event buffer
@@ -398,6 +413,36 @@ void PINT_event_retrieve(struct PVFS_mgm
return;
}
+
+void PINT_event_log_events(
+ struct PVFS_mgmt_event * events,
+ int count,
+ const char * filename)
+{
+ struct PVFS_mgmt_event * event_array = events;
+ int array_size = count;
+ const char * out_filename = filename;
+
+ if(!PINT_event_on)
+ {
+ return;
+ }
+
+ if(!events)
+ {
+ /* assume we want to log server's events locally */
+ event_array = (struct PVFS_mgmt_event*)malloc(
+ ts_ring_size*sizeof(struct PVFS_mgmt_event));
+ PINT_event_retrieve(event_array, ts_ring_size);
+ array_size = ts_ring_size;
+ out_filename = PINT_EVENT_DEFAULT_TEXTLOG_FILENAME;
+ }
+
+ gen_mutex_lock(&event_mutex);
+ PINT_textlog_generate(event_array, array_size, out_filename);
+ gen_mutex_unlock(&event_mutex);
+}
+
/*
* Local variables:
Index: pint-event.h
===================================================================
RCS file: /anoncvs/pvfs2/src/common/misc/pint-event.h,v
diff -p -u -r1.12 -r1.12.6.1
--- pint-event.h 28 Jul 2004 14:32:36 -0000 1.12
+++ pint-event.h 3 Jun 2005 15:19:03 -0000 1.12.6.1
@@ -26,12 +26,17 @@ void PINT_event_set_masks(int event_on,
void PINT_event_get_masks(int* event_on, int32_t* api_mask, int32_t* op_mask);
void PINT_event_retrieve(struct PVFS_mgmt_event* event_array,
int count);
+void PINT_event_log_events(
+ struct PVFS_mgmt_event* events, int count, const char * filename);
+
void __PINT_event_timestamp(enum PVFS_event_api api,
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags);
-
+ int8_t flags,
+ const char * sn,
+ PVFS_id_gen_t req_id);
+
#if defined(HAVE_PABLO)
#include "SystemDepend.h"
#include "Trace.h"
@@ -43,7 +48,9 @@ void __PINT_event_pablo(enum PVFS_event_
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags);
+ int8_t flags,
+ const char * event_info,
+ PVFS_id_gen_t req_id);
#endif
#if defined(HAVE_MPE)
@@ -61,7 +68,23 @@ void __PINT_event_mpe(enum PVFS_event_ap
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags);
+ int8_t flags,
+ const char * event_info,
+ PVFS_id_gen_t req_id);
+
+#endif
+
+#if defined(HAVE_TAU)
+int PINT_event_tau_init(void);
+void PINT_event_tau_finalize(void);
+
+void __PINT_event_tau(enum PVFS_event_api api,
+ int32_t operation,
+ int64_t value,
+ PVFS_id_gen_t id,
+ int8_t flags,
+ const char * event_info,
+ PVFS_id_gen_t req_id);
#endif
@@ -72,18 +95,22 @@ void __PINT_event_default(enum PVFS_even
int32_t operation,
int64_t value,
PVFS_id_gen_t id,
- int8_t flags);
+ int8_t flags,
+ const char * state_id,
+ PVFS_id_gen_t req_id);
#ifdef __PVFS2_DISABLE_EVENT__
-#define PINT_event_timestamp(__api, __operation, __value, __id, __flags) \
+#define PINT_event_timestamp(__api, __operation, __value, \
+ __id, __flags, __state_id, __req_id) \
do {} while(0)
#else
-#define PINT_event_timestamp(__api, __operation, __value, __id, __flags) \
+#define PINT_event_timestamp(__api, __operation, __value, \
+ __id, __flags, __state_id, __req_id) \
do { \
if(PINT_event_on && (PINT_event_api_mask & (__api)) && \
((PINT_event_op_mask & (__operation))||((__operation)==0))){\
__PINT_event_timestamp((__api), (__operation), (__value), (__id), \
- (__flags)); }\
+ (__flags), (__state_id), (__req_id)); }\
} while(0)
#endif
Index: state-machine-fns.h
===================================================================
RCS file: /anoncvs/pvfs2/src/common/misc/state-machine-fns.h,v
diff -p -u -r1.15 -r1.15.6.1
--- state-machine-fns.h 28 Jul 2004 14:32:37 -0000 1.15
+++ state-machine-fns.h 3 Jun 2005 15:19:03 -0000 1.15.6.1
@@ -10,6 +10,8 @@
#include <assert.h>
#include "gossip.h"
+#include "pvfs2-event.h"
+#include "pint-event.h"
/* STATE-MACHINE-FNS.H
*
@@ -23,11 +25,6 @@
* includes state-machine.h, because state-machine.h needs a key #define
* before it can be included.
*
- * The structure holding the table of PINT_OP_STATE structures also needs to
- * be declared; its name should be #defined as PINT_OP_STATE_TABLE. If you
- * don't define this, you don't get the extern or the _locate function
- * (currently client might not need them?).
- *
* A good example of this is the pvfs2-server.h in the src/server directory,
* which includes state-machine.h at the bottom, and server-state-machine.c,
* which includes first pvfs2-server.h and then state-machine-fns.h.
@@ -40,6 +37,7 @@
/* Prototypes for functions defined in here */
static inline int PINT_state_machine_halt(void);
static inline int PINT_state_machine_next(struct PINT_OP_STATE *,job_status_s *r);
+static inline int PINT_state_machine_invoke(struct PINT_OP_STATE *,job_status_s *r);
#ifdef PINT_OP_STATE_TABLE
static union PINT_state_array_values *PINT_state_machine_locate(struct PINT_OP_STATE *);
#endif
@@ -56,6 +54,34 @@ static inline int PINT_state_machine_hal
return 0;
}
+#ifndef __PINT_STATE_DEBUG
+#error PINT_STATE_DEBUG must be defined before state-machine-fns.h is included
+#endif
+
+#ifndef __PINT_STATE_EVENT
+#error PINT_STATE_EVENT_START and PINT_STATE_EVENT_STOP must be defined before stat-machine-fns.h is included
+#endif
+
+/* Function: PINT_state_machine_invoke()
+ * Params:
+ * Returns: return value of state action
+ *
+ * Synopsis: Invokes the current state action. This is useful where
+ * the state action isn't invoked from PINT_state_machine_next()
+ */
+static inline int PINT_state_machine_invoke(struct PINT_OP_STATE *s,
+ job_status_s *r)
+{
+ int ret;
+ PINT_STATE_EVENT_INIT();
+
+ PINT_STATE_DEBUG(s);
+ PINT_STATE_EVENT_START(s);
+ ret = s->current_state->state_action(s, r);
+ PINT_STATE_EVENT_END(s, r);
+ return ret;
+}
+
/* Function: PINT_state_machine_next()
Params:
Returns: return value of state action
@@ -72,6 +98,7 @@ static inline int PINT_state_machine_nex
int code_val = r->error_code; /* temp to hold the return code */
int retval; /* temp to hold return value of state action */
union PINT_state_array_values *loc; /* temp pointer into state memory */
+ PINT_STATE_EVENT_INIT();
do {
/* skip over the current state action to get to the return code list */
@@ -114,9 +141,12 @@ static inline int PINT_state_machine_nex
}
} while (loc->flag == SM_RETURN);
+ /* mark the current state's id before transitioning */
s->current_state = loc->next_state;
-
-
+
+ /* skip over the state name -- slang */
+ s->current_state += 1;
+
/* To do nested states, we check to see if the next state is
* a nested state machine, and if so we push the return state
* onto a stack */
@@ -130,20 +160,25 @@ static inline int PINT_state_machine_nex
* cross-structure dependency that I couldn't handle any more. -- Rob
*/
s->current_state = ((struct PINT_state_machine_s *) s->current_state->nested_machine)->state_machine;
+
+ /* skip over the state name -- slang */
+ s->current_state += 1;
}
/* skip over the flag so that we point to the function for the next
* state. then call it.
*/
s->current_state += 1;
-
+
+ PINT_STATE_DEBUG(s);
+ PINT_STATE_EVENT_START(s);
retval = (s->current_state->state_action)(s,r);
+ PINT_STATE_EVENT_END(s, r);
/* return to the while loop in pvfs2-server.c */
return retval;
}
-#ifdef PINT_OP_STATE_TABLE
/* Function: PINT_state_machine_locate(void)
Params:
Returns: Pointer to the start of the state machine indicated by
@@ -151,33 +186,48 @@ static inline int PINT_state_machine_nex
Synopsis: This function is used to start a state machines execution.
*/
+#ifdef PINT_OP_STATE_TABLE
static union PINT_state_array_values *PINT_state_machine_locate(struct PINT_OP_STATE *s_op)
{
union PINT_state_array_values *current_tmp;
/* check for valid inputs */
- if (!s_op || s_op->op < 0 || s_op->op > PVFS_MAX_SERVER_OP)
+ if (!s_op || s_op->op < 0
+ || s_op->op > PVFS_MAX_SERVER_OP)
{
gossip_err("State machine requested not valid\n");
return NULL;
}
- if (PINT_OP_STATE_TABLE[s_op->op].sm != NULL)
+ if (PINT_OP_STATE_TABLE[s_op->op].sm->state_machine != NULL)
{
- current_tmp = PINT_OP_STATE_TABLE[s_op->op].sm->state_machine;
- /* handle the case in which the first state points to a nested
- * machine, rather than a simple function
- */
- while(current_tmp->flag == SM_JUMP)
+ current_tmp = PINT_OP_STATE_TABLE[s_op->op].sm->state_machine;
+ /* added the state name string as the first entry in the
+ * state's array values. Skip past it to get to the type
+ * of action. --slang
+ */
+ current_tmp += 1;
+
+ /* handle the case in which the first state points to a nested
+ * machine, rather than a simple function
+ */
+ while(current_tmp->flag == SM_JUMP)
{
PINT_push_state(s_op, current_tmp);
current_tmp += 1;
current_tmp = ((struct PINT_state_machine_s *)current_tmp->nested_machine)->state_machine;
- }
+
+
+
+
+ /* skip over state name string. see above comment. --slang */
+ current_tmp += 1;
+ }
/* this returns a pointer to a "PINT_state_array_values"
* structure, whose state_action member is the function to call.
*/
- return current_tmp + 1;
+ current_tmp += 1;
+ return current_tmp;
}
gossip_err("State machine not found for operation %d\n",s_op->op);
@@ -188,7 +238,6 @@ static union PINT_state_array_values *PI
static inline union PINT_state_array_values *PINT_pop_state(struct PINT_OP_STATE *s)
{
assert(s->stackptr > 0);
-
return s->state_stack[--s->stackptr];
}
@@ -196,7 +245,6 @@ static inline void PINT_push_state(struc
union PINT_state_array_values *p)
{
assert(s->stackptr < PINT_STATE_STACK_SIZE);
-
s->state_stack[s->stackptr++] = p;
}
Index: state-machine.h
===================================================================
RCS file: /anoncvs/pvfs2/src/common/misc/state-machine.h,v
diff -p -u -r1.10 -r1.10.6.1
--- state-machine.h 28 Jul 2004 14:32:37 -0000 1.10
+++ state-machine.h 3 Jun 2005 15:19:03 -0000 1.10.6.1
@@ -18,18 +18,11 @@
* - easy access to the state data for the implementation
* - reuse across client and server (different state data)
*
- * The important thing to note about this file is that it requires that
- * PINT_OP_STATE be defined. This must be a typedef to the structure
- * that holds the necessary state information for a given state machine.
- * There are four fields that must exist and are used by the state machine
- * implementation:
- * - int op;
- * - int stackptr;
- * - PINT_state_array_values *current_state;
- * - PINT_state_array_values *state_stack[PINT_STATE_STACK_SIZE];
- *
- * Also, PINT_STATE_STACK_SIZE must be defined or enum'd before that
- * declaration.
+ * PINT_OP_STATE structure handling changed (5/31/05) to be a base
+ * struct instead of a #define and have that struct be included as the
+ * first field (this is required!) of the derived struct, allowing us
+ * to cast to the PINT_OP_STATE struct when it is passed into the
+ * generic state machine functions.
*
* The file state-machine-fns.h defines a set of functions for use in
* interacting with the state machine. There are also a couple of other
@@ -38,10 +31,8 @@
*/
#include "job.h"
+#include "msgpairarray.h"
-#ifndef PINT_OP_STATE
-#error "PINT_OP_STATE must be defined before state-machine.h is included."
-#endif
union PINT_state_array_values
{
@@ -50,6 +41,7 @@ union PINT_state_array_values
int flag;
struct PINT_state_machine_s *nested_machine; /* NOTE: this is really a PINT_state_machine * (void *)*/
union PINT_state_array_values *next_state;
+ char * name;
};
struct PINT_state_machine_s
@@ -66,10 +58,6 @@ enum {
#define ENCODE_TYPE 0
#define SM_STATE_RETURN -1
#define SM_NESTED_STATE 1
-
-/* Prototypes for functions provided by user */
-int PINT_state_machine_start(struct PINT_OP_STATE *, job_status_s *ret);
-int PINT_state_machine_complete(struct PINT_OP_STATE *);
/* NOTE: All other function prototypes are defined in state-machine-fns.h */
More information about the PVFS2-CVS
mailing list