home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_300
/
330_03
/
tskgrp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-12
|
6KB
|
232 lines
/*
--- 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 */