[Pvfs2-cvs] commit by walt in pvfs2-1/src/common/misc: state-machine-fns.c state-machine.h

CVS commit program cvs at parl.clemson.edu
Tue Aug 29 16:44:02 EDT 2006


Update of /projects/cvsroot/pvfs2-1/src/common/misc
In directory parlweb1:/tmp/cvs-serv32553/src/common/misc

Modified Files:
      Tag: WALT3
	state-machine-fns.c state-machine.h 
Log Message:
updates to parallel state machine code that get a basic test working
This test is still included in get_config.sm and needs to be removed.


Index: state-machine-fns.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/common/misc/Attic/state-machine-fns.c,v
diff -p -u -r1.1.2.10 -r1.1.2.11
--- state-machine-fns.c	1 Aug 2006 21:46:15 -0000	1.1.2.10
+++ state-machine-fns.c	29 Aug 2006 20:44:02 -0000	1.1.2.11
@@ -7,6 +7,7 @@
 #ifndef __STATE_MACHINE_FNS_H
 #define __STATE_MACHINE_FNS_H
 
+#include <stdio.h>
 #include <string.h>
 #include <assert.h>
 
@@ -60,13 +61,19 @@ int PINT_state_machine_terminate(struct 
     if (smcb->parent_smcb)
     {
         job_id_t id;
+#if 0
         /* acquire lock here */
         if (--smcb->parent_smcb->children_running == 0)
         {
+#endif
             /* wake up parent, through job interface */
-            job_null(0, smcb, 0, r, &id, smcb->context);
+            gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
+                "SM job_null called smcb %p\n", smcb->parent_smcb);
+            job_null(0, smcb->parent_smcb, 0, r, &id, smcb->context);
+#if 0
         }
         /* release lock here */
+#endif
     }
     /* call state machine completion function */
     if (smcb->terminate_fn)
@@ -91,10 +98,11 @@ int PINT_state_machine_invoke(struct PIN
     const char * machine_name;
 
     if (!(smcb) || !(smcb->current_state) ||
-            !(smcb->current_state->flag == SM_RUN) ||
+            !(smcb->current_state->flag == SM_RUN ||
+              smcb->current_state->flag == SM_PJMP) ||
             !(smcb->current_state->action.func))
     {
-        gossip_err("SM invoke called in invalid smcb\n");
+        gossip_err("SM invoke called on invalid smcb or state\n");
         return -1;
     }
 
@@ -125,24 +133,40 @@ int PINT_state_machine_invoke(struct PIN
                  state_name,
                  r->error_code);
 
+    if (smcb->current_state->flag == SM_PJMP)
+    {
+        /* start child SMs */
+        PINT_sm_start_child_frames(smcb);
+        gossip_debug(GOSSIP_STATE_MACHINE_DEBUG, 
+                "SM (%p) started %d child frames\n",
+                smcb, smcb->children_running);
+        if (smcb->children_running > 0)
+            retval = SM_ACTION_DEFERRED;
+        else
+            retval = SM_ACTION_COMPLETE;
+    }
+
     /* process return code */
     switch (retval)
     {
     case SM_ACTION_TERMINATE :
-        {
+            gossip_debug(GOSSIP_STATE_MACHINE_DEBUG, 
+                    "SM Terminates (%p)\n", smcb);
             smcb->op_terminate = 1;
-        }
+            break;
     case SM_ACTION_COMPLETE :
+            gossip_debug(GOSSIP_STATE_MACHINE_DEBUG, 
+                    "SM Returns Complete (%p)\n", smcb);
+            break;
     case SM_ACTION_DEFERRED :
-        {
-            return retval;
-        }
+            gossip_debug(GOSSIP_STATE_MACHINE_DEBUG, 
+                    "SM Returns Deferred (%p)\n", smcb);
+            break;
     default :
-        {
             /* error */
-            gossip_err("SM returned invalid return code %d\n", retval);
+            gossip_err("SM returned invalid return code %d (%p)\n",
+                    retval, smcb);
             break;
-        }
     }
 
     return retval;
@@ -187,6 +211,14 @@ int PINT_state_machine_next(struct PINT_
     }
     gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
             "SM next smcb %p op %d\n",smcb,(smcb)->op);
+    if (smcb->children_running > 0)
+    {
+        if (--smcb->children_running > 0)
+        {
+            /* SM is still deferred */
+            return SM_ACTION_DEFERRED;
+        }
+    }
     /* loop while invoke of new state returns COMPLETED */
     do {
         /* loop while returning from nested SM */
@@ -214,14 +246,14 @@ int PINT_state_machine_next(struct PINT_
 	    {
                 if (!(transtbl[i].flag == SM_TERM))
                 {
-	            gossip_lerr("Error: state machine reached terminate"
-                            " without returning SM_ACTION_TERMINATE\n");
-                }
-                {
-                if (!smcb->op_terminate)
 	            gossip_lerr("Error: state machine returned"
                            " SM_ACTION_TERMINATE but didn't reach terminate\n");
                 }
+                if (!smcb->op_terminate)
+                {
+	            gossip_lerr("Error: state machine reached terminate"
+                            " without returning SM_ACTION_TERMINATE\n");
+                }
                 /* process terminating SM */
                 PINT_state_machine_terminate(smcb, r);
                 return SM_ACTION_TERMINATE;
@@ -383,15 +415,16 @@ int PINT_smcb_alloc(
     /* if frame_size given, allocate a frame */
     if (frame_size > 0)
     {
-        (*smcb)->frame_stack[0] = malloc(frame_size);
-        if (!((*smcb)->frame_stack[0]))
+        void *new_frame = malloc(frame_size);
+        if (!new_frame)
         {
             free(*smcb);
             *smcb = NULL;
             return -PVFS_ENOMEM;
         }
         /* zero out all members */
-        memset((*smcb)->frame_stack[0], 0, frame_size);
+        memset(new_frame, 0, frame_size);
+        PINT_sm_push_frame(*smcb, 0, new_frame);
     }
     (*smcb)->op = op;
     (*smcb)->op_get_state_machine = getmach;
@@ -404,39 +437,40 @@ int PINT_smcb_alloc(
 }
 
 /* Function: PINT_smcb_free
-   Params: pointer to an smcb pointer
-   Returns: nothing, but sets the pointer to NULL
-   Synopsis: this frees an smcb struct, including its frame stack
-             and anything on the frame stack
+ * Params: pointer to an smcb pointer
+ * Returns: nothing, but sets the pointer to NULL
+ * Synopsis: this frees an smcb struct, including
+ * anything on the frame stack with a zero task_id
  */
 void PINT_smcb_free(struct PINT_smcb **smcb)
 {
     int i;
-    if (smcb)
+    assert(smcb && *smcb);
+    gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
+             "SM free smcb %p op %d\n",*smcb,(*smcb)->op);
+    for (i = 0; i < PINT_FRAME_STACK_SIZE; i++)
     {
-        if (*smcb)
+        if ((*smcb)->frame_stack[i].frame &&
+            (*smcb)->frame_stack[i].task_id == 0)
         {
-            gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
-                     "SM free smcb %p op %d\n",*smcb,(*smcb)->op);
-            for (i = 0; i < PINT_FRAME_STACK_SIZE; i++)
-            {
-                if ((*smcb)->frame_stack[i])
-                {
-                    /* DO we really want to do this??? */
-                    free((*smcb)->frame_stack[i]);
-                }
-            }
-            free(*smcb);
+            /* only free if task_id is 0 */
+            free((*smcb)->frame_stack[i].frame);
         }
-        (*smcb) = (struct PINT_smcb *)0;
+        (*smcb)->frame_stack[i].task_id = 0;
+        (*smcb)->frame_stack[i].frame = NULL;
     }
+    free(*smcb);
+    (*smcb) = (struct PINT_smcb *)0;
 }
 
 /* Function: PINT_pop_state
-   Params: pointer to an smcb pointer
-   Returns: 
-   Synopsis: 
+ * Params: pointer to an smcb pointer
+ * Returns: 
+ * Synopsis: pushes a SM pointer onto a stack for
+ *      implementing nested SMs - called by the
+ *      "next" routine above
  */
+/* should probably be STATIC - WBL */
 struct PINT_state_s *PINT_pop_state(struct PINT_smcb *smcb)
 {
     assert(smcb->stackptr > 0);
@@ -445,10 +479,13 @@ struct PINT_state_s *PINT_pop_state(stru
 }
 
 /* Function: PINT_push_state
-   Params: pointer to an smcb pointer
-   Returns: 
-   Synopsis: 
+ * Params: pointer to an smcb pointer
+ * Returns: 
+ * Synopsis: pops a SM pointer off of a stack for
+ *      implementing nested SMs - called by the
+ *      "next" routine above
  */
+/* should probably be STATIC - WBL */
 void PINT_push_state(struct PINT_smcb *smcb,
 				   struct PINT_state_s *p)
 {
@@ -458,31 +495,37 @@ void PINT_push_state(struct PINT_smcb *s
 }
 
 /* Function: PINT_sm_frame
-   Params: pointer to smcb, stack index
-   Returns: pointer to frame
-   Synopsis: returns a frame off of the frame stack
+ * Params: pointer to smcb, stack index
+ * Returns: pointer to frame
+ * Synopsis: returns a frame off of the frame stack
  */
 void *PINT_sm_frame(struct PINT_smcb *smcb, int index)
 {
-    return smcb->frame_stack[smcb->framebaseptr + index];
+    assert(smcb->framebaseptr + index < smcb->framestackptr);
+    
+    return smcb->frame_stack[smcb->framebaseptr + index].frame;
 }
 
 /* Function: PINT_sm_push_frame
-   Params: pointer to smcb, void pointer for new frame
-   Returns: 
-   Synopsis: pushes a new frame pointer onto the frame_stack
+ * Params: pointer to smcb, void pointer for new frame
+ * Returns: 
+ * Synopsis: pushes a new frame pointer onto the frame_stack
  */
-void PINT_sm_push_frame(struct PINT_smcb *smcb, void *frame_p)
+void PINT_sm_push_frame(struct PINT_smcb *smcb, int task_id, void *frame_p)
  {
+    int index;
     assert(smcb->framestackptr < PINT_FRAME_STACK_SIZE);
 
-    smcb->frame_stack[smcb->framestackptr++] = frame_p;
+    index = smcb->framestackptr;
+    smcb->framestackptr++;
+    smcb->frame_stack[index].task_id = task_id;
+    smcb->frame_stack[index].frame = frame_p;
  }
 
 /* Function: PINT_sm_set
-   Params: pointer to smcb
-   Returns: 
-   Synopsis: This moves the framebaseptr up to the stop of the frame_stack
+ * Params: pointer to smcb
+ * Returns: 
+ * Synopsis: This moves the framebaseptr up to the stop of the frame_stack
  */
 void PINT_sm_set_frame(struct PINT_smcb *smcb)
 {
@@ -491,13 +534,13 @@ void PINT_sm_set_frame(struct PINT_smcb 
     if (smcb->framestackptr == 0)
         smcb->framebaseptr = 0;
     else
-        smcb->framebaseptr = smcb->framestackptr-1;
+        smcb->framebaseptr = smcb->framestackptr - 1;
 }
 
 /* Function: PINT_sm_pop_frame
-   Params: pointer to an smcb pointer
-   Returns: frame pointer
-   Synopsis: pops a frame pointer from the frame_stack and returns it
+ * Params: pointer to an smcb pointer
+ * Returns: frame pointer
+ * Synopsis: pops a frame pointer from the frame_stack and returns it
  */
 void *PINT_sm_pop_frame(struct PINT_smcb *smcb)
 {
@@ -505,36 +548,56 @@ void *PINT_sm_pop_frame(struct PINT_smcb
     void *frame;
     assert(smcb->framestackptr > smcb->framebaseptr);
 
-    index = --smcb->framestackptr;
-    frame = smcb->frame_stack[index];
-    smcb->frame_stack[index + 1] = NULL; /* so we won't free on smcb_free */
+    smcb->framestackptr--;
+    index = smcb->framestackptr;
+    frame = smcb->frame_stack[index].frame;
+    smcb->frame_stack[index].task_id = 0;
+    /* so we won't free on smcb_free */
+    smcb->frame_stack[index].frame = NULL;
     return frame;
 }
 
-/* Function: DUMMY FUNCTION
-   Params: 
-   Returns: 
-   Synopsis: 
+/* Function: PINT_sm_task_map
+ * Params: smcb and an integer task_id
+ * Returns: The state machine a new child state should execute
+ * Synopsis: Uses the task_id and task jump table from the SM
+ *      code to decide which SM a new child should run.  Called
+ *      by the start_child_frames function
  */
-struct PINT_state_s  *PINT_sm_something(void)
+/* should probably be STATIC - WBL */
+struct PINT_state_s *PINT_sm_task_map(struct PINT_smcb *smcb, int task_id)
 {
-    return NULL;
+    struct PINT_pjmp_tbl_s *pjmptbl;
+    int i;
+
+    pjmptbl = smcb->current_state->pjtbl;
+    for (i = 0; ; i++)
+    {
+        if (pjmptbl[i].return_value == task_id ||
+                pjmptbl[i].return_value == -1)
+            return pjmptbl[i].state_machine->first_state;
+    }
 }
 
 /* Function: PINT_sm_start_child_frames
-   Params: pointer to an smcb pointer
-   Returns: 
-   Synopsis: This starts all the enw child SMs based on the frame_stack
+ * Params: pointer to an smcb pointer
+ * Returns: number of children started
+ * Synopsis: This starts all the enw child SMs based on the frame_stack
+ *      This is called by the invoke function above which expects the
+ *      number of children to be returned to decide if the state is
+ *      deferred or not.
  */
+/* should probably be STATIC - WBL */
 void PINT_sm_start_child_frames(struct PINT_smcb *smcb)
 {
-    int i;
+    int i, retval;
     struct PINT_smcb *new_sm;
-    job_status_s *r;
+    job_status_s r;
 
     assert(smcb);
 
-    for(i = smcb->framebaseptr; i < smcb->framebaseptr; i++)
+    /* framebaseptr is the current SM, start at +1 */
+    for(i = smcb->framebaseptr + 1; i < smcb->framestackptr; i++)
     {
         /* allocate smcb */
         PINT_smcb_alloc(&new_sm, smcb->op, 0, NULL,
@@ -544,11 +607,18 @@ void PINT_sm_start_child_frames(struct P
         /* increment parent's counter */
         smcb->children_running++;
         /* assign frame */
-        PINT_sm_push_frame(new_sm, smcb->frame_stack[i]);
+        PINT_sm_push_frame(new_sm, smcb->frame_stack[i].task_id,
+                smcb->frame_stack[i].frame);
         /* locate SM to run */
-        new_sm->current_state = PINT_sm_something();
+        new_sm->current_state = PINT_sm_task_map(smcb,
+                smcb->frame_stack[i].task_id);
+
+fprintf(stderr,"child %d task_id %d state %p flag %d func %p\n",
+    i, smcb->frame_stack[i].task_id, new_sm->current_state,
+    new_sm->current_state->flag, new_sm->current_state->action.func);
+
         /* invoke SM */
-        PINT_state_machine_start(new_sm, r);
+        retval = PINT_state_machine_start(new_sm, &r);
     }
 }
 

Index: state-machine.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/common/misc/state-machine.h,v
diff -p -u -r1.12.4.12 -r1.12.4.13
--- state-machine.h	1 Aug 2006 21:46:15 -0000	1.12.4.12
+++ state-machine.h	29 Aug 2006 20:44:02 -0000	1.12.4.13
@@ -39,6 +39,12 @@
  * function.  See src/server/server-state-machine.c for examples.
  */
 
+struct PINT_frame_s
+{
+    int task_id;
+    void *frame;
+};
+
 /* State machine control block - one per running instance of a state
  * machine
  */
@@ -50,7 +56,7 @@ typedef struct PINT_smcb
     int framestackptr;
     struct PINT_state_s *current_state;
     struct PINT_state_s *state_stack[PINT_STATE_STACK_SIZE];
-    void *frame_stack[PINT_FRAME_STACK_SIZE];
+    struct PINT_frame_s frame_stack[PINT_FRAME_STACK_SIZE];
     /* usage specific routinet to look up SM from OP */
     struct PINT_state_machine_s *(*op_get_state_machine)(int);
     /* state machine context and control variables */
@@ -60,6 +66,7 @@ typedef struct PINT_smcb
     int op_terminate; /* indicates SM is ready to terminate */
     int op_cancelled; /* indicates SM operation was cancelled */
     int children_running; /* the number of child SMs running */
+    /* add a lock here */
     job_context_id context; /* job context when waiting for children */
     int (*terminate_fn)(struct PINT_smcb *, job_status_s *);
     void *user_ptr; /* external user pointer */
@@ -193,9 +200,10 @@ void PINT_smcb_free(struct PINT_smcb **)
 struct PINT_state_s *PINT_pop_state(struct PINT_smcb *);
 void PINT_push_state(struct PINT_smcb *, struct PINT_state_s *);
 void *PINT_sm_frame(struct PINT_smcb *, int);
-void PINT_sm_push_frame(struct PINT_smcb *smcb, void *frame_p);
+void PINT_sm_push_frame(struct PINT_smcb *smcb, int task_id, void *frame_p);
 void PINT_sm_set_frame(struct PINT_smcb *smcb);
 void *PINT_sm_pop_frame(struct PINT_smcb *smcb);
+struct PINT_state_s *PINT_sm_task_map(struct PINT_smcb *smcb, int task_id);
 void PINT_sm_start_child_frames(struct PINT_smcb *smcb);
 
 /* This macro is used in calls to PINT_sm_fram() */



More information about the Pvfs2-cvs mailing list