Example #1
0
//--------------------------------------RETRYING STUFF-------------------------
//repeatedly called by the main loop (once after each loop)
//this function will send a message on any channel that has an expired timestamp and stuff
//waiting to be sent
//effects: decrements timestamps on channels with messages waiting to be sent
//modifies: channelQueuesArray
void randomBackoffRetry() {
  uint8_t channel, qNumber;
  
  for (channel = 1; channel <= MAX_CHANNELS; channel++) {
    disableRTC2(); //needs to be disabled before reading or writing the channelSendWaitTime variable
    qNumber = channel - 1;
    
    /*putnum_uh(channel); putstring(" "); putnum_uh(channelQueuesArray[qNumber].channelRetryLevel); putstring(" ");
      putnum_uh(channelQueuesArray[qNumber].channelSendWaitTime); putstring(" ");
      putnum_uh(channelQueuesArray[qNumber].numMessagesOnQueue); putstring("\n"); */
    
    //check if a channel has messages queued up; if it does, then see if that timestamp has expired
    //expired or not, subtract from the time stamp
    if  ((channelQueuesArray[qNumber].numMessagesOnQueue > 0) &&
	 (channelQueuesArray[qNumber].channelRetryLevel < MAX_RANDOM_BACKOFF_RETRIES) &&
	 (channelQueuesArray[qNumber].channelSendWaitTime == 0))
      {
	
	//---retry sending
	if (rbSendMessageHelper(channel, channelQueuesArray[qNumber].packetList[0].message, channelQueuesArray[qNumber].packetList[0].messageLength) == TRUE) {
	  //putstring("\nSuccesfully sent a message (FROM a queue) on channel, retry level, num messages: "); putnum_uh(channel); putstring(" ");
	  //putnum_uh(channelQueuesArray[qNumber].channelRetryLevel); putstring(" "); putnum_uh(channelQueuesArray[qNumber].numMessagesOnQueue);
	  //putstring("CHANNEL IS NOW GOOD: queue, channel "); putnum_uh(qNumber); putstring(" "); putnum_uh(channel);
	  
	  removeFirstMessageFromQueue(qNumber); //sent this message, so take it off the queue
	  refreshChannel(channel);  //NOTE: we are setting the time stamp to 0   //channel works, so don't need a high retry level now
	  
	  //since the channel became good, and we want to send all the stuff w/o delay (actually we'll delay 1 main loop)
	}
	else {
	  //channel is still bad, don't remove the message from the queue.
	  //increase the time stamp
	  //putstring("CHANNEL IS STILL BAD: queue, channel");  putnum_uh(qNumber);  putstring(" "); putnum_uh(channel);
	  
	  /*if (channel == 1)
	    {
	    putstring("\n failed retry on ch 1: level = "); putnum_ud(channelQueuesArray[qNumber].channelRetryLevel);
	    }*/
	  disableRTC2();
	  channelQueuesArray[qNumber].channelSendWaitTime  = getRandomWaitTime(channelQueuesArray[qNumber].channelRetryLevel);
	  channelQueuesArray[qNumber].channelRetryLevel++; //up the rety time
	  
	  //putstring("\nNEW WAIT TIME = "); putnum_uh(channelQueuesArray[qNumber].channelSendWaitTime); putstring("\n");
	  
	  //clear the queue if it times out, so we don't keep old messages lying around
	  if (channelQueuesArray[qNumber].channelRetryLevel == MAX_RANDOM_BACKOFF_RETRIES) {
	    channelQueuesArray[qNumber].numMessagesOnQueue = 0;
	  }
	}
      }
  }
  enableRTC2();
}
Example #2
0
/**Sends the message to sendList.  If sending fails on one of the channels, the message will be queued up
and an attempt to resend will be made later (randomBackoff style).
 * @param sendList the list of channels to send the message to
 * @param message the message to be sent
 * @param messageLength the length of the message
   @modifies channelQueuesArray
   @effects adds the message to channels in channelQueuesArray if that channel has something queued up
   or if that channel has exceeded the max number of retries
 **/
void rbmSend(uint8_t sendList, uint8_t message[], uint8_t messageLength) {                   
  //send one channel at a time
  uint8_t send_mask = 0x01;
  uint8_t channel;
  
  for (channel=1; channel<=MAX_CHANNELS; channel++) {
    uint8_t qNumber = channel - 1;
    
    if (!(sendList & send_mask)) {
      send_mask <<= 1; // try sending to the next channel
      continue;  //channel is not in the send list
    }
    
    send_mask <<= 1; //for the next time around
        
    //---don't bother sending the message if the channel to send on has something queued up
    if (channelQueuesArray[qNumber].channelRetryLevel > MAX_RANDOM_BACKOFF_RETRIES) {
      //we've already tried too many times to send a message on this channel
      //putstring("\nNOT SENDING MESSAGE.  Exceeded Max Number of tries on channel: ");  putnum_uh(channel); putstring(" "); putnum_uh(channel);
      continue;                       //channel is no good, so don't waste time sending on it
    }
    else if (channelQueuesArray[qNumber].numMessagesOnQueue > 0) {
      //something is queued up and we're currently waiting a random amount of time before sending anything
      //putstring("\nSTUFF ON QUEUE.  ADDING MESSAGE TO CHANNEL, retry level, num messages: ");  putnum_uh(channel); putstring(" ");
      //putnum_uh(channelQueuesArray[qNumber].channelRetryLevel); putstring(" "); putnum_uh(channelQueuesArray[qNumber].numMessagesOnQueue);
      
      putMessageOnQueue(qNumber, message, messageLength);       //add the message to the queue
      continue;
    }
    
    //------------------------------try and send the message. if sending fails, put it on the queue
    if (rbSendMessageHelper(channel, message, messageLength) == TRUE) {
      //putstring("\nSuccesfully sent a message (not from a queue) on channel, retry level, num messages: "); putnum_uh(channel); putstring(" ");
      //putnum_uh(channelQueuesArray[qNumber].channelRetryLevel); putstring(" "); putnum_uh(channelQueuesArray[qNumber].numMessagesOnQueue);
      refreshChannel(channel);
      continue;
    }

    //----sending failed! put the message on the queue
    //didn't succeed, so put the message on the queue and add a time stamp
    //putstring("\nFAILED SENDING: ADDING MESSAGE TO channel, retry level, num messages: ");  putnum_uh(channel);  putstring(" ");
    //putnum_uh(channelQueuesArray[qNumber].channelRetryLevel); putstring(" "); putnum_uh(channelQueuesArray[qNumber].numMessagesOnQueue);
    
    putMessageOnQueue(qNumber, message, messageLength);
    
    disableRTC2();  //the interrupt modifies the channelSendWaitTime variable, so we need to make sure the interrupt doesn't occur during a read or write
    channelQueuesArray[qNumber].channelSendWaitTime = getRandomWaitTime(channelQueuesArray[qNumber].channelRetryLevel++);
    //putstring("\nNEW WAIT TIME = "); putnum_uh(channelQueuesArray[qNumber].channelSendWaitTime); putstring("\n");
    enableRTC2();                  
  }
}
Example #3
0
void* taFn(void* arg)
{
    while (1)
    {
        int* studentId;
        TA_PRINT("I am sleeping, wake me up when you need me!");
        sig_wait_for_signal(&wakeupSignal);

        // we dequeue the student immediately, as he is not on a chair,
        // and we do not want to take the place of someone else.
        studentId = queue_dequeue(&chairsQueue);
        TA_PRINT("I am awake now :(");

        do
        {
            student* s = &students[*studentId - 1];

            // just in case the semaphore was not set yet, so we try to wait
            // until it's been set.
            while (!s->waitSem);
            // notify the student that their turn is now.
            sem_post(s->waitSem);

            // wait for the help time.
            int waitTime = getRandomWaitTime();
            TA_PRINT("Helping student #%d for %d seconds.", *studentId, waitTime);
            sleep(waitTime);

            // notify the student that we're done helping them.
            sem_post(&taHelping);

            // tiny wait to allow the student to print out debugging
            // statements before the next student does.
            usleep(1000);
        } while ((studentId = queue_dequeue(&chairsQueue)) != NULL);
    }

    return NULL;
}