/*** 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"); }
/* * 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 ); }
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; } }
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; } } } }