[Pvfs2-cvs] commit by slang in pvfs2/src/common/misc:
state-machine-fns.c state-machine.h
CVS commit program
cvs at parl.clemson.edu
Wed Apr 2 14:58:30 EST 2008
Update of /projects/cvsroot/pvfs2/src/common/misc
In directory parlweb1:/tmp/cvs-serv7334/src/common/misc
Modified Files:
Tag: pvfs-2-7-branch
state-machine-fns.c state-machine.h
Log Message:
merge of walt's base_frame changes to 2.7 branch.
Index: state-machine-fns.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/state-machine-fns.c,v
diff -p -u -r1.5.2.1 -r1.5.2.2
--- state-machine-fns.c 1 Apr 2008 23:25:07 -0000 1.5.2.1
+++ state-machine-fns.c 2 Apr 2008 19:58:30 -0000 1.5.2.2
@@ -70,7 +70,8 @@ int PINT_state_machine_halt(void)
*/
int PINT_state_machine_terminate(struct PINT_smcb *smcb, job_status_s *r)
{
- struct PINT_frame_s *my_frame, *f;
+ struct PINT_frame_s *f;
+ void *my_frame;
job_id_t id;
/* notify parent */
@@ -83,11 +84,12 @@ int PINT_state_machine_terminate(struct
(int32_t)r->error_code);
assert(smcb->parent_smcb->children_running > 0);
- my_frame = qlist_entry(
- smcb->frames.next, struct PINT_frame_s, link);
+ my_frame = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
+ /* this will loop from TOS down to the base frame */
+ /* base frame will not be processed */
qlist_for_each_entry(f, &smcb->parent_smcb->frames, link)
{
- if(my_frame->frame == f->frame)
+ if(my_frame == f->frame)
{
f->error = r->error_code;
break;
@@ -210,6 +212,9 @@ PINT_sm_action PINT_state_machine_start(
*/
smcb->immediate = 1;
+ /* set the base frame to be the current TOS, which should be 0 */
+ smcb->base_frame = smcb->frame_count - 1;
+
/* run the current state action function */
ret = PINT_state_machine_invoke(smcb, r);
if (ret == SM_ACTION_COMPLETE || ret == SM_ACTION_TERMINATE)
@@ -518,6 +523,8 @@ int PINT_smcb_alloc(
memset(*smcb, 0, sizeof(struct PINT_smcb));
INIT_QLIST_HEAD(&(*smcb)->frames);
+ (*smcb)->base_frame = -1; /* no frames yet */
+ (*smcb)->frame_count = 0;
/* if frame_size given, allocate a frame */
if (frame_size > 0)
@@ -532,6 +539,7 @@ int PINT_smcb_alloc(
/* zero out all members */
memset(new_frame, 0, frame_size);
PINT_sm_push_frame(*smcb, 0, new_frame);
+ (*smcb)->base_frame = 0;
}
(*smcb)->op = op;
(*smcb)->op_get_state_machine = getmach;
@@ -569,62 +577,92 @@ void PINT_smcb_free(struct PINT_smcb *sm
/* Function: PINT_pop_state
* Params: pointer to an smcb pointer
* Returns:
- * Synopsis: pushes a SM pointer onto a stack for
+ * Synopsis: pops a SM pointer off of a stack for
* implementing nested SMs - called by the
* "next" routine above
*/
static struct PINT_state_s *PINT_pop_state(struct PINT_smcb *smcb)
{
+ gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
+ "[SM pop_state]: (%p) op-id: %d stk-ptr: %d base-frm: %d\n",
+ smcb, smcb->op, smcb->stackptr, smcb->base_frame);
+
if(smcb->stackptr == 0)
{
+ /* this is not an error, we terminate if we return NULL */
+ /* this is return from main */
return NULL;
}
- return smcb->state_stack[--smcb->stackptr];
+
+ smcb->stackptr--;
+ smcb->base_frame = smcb->state_stack[smcb->stackptr].prev_base_frame;
+ return smcb->state_stack[smcb->stackptr].state;
}
/* Function: PINT_push_state
* Params: pointer to an smcb pointer
* Returns:
- * Synopsis: pops a SM pointer off of a stack for
+ * Synopsis: pushes a SM pointer into a stack for
* implementing nested SMs - called by the
* "next" routine above
*/
static void PINT_push_state(struct PINT_smcb *smcb,
struct PINT_state_s *p)
{
+ gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
+ "[SM push_state]: (%p) op-id: %d stk-ptr: %d base-frm: %d\n",
+ smcb, smcb->op, smcb->stackptr, smcb->base_frame);
+
assert(smcb->stackptr < PINT_STATE_STACK_SIZE);
- smcb->state_stack[smcb->stackptr++] = p;
+ smcb->state_stack[smcb->stackptr].prev_base_frame = smcb->base_frame;
+ smcb->base_frame = smcb->frame_count - 1;
+ smcb->state_stack[smcb->stackptr].state = p;
+ smcb->stackptr++;
}
/* Function: PINT_sm_frame
* Params: pointer to smcb, stack index
* Returns: pointer to frame
* Synopsis: returns a frame off of the frame stack
+ * An index of 0 indicates the base frame specified in the SMCB
+ * A +'ve index indicates a frame pushed by this SM
+ * A -'ve index indicates a frame from a prior SM
+ * smcb->frames.next is the top of stack
+ * smcb->frames.prev is the bottom of stack
*/
void *PINT_sm_frame(struct PINT_smcb *smcb, int index)
{
struct PINT_frame_s *frame_entry;
- struct qlist_head *next;
+ struct qlist_head *prev;
+ int target = smcb->base_frame + index;
+
+ gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
+ "[SM frame get]: (%p) op-id: %d index: %d base-frm: %d\n",
+ smcb, smcb->op, index, smcb->base_frame);
if(qlist_empty(&smcb->frames))
{
- gossip_debug(GOSSIP_STATE_MACHINE_DEBUG,
- "FRAME GET smcb %p index %d -> frame: NULL\n",
- smcb, index);
+ gossip_err("FRAME GET smcb %p index %d target %d -> List empty\n",
+ smcb, index, target);
return NULL;
}
else
{
- int i = 0;
-
- next = smcb->frames.next;
- while(i < index)
+ /* target should be 0 .. frame_count-1 now */
+ if (target < 0 || target >= smcb->frame_count)
+ {
+ gossip_err("FRAME GET smcb %p index %d target %d -> Out of range\n",
+ smcb, index, target);
+ return NULL;
+ }
+ prev = smcb->frames.prev;
+ while(target--)
{
- i++;
- next = next->next;
+ target--;
+ prev = prev->prev;
}
- frame_entry = qlist_entry(next, struct PINT_frame_s, link);
+ frame_entry = qlist_entry(prev, struct PINT_frame_s, link);
return frame_entry->frame;
}
}
@@ -733,9 +771,9 @@ static void PINT_sm_start_child_frames(s
{
int retval;
struct PINT_smcb *new_sm;
- struct PINT_frame_s *frame_entry;
job_status_s r;
- struct qlist_head *f;
+ struct PINT_frame_s *f;
+ void *my_frame;
assert(smcb);
@@ -743,15 +781,16 @@ static void PINT_sm_start_child_frames(s
*children_started = 0;
+ my_frame = PINT_sm_frame(smcb, PINT_FRAME_CURRENT);
/* Iterate once up front to determine how many children we are going to
* run. This has to be set before starting any children, otherwise if
* the first one immediately completes it will mistakenly believe it is
* the last one and signal the parent.
*/
- qlist_for_each(f, &smcb->frames)
+ qlist_for_each_entry(f, &smcb->frames, link)
{
- /* skip the last since its the parent frame */
- if(f->next == &smcb->frames)
+ /* run from TOS until the parent frame */
+ if(f->frame == my_frame)
{
break;
}
@@ -765,25 +804,22 @@ static void PINT_sm_start_child_frames(s
*/
*children_started = smcb->children_running;
- qlist_for_each(f, &smcb->frames)
+ qlist_for_each_entry(f, &smcb->frames, link)
{
- /* skip the last since its the parent frame */
- if(f->next == &smcb->frames)
+ /* run from TOS until the parent frame */
+ if(f->frame == my_frame)
{
break;
}
-
- frame_entry = qlist_entry(f, struct PINT_frame_s, link);
-
/* allocate smcb */
PINT_smcb_alloc(&new_sm, smcb->op, 0, NULL,
child_sm_frame_terminate, smcb->context);
/* set parent smcb pointer */
new_sm->parent_smcb = smcb;
/* assign frame */
- PINT_sm_push_frame(new_sm, frame_entry->task_id, frame_entry->frame);
+ PINT_sm_push_frame(new_sm, f->task_id, f->frame);
/* locate SM to run */
- new_sm->current_state = PINT_sm_task_map(smcb, frame_entry->task_id);
+ new_sm->current_state = PINT_sm_task_map(smcb, f->task_id);
/* invoke SM */
retval = PINT_state_machine_start(new_sm, &r);
if(retval < 0)
Index: state-machine.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/common/misc/state-machine.h,v
diff -p -u -r1.16.2.1 -r1.16.2.2
--- state-machine.h 1 Apr 2008 23:25:07 -0000 1.16.2.1
+++ state-machine.h 2 Apr 2008 19:58:30 -0000 1.16.2.2
@@ -57,6 +57,12 @@ enum PINT_state_code {
*/
#define PINT_STATE_STACK_SIZE 8
+struct PINT_state_stack_s
+{
+ struct PINT_state_s *state;
+ int prev_base_frame;
+};
+
/* State machine control block - one per running instance of a state
* machine
*/
@@ -65,10 +71,11 @@ typedef struct PINT_smcb
/* state machine execution variables */
int stackptr;
struct PINT_state_s *current_state;
- struct PINT_state_s *state_stack[PINT_STATE_STACK_SIZE];
+ struct PINT_state_stack_s state_stack[PINT_STATE_STACK_SIZE];
- struct qlist_head frames;
- int frame_count;
+ struct qlist_head frames; /* circular list of frames */
+ int base_frame; /* index of current base frame */
+ int frame_count; /* number of frames in list */
/* usage specific routinet to look up SM from OP */
struct PINT_state_machine_s *(*op_get_state_machine)(int);
More information about the Pvfs2-cvs
mailing list