home *** CD-ROM | disk | FTP | other *** search
- /*
- --- Version 2.0 89-12-17 21:19 ---
-
- CTask Subroutines
-
- Public Domain Software written by
- Thomas Wagner
- Patschkauer Weg 31
- D-1000 Berlin 33
- West Germany
- */
-
- #include <stdio.h>
-
- #include "tsk.h"
- #include "tsklocal.h"
-
-
- /*
- tsk_runable
- Make a task eligible for running. The task is removed from the
- timer queue and enqueued in the eligible queue.
-
- CAUTION: Critical section assumed entered.
- */
-
- void near tsk_runable (tcbptr task)
- {
- task->state = ST_ELIGIBLE;
- tsk_deqtimer (&task->timerq.link);
- tsk_dequeue (&task->cqueue);
- tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
- }
-
-
- /*
- tsk_runable_all
- Make all tasks in a queue eligible for running.
-
- CAUTION: Critical section assumed entered.
- */
-
- void near tsk_runable_all (queheadptr que)
- {
- queptr curr;
- tcbptr task;
-
- for (curr = que->first; curr->kind; )
- {
- task = (tcbptr)curr;
- curr = curr->next;
- task->state = ST_ELIGIBLE;
- tsk_deqtimer (&task->timerq.link);
- tsk_enqueue (task->qhead = &GLOBDATA eligible_queue, &task->cqueue);
- }
- tsk_init_qhead (que);
- }
-
-
- /*
- tsk_wait
- put current running task in wait state.
- Note that the task is NOT enqueued in the respective queue
- here, this is done by the scheduler based on the queue head
- pointer. Only the timeout queue is affected directly.
-
- CAUTION: Critical section assumed entered.
- */
-
- void near tsk_wait (queheadptr que, dword timeout)
- {
- tcbptr curr;
-
- curr = GLOBDATA current_task;
- /*
- Note: The following test shouldn't be necessary. However,
- there is a time when the current task is *not* running, and
- that's while the scheduler is waiting for a task to become
- eligible. If an interrupt handler causes the current task to
- be made waiting during this time, we have to take care not to
- kill the eligible queue. Well, no interrupt handler should ever
- do such a nasty thing, but...
- */
- if (curr->state != ST_RUNNING)
- {
- tsk_dequeue (&curr->cqueue);
- tsk_deqtimer (&curr->timerq.link);
- tsk_enqueue (que, &curr->cqueue);
- }
- curr->qhead = que;
- curr->state = ST_WAITING;
- if (timeout)
- {
- tsk_enqtimer (&curr->timerq.link, timeout);
- curr->timerq.tstate = TSTAT_COUNTDOWN;
- }
- schedule ();
- }
-
-
- /*
- tsk_kill
- mark task as killed.
-
- CAUTION: Critical section assumed entered.
- */
-
- void near tsk_kill (tcbptr task)
- {
- task->state = ST_KILLED;
- task->qhead = NULL;
- tsk_deqtimer (&task->timerq.link);
-
- #if (TSK_NAMED)
- tsk_dequeue ((queptr)&task->name.list);
- #endif
-
- #if (TSK_DYNAMIC)
- if (task->flags & F_STTEMP)
- tsk_free (task->stack);
- if (task->flags & F_TEMP)
- tsk_free (task);
- #endif
- }
-
- /*
- tsk_kill_queue
- Removes all tasks from a queue. For internal use only.
-
- CAUTION: Critical section assumed entered.
- */
-
- void near tsk_kill_queue (queheadptr que)
- {
- queptr curr, next;
-
- for (curr = que->first; curr->kind; )
- {
- next = curr->next;
- tsk_kill ((tcbptr)curr);
- curr = next;
- }
- tsk_init_qhead (que);
- }
-
-
- #if (CLOCK_MSEC)
-
- dword near tsk_timeout (dword tout)
- {
- dword t;
-
- t = (dword) (((double)tout / tick_factor) + 0.5);
- return (t) ? t : 1;
- }
-
- #endif
-
- #if (TSK_NAMED)
-
-
- /*
- tsk_copy_name
- A replacement for strcpy, used for copying names. The C-runtime
- strcpy is not used here to keep the kernel model independent.
- */
-
- void near tsk_copy_name (nameptr elem, byteptr name)
- {
- byteptr n;
- int i;
-
- n = elem->name;
- if (name != NULL)
- for (i = 0; i < 8; i++)
- if ((*n++ = *name++) == 0)
- break;
- *n = 0;
- }
-
-
- /*
- tsk_add_name
- Initialise name-list element and insert it into the name list.
- NOTE: no check is made for duplicate names; names are not sorted.
- */
-
- void near tsk_add_name (nameptr elem, byteptr name, byte kind, farptr strucp)
- {
- CRITICAL;
-
- elem->list.kind = kind;
- elem->strucp = strucp;
- tsk_copy_name (elem, name);
-
- C_ENTER;
- #if (GROUPS)
- tsk_putqueue (&GLOBDATA current_task->group->namelist.list, (queptr)&elem->list);
- #else
- tsk_putqueue (&GLOBDATA name_list.list, &elem.list);
- #endif
- C_LEAVE;
- }
-
-
- /*
- tsk_del_name
- delete name-element from the name-list.
- */
-
- void near tsk_del_name (nameptr elem)
- {
- CRITICAL;
-
- C_ENTER;
- tsk_dequeue ((queptr)&elem->list);
- C_LEAVE;
- }
-
-
- /*
- find_name
- find structure, given name and type.
- If type is zero, the first name-element matching the name is returned.
- If type is nonzero, the first structure matching the name and type is
- returned.
- */
-
- local int near tsk_streq (byteptr n1, byteptr n2)
- {
- while (*n1 && *n1 == *n2)
- {
- n1++;
- n2++;
- }
- return *n1 == *n2;
- }
-
- #if (GROUPS)
- farptr far find_group_name (gcbptr group, byteptr name, int kind)
- {
- queptr curr;
-
- if (kind == TYP_GROUP && tsk_streq (name, group->namelist.name))
- return group;
-
- for (curr = group->namelist.list.first; curr->kind; curr = curr->next)
- if (kind < 0 || (int)curr->kind == kind)
- if (tsk_streq (name, ((nameptr)curr)->name))
- return (kind >= 0) ? ((nameptr)curr)->strucp : curr;
-
- return NULL;
- }
- #endif
-
-
- farptr far find_name (byteptr name, int kind)
- {
- #if (GROUPS)
- farptr curr;
- gcbptr group;
-
- if (tsk_global == NULL)
- if (!ctask_resident ())
- return NULL;
-
- for (group = GLOBDATA current_task->group;
- group != NULL; group = group->home)
- if ((curr = find_group_name (group, name, kind)) != NULL)
- return curr;
- #else
- queueptr curr;
-
- if (kind == TYP_GROUP && tsk_streq (name, GLOBDATA name_list.name))
- return group;
-
- for (curr = GLOBDATA name_list.list.first; curr->kind;
- curr = curr->next)
- if (kind < 0 || (int)curr->kind == kind)
- if (tsk_streq (name, ((nameptr)curr)->name))
- return (kind >= 0) ? ((nameptr)curr)->strucp : curr;
- #endif
-
- return NULL;
- }
- #endif
-
- /*
- tsk_init_qhead
- Initializes the head of a queue.
- */
-
- void near tsk_init_qhead (queheadptr head)
- {
- head->kind = 0;
- head->first = head->last = (queptr)head;
- }
-
-