⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tskcnt.c

📁 一个多任务操作系统CTask的源代码 用C语言编写
💻 C
字号:
/*
   --- Version 2.2 91-05-17 00:00 ---

   TSKCNT.C - CTask - Counter handling routines.

   Public Domain Software written by
      Thomas Wagner
      Ferrari electronic Gmbh
      Beusselstrasse 27
      D-1000 Berlin 21
      Germany

   Version 2.1 adds the dec_counter operation, and changes inc_counter
   to return the new value of the counter state (previously, it returned
   nothing).
*/

#include "tsk.h"
#include "tsklocal.h"

/*
   create_counter - initialises counter.
*/

counterptr Globalfunc create_counter (counterptr cnt TN(byteptr name))
{
#if (TSK_DYNAMIC)
   if (cnt == LNULL)
      {
      if ((cnt = (counterptr)tsk_palloc (sizeof (counter))) == LNULL)
         return LNULL;
      cnt->flags = F_TEMP;
      }
   else
      cnt->flags = 0;
#endif

   tsk_init_qhead (&cnt->wait_set, TYP_COUNTER);
   tsk_init_qhead (&cnt->wait_clear, TYP_COUNTER);
   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 Globalfunc delete_counter (counterptr cnt)
{
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Delete Counter");

   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_pfree (cnt);
#endif
}


/*
   clear_counter  - Sets counter to zero. All tasks waiting for
                    Counter zero are made eligible.
*/

void Globalfunc clear_counter (counterptr cnt)
{
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Clear Counter");

   C_ENTER;
   cnt->state = 0L;
   tsk_runable_all (&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.
*/

int Globalfunc wait_counter_set (counterptr cnt, dword timeout)
{
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Wait Counter Set");

   C_ENTER;
   if (cnt->state)
      {
      if (!--cnt->state)
         tsk_runable_all (&cnt->wait_clear);
      C_LEAVE;
      return 0;
      }

   GLOBDATA current_task->retptr = LNULL;
   tsk_wait (&cnt->wait_set, timeout);
   return (int)((dword)GLOBDATA current_task->retptr);
}

/*
   wait_counter_clear - Wait until counter is == 0. If counter is == 0 on
                       entry, the task continues to run.
*/

int Globalfunc wait_counter_clear (counterptr cnt, dword timeout)
{
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Wait Counter Clear");

   C_ENTER;
   if (!cnt->state)
      {
      C_LEAVE;
      return 0;
      }

   GLOBDATA current_task->retptr = LNULL;
   tsk_wait (&cnt->wait_clear, timeout);
   return (int)((dword)GLOBDATA current_task->retptr);
}


/*
   inc_counter - Increment counter. If there are tasks waiting for the
                 set state, the first task in the queue is made eligible.
                 Returns new value of counter state.
*/

dword Globalfunc inc_counter (counterptr cnt)
{
   dword st;
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Inc Counter");

   C_ENTER;
   if (cnt->wait_set.first->kind & Q_HEAD)
      {
      st = ++cnt->state;
      C_LEAVE;
      return st;
      }
   tsk_runable ((tcbptr)cnt->wait_set.first);
   C_LEAVE;
   return 0L;
}


/*
   dec_counter - Decrement counter. If there are tasks waiting for the
                 zero state, all are made eligible.
                 Returns new value of counter state.
*/

dword Globalfunc dec_counter (counterptr cnt)
{
   dword st;
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Dec Counter");

   C_ENTER;
   if (cnt->state)
      {
      if ((st = --cnt->state) == 0)
         tsk_runable_all (&cnt->wait_clear);
      C_LEAVE;
      return st;
      }
   C_LEAVE;
   return 0L;
}


/*
   check_counter - return current counter state.
*/

dword Globalfunc check_counter (counterptr cnt)
{
   CHECK_EVTPTR (cnt, TYP_COUNTER, "Check Counter");
   return cnt->state;
}



/*
   set_counter  - Sets counter to given value. Depending on the value,
                  tasks waiting for counter zero or counter set are made
                  eligible.
*/

void Globalfunc set_counter (counterptr cnt, dword val)
{
   CRITICAL;

   CHECK_EVTPTR (cnt, TYP_COUNTER, "Set Counter");

   C_ENTER;
   while (val && !(cnt->wait_set.first->kind & Q_HEAD))
      {
      tsk_runable ((tcbptr)cnt->wait_set.first);
      val--;
      }
   if (!val)
      tsk_runable_all (&cnt->wait_clear);
   cnt->state = val;
   C_LEAVE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -