home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
djsrc106.arj
/
TASK.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-20
|
3KB
|
164 lines
#include <stdio.h>
#include <string.h>
#include <pc.h>
#include "Task.h"
#define dprintf if(0)printf
Task *thisTask=0;
static Task *task_list=0;
void TaskList()
{
Task *t;
for (t=task_list; t; t=t->next)
{
char *rs="Unknown";
switch (t->run_state)
{
case Task::Running: rs="Running"; break;
case Task::Blocked: rs="Blocked"; break;
case Task::Waiting: rs="Waiting"; break;
case Task::Dead: rs="Dead"; break;
}
dprintf(" 0x%08x p=0x%08x s=%s\n", t, t->parent, rs);
}
}
static int fall_off_end()
{
int rv;
asm("movl %%eax,%0" : "=g" (rv) );
Return(rv);
return 0;
}
Task::Task(TaskProc proc, int val, void* ptr, int stacksize)
{
prev = 0;
next = task_list;
if (task_list)
task_list->prev = this;
task_list = this;
parent = thisTask;
run_state = Running;
memset(state, 0, sizeof(state));
stack = 0;
if (proc)
{
stack_len = stacksize;
stack = new unsigned[stacksize];
unsigned *sp = stack+stacksize;
*--sp = (unsigned) ptr;
*--sp = (unsigned) val;
*--sp = (unsigned) fall_off_end;
state->esp = (unsigned)(stack+stacksize-3);
state->eip = (unsigned long) proc;
}
if (thisTask == 0)
thisTask = this;
dprintf("Task::Task -> 0x%x\n", this);
}
Task::~Task()
{
dprintf("Task::~Task <= 0x%x\n", this);
if (task_list == this)
task_list = next;
if (prev)
prev->next = next;
if (next)
next->prev = prev;
if (parent)
parent->run_state = Running;
if (stack)
delete stack;
if (this == thisTask)
Yield();
TaskList();
}
int Task::ReturnValue()
{
return ret_val;
}
int Wait(Task* child)
{
int rv;
int waiting = 1;
if (child)
dprintf("Task::Wait for 0x%x\n", child);
else
dprintf("Task::Wait\n");
while (waiting)
{
waiting = 0;
if (child)
{
if (child->run_state == Task::Dead)
{
rv = child->ret_val;
delete child;
return rv;
}
}
Task *t, *tn;
for (t=task_list; t; t=tn)
{
tn = t->next;
if (t->parent == thisTask)
{
if (t->run_state == Task::Dead)
{
dprintf("Dead child 0x%x\n", t);
delete t;
}
else
{
dprintf("Running child 0x%x\n", t);
waiting = 1;
}
}
}
if (waiting)
{
dprintf("parent waiting...\n");
thisTask->run_state = Task::Waiting;
Yield();
}
}
}
void Return(int rv)
{
dprintf("Task::Return(%d) <- 0x%x\n", rv, thisTask);
thisTask->ret_val = rv;
thisTask->run_state = Task::Dead;
if (thisTask->parent)
thisTask->parent->run_state = Task::Running;
Yield();
}
void Yield()
{
dprintf("Task::Yield 0x%x -> ", thisTask);
fflush(stdout);
if (setjmp(thisTask->state))
return;
while (1)
{
if (thisTask->next)
thisTask = thisTask->next;
else
thisTask = task_list;
if (thisTask->run_state == Task::Running)
break;
}
dprintf("0x%x (0x%x)\n", thisTask, thisTask->state->eip);
longjmp(thisTask->state,1);
}