* 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>controller_id</b> -- The unique id of the resource being arbitrated
+ * @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];
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();
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;
async command error_t ResourceDefaultOwner.release() {
atomic {
- if(resId == CONTROLLER_ID) {
+ if(resId == default_owner_id) {
if(state == RES_GRANTING) {
post grantedTask();
return SUCCESS;
Check if the Resource is currently in use
*/
async command bool ArbiterInfo.inUse() {
+ atomic {
+ if (state == RES_CONTROLLED)
+ return FALSE;
+ }
return TRUE;
}
will be 0xFF
*/
async command uint8_t ArbiterInfo.userId() {
- atomic return resId;
+ atomic {
+ if(state != RES_BUSY)
+ return NO_RES;
+ return resId;
+ }
}
/**
*/
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() {