[Tinyos-devel] SimpleArbiterP bug
Kevin Klues
klueska at gmail.com
Wed Oct 15 11:00:56 PDT 2008
Its definitely necessary in the case of immediateRequest(). Not so
necessary in the normal request() case.
Kevin
On Wed, Oct 15, 2008 at 10:48 AM, Razvan Musaloiu-E. <razvanm at cs.jhu.edu> wrote:
> Hi!
>
> On Wed, 15 Oct 2008, Philip Levis wrote:
>
>> I think this is a bug in SimpleArbiterP, but wanted to check with
>> everyone to make sure. In particular, whether there are existing
>> systems which depend on the current behavior, such that fixing it
>> would break them.
>>
>> A bit of background: arbiters (power locks) are built around
>> SimpleArbiterP. SimpleArbiterP uses a queue interface, and the
>> implementation of that queue interface controls its locking policy
>> (e.g., First-come, first-served vs. round-robin).
>>
>> The test case is as follows. I'm using indentation to show the call
>> graph. E.g., 2a is called on 2's stack frame.
>>
>> 1. Client A requests and acquires power lock P
>> 2. Client B requests power lock P
>> 2a. P signals to Client A that the lock has been requested
>> 2aa. Client A releases P
>> 2ab. Client A re-requests P
>>
>> In this case, I think that P should grant to B; 2aa and 2ab are a
>> yield from A. When B releases the lock, A will re-acquire it. However,
>> the request code looks like this (immediateRequest is similar):
>>
>> async command error_t Resource.request[uint8_t id]() {
>> signal ResourceRequested.requested[resId]();
>
> Is this signal absolutely necessary here? Could we move it to a taks? What
> we have here is basically an instance of the first programming hint:
> It dangerous to signal events from commands, as you might cause a
> very long call loop, corrupt memory and crash your program.
>
> --
> Razvan ME
>
>> atomic {
>> if(state == RES_CONTROLLED) {
>> state = RES_GRANTING;
>> reqResId = id;
>> }
>> else return call Queue.enqueue(id);
>> }
>> signal ResourceDefaultOwner.requested();
>> return SUCCESS;
>> }
>>
>> Because requested() is signaled before the caller's request is put on
>> the queue, then in the case above, this is what happens:
>>
>> 1. Client A requests and acquires power lock P
>> 2. Client B requests power lock P
>> 2a. P signals to Client A that the lock has been requested
>> 2aa. Client A releases P
>> 2ab. Client A re-requests P
>> 2aba. P puts A at head of queue
>> 2abb. P posts a task to grant A the lock
>> 2b. P puts B on queue
>> ....
>> 3. A re-acquires lock, while B is waiting on queue
>>
>> I think the code should be this:
>>
>> async command error_t Resource.request[uint8_t id]() {
>> bool getsNow = TRUE;
>> atomic {
>> if(state == RES_CONTROLLED) {
>> state = RES_GRANTING;
>> reqResId = id;
>> getsNow = FALSE;
>> }
>> }
>> if (getsNow == FALSE) {
>> error_t rval = call Queue.enqueue(id);
>> signal ResourceRequested.requested[resId]();
>> return rval;
>> }
>> else {
>> signal ResourceDefaultOwner.requested();
>> return SUCCESS;
>> }
>> }
>>
>> Thoughts?
>>
>> Phil
>>
>>
>> _______________________________________________
>> Tinyos-devel mailing list
>> Tinyos-devel at millennium.berkeley.edu
>> https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-devel
>>
> _______________________________________________
> Tinyos-devel mailing list
> Tinyos-devel at millennium.berkeley.edu
> https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-devel
>
--
~Kevin
More information about the Tinyos-devel
mailing list