// TCCNT.C - TCtask - Counter handling routines. // V1.1 T.Wagner // V1.2 TECON Ltd. #include #include "tsk.h" #include "tclocal.h" // create_counter - initialises counter. counterptr create_counter (counterptr cnt #if (TSK_NAMEPAR) ,charptr name #endif ) { #if (TSK_DYNAMIC) if (cnt == NULL) { if ((cnt = tsk_alloc (sizeof (counter))) == NULL) return NULL; cnt->flags = F_TEMP; } else cnt->flags = 0; #endif cnt->wait_set = cnt->wait_clear = NULL; cnt->state = 0; #if (TSK_NAMED) tsk_add_name (&cnt->name, name, TYP_COUNTER, cnt); #endif return cnt; } // delete_counter - kills all processes waiting for counter void delete_counter (counterptr cnt) { CRITICAL; C_ENTER; tsk_kill_queue (&(cnt->wait_set)); tsk_kill_queue (&(cnt->wait_clear)); cnt->state = 0L; C_LEAVE; #if (TSK_NAMED) tsk_del_name (&cnt->name); #endif #if (TSK_DYNAMIC) if (cnt->flags & F_TEMP) tsk_free(cnt); #endif } // clear_counter - Sets counter to zero. All tasks waiting for // Counter zero are made eligible. void clear_counter (counterptr cnt) { CRITICAL; C_ENTER; cnt->state = 0L; while (cnt->wait_clear != NULL) cnt->wait_clear = tsk_runable(cnt->wait_clear); C_LEAVE; } // wait_counter_set - Wait until counter is != 0. If counter is != 0 on // entry, the counter is decremented and the task // continues to run. If the counter is decremented to // zero, tasks waiting for zero are made eligible. word_s wait_counter_set (counterptr cnt, dword timeout) { CRITICAL; C_ENTER; if (cnt->state) { // C_ENTER; if (!(--cnt->state)) while (cnt->wait_clear != NULL) cnt->wait_clear =tsk_runable(cnt->wait_clear); C_LEAVE; return 0; } tsk_current->retptr = NULL; tsk_wait (&cnt->wait_set, timeout); return (word_s)tsk_current->retptr; } // wait_counter_clear - Wait until counter is == 0. If counter is == 0 on // entry, the task continues to run. word_s wait_counter_clear (counterptr cnt, dword timeout) { CRITICAL; C_ENTER; if (!cnt->state){ C_LEAVE; return 0; } tsk_current->retptr = NULL; tsk_wait (&cnt->wait_clear, timeout); return (word_s)tsk_current->retptr; } // inc_counter - Increment counter. If there are tasks waiting for the // set state, the first task in the queue is made eligible. void inc_counter (counterptr cnt) { tcbptr curr; CRITICAL; C_ENTER; if ((curr = cnt->wait_set) == NULL) cnt->state++; else cnt->wait_set = tsk_runable(curr); C_LEAVE; } // check_counter - return current counter state. dword check_counter (counterptr cnt) { return cnt->state; }