home *** CD-ROM | disk | FTP | other *** search
- /*
- --- Version 2.2 90-10-12 10:33 ---
-
- 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 = 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 = 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 = 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 */
-
-