[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/layers MessageBufferLayerP.nc, 1.4, 1.5

Miklos Maroti mmaroti at users.sourceforge.net
Thu Jul 8 13:04:38 PDT 2010


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/rf2xx/layers
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv23461

Modified Files:
	MessageBufferLayerP.nc 
Log Message:
Fix a race condition in the code path for retrying transmissions (found by Andreas Huber)

Index: MessageBufferLayerP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/rf2xx/layers/MessageBufferLayerP.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** MessageBufferLayerP.nc	29 Jun 2010 22:07:46 -0000	1.4
--- MessageBufferLayerP.nc	8 Jul 2010 20:04:36 -0000	1.5
***************
*** 31,34 ****
--- 31,35 ----
   *
   * Author: Miklos Maroti
+  *         Andreas Huber <huberan at ee.ethz.ch>
   */
  
***************
*** 60,73 ****
  /*----------------- State -----------------*/
  
! 	norace uint8_t state;	// written only from tasks
  	enum
  	{
  		STATE_READY = 0,
  		STATE_TX_PENDING = 1,
! 		STATE_TX_SEND = 2,
! 		STATE_TX_DONE = 3,
! 		STATE_TURN_ON = 4,
! 		STATE_TURN_OFF = 5,
! 		STATE_CHANNEL = 6,
  	};
  
--- 61,75 ----
  /*----------------- State -----------------*/
  
! 	tasklet_norace uint8_t state;
  	enum
  	{
  		STATE_READY = 0,
  		STATE_TX_PENDING = 1,
! 		STATE_TX_RETRY = 2,
! 		STATE_TX_SEND = 3,
! 		STATE_TX_DONE = 4,
! 		STATE_TURN_ON = 5,
! 		STATE_TURN_OFF = 6,
! 		STATE_CHANNEL = 7,
  	};
  
***************
*** 81,88 ****
  			error = EBUSY;
  		else
  			error = call RadioState.turnOn();
  
! 		if( error == SUCCESS )
! 			state = STATE_TURN_ON;
  
  		call Tasklet.resume();
--- 83,92 ----
  			error = EBUSY;
  		else
+ 		{
  			error = call RadioState.turnOn();
  
! 			if( error == SUCCESS )
! 				state = STATE_TURN_ON;
! 		}
  
  		call Tasklet.resume();
***************
*** 100,107 ****
  			error = EBUSY;
  		else
  			error = call RadioState.turnOff();
  
! 		if( error == SUCCESS )
! 			state = STATE_TURN_OFF;
  
  		call Tasklet.resume();
--- 104,113 ----
  			error = EBUSY;
  		else
+ 		{
  			error = call RadioState.turnOff();
  
! 			if( error == SUCCESS )
! 				state = STATE_TURN_OFF;
! 		}
  
  		call Tasklet.resume();
***************
*** 119,126 ****
  			error = EBUSY;
  		else
  			error = call RadioState.setChannel(channel);
  
! 		if( error == SUCCESS )
! 			state = STATE_CHANNEL;
  
  		call Tasklet.resume();
--- 125,134 ----
  			error = EBUSY;
  		else
+ 		{
  			error = call RadioState.setChannel(channel);
  
! 			if( error == SUCCESS )
! 				state = STATE_CHANNEL;
! 		}
  
  		call Tasklet.resume();
***************
*** 173,177 ****
  
  	message_t* txMsg;
! 	error_t txError;
  	uint8_t retries;
  
--- 181,185 ----
  
  	message_t* txMsg;
! 	tasklet_norace error_t txError;
  	uint8_t retries;
  
***************
*** 181,211 ****
  	task void sendTask()
  	{
! 		error_t error;
  
! 		ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND );
  
! 		atomic error = txError;
! 		if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES )
! 			state = STATE_TX_DONE;
! 		else
! 		{
! 			call Tasklet.suspend();
  
! 			error = call RadioSend.send(txMsg);
! 			if( error == SUCCESS )
  				state = STATE_TX_SEND;
- 			else if( retries == MAX_RETRIES )
- 				state = STATE_TX_DONE;
  			else
! 				state = STATE_TX_PENDING;
! 
! 			call Tasklet.resume();
  		}
! 
! 		if( state == STATE_TX_DONE )
  		{
  			state = STATE_READY;
! 			signal Send.sendDone(txMsg, error);
  		}
  	}
  
--- 189,216 ----
  	task void sendTask()
  	{
! 		bool done = FALSE;
  
! 		call Tasklet.suspend();
  
! 		ASSERT( state == STATE_TX_PENDING || state == STATE_TX_DONE );
  
! 		if( state == STATE_TX_PENDING && ++retries <= MAX_RETRIES )
! 		{
! 			txError = call RadioSend.send(txMsg);
! 			if( txError == SUCCESS )
  				state = STATE_TX_SEND;
  			else
! 				state = STATE_TX_RETRY;
  		}
! 		else
  		{
  			state = STATE_READY;
! 			done = TRUE;
  		}
+ 
+ 		call Tasklet.resume();
+ 
+ 		if( done )
+ 			signal Send.sendDone(txMsg, txError);
  	}
  
***************
*** 214,218 ****
  		ASSERT( state == STATE_TX_SEND );
  
! 		atomic txError = error;
  		post sendTask();
  	}
--- 219,228 ----
  		ASSERT( state == STATE_TX_SEND );
  
! 		txError = error;
! 		if( error == SUCCESS )
! 			state = STATE_TX_DONE;
! 		else
! 			state = STATE_TX_PENDING;
! 
  		post sendTask();
  	}
***************
*** 220,238 ****
  	command error_t Send.send(message_t* msg)
  	{
  		if( state != STATE_READY )
! 			return EBUSY;
  
! 		txMsg = msg;
! 		state = STATE_TX_PENDING;
! 		retries = 0;
! 		post sendTask();
  
! 		return SUCCESS;
  	}
  
  	tasklet_async event void RadioSend.ready()
  	{
! 		if( state == STATE_TX_PENDING )
  			post sendTask();
  	}
  
--- 230,260 ----
  	command error_t Send.send(message_t* msg)
  	{
+ 		error_t result;
+ 
+ 		call Tasklet.suspend();
+ 
  		if( state != STATE_READY )
! 			result = EBUSY;
! 		else
! 		{
! 			txMsg = msg;
! 			state = STATE_TX_PENDING;
! 			retries = 0;
! 			post sendTask();
! 			result = SUCCESS;
! 		}
  
! 		call Tasklet.resume();
  
! 		return result;
  	}
  
  	tasklet_async event void RadioSend.ready()
  	{
! 		if( state == STATE_TX_RETRY )
! 		{
! 			state = STATE_TX_PENDING;
  			post sendTask();
+ 		}
  	}
  
***************
*** 243,257 ****
  	command error_t Send.cancel(message_t* msg)
  	{
! 		if( state == STATE_TX_PENDING )
! 		{
! 			state = STATE_READY;
  
! 			// TODO: check if sendDone can be called before cancel returns
! 			signal Send.sendDone(msg, ECANCEL);
  
! 			return SUCCESS;
  		}
  		else
! 			return FAIL;
  	}
  
--- 265,288 ----
  	command error_t Send.cancel(message_t* msg)
  	{
! 		error_t result;
  
! 		call Tasklet.suspend();
  
! 		ASSERT( msg == txMsg );
! 
! 		if( state == STATE_TX_PENDING || state == STATE_TX_RETRY )
! 		{
! 			state = STATE_TX_DONE;
! 			txError = ECANCEL;
! 			result = SUCCESS;
! 
! 			post sendTask();
  		}
  		else
! 			result = EBUSY;
! 
! 		call Tasklet.resume();
! 
! 		return result;
  	}
  



More information about the Tinyos-2-commits mailing list