[Tinyos Core WG] Tep 115

Philip Levis pal at cs.stanford.edu
Mon Feb 12 09:21:05 PST 2007


On Feb 12, 2007, at 7:39 AM, Kevin Klues wrote:

> I really don't like the idea of start() returning SUCCESS when the  
> device is already on because it seems strange to me to have to  
> signal a startDone() event in these cases.  We could just not  
> signal the event, but I like to think that whenever you get a  
> SUCCESS on start() it will be followed by a startDone().  By simply  
> returning FAIL in these cases, this problem could be avoided.
>
> If we return FAIL on these calls, then returning EBUSY when  
> starting would be ambiguous since you wouldn't know whether you  
> should try and call start() again later or not.  You wouldn't want  
> to if it was returned while waiting on a startDone(), but you might  
> if it was because you were waiting on a stopDone().
>
> With my proposal you would know the following information based on  
> all return values...
> SUCCESS - your call to try and start the device succeeded and you  
> will receive a startDone() event letting you know if it actually  
> started up or not.


> FAIL - You really shouldn't have been calling start() in the first  
> place because a) the device is already on or b) you are still  
> waiting on a startDone() event at which point you will proceed as  
> if your redundant call to start had succeeded.

Right -- the issue is that FAIL tells you that you shouldn't have  
called start(), but it doesn't tell you when you can start an  
operation. How would you possibly write code to handle FAIL? You  
don't know whether an event is coming or not.

This comes down to what the priorities are; is it to allow possibly  
faulty code to detect that it has done something wrong, or to  
simplify the interface so it's easier to write code that will work  
properly? I think you FAIL case falls into the former category.

Here's another approach: the return code to the call should clearly  
tell you 2 things:

1) Whether or not you will receive a completion event for the  
requested operation;
2) Whether or not you will receive a completion event for the *other*  
operation.

There are two options for such a table. This is the first (with FAIL  
on redundant operations):

+----------------------+-----------+------------+----------+----------+
| Call                 | Device On | Device Off | Starting | Stopping |
+======================+===========+============+==========+==========+
| SplitControl.start() |  FAIL     |  SUCCESS   | SUCCESS  |  EBUSY   |
|                      |           |  FAIL      |          |          |
+----------------------+-----------+------------+----------+----------+
| SplitControl.stop()  |  SUCCESS  |  FAIL      | EBUSY    | SUCCESS  |
|                      |  FAIL     |            |          |          |
+----------------------+-----------+------------+----------+----------+
| operation            |  depends  |  FAIL      | FAIL     | FAIL     |
|                      |           |  EOFF      | EOFF     | EOFF     |
|                      |           |  EOFF      | SUCCESS  |          |
+----------------------+-----------+------------+----------+----------+

This is the first (with SUCCESS and events on redundant operations):

+----------------------+-----------+------------+----------+----------+
| Call                 | Device On | Device Off | Starting | Stopping |
+======================+===========+============+==========+==========+
| SplitControl.start() |  SUCCESS  |  SUCCESS   | SUCCESS  |  EBUSY   |
|                      |           |  FAIL      |          |          |
+----------------------+-----------+------------+----------+----------+
| SplitControl.stop()  |  SUCCESS  |  SUCCESS   | EBUSY    | SUCCESS  |
|                      |  FAIL     |            |          |          |
+----------------------+-----------+------------+----------+----------+
| operation            |  depends  |  FAIL      | FAIL     | FAIL     |
|                      |           |  EOFF      | EOFF     | EOFF     |
|                      |           |  EOFF      | SUCCESS  |          |
+----------------------+-----------+------------+----------+----------+

In both of these cases, you can follow this logic in a caller:

1) If you receive a SUCCESS, you can expect a completion event;
2) If you receive an EBUSY, you can expect a completion event for the  
other operation;
3) If you receive a FAIL, you should not expect an event.

This gives you a pretty clear and simple FSM on the caller side. With  
your proposal, the FAIL on redundant operations requires you to keep  
an extra bit of state (have I called this but not yet received the  
event?) in order to decipher the FAIL.

I think the tradeoff in start() when on and stop() when off is  
whether we want to push  state into the caller or make the callee  
more complex. If start() when on returns FAIL, then the caller needs  
to keep track of whether the underlying component is started or not.  
This goes back to Joe's comment on Jan 11, 2005 that a getState()  
command would be useful. If start() when on returns SUCCESS, then the  
callee needs to post a task or otherwise generate a startDone(), but  
the caller doesn't have to keep a bit of state.

A third option might be to return a value besides SUCCESS and FAIL in  
response to a start() when on... this would make the upper state  
machine a lot simpler. E.g.:

SUCCESS: you will receive an event
EBUSY : you will receive an event for the other operation
FAIL: you will not receive an event
EALREADY: system is already in that state

So this:

+----------------------+-----------+------------+----------+----------+
| Call                 | Device On | Device Off | Starting | Stopping |
+======================+===========+============+==========+==========+
| SplitControl.start() |  EALREADY |  SUCCESS   | SUCCESS  |  EBUSY   |
|                      |           |  FAIL      |          |          |
+----------------------+-----------+------------+----------+----------+
| SplitControl.stop()  |  SUCCESS  |  EALREADY  | EBUSY    | SUCCESS  |
|                      |  FAIL     |            |          |          |
+----------------------+-----------+------------+----------+----------+
| operation            |  depends  |  FAIL      | FAIL     | FAIL     |
|                      |           |  EOFF      | EOFF     | EOFF     |
|                      |           |  EOFF      | SUCCESS  |          |
+----------------------+-----------+------------+----------+----------+

Phil


More information about the Tinyos-2.0wg mailing list