home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload
/
ShartewareOverload.cdr
/
progm
/
ctask.zip
/
TSKSUB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-03-01
|
4KB
|
194 lines
/*
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_enqueue inserts a task into a queue based on priority.
*/
void far tsk_enqueue (tcbptr task, tqueptr que)
{
tcbptr last, curr;
last = NULL;
curr = *que;
while (curr != NULL && curr->prior >= task->prior)
{
last = curr;
curr = curr->next;
}
task->next = curr;
if (last == NULL)
*que = task;
else
last->next = task;
task->queue = que;
}
/*
tsk_unqueue
Removes a task from somewhere in the middle of a queue. It is only
used when stopping or prematurely waking a task, since in all other
circumstances a task is only removed from the head of a queue.
*/
void far tsk_unqueue (tcbptr task)
{
tcbptr last, curr;
if (task->state == ST_RUNNING || task->queue == NULL)
return;
last = NULL;
curr = *task->queue;
while (curr != task)
{
if (curr == NULL)
return;
last = curr;
curr = curr->next;
}
if (last == NULL)
*task->queue = curr->next;
else
last->next = curr->next;
task->queue = NULL;
}
/*
tsk_enqtimer inserts a task into the timer queue.
*/
void far tsk_enqtimer (tcbptr task, dword tout)
{
dlinkptr curr;
if (tout == 0)
return;
/*
Tasks are not sorted in the timer queue, so the task is inserted
at the queue head. The timer task has to step through all tasks
in the queue to cont down the timeout, so sorting would not bring
any advantages.
*/
curr = &task->timerq;
curr->follow = tsk_timer.follow;
curr->prev = &tsk_timer;
tsk_timer.follow = curr;
curr->follow->prev = curr;
curr->timeout = tout;
task->flags |= F_TIMER;
}
/*
tsk_unqtimer
Removes a task from the timer queue.
*/
void far tsk_unqtimer (tcbptr task)
{
dlinkptr curr;
if (!(task->flags & F_TIMER))
return;
task->flags &= ~F_TIMER;
curr = &task->timerq;
curr->prev->follow = curr->follow;
curr->follow->prev = curr->prev;
}
/*
tsk_runable
make a task eligible for running. The task is removed from the
timer queue and enqueued in the eligible queue. The old "next"
pointer of the tcb is returned. This assumes that the task
is removed from the head of a queue.
*/
tcbptr far tsk_runable (tcbptr task)
{
tcbptr nxt;
nxt = task->next;
task->state = ST_ELIGIBLE;
tsk_unqtimer (task);
tsk_enqueue (task, &tsk_eligible);
return nxt;
}
/*
tsk_wakeup
make a task eligible for running. The task is removed from the
timer queue and enqueued in the eligible queue.
This routine assumes that the task is removed from the middle of
a queue.
*/
void far tsk_wakeup (tcbptr task)
{
task->state = ST_ELIGIBLE;
tsk_unqueue (task);
tsk_unqtimer (task);
tsk_enqueue (task, &tsk_eligible);
}
/*
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.
*/
void far tsk_wait (tqueptr que, dword timeout)
{
tsk_current->state = ST_WAITING;
tsk_current->queue = que;
tsk_enqtimer (tsk_current, timeout);
schedule ();
}
/*
tsk_kill_queue
Removes all tasks from a queue. For internal use only, critical
section assumed entered.
*/
void far tsk_kill_queue (tqueptr que)
{
tcbptr curr;
for (curr = *que; curr != NULL; curr = curr->next)
{
tsk_unqtimer (curr);
curr->state = ST_KILLED;
}
*que = NULL;
}