Phil Carns wrote:
Walter B. Ligon III wrote:
OK, guys, I have another issue I want input on. When child SMs
terminate they have to notify their parent. The parent has to wait
for all the children to terminate. So I've been thinking to use the
job subsystem for this: the parent would post a job to wait for N
children,
and each child would post a job, the last one releasing the parent.
Now I see two ways to implement this - one is to implement this
directly in the state machine code. The parent simply stops running
(because it does not schedule a job yet returns DEFERRED). Each child
decrements a counter, and when it hits 0 the parent is restarted.
This is a little ugly because the waiting parent is not being held on
any list or queue (up to now all waiting SMs are in the job
subsystem), also the last terminating child becomes the parent as it
starts executing the parent code. Things can get weird when one SM
starts children that start children, and so on.
Now the other way to implement this is with the job subsystem as I
suggested above. Much cleaner except for one thing: up to now the
state machine subsystem has had no dependency at all on the job
subsystem. If we do it this way, this function only works with the
job system intact. I'd prefer not to do this, but it does seem the
cleanest, most logical means.
I like the job approach. I guess this is an extra dependency because
the sms would be calling these particular job functions implicitly,
rather than relying on the state functions to handle those posts and
releases? We definitely haven't done that before, but at least in this
case the job function that the sm infrastructure would be depending on
is the simplest one in the arsenal :) It shouldn't be hard for someone
to reimplement that particular functionality if they wanted to use the
state machine mechanism in another project.
If you weren't planning on these job calls to be implicit, then I'm not
sure where the extra dependency is- we already use jobs to trigger all
of the other "normal" transitions.
This reminded me of a question, though- is there going to be a standard
mechanism for the children to report each of their independent error
codes to the parent sm? Or do the children need to just keep a
reference to the parent sm structure and manually fill in an array or
something?
I guess I have a broader question of how data that the children generate
(like a handle value or an attr structure) gets transferred to the
parent. Does the parent copy this stuff from the child after the child
finishes, or does the child copy it to the parent before it exits? I
think we talked about this before at some point but I forgot what the
plan is. It would be nice if we made the developer define macros or
something to dictate what the input parameters need to be filled in when
invoking a child and what output parameters can be retrieved when it
finishes. Otherwise it starts getting tricky to remember what fields
need to be set in the sm structure before kicking something off.
Phil, first your questions: The parent will push a "frame" onto a stack
for each child it is starting. A frame is everything that used to be in
either a s_op or sm_p on the server or client, except for the stuff that
actually runs the SM (now in an smcb). The parent can pass in anything
it wants by filling in the fields appropriately. When each child runs
that struct will appear to be its "current" frame. Each child can leave
that frame in any condition it wants, with any values of buffers the
child wants to leave for the parent. After the children are done the
parent can pop each frame off the stack and do what it wants with it.
Thus there is plenty of flexibility on how you want to handle passing
things in and out, all under control of the server or client code.
As for providing macros for setting up and tearing down frames, we can
certainly do that. I'm not sure hoe much that really helps, but we can
do it.
Now, an implementation question - one approach to this job/counter thing
is to have two job calls, one for the parent, and one of the children.
Another approach is for the parent to simple set a counter and not call
anything. The children come along, decrement the count, and if zero,
call job_null() to awaken the parent. Requires no modification in the
job layer, minimizes dependency. What do you think? Should the job
layer have more of a roll, or keep it minimum?
Walt
--
Dr. Walter B. Ligon III
Associate Professor
ECE Department
Clemson University
_______________________________________________
Pvfs2-developers mailing list
Pvfs2-developers@beowulf-underground.org
http://www.beowulf-underground.org/mailman/listinfo/pvfs2-developers