[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