]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/system/ArbiterP.nc
Merge TinyOS 2.1.1 into master.
[tinyos-2.x.git] / tos / system / ArbiterP.nc
index 12ddd8fbbaf0f05d63daa7975a566032342159d4..b07f975dc4e5b2b2e762a90c020aff7772ec43cf 100644 (file)
@@ -34,7 +34,7 @@
  * This component provides the Resource, ResourceRequested, ArbiterInfo, 
  * and ResourceDefaultOwner interfaces and uses the ResourceConfigure interface as
  * described in TEP 108.  It provides arbitration to a shared resource.
- * An Queue is used to keep track of which users have put
+ * A Queue is used to keep track of which users have put
  * in requests for the resource.  Upon the release of the resource by one
  * of these users, the queue is checked and the next user
  * that has a pending request will ge granted control of the resource.  If
  * interface gains access to the resource, and holds onto it until
  * another user makes a request.
  *
- * @param <b>resourceName</b> -- The name of the Resource being shared
+ * @param <b>default_owner_id</b> -- The id of the default owner of this 
+ *        resource
  * 
  * @author Kevin Klues (klues@tkn.tu-berlin.de)
  * @author Philip Levis
  */
  
-generic module ArbiterP(uint8_t controller_id) {
+generic module ArbiterP(uint8_t default_owner_id) @safe() {
   provides {
     interface Resource[uint8_t id];
     interface ResourceRequested[uint8_t id];
@@ -64,10 +65,11 @@ generic module ArbiterP(uint8_t controller_id) {
 implementation {
 
   enum {RES_CONTROLLED, RES_GRANTING, RES_IMM_GRANTING, RES_BUSY};
-  enum {CONTROLLER_ID = controller_id};
+  enum {default_owner_id = default_owner_id};
+  enum {NO_RES = 0xFF};
 
   uint8_t state = RES_CONTROLLED;
-  norace uint8_t resId = CONTROLLER_ID;
+  norace uint8_t resId = default_owner_id;
   norace uint8_t reqResId;
   
   task void grantedTask();
@@ -108,15 +110,18 @@ implementation {
       if(state == RES_BUSY && resId == id) {
         if(call Queue.isEmpty() == FALSE) {
           reqResId = call Queue.dequeue();
+          resId = NO_RES;
           state = RES_GRANTING;
           post grantedTask();
+          call ResourceConfigure.unconfigure[id]();
         }
         else {
-          resId = CONTROLLER_ID;
+          resId = default_owner_id;
           state = RES_CONTROLLED;
+          call ResourceConfigure.unconfigure[id]();
           signal ResourceDefaultOwner.granted();
         }
-        call ResourceConfigure.unconfigure[id]();
+        return SUCCESS;
       }
     }
     return FAIL;
@@ -124,7 +129,7 @@ implementation {
 
   async command error_t ResourceDefaultOwner.release() {
     atomic {
-      if(resId == CONTROLLER_ID) {
+      if(resId == default_owner_id) {
         if(state == RES_GRANTING) {
           post grantedTask();
           return SUCCESS;
@@ -143,6 +148,10 @@ implementation {
     Check if the Resource is currently in use
   */    
   async command bool ArbiterInfo.inUse() {
+    atomic {
+      if (state == RES_CONTROLLED)
+        return FALSE;
+    }
     return TRUE;
   }
 
@@ -152,7 +161,11 @@ implementation {
     will be 0xFF
   */      
   async command uint8_t ArbiterInfo.userId() {
-    atomic return resId;
+    atomic {
+      if(state != RES_BUSY)
+        return NO_RES;
+      return resId;
+    }
   }
 
   /**
@@ -160,13 +173,15 @@ implementation {
    */      
   async command uint8_t Resource.isOwner[uint8_t id]() {
     atomic {
-      if(resId == id) return TRUE;
+      if(resId == id && state == RES_BUSY) return TRUE;
       else return FALSE;
     }
   }
 
   async command uint8_t ResourceDefaultOwner.isOwner() {
-    return call Resource.isOwner[CONTROLLER_ID]();
+    atomic return (state == RES_CONTROLLED
+            || (resId == default_owner_id
+                && (state == RES_GRANTING || state == RES_IMM_GRANTING)));
   }
   
   task void grantedTask() {