Example #1
0
/*** get_qentry *******************************************************
   Return an entry from the work queue.  If the queue is empty, this
   fuction blocks.
**********************************************************************/
void get_qentry( Context *ctx, Irregular_Context *itx,
                 int *type,
                 int *i1, int *i2, int *i3,
                 float *f1, float *f2, float *f3, float *f4, float *f5 )
{
   if (Debug) printf("get_qentry\n");

   LOCK_ON( qlock );

   while (qsize==0) {
      qwaiters++;
      LOCK_OFF( qlock );
      WAIT_SEM( qnotempty );
      LOCK_ON( qlock );
      qwaiters--;
   }


   if (qsize>0) {
      /* remove from head */
      *ctx = queue[qhead].ctx;
      *itx = queue[qhead].itx;
      *type = queue[qhead].type;
      *i1 = queue[qhead].i1;
      *i2 = queue[qhead].i2;
      *i3 = queue[qhead].i3;
      *f1 = queue[qhead].f1;
      *f2 = queue[qhead].f2;
      *f3 = queue[qhead].f3;
      *f4 = queue[qhead].f4;
      *f5 = queue[qhead].f5;

      if (Debug) printf("REMOVED FROM POS=%d\n", qhead );

      if (*type!=TASK_QUIT) {
         qhead++;
         if (qhead==QSIZE)
           qhead = 0;

         qsize--;
      }

   }
   else {
      *type = TASK_NULL;
   }
   LOCK_OFF( qlock );
   if (Debug) printf("return\n");
}
Example #2
0
/*
 * Return number of entries still in the queue and the number of threads
 * waiting for work to do.
 * If size==0 and waiters==NumWorkThreads then we're idle.
 */
void get_queue_info( int *size, int *waiters )
{
   LOCK_ON( qlock );
   *size = qsize;
   *waiters = qwaiters;
   LOCK_OFF( qlock );
}
Example #3
0
static void load_record(Irregular_Context itx, int time, int record)
{
   int p;

   LOCK_ON( itx->Mutex );

   if (itx->RecordTable[time][record].CachePos > 0){
      /* already in the cache */
      p = itx->RecordTable[time][record].CachePos;
      if (p >= 0){
         itx->RecordCache[p].Locked = 1;
         itx->RecordCache[p].Age = itx->CacheClock++;
         itx->RecordCache[p].Locked = 0;
      }
      LOCK_OFF( itx->Mutex );
      return;
   }
   else{
      /* not in cache */
      int g;
      g = get_empty_irreg_cache_pos(itx);
      if (!irregular_v5dReadRecord( &itx->G, time, record,
          itx->RecordCache[g].Value,
          itx->RecordCache[g].SoundingValue,
          itx->RecordCache[g].CharData,
          itx->RecordCache[g].SoundingLevel)){
         printf("Error: unable to read record information\n");
         LOCK_OFF( itx->Mutex );
         itx->RecordCache[g].Locked = 0;
         return;
      }
      itx->RecordTable[time][record].DataType = itx->RecordCache[g].DataType;
      itx->RecordTable[time][record].Value = itx->RecordCache[g].Value;
      itx->RecordTable[time][record].SoundingValue = itx->RecordCache[g].SoundingValue;
      itx->RecordTable[time][record].SoundingLevel = itx->RecordCache[g].SoundingLevel;
      itx->RecordTable[time][record].CharData = itx->RecordCache[g].CharData;

      itx->RecordTable[time][record].CachePos = g;
      itx->RecordCache[g].Locked = 1;
      itx->RecordCache[g].Timestep = time;
      itx->RecordCache[g].Rec = record;
      itx->RecordCache[g].Age = itx->CacheClock++;
      LOCK_OFF(itx->Mutex);
      itx->RecordCache[g].Locked = 0;
      return;
   }
}
Example #4
0
static void add_qentry( Context ctx, Irregular_Context itx, 
                        int urgent, int type,
                        int i1, int i2, int i3,
                        float f1, float f2, float f3, float f4, float f5 )
{
   int pos, i, found=0;

   LOCK_ON( qlock );
   while (qsize==QSIZE-2) {
      if (Debug)
         printf("QUEUE FULL!!!\n");
      LOCK_OFF( qlock );
/* WLH 6 Nov 98
      sleep(1);
*/
      /* WLH 6 Nov 98 */
      if (NumThreads==1) {
        do_one_task( 0 );
      }
      else {
        sleep(1);  /* wait a second for the queue to empty a bit */
      }

      LOCK_ON( qlock );
   }

   /* check if already in the queue */
   pos = qhead;
   found = 0;

   for (i=0;i<qsize;i++) {
      /* check if request is already in the queue */
      if (ctx && queue[pos].ctx==ctx &&
          type!=TASK_TRAJ &&
          queue[pos].type==type &&     /* only need to test */
          queue[pos].i1==i1 &&         /* the first four fields */
          queue[pos].i2==i2) {
         /* already in queue, cancel it if urgent */
         found = 1;
         if (urgent)
           queue[pos].type = TASK_NULL;
         break;
      }
      else if (itx && queue[pos].ctx==ctx &&
          queue[pos].type==type &&     /* only need to test */
          queue[pos].i1==i1 &&         /* the first four fields */
          queue[pos].i2==i2) {
         /* already in queue, cancel it if urgent */
         found = 1;
         if (urgent)
           queue[pos].type = TASK_NULL;
         break;
      }
      else {
         pos++;
         if (pos==QSIZE)
           pos = 0;
      }
   }

   if (urgent) {
      /* insert at head */
      if (qhead==0)
         qhead = QSIZE-1;
      else
         qhead--;
      pos = qhead;
      qsize++;
      SIGNAL_SEM( qnotempty );
   }
   else if (!found) {
      /* insert at tail */
      pos = qtail;
      qtail++;
      if (qtail==QSIZE)
        qtail = 0;
      qsize++;
      SIGNAL_SEM( qnotempty );
   }

   queue[pos].ctx = ctx;
   queue[pos].itx = itx;
   queue[pos].type = type;
   queue[pos].i1 = i1;
   queue[pos].i2 = i2;
   queue[pos].i3 = i3;
   queue[pos].f1 = f1;
   queue[pos].f2 = f2;
   queue[pos].f3 = f3;
   queue[pos].f4 = f4;
   queue[pos].f5 = f5;

   if (Debug) { 
      if (urgent)
        printf("**URGENT** **URGENT** **URGENT** **URGENT** ");
      printf("ADDED AT POS=%d\n", pos );
   } 

   LOCK_OFF( qlock );
}
static portTASK_FUNCTION( vHitTask, pvParameters ) {
  int status = INIT;
  int hit_counter = 0;  
  unsigned short hit_interval[HIT_BUTTON_TIMES - 1];
  int hit_interval_index = 0;
  TickType_t tmp_tick, hit_period, hit_previous_tick = 0;  
  int i;
  
	/* The parameters are not used. */
	( void ) pvParameters;
  
  for(;;) {
    switch (status) {
      case INIT: {
        /* Lock up the box */
        LOCK_OFF();
        /* Empty hit interval buffer */
        for (i = 0; i< (HIT_BUTTON_TIMES - 1); i++)
          hit_interval[i] = 0;
        hit_period = 0;
        hit_counter = 0;
        hit_interval_index = 0;
        /* Disable play button interrupt */
        DISABLE_HIT_BUTTON_IT();
        /* Clean play button semaphore */
        while (pdTRUE == xSemaphoreTake(xHitSemaphore, 0));
        /* Enable hit button interrupt */
        ENABLE_HIT_BUTTON_IT();
        status = IDLE;
        break;
      }
      case IDLE: {
        /* Occur when play button is pressed */        
        if (pdTRUE == xSemaphoreTake(xHitSemaphore, portMAX_DELAY)) {
          /* Skip the key jitter step */
          vTaskDelay((TickType_t)KEY_JITTER_DELAY_MS);
          /* Check whether the button was pressed */
          if (Bit_SET == HIT_BUTTON_STATUS()) {
            hit_previous_tick = xTaskGetTickCount();
            hit_counter++;
            status = PROCESS;
          }
          /* Enable hit button interrupt */
          ENABLE_HIT_BUTTON_IT();
        }
        
        break;
      }
      case PROCESS: {
        /* Occur when play button is pressed */        
        if (pdTRUE == xSemaphoreTake(xHitSemaphore, portMAX_DELAY)) {
          /* Skip the key jitter step */
          vTaskDelay((TickType_t)KEY_JITTER_DELAY_MS);
          /* Check whether the button was pressed */
          if (Bit_SET == HIT_BUTTON_STATUS()) {
            /* Update hit interval */
            tmp_tick = xTaskGetTickCount();
            hit_period -= hit_interval[hit_interval_index];
            hit_interval[hit_interval_index] = tmp_tick - hit_previous_tick;
            hit_period += hit_interval[hit_interval_index];
            hit_previous_tick = tmp_tick;
            hit_interval_index++;
            if (hit_interval_index == HIT_BUTTON_TIMES - 1)
              hit_interval_index = 0;
            /* Increase hit counter */
            hit_counter++;
            
            if(hit_counter >= HIT_BUTTON_TIMES) {
              hit_counter = HIT_BUTTON_TIMES;
              if (hit_period <= HIT_BUTTON_PERIOD) {
                status = ACTION;
              } else {
                ENABLE_HIT_BUTTON_IT();
              }
            } else {
              ENABLE_HIT_BUTTON_IT();
            }
          } else {
            ENABLE_HIT_BUTTON_IT();
          }
        }
        
        break;
      }
      case ACTION: {
        /* Open the box */
        LOCK_ON();
        status = FINISH;
        break;
      }
      case FINISH: {
        /* Reset logic */
        if (pdTRUE == xSemaphoreTake(xResetSemaphore, portMAX_DELAY)) {
          status = INIT;
        }
        break;
      }
    }
  }
}