FreeCalypso > hg > fc-tourmaline
diff src/gpf/osl/os_pro_fl.c @ 0:4e78acac3d88
src/{condat,cs,gpf,nucleus}: import from Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 16 Oct 2020 06:23:26 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/gpf/osl/os_pro_fl.c Fri Oct 16 06:23:26 2020 +0000 @@ -0,0 +1,236 @@ +/* + * This C module is a reconstruction based on the disassembly of + * os_pro.obj in frame_na7_db_fl.lib from the Leonardo package. + */ + +/* set of included headers from COFF symtab: */ +#include <stdio.h> +#include <string.h> +#include "nucleus.h" +#include "typedefs.h" +#include "os.h" +#include "gdi.h" +#include "os_types.h" +#include "os_glob.h" + +typedef unsigned char u_char; + +extern VOID *TCD_Current_Thread; +extern T_OS_TASK_TABLE_ENTRY TaskTable[]; +extern VOID os_TaskEntry(UNSIGNED, VOID *); + +static NU_SEMAPHORE ProSemCB; + +#define OS_NU_TASK_MAGIC 0xdeafbeef + +static int +os_GetTaskEntry(USHORT Index, OS_HANDLE *Handle) +{ + static USHORT Idx; + + if (Index == FIRST_ENTRY) + Idx = 0; + if (Index == FIRST_ENTRY || Index == NEXT_ENTRY) { + while (++Idx <= MaxTasks && !TaskTable[Idx].Name[0]) + ; + } else + Idx = Index; + if (Idx <= MaxTasks && TaskTable[Idx].Name[0]) { + *Handle = Idx; + return(0); + } else + return(-1); +} + +GLOBAL LONG +os_TaskInformation(USHORT Index, char *Buffer) +{ + DATA_ELEMENT TaskStatus; + OPTION Prio, Preempt; + UNSIGNED Count, TimeSlice, Size, MinStack; + OS_HANDLE Handle; + CHAR Name[NU_MAX_NAME]; + u_char *StackBase, *sp; + USHORT Untouched; + + if (os_GetTaskEntry(Index, &Handle) < 0) + return(OS_ERROR); + if (NU_Task_Information(&TaskTable[Handle].TaskCB.TCB, Name, + &TaskStatus, &Count, &Prio, &Preempt, + &TimeSlice, (VOID **) &StackBase, + &Size, &MinStack) != NU_SUCCESS) + return(OS_ERROR); + Untouched = 0; + for (sp = StackBase; sp < StackBase + Size; sp++) { + if (*sp != INITIAL_STACK_VALUE) + break; + Untouched++; + } + sprintf(Buffer, + "Name:%s Stat:%d Count:%ld Prio:%d Stack:%lx Size:%ld Untouched:%d", + Name, TaskStatus, Count, 255 - Prio, (ULONG) StackBase, + (LONG) Size, Untouched); + return(OS_OK); +} + +GLOBAL LONG +os_StopTask(OS_HANDLE Caller, OS_HANDLE TaskHandle) +{ + if (NU_Suspend_Task(&TaskTable[TaskHandle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_StartTask(OS_HANDLE Caller, OS_HANDLE TaskHandle, ULONG Value) +{ + if (NU_Resume_Task(&TaskTable[TaskHandle].TaskCB.TCB) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +} + +GLOBAL LONG +os_ProInit(void) +{ + USHORT i; + + if (NU_Create_Semaphore(&ProSemCB, "PROSEM", 1, NU_PRIORITY) + != NU_SUCCESS) + return(OS_ERROR); + for (i = 1; i <= MaxTasks; i++) + memset(&TaskTable[i], 0, sizeof(T_OS_TASK_TABLE_ENTRY)); + return(OS_OK); +} + +GLOBAL unsigned char +os_GetTaskState(OS_HANDLE Caller, OS_HANDLE Handle) +{ + if (TaskTable[Handle].Name[0]) + return(TaskTable[Handle].TaskCB.TCB.tc_status); + else + return(255); +} + +GLOBAL LONG +os_GetTaskHandle(OS_HANDLE Caller, char *Name, OS_HANDLE *TaskHandle) +{ + USHORT i; + + if (!Name) { + OS_NU_TASK *os_nu_task = (OS_NU_TASK *) TCD_Current_Thread; + + if (os_nu_task && os_nu_task->magic_nr == OS_NU_TASK_MAGIC) + *TaskHandle = os_nu_task->handle; + else + *TaskHandle = OS_NOTASK; + return(OS_OK); + } + for (i = 1; i <= MaxTasks; i++) + if (TaskTable[i].Name[0] && + !strncmp(Name, TaskTable[i].Name, RESOURCE_NAMELEN - 1)) { + *TaskHandle = i; + return(OS_OK); + } + return(OS_ERROR); +} + +GLOBAL LONG +os_GetTaskData(OS_HANDLE Handle, unsigned **tcb, + u_char **stackbegin, u_char **stackend) +{ + NU_TASK *task; + + if (!TaskTable[Handle].Name[0]) + return(OS_ERROR); + task = &TaskTable[Handle].TaskCB.TCB; + *tcb = (unsigned *) task; + *stackbegin = (u_char *) task->tc_stack_start; + *stackend = (u_char *) task->tc_stack_end; + return(OS_OK); +} + +GLOBAL LONG +os_GetScheduleCount(OS_HANDLE task_handle, int *schedule_count) +{ + NU_TASK *task_cb; + + if (task_handle > MaxTasks) + return(OS_ERROR); + if (!TaskTable[task_handle].Name[0]) + return(OS_ERROR); + if (task_handle == OS_NOTASK) + task_cb = (NU_TASK *) TCD_Current_Thread; + else + task_cb = &TaskTable[task_handle].TaskCB.TCB; + *schedule_count = task_cb->tc_scheduled; + return(OS_OK); +} + +GLOBAL LONG +os_DestroyTask(OS_HANDLE Caller, OS_HANDLE TaskHandle) +{ + STATUS sts; + + if (NU_Terminate_Task(&TaskTable[TaskHandle].TaskCB.TCB) != NU_SUCCESS) + return(OS_ERROR); + if (NU_Delete_Task(&TaskTable[TaskHandle].TaskCB.TCB) != NU_SUCCESS) + return(OS_ERROR); + if (os_DeallocateMemory(Caller, TaskTable[TaskHandle].Stack) != OS_OK) + return(OS_ERROR); + sts = NU_Obtain_Semaphore(&ProSemCB, NU_SUSPEND); + TaskTable[TaskHandle].Name[0] = 0; + if (sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_CreateTask(OS_HANDLE Caller, char *Name, + void (*TaskEntry)(OS_HANDLE, ULONG), ULONG StackSize, + USHORT Priority, OS_HANDLE *TaskHandle, OS_HANDLE MemPoolHandle) +{ + STATUS sem_sts; + USHORT Handle; + u_char *stack; + + sem_sts = NU_Obtain_Semaphore(&ProSemCB, NU_SUSPEND); + for (Handle = 1; Handle <= MaxTasks; Handle++) + if (!TaskTable[Handle].Name[0]) + break; + if (Handle > MaxTasks) { +return_error: if (sem_sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_ERROR); + } + if (os_AllocateMemory(Handle, &TaskTable[Handle].Stack, StackSize + 4, + 0, MemPoolHandle) != OS_OK) + goto return_error; + stack = (u_char *)TaskTable[Handle].Stack + 4; + memset(stack, INITIAL_STACK_VALUE, StackSize); + *TaskTable[Handle].Stack = GUARD_PATTERN; + if (NU_Create_Task(&TaskTable[Handle].TaskCB.TCB, Name, os_TaskEntry, + Handle, 0, stack, StackSize, + 255 - Priority, 0, NU_PREEMPT, NU_NO_START) + != NU_SUCCESS) + goto return_error; + strncpy(TaskTable[Handle].Name, Name, RESOURCE_NAMELEN); + TaskTable[Handle].Name[RESOURCE_NAMELEN-1] = 0; + TaskTable[Handle].TaskEntry = TaskEntry; + TaskTable[Handle].TaskCB.magic_nr = OS_NU_TASK_MAGIC; + TaskTable[Handle].TaskCB.handle = Handle; + *TaskHandle = Handle; + if (sem_sts == NU_SUCCESS) + NU_Release_Semaphore(&ProSemCB); + return(OS_OK); +} + +GLOBAL LONG +os_ChangePreemption(char preempt) +{ + if (NU_Change_Preemption(preempt) == NU_SUCCESS) + return(OS_OK); + else + return(OS_ERROR); +}