This source file includes following definitions.
- nextfreetss
- LinkTask
- DoFork
- DoExec
- Do_Wait
- NewKernelTask
- NewLowPriTask
- KillTask
- BlockTask
- UnBlockTask
- PidToTask
- dummyTask
- ParseEnvironmentString
- StartTasks
#include "kstructs.h"
#include "kernel.h"
#include "memory.h"
#include "filesystem.h"
#include "fat.h"
#include "tasklist.h"
struct Task *
NewKernelTask(void *TaskCode);
long
ParseEnvironmentString(long *);
struct Task *currentTask;
struct TaskList *runnableTasks;
struct TaskList *blockedTasks;
struct Task *lowPriTask;
struct TaskList *allTasks;
struct TaskList *deadTasks;
long canSwitch;
long pass;
extern unsigned short int *PMap;
extern long nPagesFree;
extern long nPages;
static long nextpid = 3;
struct Task *
nextfreetss()
{
struct Task *temp = (struct Task *) TaskStruct;
while (temp->pid != 0)
temp++;
return (temp);
}
void LinkTask(struct Task *task)
{
asm("cli");
allTasks = AddToTailOfTaskList(allTasks, task);
runnableTasks = AddToTailOfTaskList(runnableTasks, task);
asm("sti");
}
long DoFork()
{
struct Task *task = nextfreetss();
copyMem((unsigned char *) currentTask, (unsigned char *) task,
sizeof(struct Task));
int pid = task->pid = nextpid++;
task->currentDirName = AllocKMem(strlen(currentTask->currentDirName) + 1);
strcpy(task->currentDirName, currentTask->currentDirName);
task->parentPort = 0;
task->cr3 = (long) VCreatePageDir(pid, currentTask->pid);
task->forking = 1;
struct FCB *fcbin = (struct FCB *) AllocKMem(sizeof(struct FCB));
fcbin->fileDescriptor = STDIN;
fcbin->deviceType = KBD;
task->fcbList = fcbin;
struct FCB *fcbout = (struct FCB *) AllocKMem(sizeof(struct FCB));
fcbout->fileDescriptor = STDOUT;
fcbout->deviceType = CONS;
fcbin->nextFCB = fcbout;
;
struct FCB *fcberr = (struct FCB *) AllocKMem(sizeof(struct FCB));
fcberr->fileDescriptor = STDERR;
fcberr->deviceType = CONS;
fcbout->nextFCB = fcberr;
fcberr->nextFCB = 0;
asm("cli");
LinkTask(task);
asm("sti");
SaveRegisters(task);
if (pid == currentTask->pid)
pid = 0;
return pid;
}
long DoExec(char *name, char *environment)
{
struct FCB *fHandle;
long codelen, datalen;
char header[9];
long *data;
long currentPage;
long size;
long argc;
long argv;
char *kname = AllocKMem(strlen(name) + 6);
strcpy(kname, "/BIN/");
strcat(kname, name);
struct Message *FSMsg = ALLOCMSG;
FSMsg->nextMessage = 0;
FSMsg->byte = OPENFILE;
FSMsg->quad = (long) kname;
FSMsg->quad2 = (long) fHandle;
SendReceiveMessage((struct MessagePort *) FSPort, FSMsg);
fHandle = (struct FCB *) FSMsg->quad;
if (fHandle)
{
ReadFromFile(fHandle, header, 9);
ReadFromFile(fHandle, (char *) &codelen, 8);
ReadFromFile(fHandle, (char *) &datalen, 8);
currentPage = UserCode;
size = codelen;
ClearUserMemory();
while (size > 0)
{
AllocAndCreatePTE(currentPage, currentTask->pid, RW | US | P);
size -= PageSize;
currentPage += PageSize;
}
copyMem((char *)header, (char *)UserCode, 9);
copyMem((char *)&codelen, (char *)UserCode + 9, 8);
copyMem((char *)&datalen, (char *)UserCode + 17, 8);
ReadFromFile(fHandle, (char *) UserCode + 25, codelen - 25);
currentPage = UserData;
size = datalen + sizeof(struct MemStruct);
while (size > 0)
{
AllocAndCreatePTE(currentPage, currentTask->pid, RW | US | P);
size -= PageSize;
currentPage += PageSize;
}
ReadFromFile(fHandle, (char *) UserData, datalen);
data = (long *) (UserData + datalen);
data[0] = 0;
data[1] = PageSize - datalen - sizeof(struct MemStruct);
currentTask->firstfreemem = UserData + datalen;
FSMsg->nextMessage = 0;
FSMsg->byte = CLOSEFILE;
FSMsg->quad = (long) fHandle;
SendReceiveMessage((struct MessagePort *) FSPort, FSMsg);
DeallocMem(kname);
DeallocMem(FSMsg);
char *newenv = AllocMem(81,
(struct MemStruct *) currentTask->firstfreemem);
copyMem(environment, newenv, 81);
currentTask->environment = newenv;
argc = ParseEnvironmentString(&argv);
currentTask->argv = (unsigned char **) argv;
asm("mov %0,%%rdi;" "mov %1,%%rsi":
: "r"(argc), "r"(argv):"%rax", "%rdi");
return 0;
}
else
{
DeallocMem(kname);
DeallocMem(FSMsg);
return 1;
}
}
void Do_Wait(unsigned short pid)
{
struct Task *task = PidToTask(pid);
struct MessagePort *parentPort = AllocMessagePort();
struct Message *message = ALLOCMSG;
task->parentPort = parentPort;
ReceiveMessage(parentPort, message);
DeallocMem(message);
DeallocMem(parentPort);
}
struct Task *
NewKernelTask(void *TaskCode)
{
long *stack;
struct Task *task = nextfreetss();
long *data;
task->pid = nextpid++;
task->waiting = 0;
task->cr3 = (long) VCreatePageDir(task->pid, 0);
task->ds = data64;
stack = (long *) (TempUStack + PageSize) - 5;
task->rsp = (long) ((long *) (UserStack + PageSize) - 5);
task->r15 = (long) task;
stack[0] = (long) TaskCode;
stack[1] = code64;
stack[2] = 0x2202;
stack[3] = (long) UserStack + PageSize;
stack[4] = data64;
asm("cli");
LinkTask(task);
data = (long *) TempUserData;
data[0] = 0;
data[1] = PageSize - sizeof(struct MemStruct);
task->firstfreemem = UserData;
task->environment = (void *) 0;
task->parentPort = (void *) 0;
task->currentDirName = currentTask->currentDirName;
task->argv = 0;
task->console = 0;
asm("sti");
return (task);
}
void NewLowPriTask(void *TaskCode)
{
lowPriTask = NewKernelTask(TaskCode);
runnableTasks = RemoveFromTaskList(runnableTasks, lowPriTask);
lowPriTask->nexttask = (struct Task *) 0;
}
void KillTask(void)
{
struct Task *task = currentTask;
if (task->parentPort)
{
struct Message *m = ALLOCMSG;
m->quad = 0;
SendMessage(task->parentPort, m);
DeallocMem(m);
}
if (task->environment) DeallocMem(task->environment);
if (task->argv) DeallocMem(task->argv);
asm("cli");
runnableTasks = RemoveFromTaskList(runnableTasks, task);
struct FCB *temp;
while (task->fcbList)
{
temp = task->fcbList->nextFCB;
if (task->fcbList->deviceType == FILE)
KCloseFile(task->fcbList);
else
DeallocMem(task->fcbList);
task->fcbList = temp;
}
if (currentTask->pid != 2)
DeallocMem(currentTask->currentDirName);
deadTasks = AddToHeadOfTaskList(deadTasks, currentTask);
allTasks = RemoveFromTaskList(allTasks, currentTask);
task->pid = 0;
SWTASKS;
}
void BlockTask(struct Task *task)
{
canSwitch++;
runnableTasks = RemoveFromTaskList(runnableTasks, task);
blockedTasks = AddToTailOfTaskList(blockedTasks, task);
canSwitch--;
}
void UnBlockTask(struct Task *task)
{
canSwitch++;
blockedTasks = RemoveFromTaskList(blockedTasks, task);
runnableTasks = AddToTailOfTaskList(runnableTasks, task);
canSwitch--;
}
struct Task *
PidToTask(long pid)
{
struct TaskList *tempTask = allTasks;
while (tempTask)
{
if (tempTask->task->pid == pid)
break;
tempTask = tempTask->next;
}
return tempTask->task;
}
void dummyTask()
{
unsigned short int pid;
struct TaskList *t;
int count;
while (1)
{
if (deadTasks)
{
t = deadTasks;
deadTasks = deadTasks->next;
pid = t->task->pid;
DeallocMem(t);
for (count = 0; count < nPages; count++)
{
if (PMap[count] == pid)
{
PMap[count] = 0;
nPagesFree++;
}
}
}
else
asm("hlt");
}
}
long ParseEnvironmentString(long *l)
{
long argc = 0;
int count = 0;
char *env = currentTask->environment;
*l = (long) AllocMem(80, (struct MemStruct *) currentTask->firstfreemem);
long *argv = (long *) *l;
argv[0] = (long) env;
while (env[count])
{
while (env[count] && env[count] != ' ')
{
count++;
}
argc++;
if (env[count])
{
env[count] = 0;
argv[argc] = (long) env + ++count;
}
}
return argc;
}
extern void kbTaskCode(void);
extern void consoleTaskCode(void);
extern void fsTaskCode(void);
void StartTasks()
{
NewLowPriTask(dummyTask);
GoToSleep(10);
NewKernelTask(kbTaskCode);
GoToSleep(10);
NewKernelTask(consoleTaskCode);
GoToSleep(10);
NewKernelTask(fsTaskCode);
GoToSleep(10);
}