External; {* * Create a task with given name, priority, and stack size. * It will use the default exception and trap handlers for now. *} {$I "Include/Exec.i"} {$I "Include/Ports.i"} { This type is also defined in Tasks.i. I redefined it here since Tasks.i also declares CreateTask and DeleteTask as external routines. } TYPE Task = RECORD tcNode : Node; tcFlags : Byte; tcState : Byte; tcIDNestCnt : Byte; tcTDNestCnt : Byte; tcSigAlloc : Integer; tcSigWait : Integer; tcSigRecvd : Integer; tcSigExcept : Integer; tcTrapAlloc : Short; tcTrapAble : Short; tcExceptData : Address; tcExceptCode : Address; tcTrapData : Address; tcTrapCode : Address; tcSPReg : Address; tcSPLower : Address; tcSPUpper : Address; tcSwitch : Address; tcLaunch : Address; tcMemEntry : List; tcUserData : Address; end; TaskPtr = ^Task; Function CreateTask(name : String; pri : Byte; initPC : Address; stackSize : Integer) : TaskPtr; var NewTask : TaskPtr; DataSize: Integer; begin DataSize := (stackSize and $fffffc) + 1; { This should be broken into two allocations: task of PUBLIC and stack of PRIVATE } newTask := AllocMem(SizeOf(Task) + dataSize, MemClear + MemPublic); if NewTask = Nil then CreateTask := Nil; with NewTask^ do begin tcSPLower := Address(Integer(newTask) + SizeOf(Task)); tcSPUpper := Address((Integer(tcSPLower) + dataSize) and $fffffe); tcSPReg := tcSPUpper; with tcNode do begin lnType := Ord(NTTask); lnPri := pri; lnName := name; end; end; AddTask(newTask, initPC, Nil); CreateTask := NewTask; end; Procedure DeleteTask(tc : TaskPtr); begin RemTask(tc); { does not handle self deletion properly } FreeMem(tc, Integer(tc^.tcSPUpper) - Integer(tc)); end;