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

📄 tskgrp.c

📁 一个嵌入式实时操作系统源码
💻 C
字号:
/*
   --- Version 2.2 91-05-16 23:55 ---

   TSKGRP.C - CTask - Create/Remove groups.

   CTask - a Multitasking Kernel for C

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

   No rights reserved.

   This file is new with version 2.1.
   Version 2.1 separates the functions previously collected in tskmain.c into
         tskmain.c - Install tasker and groups
         tskinst.c - Install/Remove main kernel
         tskgrp.c  - Create/remove groups
         tsktask.c - Task creation and deletion
         tsktutl.c - Task utilities (get/set priority etc.)
         tskutil.c - General utilities (preemption, t_delay)

   Note: This file will be skipped completely if groups are disabled.
*/

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

#if(GROUPS)

/* --------------------------------------------------------------------- */

typedef struct {
               word  int20;
               word  mem_end;
               byte  reserved1;
               byte  syscall [5];
               dword exit_addr;        /* Where DOS jumps to on EXIT */
               dword ctl_c_addr;
               dword crit_err_addr;
               word  parent_psp;
               byte  open_files [20];
               word  env_segment;
               dword caller_stack;     /* SS:SP of caller for SPAWN */
               word  filetab_len;      /* Number of entries in file table */
               dword filetab_ptr;      /* file table pointer */
               dword nested_psp;       /* whatever that's supposed to mean */
               } psp;

typedef psp far *pspptr;

/* --------------------------------------------------------------------- */


void Localfunc tsk_create_group (gcbptr group, byteptr name)
{
   pspptr pspp;
   word _psp;
   CRITICAL;

#if (DOS)
   _psp = tsk_getpsp ();
   pspp = (pspptr)TMK_FP(_psp, 0);
#endif

#if (TSK_DYNAMIC)
#if (TSK_DYNLOAD)
   group->palloc = tsk_alloc;
   group->pfree = tsk_free;
#else
   group->palloc = LNULL;
   group->pfree = LNULL;
#endif
#endif

   tsk_init_qhead (&group->namelist.list, TYP_GROUP);
   tsk_init_qhead (&group->telem_list, TYP_GROUP);
   tsk_init_qhead (&group->ticker_list, TYP_GROUP);
   tsk_copy_name (&group->namelist, name);
   group->creator = GLOBDATA current_task;
   group->branch = LNULL;
   group->home = GLOBDATA current_task->group;
   group->remove = LNULL;

   C_ENTER;
#if (DOS)
   group->exit_addr = pspp->exit_addr;
   group->create_psp = _psp;
   if (!(tsk_instflags & IFL_NOEXITCHECK))
      pspp->exit_addr = (dword)GLOBDATA emergency_exit;
#endif
   group->level = group->home->branch;
   group->home->branch = group;
   GLOBDATA current_task->group = group;
   C_LEAVE;
}


/* --------------------------------------------------------------------- */

/*
   tsk_kill_group
      Kills all tasks in the current group and unlinks all structures
      from the name list.
*/


void Localfunc tsk_kill_group (gcbptr group)
{
   nameptr curr;
   tcbptr tsk;
#if (GROUPS)
   queptr qptr;
#endif
#if (DOS)
   pspptr pspp;
#endif

   tsk_remove_chain (group->remove);
   tsk_dis_preempt ();

#if (DOS)
   pspp = (pspptr)TMK_FP (group->create_psp, 0);
   pspp->exit_addr = group->exit_addr;
   if (group->save_psp)
      {
      group->creator->base_psp = group->save_psp;
      group->creator->psp_sssp = group->save_sssp;
      pspp = (pspptr)TMK_FP (group->save_psp, 0);
      pspp->caller_stack = group->save_sssp;
      }

#endif

   curr = (nameptr)group->namelist.list.first;

   while (!(curr->list.kind & Q_HEAD))
      {
      tsk_del_name (curr);
      if (curr->list.kind == TYP_TCB)
         {
         tsk = (tcbptr)curr->strucp;
         if (tsk != GLOBDATA current_task && !(tsk->flags & F_PERM))
            kill_task (tsk);
         }

      curr = (nameptr)group->namelist.list.first;
      }

   qptr = group->telem_list.first;
   while (!(qptr->kind & Q_HEAD))
      {
      tsk_dequeue (qptr);
      tsk_deqtimer ((queptr)TSK_STRUCTOP(tlink,qptr,chain));
      qptr = group->telem_list.first;
      }

   qptr = group->ticker_list.first;
   while (!(qptr->kind & Q_HEAD))
      {
      delete_ticker (TSK_STRUCTOP(ticker,qptr,chain));
      qptr = group->ticker_list.first;
      }

   group->creator->group = group->home;

   tsk_ena_preempt ();
}


/*
   tsk_remove_group
      The current group is unlinked from the group chain, then
      all tasks in the current group, and in all subgroups,
      are killed via "tsk_kill_group".

      Returns  0 on normal completion,
               1 when last group must be removed (including the tasker),
              -1 when the group structure was messed up.

      CAUTION: This routine is for use by the TSKDOS and remove_tasker
               modules ONLY! Do not call it directly.
*/

int Localfunc tsk_remove_group (gcbptr group, int freemem)
{
   CRITICAL;
   gcbptr curr, last;

   C_ENTER;
   while (group->branch != LNULL)
      tsk_remove_group (group->branch, 1);

   if (group->home == LNULL)
      return 1;

   last = LNULL;
   curr = group->home->branch;

   while (curr != LNULL && curr != group)
      {
      last = curr;
      curr = curr->level;
      }
   if (curr == LNULL)
      return -1;

   if (last == LNULL)
      group->home->branch = group->level;
   else
      last->level = group->level;

   GLOBDATA current_task->group = group->home;

   tsk_kill_group (group);
#if (DOS)
   if (freemem)
      tsk_free_mem (group->create_psp);
#endif

   C_LEAVE;
   if (!freemem)
      preempt_on ();
   return 0;
}

#endif /* groups */

⌨️ 快捷键说明

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