[Tinyos-2-commits] CVS: tinyos-2.x/tos/system AMQueueImplP.nc, 1.4, 1.5

akoepke andreaskoepke at users.sourceforge.net
Thu Mar 15 06:03:09 PDT 2007


Update of /cvsroot/tinyos/tinyos-2.x/tos/system
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv20697

Modified Files:
	AMQueueImplP.nc 
Log Message:
implemented AMSend.cancel, sendDone(ECANCEL) will be signalled after the
command returned.
updated logic of nextPacket


Index: AMQueueImplP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/system/AMQueueImplP.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** AMQueueImplP.nc	12 Dec 2006 18:23:46 -0000	1.4
--- AMQueueImplP.nc	15 Mar 2007 13:03:06 -0000	1.5
***************
*** 1,25 ****
  // $Id$
  /*
!  * "Copyright (c) 2005 Stanford University. All rights reserved.
!  *
!  * Permission to use, copy, modify, and distribute this software and
!  * its documentation for any purpose, without fee, and without written
!  * agreement is hereby granted, provided that the above copyright
!  * notice, the following two paragraphs and the author appear in all
!  * copies of this software.
!  * 
!  * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
!  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
!  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
!  * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
!  * DAMAGE.
!  * 
!  * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
!  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
!  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
!  * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
!  * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
!  * ENHANCEMENTS, OR MODIFICATIONS."
!  */
  
  /**
--- 1,25 ----
  // $Id$
  /*
! * "Copyright (c) 2005 Stanford University. All rights reserved.
! *
! * Permission to use, copy, modify, and distribute this software and
! * its documentation for any purpose, without fee, and without written
! * agreement is hereby granted, provided that the above copyright
! * notice, the following two paragraphs and the author appear in all
! * copies of this software.
! * 
! * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
! * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
! * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
! * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
! * DAMAGE.
! * 
! * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
! * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
! * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
! * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
! * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
! * ENHANCEMENTS, OR MODIFICATIONS."
! */
  
  /**
***************
*** 36,187 ****
  
  generic module AMQueueImplP(int numClients) {
!   provides interface Send[uint8_t client];
!   uses{
!     interface AMSend[am_id_t id];
!     interface AMPacket;
!     interface Packet;
!   }
  }
  
  implementation {
! 
!   
!   enum {
!     QUEUE_EMPTY = 255,
!   };
! 
!   typedef struct {
!     message_t* msg;
!   } queue_entry_t;
    
!   uint8_t current = QUEUE_EMPTY;
!   queue_entry_t queue[numClients];
! 
  
!   void tryToSend();
    
!   void nextPacket() {
!     uint16_t i;
!     uint8_t initial = current;
!     if (initial == QUEUE_EMPTY) {
!       initial = 0;
!     }
!     i = initial;
!     for (; i < (initial + numClients); i++) {
!       uint8_t client = (uint8_t)i % numClients;
!       if (queue[client].msg != NULL) {
! 	current = client;
! 	return;
!       }
      }
-     current = QUEUE_EMPTY;
-   }
-   
- 
-   /**
-    * Accepts a properly formatted AM packet for later sending.
-    * Assumes that someone has filled in the AM packet fields
-    * (destination, AM type).
-    *
-    * @param msg - the message to send
-    * @param len - the length of the payload
-    *
-    */
-   
-   command error_t Send.send[uint8_t clientId](message_t* msg,
-                                               uint8_t len) {
-     if (clientId > numClients) {return FAIL;}
-     if (queue[clientId].msg != NULL) {return EBUSY;}
-     dbg("AMQueue", "AMQueue: request to send from %hhu (%p): passed checks\n", clientId, msg);
  
!     queue[clientId].msg = msg;
!     call Packet.setPayloadLength(msg, len);
      
!     if (current == QUEUE_EMPTY) {
!       error_t err;
!       am_id_t amId = call AMPacket.type(msg);
!       am_addr_t dest = call AMPacket.destination(msg);
! 
!       dbg("AMQueue", "%s: request to send from %hhu (%p): queue empty\n", __FUNCTION__, clientId, msg);
!       current = clientId;
! 
!       err = call AMSend.send[amId](dest, msg, len);
!       if (err != SUCCESS) {
!         dbg("AMQueue", "%s: underlying send failed.\n", __FUNCTION__);
! 	current = QUEUE_EMPTY;
! 	queue[clientId].msg = NULL;
!       }
!       return err;
!     }
!     else {
!       dbg("AMQueue", "AMQueue: request to send from %hhu (%p): queue not empty\n", clientId, msg);
      }
-     return SUCCESS;
-   }
  
!   command error_t Send.cancel[uint8_t clientId](message_t* msg) {
!     if (clientId > numClients ||         // Not a valid client    
! 	queue[clientId].msg == NULL ||    // No packet pending
! 	queue[clientId].msg != msg) {     // Not the right packet
!       return FAIL;
      }
!     if (current == clientId) {
!       am_id_t amId = call AMPacket.type(msg);
!       error_t err = call AMSend.cancel[amId](msg);
!       if (err == SUCCESS) {
! 	// remove it from the queue
! 	nextPacket();
!       }
!       return err;
      }
!     else {
!       queue[clientId].msg = NULL;
!       return SUCCESS;
      }
-   }
  
!   task void errorTask() {
!     message_t* msg = queue[current].msg;
!     queue[current].msg = NULL;
!     signal Send.sendDone[current](msg, FAIL);
!     tryToSend();
!   }
  
!   // NOTE: Increments current!
!   void tryToSend() {
!     nextPacket();
!     if (current != QUEUE_EMPTY) {
!       error_t nextErr;
!       message_t* nextMsg = queue[current].msg;
!       am_id_t nextId = call AMPacket.type(nextMsg);
!       am_addr_t nextDest = call AMPacket.destination(nextMsg);
!       uint8_t len = call Packet.payloadLength(nextMsg);
!       nextErr = call AMSend.send[nextId](nextDest, nextMsg, len);
!       if (nextErr != SUCCESS) {
! 	post errorTask();
!       }
      }
-   }
    
!   event void AMSend.sendDone[am_id_t id](message_t* msg, error_t err) {
!     if (queue[current].msg == msg) {
!       uint8_t last = current;
!       dbg("PointerBug", "%s received send done for %p, signaling for %p.\n", __FUNCTION__, msg, queue[current].msg);
!       queue[last].msg = NULL;
!       tryToSend();
!       signal Send.sendDone[last](msg, err);
      }
-   }
-   
-   command uint8_t Send.maxPayloadLength[uint8_t id]() {
-     return call AMSend.maxPayloadLength[0]();
-   }
  
!   command void* Send.getPayload[uint8_t id](message_t* m) {
!     return call AMSend.getPayload[0](m);
!   }
  
!  default event void Send.sendDone[uint8_t id](message_t* msg, error_t err) {
!    // Do nothing
!  }
  }
--- 36,202 ----
  
  generic module AMQueueImplP(int numClients) {
!     provides interface Send[uint8_t client];
!     uses{
!         interface AMSend[am_id_t id];
!         interface AMPacket;
!         interface Packet;
!     }
  }
  
  implementation {
!     typedef struct {
!         message_t* msg;
!     } queue_entry_t;
    
!     uint8_t current = numClients; // mark as empty
!     queue_entry_t queue[numClients];
!     uint8_t cancelMask[numClients/8 + 1];
  
!     void tryToSend();
    
!     void nextPacket() {
!         uint8_t i;
!         current = (current + 1) % numClients;
!         for(i = 0; i < numClients; i++) {
!             if((queue[current].msg == NULL) ||
!                (cancelMask[current/8] & (1 << current%8)))
!             {
!                 current = (current + 1) % numClients;
!             }
!             else {
!                 break;
!             }
!         }
!         if(i >= numClients) current = numClients;
      }
  
!     /**
!      * Accepts a properly formatted AM packet for later sending.
!      * Assumes that someone has filled in the AM packet fields
!      * (destination, AM type).
!      *
!      * @param msg - the message to send
!      * @param len - the length of the payload
!      *
!      */
!     command error_t Send.send[uint8_t clientId](message_t* msg,
!                                                 uint8_t len) {
!         if (clientId >= numClients) {
!             return FAIL;
!         }
!         if (queue[clientId].msg != NULL) {
!             return EBUSY;
!         }
!         dbg("AMQueue", "AMQueue: request to send from %hhu (%p): passed checks\n", clientId, msg);
!         
!         queue[clientId].msg = msg;
!         call Packet.setPayloadLength(msg, len);
      
!         if (current >= numClients) { // queue empty
!             error_t err;
!             am_id_t amId = call AMPacket.type(msg);
!             am_addr_t dest = call AMPacket.destination(msg);
!       
!             dbg("AMQueue", "%s: request to send from %hhu (%p): queue empty\n", __FUNCTION__, clientId, msg);
!             current = clientId;
!             
!             err = call AMSend.send[amId](dest, msg, len);
!             if (err != SUCCESS) {
!                 dbg("AMQueue", "%s: underlying send failed.\n", __FUNCTION__);
!                 current = numClients;
!                 queue[clientId].msg = NULL;
!                 
!             }
!             return err;
!         }
!         else {
!             dbg("AMQueue", "AMQueue: request to send from %hhu (%p): queue not empty\n", clientId, msg);
!         }
!         return SUCCESS;
      }
  
!     task void CancelTask() {
!         uint8_t i,j,mask,last;
!         message_t *msg;
!         for(i = 0; i < numClients/8 + 1; i++) {
!             if(cancelMask[i]) {
!                 for(mask = 1, j = 0; j < 8; j++) {
!                     if(cancelMask[i] & mask) {
!                         last = i*8 + j;
!                         msg = queue[last].msg;
!                         queue[last].msg = NULL;
!                         cancelMask[i] &= ~mask;
!                         signal Send.sendDone[last](msg, ECANCEL);
!                     }
!                     mask <<= 1;
!                 }
!             }
!         }
      }
!     
!     command error_t Send.cancel[uint8_t clientId](message_t* msg) {
!         if (clientId >= numClients ||         // Not a valid client    
!             queue[clientId].msg == NULL ||    // No packet pending
!             queue[clientId].msg != msg) {     // Not the right packet
!             return FAIL;
!         }
!         if(current == clientId) {
!             am_id_t amId = call AMPacket.type(msg);
!             error_t err = call AMSend.cancel[amId](msg);
!             return err;
!         }
!         else {
!             cancelMask[clientId/8] |= 1 << clientId % 8;
!             post CancelTask();
!             return SUCCESS;
!         }
      }
! 
!     void sendDone(uint8_t last, message_t *msg, error_t err) {
!         queue[last].msg = NULL;
!         tryToSend();
!         signal Send.sendDone[last](msg, err);
      }
  
!     task void errorTask() {
!         sendDone(current, queue[current].msg, FAIL);
!     }
  
!     // NOTE: Increments current!
!     void tryToSend() {
!         nextPacket();
!         if (current < numClients) { // queue not empty
!             error_t nextErr;
!             message_t* nextMsg = queue[current].msg;
!             am_id_t nextId = call AMPacket.type(nextMsg);
!             am_addr_t nextDest = call AMPacket.destination(nextMsg);
!             uint8_t len = call Packet.payloadLength(nextMsg);
!             nextErr = call AMSend.send[nextId](nextDest, nextMsg, len);
!             if(nextErr != SUCCESS) {
!                 post errorTask();
!             }
!         }
      }
    
!     event void AMSend.sendDone[am_id_t id](message_t* msg, error_t err) {
!         if(queue[current].msg == msg) {
!             sendDone(current, msg, err);
!         }
!         else {
!             dbg("PointerBug", "%s received send done for %p, signaling for %p.\n",
!                 __FUNCTION__, msg, queue[current].msg);
!         }
!     }
!     
!     command uint8_t Send.maxPayloadLength[uint8_t id]() {
!         return call AMSend.maxPayloadLength[0]();
      }
  
!     command void* Send.getPayload[uint8_t id](message_t* m) {
!         return call AMSend.getPayload[0](m);
!     }
  
!     default event void Send.sendDone[uint8_t id](message_t* msg, error_t err) {
!         // Do nothing
!     }
  }



More information about the Tinyos-2-commits mailing list