home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / CTASK22.ZIP / TSKGRP.C < prev    next >
C/C++ Source or Header  |  1990-10-12  |  6KB  |  232 lines

  1. /*
  2.    --- Version 2.2 90-10-12 10:33 ---
  3.  
  4.    TSKGRP.C - CTask - Create/Remove groups.
  5.  
  6.    CTask - a Multitasking Kernel for C
  7.  
  8.    Public Domain Software written by
  9.       Thomas Wagner
  10.       Ferrari electronic Gmbh
  11.       Beusselstrasse 27
  12.       D-1000 Berlin 21
  13.       Germany
  14.  
  15.    No rights reserved.
  16.  
  17.    This file is new with version 2.1.
  18.    Version 2.1 separates the functions previously collected in tskmain.c into
  19.          tskmain.c - Install tasker and groups
  20.          tskinst.c - Install/Remove main kernel
  21.          tskgrp.c  - Create/remove groups
  22.          tsktask.c - Task creation and deletion
  23.          tsktutl.c - Task utilities (get/set priority etc.)
  24.          tskutil.c - General utilities (preemption, t_delay)
  25.  
  26.    Note: This file will be skipped completely if groups are disabled.
  27. */
  28.  
  29. #include "tsk.h"
  30. #include "tsklocal.h"
  31.  
  32. #if(GROUPS)
  33.  
  34. /* --------------------------------------------------------------------- */
  35.  
  36. typedef struct {
  37.                word  int20;
  38.                word  mem_end;
  39.                byte  reserved1;
  40.                byte  syscall [5];
  41.                dword exit_addr;        /* Where DOS jumps to on EXIT */
  42.                dword ctl_c_addr;
  43.                dword crit_err_addr;
  44.                word  parent_psp;
  45.                byte  open_files [20];
  46.                word  env_segment;
  47.                dword caller_stack;     /* SS:SP of caller for SPAWN */
  48.                word  filetab_len;      /* Number of entries in file table */
  49.                dword filetab_ptr;      /* file table pointer */
  50.                dword nested_psp;       /* whatever that's supposed to mean */
  51.                } psp;
  52.  
  53. typedef psp far *pspptr;
  54.  
  55. /* --------------------------------------------------------------------- */
  56.  
  57.  
  58. void Localfunc tsk_create_group (gcbptr group, byteptr name)
  59. {
  60.    pspptr pspp;
  61.    word _psp;
  62.    CRITICAL;
  63.  
  64. #if (DOS)
  65.    _psp = tsk_getpsp ();
  66.    pspp = TMK_FP(_psp, 0);
  67. #endif
  68.  
  69. #if (TSK_DYNAMIC)
  70. #if (TSK_DYNLOAD)
  71.    group->palloc = tsk_alloc;
  72.    group->pfree = tsk_free;
  73. #else
  74.    group->palloc = LNULL;
  75.    group->pfree = LNULL;
  76. #endif
  77. #endif
  78.  
  79.    tsk_init_qhead (&group->namelist.list, TYP_GROUP);
  80.    tsk_init_qhead (&group->telem_list, TYP_GROUP);
  81.    tsk_init_qhead (&group->ticker_list, TYP_GROUP);
  82.    tsk_copy_name (&group->namelist, name);
  83.    group->creator = GLOBDATA current_task;
  84.    group->branch = LNULL;
  85.    group->home = GLOBDATA current_task->group;
  86.    group->remove = LNULL;
  87.  
  88.    C_ENTER;
  89. #if (DOS)
  90.    group->exit_addr = pspp->exit_addr;
  91.    group->create_psp = _psp;
  92.    if (!(tsk_instflags & IFL_NOEXITCHECK))
  93.       pspp->exit_addr = (dword)GLOBDATA emergency_exit;
  94. #endif
  95.    group->level = group->home->branch;
  96.    group->home->branch = group;
  97.    GLOBDATA current_task->group = group;
  98.    C_LEAVE;
  99. }
  100.  
  101.  
  102. /* --------------------------------------------------------------------- */
  103.  
  104. /*
  105.    tsk_kill_group
  106.       Kills all tasks in the current group and unlinks all structures
  107.       from the name list.
  108. */
  109.  
  110.  
  111. void Localfunc tsk_kill_group (gcbptr group)
  112. {
  113.    nameptr curr;
  114.    tcbptr tsk;
  115. #if (GROUPS)
  116.    queptr qptr;
  117. #endif
  118. #if (DOS)
  119.    pspptr pspp;
  120. #endif
  121.  
  122.    tsk_remove_chain (group->remove);
  123.    tsk_dis_preempt ();
  124.  
  125. #if (DOS)
  126.    pspp = TMK_FP (group->create_psp, 0);
  127.    pspp->exit_addr = group->exit_addr;
  128.    if (group->save_psp)
  129.       {
  130.       group->creator->base_psp = group->save_psp;
  131.       group->creator->psp_sssp = group->save_sssp;
  132.       pspp = TMK_FP (group->save_psp, 0);
  133.       pspp->caller_stack = group->save_sssp;
  134.       }
  135.  
  136. #endif
  137.  
  138.    curr = (nameptr)group->namelist.list.first;
  139.  
  140.    while (!(curr->list.kind & Q_HEAD))
  141.       {
  142.       tsk_del_name (curr);
  143.       if (curr->list.kind == TYP_TCB)
  144.          {
  145.          tsk = (tcbptr)curr->strucp;
  146.          if (tsk != GLOBDATA current_task && !(tsk->flags & F_PERM))
  147.             kill_task (tsk);
  148.          }
  149.  
  150.       curr = (nameptr)group->namelist.list.first;
  151.       }
  152.  
  153.    qptr = group->telem_list.first;
  154.    while (!(qptr->kind & Q_HEAD))
  155.       {
  156.       tsk_dequeue (qptr);
  157.       tsk_deqtimer ((queptr)TSK_STRUCTOP(tlink,qptr,chain));
  158.       qptr = group->telem_list.first;
  159.       }
  160.  
  161.    qptr = group->ticker_list.first;
  162.    while (!(qptr->kind & Q_HEAD))
  163.       {
  164.       delete_ticker (TSK_STRUCTOP(ticker,qptr,chain));
  165.       qptr = group->ticker_list.first;
  166.       }
  167.  
  168.    group->creator->group = group->home;
  169.  
  170.    tsk_ena_preempt ();
  171. }
  172.  
  173.  
  174. /*
  175.    tsk_remove_group
  176.       The current group is unlinked from the group chain, then
  177.       all tasks in the current group, and in all subgroups,
  178.       are killed via "tsk_kill_group".
  179.  
  180.       Returns  0 on normal completion,
  181.                1 when last group must be removed (including the tasker),
  182.               -1 when the group structure was messed up.
  183.  
  184.       CAUTION: This routine is for use by the TSKDOS and remove_tasker
  185.                modules ONLY! Do not call it directly.
  186. */
  187.  
  188. int Localfunc tsk_remove_group (gcbptr group, int freemem)
  189. {
  190.    CRITICAL;
  191.    gcbptr curr, last;
  192.  
  193.    C_ENTER;
  194.    while (group->branch != LNULL)
  195.       tsk_remove_group (group->branch, 1);
  196.  
  197.    if (group->home == LNULL)
  198.       return 1;
  199.  
  200.    last = LNULL;
  201.    curr = group->home->branch;
  202.  
  203.    while (curr != LNULL && curr != group)
  204.       {
  205.       last = curr;
  206.       curr = curr->level;
  207.       }
  208.    if (curr == LNULL)
  209.       return -1;
  210.  
  211.    if (last == LNULL)
  212.       group->home->branch = group->level;
  213.    else
  214.       last->level = group->level;
  215.  
  216.    GLOBDATA current_task->group = group->home;
  217.  
  218.    tsk_kill_group (group);
  219. #if (DOS)
  220.    if (freemem)
  221.       tsk_free_mem (group->create_psp);
  222. #endif
  223.  
  224.    C_LEAVE;
  225.    if (!freemem)
  226.       preempt_on ();
  227.    return 0;
  228. }
  229.  
  230. #endif /* groups */
  231.  
  232.