From: John Hodge Date: Fri, 25 Sep 2009 00:25:29 +0000 (+0800) Subject: Separated Architecture independent thread controll into the root of the tree X-Git-Tag: rel0.06~525 X-Git-Url: https://git.ucc.asn.au/?a=commitdiff_plain;h=f119d0e5b18b7286d04fc536a94e0f96e3c51714;p=tpg%2Facess2.git Separated Architecture independent thread controll into the root of the tree --- diff --git a/Kernel/Makefile b/Kernel/Makefile index de3c071c..68b84b8b 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -18,7 +18,7 @@ ASFLAGS += -D ARCH=\"$(ARCH)\" LDFLAGS += -T arch/$(ARCHDIR)/link.ld OBJ = $(addprefix arch/$(ARCHDIR)/,$(A_OBJ)) -OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o +OBJ += heap.o messages.o debug.o modules.o lib.o syscalls.o system.o threads.o OBJ += binary.o bin/elf.o OBJ += vfs/main.o vfs/open.o vfs/acls.o vfs/dir.o vfs/io.o vfs/mount.o vfs/memfile.o vfs/nodecache.o OBJ += vfs/fs/root.o vfs/fs/devfs.o vfs/fs/fat.o diff --git a/Kernel/arch/x86/errors.c b/Kernel/arch/x86/errors.c index a8d89ac4..2c3582cd 100644 --- a/Kernel/arch/x86/errors.c +++ b/Kernel/arch/x86/errors.c @@ -7,7 +7,7 @@ // === IMPORTS === extern void MM_PageFault(Uint Addr, Uint ErrorCode, tRegs *Regs); -extern void Proc_DumpThreads(); +extern void Threads_Dump(); // === CODE === /** @@ -46,7 +46,7 @@ void ErrorHandler(tRegs *Regs) Warning(" CR3: 0x%08x", cr); // Dump running threads - Proc_DumpThreads(); + Threads_Dump(); for(;;) __asm__ __volatile__ ("hlt"); } diff --git a/Kernel/arch/x86/include/arch.h b/Kernel/arch/x86/include/arch.h index 9c16b182..0611c6c4 100644 --- a/Kernel/arch/x86/include/arch.h +++ b/Kernel/arch/x86/include/arch.h @@ -42,6 +42,7 @@ #define LOCK(lockptr) do {int v=1;\ while(v)__asm__ __volatile__("lock xchgl %%eax, (%%edi)":"=a"(v):"a"(1),"D"(lockptr));}while(0) #define RELEASE(lockptr) __asm__ __volatile__("lock andl $0, (%%edi)"::"D"(lockptr)); +#define HALT() __asm__ __volatile__ ("hlt") // === TYPES === typedef unsigned int Uint; // Unsigned machine native integer @@ -109,6 +110,18 @@ typedef struct { Uint8 BaseHi; } __attribute__ ((packed)) tGDT; +typedef struct { + #if USE_PAE + Uint PDPT[4]; + #else + Uint CR3; + #endif +} tMemoryState; + +typedef struct { + Uint EIP, ESP, EBP; +} tTaskState; + // --- Interface Flags & Macros #define CLONE_VM 0x10 diff --git a/Kernel/arch/x86/include/proc.h b/Kernel/arch/x86/include/proc.h index 6e559bed..6619ec0d 100644 --- a/Kernel/arch/x86/include/proc.h +++ b/Kernel/arch/x86/include/proc.h @@ -5,52 +5,12 @@ #ifndef _PROC_H #define _PROC_H +#include + // === CONSTANTS === #define GETMSG_IGNORE ((void*)-1) // === TYPES === -typedef struct sMessage { - struct sMessage *Next; - Uint Source; - Uint Length; - Uint8 Data[]; -} tMsg; // sizeof = 12+ - -typedef struct sThread { - struct sThread *Next; - int IsLocked; - int Status; //!< Thread Status - - Uint TID; //!< Thread ID - Uint TGID; //!< Thread Group (Process) - Uint UID, GID; //!< User and Group - char *ThreadName; //!< Name of thread - - Uint ESP, EBP, EIP; //!< State on switch - #if USE_PAE - Uint64 PML4[3]; //!< Address Space - #else - Uint CR3; //!< Memory Space - #endif - - Uint KernelStack; //!< Thread's Kernel Stack - - tMsg *Messages; //!< Message Queue - tMsg *LastMessage; //!< Last Message (speeds up insertion) - - int Quantum, Remaining; //!< Quantum Size and remaining timesteps - int NumTickets; //!< Priority - Chance of gaining CPU - - Uint Config[NUM_CFG_ENTRIES]; //!< Per-process configuration -} tThread; // sizeof = 68 - -enum { - THREAD_STAT_NULL, - THREAD_STAT_ACTIVE, - THREAD_STAT_SLEEPING, - THREAD_STAT_WAITING, - THREAD_STAT_DEAD -}; typedef struct sTSS { Uint32 Link; @@ -67,17 +27,8 @@ typedef struct sTSS { Uint16 Resvd, IOPB; // IO Permissions Bitmap } tTSS; -// === GLOBALS === -extern tThread *gCurrentThread; - // === FUNCTIONS === extern void Proc_Start(); extern int Proc_Clone(Uint *Err, Uint Flags); -extern void Proc_Exit(); -extern void Proc_Yield(); -extern void Proc_Sleep(); -extern void Proc_SetTickets(int Num); -extern tThread *Proc_GetThread(Uint TID); -extern void Thread_Wake(tThread *Thread); #endif diff --git a/Kernel/arch/x86/main.c b/Kernel/arch/x86/main.c index 710923d4..304c3dd8 100644 --- a/Kernel/arch/x86/main.c +++ b/Kernel/arch/x86/main.c @@ -17,10 +17,10 @@ extern void Desctab_Install(); extern void MM_PreinitVirtual(); extern void MM_Install(tMBoot_Info *MBoot); extern void MM_InstallVirtual(); -extern void Proc_Start(); +extern void Threads_Init(); extern Uint Proc_Clone(Uint *Err, Uint Flags); -extern void Proc_Sleep(); -extern void Proc_Exit(); +extern void Threads_Sleep(); +extern void Threads_Exit(); // === GLOBALS === @@ -41,7 +41,7 @@ int kmain(Uint MbMagic, tMBoot_Info *MbInfo) Log("Starting Multitasking..."); // Start Multitasking - Proc_Start(); + Threads_Init(); Log("Starting VFS..."); // Load Virtual Filesystem @@ -71,6 +71,6 @@ int kmain(Uint MbMagic, tMBoot_Info *MbInfo) System_Init( (char*)(MbInfo->CommandLine + KERNEL_BASE) ); // Sleep forever (sleeping beauty) - for(;;) Proc_Sleep(); + for(;;) Threads_Sleep(); return 0; } diff --git a/Kernel/arch/x86/mm_virt.c b/Kernel/arch/x86/mm_virt.c index a022da2b..2e726ccf 100644 --- a/Kernel/arch/x86/mm_virt.c +++ b/Kernel/arch/x86/mm_virt.c @@ -381,7 +381,7 @@ Uint MM_ClearUser() Uint MM_Clone() { Uint i, j; - Uint kStackBase = gCurrentThread->KernelStack - KERNEL_STACK_SIZE; + Uint kStackBase = Proc_GetCurThread()->KernelStack - KERNEL_STACK_SIZE; void *tmp; //ENTER(""); @@ -621,7 +621,7 @@ Uint MM_MapTemp(tPAddr PAddr) return TEMP_MAP_ADDR + (i << 12); } RELEASE( &gilTempMappings ); - Proc_Yield(); + Threads_Yield(); } } diff --git a/Kernel/arch/x86/proc.c b/Kernel/arch/x86/proc.c index 0f9f449f..31eb0557 100644 --- a/Kernel/arch/x86/proc.c +++ b/Kernel/arch/x86/proc.c @@ -12,9 +12,6 @@ // === CONSTANTS === #define SWITCH_MAGIC 0xFFFACE55 // There is no code in this area -#define DEFAULT_QUANTUM 10 -#define DEFAULT_TICKETS 5 -#define MAX_TICKETS 10 #define TIMER_DIVISOR 11931 //~100Hz // === IMPORTS === @@ -22,59 +19,30 @@ extern tGDT gGDT[]; extern Uint GetEIP(); // start.asm extern Uint32 gaInitPageDir[1024]; // start.asm extern void Kernel_Stack_Top; +extern volatile int giThreadListLock; +extern int giNumCPUs; +extern int giNextTID; +extern int giTotalTickets; +extern int giNumActiveThreads; +extern tThread *gActiveThreads; +extern tThread *gSleepingThreads; +extern tThread *gDeleteThreads; // === PROTOTYPES === -void Proc_Start(); +void ArchThreads_Init(); +tThread *Proc_GetCurThread(); void Proc_ChangeStack(); int Proc_Clone(Uint *Err, Uint Flags); -void Proc_Exit(); -void Proc_Yield(); -void Proc_Sleep(); -static tThread *Proc_int_GetPrevThread(tThread **List, tThread *Thread); void Proc_Scheduler(); -Sint64 now(); -Uint rand(); // === GLOBALS === -// -- Core Thread -- -tThread gThreadZero = { - NULL, 0, // Next, Lock - THREAD_STAT_ACTIVE, // Status - 0, 0, // TID, TGID - 0, 0, // UID, GID - "ThreadZero", // Name - 0, 0, 0, // ESP, EBP, EIP (Set on switch) - #if USE_PAE - {0,0,0}, // PML4 Entries - #else - (Uint)&gaInitPageDir-KERNEL_BASE, // CR3 - #endif - (Uint)&Kernel_Stack_Top, // Kernel Stack (Unused as it is PL0) - NULL, NULL, // Messages, Last Message - DEFAULT_QUANTUM, DEFAULT_QUANTUM, // Quantum, Remaining - DEFAULT_TICKETS, - {0} // Default config to zero - }; -// -- Processes -- -// --- Locks --- -volatile int giThreadListLock = 0; ///\note NEVER use a heap function while locked // --- Current State --- #if USE_MP tThread **gCurrentThread = NULL; -# define CUR_THREAD gCurrentThread[0] #else tThread *gCurrentThread = NULL; -# define CUR_THREAD gCurrentThread #endif -volatile int giNumActiveThreads = 0; -volatile int giTotalTickets = 0; -volatile Uint giNextTID = 1; -// --- Thread Lists --- -tThread *gActiveThreads = NULL; // Currently Running Threads -tThread *gSleepingThreads = NULL; // Sleeping Threads -tThread *gDeleteThreads = NULL; // Threads to delete // --- Multiprocessing --- - int giNumCPUs = 1; #if USE_MP tMPInfo *gMPTable = NULL; #endif @@ -88,13 +56,12 @@ tTSS gTSS0 = {0}; // === CODE === /** - * \fn void Proc_Start() + * \fn void ArchThreads_Init() * \brief Starts the process scheduler */ -void Proc_Start() +void ArchThreads_Init() { Uint pos = 0; - #if USE_MP // -- Initialise Multiprocessing // Find MP Floating Table @@ -161,33 +128,29 @@ void Proc_Start() outb(0x40, TIMER_DIVISOR&0xFF); // Low Byte of Divisor outb(0x40, (TIMER_DIVISOR>>8)&0xFF); // High Byte - // Create Initial Task - gActiveThreads = &gThreadZero; - gCurrentThread = &gThreadZero; - giTotalTickets = gThreadZero.NumTickets; - giNumActiveThreads = 1; - // Create Per-Process Data Block MM_Allocate(MM_PPD_CFG); // Change Stacks Proc_ChangeStack(); - #if 1 - // Create Idle Task - if(Proc_Clone(0, 0) == 0) - { - gCurrentThread->ThreadName = "Idle Thread"; - Proc_SetTickets(0); // Never called randomly - gCurrentThread->Quantum = 1; // 1 slice quantum - for(;;) __asm__ __volatile__ ("hlt"); // Just yeilds - } - #endif - // Start Interrupts (and hence scheduler) __asm__ __volatile__("sti"); } +/** + * \fn tThread *Proc_GetCurThread() + * \brief Gets the current thread + */ +tThread *Proc_GetCurThread() +{ + #if USE_MP + return NULL; + #else + return gCurrentThread; + #endif +} + /** * \fn void Proc_ChangeStack() * \brief Swaps the current stack for a new one (in the proper stack reigon) @@ -263,7 +226,7 @@ int Proc_Clone(Uint *Err, Uint Flags) // Initialise Memory Space (New Addr space or kernel stack) if(Flags & CLONE_VM) { newThread->TGID = newThread->TID; - newThread->CR3 = MM_Clone(); + newThread->MemState.CR3 = MM_Clone(); } else { Uint tmpEbp, oldEsp = esp; @@ -297,6 +260,7 @@ int Proc_Clone(Uint *Err, Uint Flags) newThread->Next = NULL; newThread->IsLocked = 0; newThread->TID = giNextTID++; + newThread->PTID = gCurrentThread->TID; // Clear message list (messages are not inherited) newThread->Messages = NULL; @@ -306,8 +270,8 @@ int Proc_Clone(Uint *Err, Uint Flags) newThread->Remaining = newThread->Quantum; // Save core machine state - newThread->ESP = esp; - newThread->EBP = ebp; + newThread->SavedState.ESP = esp; + newThread->SavedState.EBP = ebp; eip = GetEIP(); if(eip == SWITCH_MAGIC) { outb(0x20, 0x20); // ACK Timer and return as child @@ -315,9 +279,7 @@ int Proc_Clone(Uint *Err, Uint Flags) } // Set EIP as parent - newThread->EIP = eip; - - //Log(" Proc_Clone: giTimestamp = %i.%07i", (Uint)giTimestamp, (Uint)giPartMiliseconds/214); + newThread->SavedState.EIP = eip; // Lock list and add to active LOCK( &giThreadListLock ); @@ -330,18 +292,58 @@ int Proc_Clone(Uint *Err, Uint Flags) return newThread->TID; } +#if 0 /** - * \fn void Proc_SetThreadName() - * \brief Sets the thread's name + * \fn void Proc_SetSignalHandler(int Num, void *Handler) + * \brief Sets the signal handler for a signal */ -void Proc_SetThreadName(char *NewName) +void Proc_SetSignalHandler(int Num, void *Handler) { - if( (Uint)CUR_THREAD->ThreadName > 0xC0400000 ) - free( CUR_THREAD->ThreadName ); - CUR_THREAD->ThreadName = malloc(strlen(NewName)+1); - strcpy(CUR_THREAD->ThreadName, NewName); + if(Num < 0 || Num >= NSIG) return; + + gCurrentThread->SignalHandlers[Num] = Handler; +} + +/** + * \fn void Proc_SendSignal(int TID, int Num) + */ +void Proc_SendSignal(int TID, int Num) +{ + tThread *thread = Proc_GetThread(TID); + void *handler; + + if(!thread) return ; + + handler = thread->SignalHandlers[Num]; + + // Panic? + if(handler == SIG_ERR) { + Proc_Kill(TID); + return ; + } + // Dump Core? + if(handler == -2) { + Proc_Kill(TID); + return ; + } + // Ignore? + if(handler == -2) return; + + // Check the type and handle if the thread is already in a signal + if(thread->CurSignal != 0) { + if(Num < _SIGTYPE_FATAL) + Proc_Kill(TID); + } else { + while(thread->CurSignal != 0) + Proc_Yield(); + } + } + + //TODO: } +#endif + /** * \fn Uint Proc_MakeUserStack() * \brief Creates a new user stack @@ -434,153 +436,6 @@ void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char ** for(;;); } -/** - * \fn void Proc_Exit() - * \brief Kill the current process - */ -void Proc_Exit() -{ - tThread *thread; - tMsg *msg; - - ///\note Double lock is needed due to overlap of locks - - // Lock thread (stop us recieving messages) - LOCK( &gCurrentThread->IsLocked ); - - // Lock thread list - LOCK( &giThreadListLock ); - - // Get previous thread on list - thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread ); - if(!thread) { - Warning("Proc_Exit - Current thread is not on the active queue"); - return; - } - - // Clear Message Queue - while( gCurrentThread->Messages ) - { - msg = gCurrentThread->Messages->Next; - free( gCurrentThread->Messages ); - gCurrentThread->Messages = msg; - } - - gCurrentThread->Remaining = 0; // Clear Remaining Quantum - gCurrentThread->Quantum = 0; // Clear Quantum to indicate dead thread - thread->Next = gCurrentThread->Next; // Remove from active - - // Add to delete queue - if(gDeleteThreads) { - gCurrentThread->Next = gDeleteThreads; - gDeleteThreads = gCurrentThread; - } else { - gCurrentThread->Next = NULL; - gDeleteThreads = gCurrentThread; - } - - giNumActiveThreads --; - giTotalTickets -= gCurrentThread->NumTickets; - - // Mark thread as sleeping - gCurrentThread->Status = THREAD_STAT_DEAD; - - // Release spinlocks - RELEASE( &gCurrentThread->IsLocked ); // Released first so that it IS released - RELEASE( &giThreadListLock ); - __asm__ __volatile__ ("hlt"); -} - -/** - * \fn void Proc_Yield() - * \brief Yield remainder of timeslice - */ -void Proc_Yield() -{ - gCurrentThread->Quantum = 0; - __asm__ __volatile__ ("hlt"); -} - -/** - * \fn void Proc_Sleep() - * \brief Take the current process off the run queue - */ -void Proc_Sleep() -{ - tThread *thread; - - //Log("Proc_Sleep: %i going to sleep", gCurrentThread->TID); - - // Acquire Spinlock - LOCK( &giThreadListLock ); - - // Get thread before current thread - thread = Proc_int_GetPrevThread( &gActiveThreads, gCurrentThread ); - if(!thread) { - Warning("Proc_Sleep - Current thread is not on the active queue"); - return; - } - - // Don't sleep if there is a message waiting - if( gCurrentThread->Messages ) { - RELEASE( &giThreadListLock ); - return; - } - - // Unset remaining timeslices (force a task switch on timer fire) - gCurrentThread->Remaining = 0; - - // Remove from active list - thread->Next = gCurrentThread->Next; - - // Add to Sleeping List (at the top) - gCurrentThread->Next = gSleepingThreads; - gSleepingThreads = gCurrentThread; - - // Reduce the active count & ticket count - giNumActiveThreads --; - giTotalTickets -= gCurrentThread->NumTickets; - - // Mark thread as sleeping - gCurrentThread->Status = THREAD_STAT_SLEEPING; - - // Release Spinlock - RELEASE( &giThreadListLock ); - - __asm__ __volatile__ ("hlt"); -} - -/** - * \fn void Thread_Wake( tThread *Thread ) - * \brief Wakes a sleeping/waiting thread up - */ -void Thread_Wake(tThread *Thread) -{ - tThread *prev; - switch(Thread->Status) - { - case THREAD_STAT_ACTIVE: break; - case THREAD_STAT_SLEEPING: - LOCK( &giThreadListLock ); - prev = Proc_int_GetPrevThread(&gSleepingThreads, Thread); - prev->Next = Thread->Next; // Remove from sleeping queue - Thread->Next = gActiveThreads; // Add to active queue - gActiveThreads = Thread; - Thread->Status = THREAD_STAT_ACTIVE; - RELEASE( &giThreadListLock ); - break; - case THREAD_STAT_WAITING: - Warning("Thread_Wake - Waiting threads are not currently supported"); - break; - case THREAD_STAT_DEAD: - Warning("Thread_Wake - Attempt to wake dead thread (%i)", Thread->TID); - break; - default: - Warning("Thread_Wake - Unknown process status (%i)\n", Thread->Status); - break; - } -} - /** * \fn int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) * \brief Demotes a process to a lower permission level @@ -613,99 +468,6 @@ int Proc_Demote(Uint *Err, int Dest, tRegs *Regs) return 0; } -/** - * \fn void Proc_SetTickets(int Num) - * \brief Sets the 'priority' of a task - */ -void Proc_SetTickets(int Num) -{ - if(Num < 0) return; - if(Num > MAX_TICKETS) Num = MAX_TICKETS; - - LOCK( &giThreadListLock ); - giTotalTickets -= gCurrentThread->NumTickets; - gCurrentThread->NumTickets = Num; - giTotalTickets += Num; - //LOG("giTotalTickets = %i", giTotalTickets); - RELEASE( &giThreadListLock ); -} - -/** - * \fn tThread *Proc_GetThread(Uint TID) - * \brief Gets a thread given its TID - */ -tThread *Proc_GetThread(Uint TID) -{ - tThread *thread; - - // Search Active List - for(thread = gActiveThreads; - thread; - thread = thread->Next) - { - if(thread->TID == TID) - return thread; - } - - // Search Sleeping List - for(thread = gSleepingThreads; - thread; - thread = thread->Next) - { - if(thread->TID == TID) - return thread; - } - - return NULL; -} - -/** - * \fn static tThread *Proc_int_GetPrevThread(tThread *List, tThread *Thread) - * \brief Gets the previous entry in a thead linked list - */ -static tThread *Proc_int_GetPrevThread(tThread **List, tThread *Thread) -{ - tThread *ret; - // First Entry - if(*List == Thread) { - return (tThread*)List; - } else { - for(ret = *List; - ret->Next && ret->Next != Thread; - ret = ret->Next - ); - // Error if the thread is not on the list - if(!ret->Next || ret->Next != Thread) { - return NULL; - } - } - return ret; -} - -/** - * \fn void Proc_DumpThreads() - * \brief Dums a list of currently running threads - */ -void Proc_DumpThreads() -{ - tThread *thread; - - Log("Active Threads:"); - for(thread=gActiveThreads;thread;thread=thread->Next) - { - Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName); - Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum); - Log(" CR3 0x%x, KStack 0x%x", thread->CR3, thread->KernelStack); - } - Log("Sleeping Threads:"); - for(thread=gSleepingThreads;thread;thread=thread->Next) - { - Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName); - Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum); - Log(" CR3 0x%x, KStack 0x%x", thread->CR3, thread->KernelStack); - } -} - /** * \fn void Proc_Scheduler(int CPU) * \brief Swap current thread and clears dead threads @@ -749,9 +511,9 @@ void Proc_Scheduler(int CPU) if(eip == SWITCH_MAGIC) return; // Check if a switch happened // Save machine state - gCurrentThread->ESP = esp; - gCurrentThread->EBP = ebp; - gCurrentThread->EIP = eip; + gCurrentThread->SavedState.ESP = esp; + gCurrentThread->SavedState.EBP = ebp; + gCurrentThread->SavedState.EIP = eip; // Special case: 1 thread if(giNumActiveThreads == 1) @@ -792,31 +554,13 @@ void Proc_Scheduler(int CPU) performSwitch: // Set address space //MM_SetCR3( gCurrentThread->CR3 ); - __asm__ __volatile__ ("mov %0, %%cr3"::"a"(gCurrentThread->CR3)); + __asm__ __volatile__ ("mov %0, %%cr3"::"a"(gCurrentThread->MemState.CR3)); // Switch threads __asm__ __volatile__ ( "mov %1, %%esp\n\t" "mov %2, %%ebp\n\t" "jmp *%3" : : - "a"(SWITCH_MAGIC), "b"(gCurrentThread->ESP), - "d"(gCurrentThread->EBP), "c"(gCurrentThread->EIP)); + "a"(SWITCH_MAGIC), "b"(gCurrentThread->SavedState.ESP), + "d"(gCurrentThread->SavedState.EBP), "c"(gCurrentThread->SavedState.EIP)); for(;;); // Shouldn't reach here } - -// --- Process Structure Access Functions --- -int Proc_GetPID() -{ - return gCurrentThread->TGID; -} -int Proc_GetTID() -{ - return gCurrentThread->TID; -} -int Proc_GetUID() -{ - return gCurrentThread->UID; -} -int Proc_GetGID() -{ - return gCurrentThread->GID; -} diff --git a/Kernel/arch/x86/start.asm b/Kernel/arch/x86/start.asm index e1cc70ad..3da50755 100644 --- a/Kernel/arch/x86/start.asm +++ b/Kernel/arch/x86/start.asm @@ -58,7 +58,7 @@ _GetEIP: ret [extern _Proc_Clone] -[extern _Proc_Exit] +[extern _Threads_Exit] [global _SpawnTask] _SpawnTask: ; Call Proc_Clone with Flags=0 @@ -77,7 +77,7 @@ _SpawnTask: ; Child push edx ; Argument call ebx ; Function - call _Proc_Exit ; Kill Thread + call _Threads_Exit ; Kill Thread .parent: ret diff --git a/Kernel/binary.c b/Kernel/binary.c index 46d086c0..ae8207bf 100644 --- a/Kernel/binary.c +++ b/Kernel/binary.c @@ -34,9 +34,9 @@ typedef struct sKernelBin { // === IMPORTS === extern int Proc_Clone(Uint *Err, Uint Flags); -extern void Proc_SetThreadName(char *Name); +extern void Threads_SetName(char *Name); extern Uint MM_ClearUser(); -extern void Proc_Exit(); +extern void Threads_Exit(); extern void Proc_StartUser(Uint Entrypoint, Uint *Bases, int ArgC, char **ArgV, char **EnvP, int DataSize); extern tKernelSymbol gKernelSymbols[]; extern void gKernelSymbolsEnd; @@ -146,7 +146,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP) strcpy(savedFile, File); // --- Set Process Name - Proc_SetThreadName(File); + Threads_SetName(File); // --- Clear User Address space MM_ClearUser(); @@ -157,7 +157,7 @@ int Proc_Execve(char *File, char **ArgV, char **EnvP) if(bases[0] == 0) { Warning("Proc_Execve - Unable to load '%s'", File); - Proc_Exit(); + Threads_Exit(); for(;;); } diff --git a/Kernel/debug.c b/Kernel/debug.c index 8df36091..bd3b4074 100644 --- a/Kernel/debug.c +++ b/Kernel/debug.c @@ -9,7 +9,7 @@ #define E9(ch) __asm__ __volatile__ ("outb %%al, $0xe9"::"a"(((Uint8)ch))) // === IMPORTS === -extern void Proc_DumpThreads(); +extern void Threads_Dump(); // === GLOBALS === int gDebug_Level = 0; @@ -183,7 +183,7 @@ void Panic(char *Fmt, ...) va_end(args); E9('\n'); - Proc_DumpThreads(); + Threads_Dump(); __asm__ __volatile__ ("xchg %bx, %bx"); __asm__ __volatile__ ("cli;\n\thlt"); diff --git a/Kernel/drv/ata_x86.c b/Kernel/drv/ata_x86.c index a4c53065..837085ba 100644 --- a/Kernel/drv/ata_x86.c +++ b/Kernel/drv/ata_x86.c @@ -793,7 +793,7 @@ int ATA_ReadDMA(Uint8 Disk, Uint64 Address, Uint Count, void *Buffer) ATA_int_BusMasterWriteByte( cont << 3, 9 ); // Read and start // Wait for transfer to complete - while( gaATA_IRQs[cont] == 0 ) Proc_Yield(); + while( gaATA_IRQs[cont] == 0 ) Threads_Yield(); // Complete Transfer ATA_int_BusMasterWriteByte( cont << 3, 0 ); // Write and stop diff --git a/Kernel/drv/vterm.c b/Kernel/drv/vterm.c index 2cdd84ff..e5abc737 100644 --- a/Kernel/drv/vterm.c +++ b/Kernel/drv/vterm.c @@ -242,10 +242,9 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) case VT_MODE_TEXT8: while(pos < Length) { - while(term->InputRead == term->InputWrite) Proc_Yield(); + while(term->InputRead == term->InputWrite) Threads_Yield(); while(term->InputRead != term->InputWrite) { - LOG("WriteUTF8(%p, 0x%x)", Buffer+pos, term->InputBuffer[term->InputRead]); pos += WriteUTF8(Buffer+pos, term->InputBuffer[term->InputRead]); term->InputRead ++; term->InputRead %= MAX_INPUT_CHARS; @@ -256,7 +255,7 @@ Uint64 VT_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer) case VT_MODE_TEXT32: while(pos < Length) { - while(term->InputRead == term->InputWrite) Proc_Yield(); + while(term->InputRead == term->InputWrite) Threads_Yield(); while(term->InputRead != term->InputWrite) { ((Uint32*)Buffer)[pos] = term->InputBuffer[term->InputRead]; diff --git a/Kernel/heap.c b/Kernel/heap.c index 90b7256e..68239187 100644 --- a/Kernel/heap.c +++ b/Kernel/heap.c @@ -359,6 +359,23 @@ void *realloc(void *__ptr, size_t __size) return NULL; } +/** + * \fn int IsHeap(void *Ptr) + * \brief Checks if an address is a heap address + */ +int IsHeap(void *Ptr) +{ + tHeapHead *head; + if((Uint)Ptr < (Uint)gHeapStart) return 0; + if((Uint)Ptr > (Uint)gHeapEnd) return 0; + + head = (void*)( (Uint)Ptr - sizeof(tHeapHead) ); + if(head->Magic != MAGIC_USED && head->Magic != MAGIC_FREE) + return 0; + + return 1; +} + #if WARNINGS void Heap_Dump() { diff --git a/Kernel/include/common.h b/Kernel/include/common.h index 827d8ff0..4fb0952f 100644 --- a/Kernel/include/common.h +++ b/Kernel/include/common.h @@ -87,10 +87,12 @@ extern int strpos8(char *str, Uint32 search); extern void itoa(char *buf, Uint num, int base, int minLength, char pad); extern int ReadUTF8(Uint8 *str, Uint32 *Val); extern int WriteUTF8(Uint8 *str, Uint32 Val); +extern Uint rand(); // --- Heap --- extern void *malloc(size_t size); extern void *realloc(void *ptr, size_t size); extern void free(void *Ptr); +extern int IsHeap(void *Ptr); // --- Modules --- extern int Module_LoadMem(void *Buffer, Uint Length, char *ArgStr); extern int Module_LoadFile(char *Path, char *ArgStr); @@ -99,11 +101,12 @@ extern Sint64 timestamp(int sec, int mins, int hrs, int day, int month, int year extern Sint64 now(); // --- Threads --- extern int Proc_Spawn(char *Path); -extern void Proc_Exit(); -extern void Proc_Yield(); -extern int Proc_GetCfg(int Index); -extern int Proc_GetUID(); -extern int Proc_GetGID(); +extern void Threads_Exit(); +extern void Threads_Yield(); +extern void Threads_Sleep(); +extern int Threads_GetCfg(int Index); +extern int Threads_GetUID(); +extern int Threads_GetGID(); extern int SpawnTask(tThreadFunction Function, void *Arg); #include diff --git a/Kernel/include/threads.h b/Kernel/include/threads.h new file mode 100644 index 00000000..644d0333 --- /dev/null +++ b/Kernel/include/threads.h @@ -0,0 +1,66 @@ +/* + */ +#ifndef _THREADS_H_ +#define _THREADS_H_ + +#include +#include + +typedef struct sMessage +{ + struct sMessage *Next; + Uint Source; + Uint Length; + Uint8 Data[]; +} tMsg; // sizeof = 12+ + +typedef struct sThread +{ + struct sThread *Next; //!< Next thread in list + int IsLocked; //!< Thread's spinlock + int Status; //!< Thread Status + int RetStatus; //!< Return Status + + Uint TID; //!< Thread ID + Uint TGID; //!< Thread Group (Process) + Uint PTID; //!< Parent Thread ID + Uint UID, GID; //!< User and Group + char *ThreadName; //!< Name of thread + + tVAddr KernelStack; //!< Kernel Stack Base + + //! Memory Manager State + tMemoryState MemState; + + //! State on task switch + tTaskState SavedState; + + int CurSignal; //!< Signal currently being handled (0 for none) + tVAddr SignalHandlers[NSIG]; //!< Signal Handler List + tTaskState SignalState; //!< Saved state for signal handler + + tMsg *Messages; //!< Message Queue + tMsg *LastMessage; //!< Last Message (speeds up insertion) + + int Quantum, Remaining; //!< Quantum Size and remaining timesteps + int NumTickets; //!< Priority - Chance of gaining CPU + + Uint Config[NUM_CFG_ENTRIES]; //!< Per-process configuration +} tThread; + + +enum { + THREAD_STAT_NULL, + THREAD_STAT_ACTIVE, + THREAD_STAT_SLEEPING, + THREAD_STAT_WAITING, + THREAD_STAT_ZOMBIE, + THREAD_STAT_DEAD +}; + +// === FUNCTIONS === +extern tThread *Proc_GetCurThread(); +extern tThread *Threads_GetThread(Uint TID); +extern void Threads_Wake(tThread *Thread); + +#endif diff --git a/Kernel/messages.c b/Kernel/messages.c index 31ae8f37..93cf6ca4 100644 --- a/Kernel/messages.c +++ b/Kernel/messages.c @@ -26,7 +26,7 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data) } // Get thread - thread = Proc_GetThread( Dest ); + thread = Threads_GetThread( Dest ); // Error check if(!thread) { return -1; } @@ -40,7 +40,7 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data) // Create message msg = malloc( sizeof(tMsg)+Length ); msg->Next = NULL; - msg->Source = gCurrentThread->TID; + msg->Source = Proc_GetCurThread()->TID; msg->Length = Length; memcpy(msg->Data, Data, Length); @@ -55,7 +55,7 @@ int Proc_SendMessage(Uint *Err, Uint Dest, int Length, void *Data) RELEASE(&thread->IsLocked); - Thread_Wake( thread ); + Threads_Wake( thread ); return 0; } @@ -68,35 +68,36 @@ int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer) { int ret; void *tmp; + tThread *cur = Proc_GetCurThread(); // Check if queue has any items - if(!gCurrentThread->Messages) { + if(!cur->Messages) { return 0; } - LOCK( &gCurrentThread->IsLocked ); + LOCK( &cur->IsLocked ); if(Source) - *Source = gCurrentThread->Messages->Source; + *Source = cur->Messages->Source; // Get message length if( !Buffer ) { - ret = gCurrentThread->Messages->Length; - RELEASE( &gCurrentThread->IsLocked ); + ret = cur->Messages->Length; + RELEASE( &cur->IsLocked ); return ret; } // Get message if(Buffer != GETMSG_IGNORE) - memcpy(Buffer, gCurrentThread->Messages->Data, gCurrentThread->Messages->Length); - ret = gCurrentThread->Messages->Length; + memcpy(Buffer, cur->Messages->Data, cur->Messages->Length); + ret = cur->Messages->Length; // Remove from list - tmp = gCurrentThread->Messages->Next; - free(gCurrentThread->Messages); - gCurrentThread->Messages = tmp; + tmp = cur->Messages->Next; + free(cur->Messages); + cur->Messages = tmp; - RELEASE( &gCurrentThread->IsLocked ); + RELEASE( &cur->IsLocked ); return ret; } diff --git a/Kernel/syscalls.c b/Kernel/syscalls.c index 8e02c5de..47200c62 100644 --- a/Kernel/syscalls.c +++ b/Kernel/syscalls.c @@ -11,11 +11,17 @@ // === IMPORTS === extern int Proc_Clone(Uint *Err, Uint Flags); +extern int Threads_WaitTID(int TID, int *status); extern Uint Proc_SendMessage(Uint *Err, Uint Dest, Uint Length, void *Data); extern int Proc_GetMessage(Uint *Err, Uint *Source, void *Buffer); extern int Proc_Execve(char *File, char **ArgV, char **EnvP); extern Uint Binary_Load(char *file, Uint *entryPoint); extern int VFS_FInfo(int FD, void *Dest, int MaxACLs); +extern int Threads_SetName(char *NewName); +extern int Threads_GetPID(); +extern int Threads_GetTID(); +extern int Threads_GetUID(); +extern int Threads_GetGID(); // === CODE === void SyscallHandler(tSyscallRegs *Regs) @@ -31,13 +37,13 @@ void SyscallHandler(tSyscallRegs *Regs) switch(Regs->Num) { // -- Exit the current thread - case SYS_EXIT: Proc_Exit(); break; + case SYS_EXIT: Threads_Exit(); break; // -- Put the current thread to sleep - case SYS_SLEEP: Proc_Sleep(); Log(" SyscallHandler: %i is alive", gCurrentThread->TID); break; + case SYS_SLEEP: Threads_Sleep(); break; // -- Yield current timeslice - case SYS_YIELD: Proc_Yield(); break; + case SYS_YIELD: Threads_Yield(); break; // -- Clone the current thread case SYS_CLONE: @@ -54,6 +60,11 @@ void SyscallHandler(tSyscallRegs *Regs) ret = -1; break; + // -- Wait for a thread + case SYS_WAITTID: + ret = Threads_WaitTID(Regs->Arg1, (void*)Regs->Arg2); + break; + case SYS_GETPHYS: ret = MM_GetPhysAddr(Regs->Arg1); break; @@ -65,11 +76,11 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_UNMAP: MM_Deallocate(Regs->Arg1); break; // -- Get Thread/Process IDs - case SYS_GETTID: ret = gCurrentThread->TID; break; - case SYS_GETPID: ret = gCurrentThread->TGID; break; + case SYS_GETTID: ret = Threads_GetTID(); break; + case SYS_GETPID: ret = Threads_GetPID(); break; // -- Get User/Group IDs - case SYS_GETUID: ret = gCurrentThread->UID; break; - case SYS_GETGID: ret = gCurrentThread->GID; break; + case SYS_GETUID: ret = Threads_GetUID(); break; + case SYS_GETGID: ret = Threads_GetGID(); break; // -- Send Message case SYS_SENDMSG: @@ -84,16 +95,7 @@ void SyscallHandler(tSyscallRegs *Regs) case SYS_SETNAME: // Sanity Check if(!Regs->Arg1) { ret = -1; err = -EINVAL; break; } - // Lock Process - LOCK( &gCurrentThread->IsLocked ); - // Free old name - if(gCurrentThread->ThreadName && (Uint)gCurrentThread->ThreadName > 0xE0800000) - free(gCurrentThread->ThreadName); - // Change name - gCurrentThread->ThreadName = malloc( strlen( (char*)Regs->Arg1 ) + 1 ); - strcpy(gCurrentThread->ThreadName, (char*)Regs->Arg1); - // Unlock - RELEASE( &gCurrentThread->IsLocked ); + Threads_SetName( (void*)Regs->Arg1 ); break; // --- diff --git a/Kernel/threads.c b/Kernel/threads.c new file mode 100644 index 00000000..fb14f4d7 --- /dev/null +++ b/Kernel/threads.c @@ -0,0 +1,448 @@ +/* + * Acess2 + * threads.c + * - Common Thread Control + */ +#include +#include + +// === CONSTANTS === +#define DEFAULT_QUANTUM 10 +#define DEFAULT_TICKETS 5 +#define MAX_TICKETS 10 + +// === IMPORTS === +extern void ArchThreads_Init(); +extern tThread *Proc_GetCurThread(); +extern int Proc_Clone(Uint *Err, Uint Flags); + +// === PROTOTYPES === +void Threads_Init(); +void Threads_SetName(char *NewName); +void Threads_SetTickets(int Num); + int Threads_WaitTID(int TID, int *status); +tThread *Threads_GetThread(Uint TID); +tThread *Threads_int_GetPrev(tThread **List, tThread *Thread); +void Threads_Exit(int TID, int Status); +void Threads_Kill(tThread *Thread, int Status); +void Threads_Yield(); +void Threads_Sleep(); +void Threads_Wake(tThread *Thread); + int Threads_GetPID(); + int Threads_GetTID(); + int Threads_GetUID(); + int Threads_GetGID(); +void Threads_Dump(); + +// === GLOBALS === +// -- Core Thread -- +tThread gThreadZero = { + NULL, 0, // Next, Lock + THREAD_STAT_ACTIVE, // Status + 0, // Exit Status + 0, 0, // TID, TGID + 0, 0, // UID, GID + 0, // Parent Thread ID + "ThreadZero", // Name + + 0, // Kernel Stack + {0}, // Saved State + {0}, // VM State + + 0, {0}, {0}, // Signal State + + NULL, NULL, // Messages, Last Message + DEFAULT_QUANTUM, DEFAULT_QUANTUM, // Quantum, Remaining + DEFAULT_TICKETS, + {0} // Default config to zero + }; +// -- Processes -- +// --- Locks --- +volatile int giThreadListLock = 0; ///\note NEVER use a heap function while locked +// --- Current State --- +volatile int giNumActiveThreads = 0; +volatile int giTotalTickets = 0; +volatile Uint giNextTID = 1; +// --- Thread Lists --- +tThread *gActiveThreads = NULL; // Currently Running Threads +tThread *gSleepingThreads = NULL; // Sleeping Threads +tThread *gDeleteThreads = NULL; // Threads to delete + int giNumCPUs = 1; + +// === CODE === +/** + * \fn void Threads_Init() + * \brief Initialse the thread list + */ +void Threads_Init() +{ + ArchThreads_Init(); + + // Create Initial Task + gActiveThreads = &gThreadZero; + giTotalTickets = gThreadZero.NumTickets; + giNumActiveThreads = 1; + + #if 1 + // Create Idle Task + if(Proc_Clone(0, 0) == 0) + { + tThread *cur = Proc_GetCurThread(); + cur->ThreadName = "Idle Thread"; + Threads_SetTickets(0); // Never called randomly + cur->Quantum = 1; // 1 slice quantum + for(;;) __asm__ __volatile__ ("hlt"); // Just yeilds + } + #endif +} + +/** + * \fn void Threads_SetName(char *NewName) + * \brief Sets the current thread's name + */ +void Threads_SetName(char *NewName) +{ + tThread *cur = Proc_GetCurThread(); + if( IsHeap(cur->ThreadName) ) + free( cur->ThreadName ); + cur->ThreadName = malloc(strlen(NewName)+1); + strcpy(cur->ThreadName, NewName); +} + +/** + * \fn void Threads_SetTickets(int Num) + * \brief Sets the 'priority' of a task + */ +void Threads_SetTickets(int Num) +{ + tThread *cur = Proc_GetCurThread(); + if(Num < 0) return; + if(Num > MAX_TICKETS) Num = MAX_TICKETS; + + LOCK( &giThreadListLock ); + giTotalTickets -= cur->NumTickets; + cur->NumTickets = Num; + giTotalTickets += Num; + //LOG("giTotalTickets = %i", giTotalTickets); + RELEASE( &giThreadListLock ); +} + +/** + * \fn void Threads_WaitTID(int TID, int *status) + * \brief Wait for a task to change state + */ +int Threads_WaitTID(int TID, int *status) +{ + // Any Child + if(TID == -1) { + + return -1; + } + + // Any peer/child thread + if(TID == 0) { + + return -1; + } + + // TGID = abs(TID) + if(TID < -1) { + return -1; + } + + // Specific Thread + if(TID > 0) { + tThread *t = Threads_GetThread(TID); + int initStatus = t->Status; + int ret; + while(t->Status == initStatus) Threads_Yield(); + ret = t->RetStatus; + switch(t->Status) + { + case THREAD_STAT_ZOMBIE: + t->Status = THREAD_STAT_DEAD; + *status = 0; + break; + default: + *status = -1; + break; + } + return ret; + } + + return -1; +} + +/** + * \fn tThread *Threads_GetThread(Uint TID) + * \brief Gets a thread given its TID + */ +tThread *Threads_GetThread(Uint TID) +{ + tThread *thread; + + // Search Active List + for(thread = gActiveThreads; + thread; + thread = thread->Next) + { + if(thread->TID == TID) + return thread; + } + + // Search Sleeping List + for(thread = gSleepingThreads; + thread; + thread = thread->Next) + { + if(thread->TID == TID) + return thread; + } + + return NULL; +} + +/** + * \fn tThread *Threads_int_GetPrev(tThread *List, tThread *Thread) + * \brief Gets the previous entry in a thead linked list + */ +tThread *Threads_int_GetPrev(tThread **List, tThread *Thread) +{ + tThread *ret; + // First Entry + if(*List == Thread) { + return (tThread*)List; + } else { + for(ret = *List; + ret->Next && ret->Next != Thread; + ret = ret->Next + ); + // Error if the thread is not on the list + if(!ret->Next || ret->Next != Thread) { + return NULL; + } + } + return ret; +} + +/** + * \fn void Threads_Exit(int TID, int Status) + * \brief Exit the current process + */ +void Threads_Exit(int TID, int Status) +{ + Threads_Kill( Proc_GetCurThread(), (Uint)Status & 0xFF ); +} + +/** + * \fn void Threads_Kill(tThread *Thread, int Status) + * \brief Kill a thread + * \param TID Thread ID (0 for current) + */ +void Threads_Kill(tThread *Thread, int Status) +{ + tThread *prev; + tMsg *msg; + + // Kill all children + #if 0 + { + tThread *child; + for(child = gActiveThreads; + child; + child = child->Next) + { + if(child->PTID == gCurrentThread->TID) + Threads_Kill(child, -1); + } + } + #endif + + ///\note Double lock is needed due to overlap of locks + + // Lock thread (stop us recieving messages) + LOCK( &Thread->IsLocked ); + + // Lock thread list + LOCK( &giThreadListLock ); + + // Get previous thread on list + prev = Threads_int_GetPrev( &gActiveThreads, Thread ); + if(!prev) { + Warning("Proc_Exit - Current thread is not on the active queue"); + return; + } + + // Clear Message Queue + while( Thread->Messages ) + { + msg = Thread->Messages->Next; + free( Thread->Messages ); + Thread->Messages = msg; + } + + Thread->Remaining = 0; // Clear Remaining Quantum + Thread->Quantum = 0; // Clear Quantum to indicate dead thread + prev->Next = Thread->Next; // Remove from active + + giNumActiveThreads --; + giTotalTickets -= Thread->NumTickets; + + // Mark thread as a zombie + Thread->RetStatus = Status; + + // Don't Zombie if we are being killed as part of a tree + if(Status == -1) + { + Thread->Status = THREAD_STAT_DEAD; + // Add to delete queue + if(gDeleteThreads) { + Thread->Next = gDeleteThreads; + gDeleteThreads = Thread; + } else { + Thread->Next = NULL; + gDeleteThreads = Thread; + } + } else { + Thread->Status = THREAD_STAT_ZOMBIE; + } + + // Release spinlocks + RELEASE( &Thread->IsLocked ); // Released first so that it IS released + RELEASE( &giThreadListLock ); + if(Status != -1) HALT(); +} + +/** + * \fn void Threads_Yield() + * \brief Yield remainder of timeslice + */ +void Threads_Yield() +{ + Proc_GetCurThread()->Quantum = 0; + HALT(); +} + +/** + * \fn void Threads_Sleep() + * \brief Take the current process off the run queue + */ +void Threads_Sleep() +{ + tThread *cur = Proc_GetCurThread(); + tThread *thread; + + //Log("Proc_Sleep: %i going to sleep", gCurrentThread->TID); + + // Acquire Spinlock + LOCK( &giThreadListLock ); + + // Get thread before current thread + thread = Threads_int_GetPrev( &gActiveThreads, cur ); + if(!thread) { + Warning("Proc_Sleep - Current thread is not on the active queue"); + return; + } + + // Don't sleep if there is a message waiting + if( cur->Messages ) { + RELEASE( &giThreadListLock ); + return; + } + + // Unset remaining timeslices (force a task switch on timer fire) + cur->Remaining = 0; + + // Remove from active list + thread->Next = cur->Next; + + // Add to Sleeping List (at the top) + cur->Next = gSleepingThreads; + gSleepingThreads = cur; + + // Reduce the active count & ticket count + giNumActiveThreads --; + giTotalTickets -= cur->NumTickets; + + // Mark thread as sleeping + cur->Status = THREAD_STAT_SLEEPING; + + // Release Spinlock + RELEASE( &giThreadListLock ); + + HALT(); +} + + +/** + * \fn void Threads_Wake( tThread *Thread ) + * \brief Wakes a sleeping/waiting thread up + */ +void Threads_Wake(tThread *Thread) +{ + tThread *prev; + switch(Thread->Status) + { + case THREAD_STAT_ACTIVE: break; + case THREAD_STAT_SLEEPING: + LOCK( &giThreadListLock ); + prev = Threads_int_GetPrev(&gSleepingThreads, Thread); + prev->Next = Thread->Next; // Remove from sleeping queue + Thread->Next = gActiveThreads; // Add to active queue + gActiveThreads = Thread; + Thread->Status = THREAD_STAT_ACTIVE; + RELEASE( &giThreadListLock ); + break; + case THREAD_STAT_WAITING: + Warning("Thread_Wake - Waiting threads are not currently supported"); + break; + case THREAD_STAT_DEAD: + Warning("Thread_Wake - Attempt to wake dead thread (%i)", Thread->TID); + break; + default: + Warning("Thread_Wake - Unknown process status (%i)\n", Thread->Status); + break; + } +} + +// --- Process Structure Access Functions --- +int Threads_GetPID() +{ + return Proc_GetCurThread()->TGID; +} +int Threads_GetTID() +{ + return Proc_GetCurThread()->TID; +} +int Threads_GetUID() +{ + return Proc_GetCurThread()->UID; +} +int Threads_GetGID() +{ + return Proc_GetCurThread()->GID; +} + +/** + * \fn void Threads_Dump() + * \brief Dums a list of currently running threads + */ +void Threads_Dump() +{ + tThread *thread; + + Log("Active Threads:"); + for(thread=gActiveThreads;thread;thread=thread->Next) + { + Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName); + Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum); + Log(" KStack 0x%x", thread->KernelStack); + } + Log("Sleeping Threads:"); + for(thread=gSleepingThreads;thread;thread=thread->Next) + { + Log(" %i (%i) - %s", thread->TID, thread->TGID, thread->ThreadName); + Log(" %i Tickets, Quantum %i", thread->NumTickets, thread->Quantum); + Log(" KStack 0x%x", thread->KernelStack); + } +} diff --git a/Kernel/vfs/acls.c b/Kernel/vfs/acls.c index 52c802c6..5a112ded 100644 --- a/Kernel/vfs/acls.c +++ b/Kernel/vfs/acls.c @@ -19,8 +19,8 @@ tVFS_ACL gVFS_ACL_EveryoneRO = { {0,-1}, {0,VFS_PERM_READ} }; int VFS_CheckACL(tVFS_Node *Node, Uint Permissions) { int i; - int uid = Proc_GetUID(); - int gid = Proc_GetGID(); + int uid = Threads_GetUID(); + int gid = Threads_GetGID(); // Root can do anything if(uid == 0) return 1; diff --git a/Usermode/Applications/CLIShell_src/main.c b/Usermode/Applications/CLIShell_src/main.c index f753788d..d605baa7 100644 --- a/Usermode/Applications/CLIShell_src/main.c +++ b/Usermode/Applications/CLIShell_src/main.c @@ -97,35 +97,35 @@ int main(int argc, char *argv[], char *envp[]) cBUILTINS[length].fcn(iArgCount-1, &saArgs[1]); break; } - } - // Calling a file - if(length == BUILTIN_COUNT) - { - GeneratePath(saArgs[1], gsCurrentDirectory, gsTmpBuffer); - // Use length in place of fp - length = open(gsTmpBuffer, 0); - // Check file existence - if(length == -1) { - Print("Unknown Command: `");Print(saArgs[1]);Print("'\n"); // Error Message - continue; - } - // Check if the file is a directory - finfo( length, &info ); - close( length ); - if(info.flags & FILEFLAG_DIRECTORY) { - Print("`");Print(saArgs[1]); // Error Message - Print("' is a directory.\n"); - continue; - } - pid = clone(CLONE_VM, 0); - if(pid == 0) execve(gsTmpBuffer, &saArgs[1], NULL); - if(pid <= 0) { - Print("Unablt to create process: `");Print(gsTmpBuffer);Print("'\n"); // Error Message - //SysDebug("pid = %i\n", pid); - } - else { - //waitpid(pid, K_WAITPID_DIE); - } + } + + if(length != BUILTIN_COUNT) continue; + + // - Calling a file + GeneratePath(saArgs[1], gsCurrentDirectory, gsTmpBuffer); + // Use length in place of fp + length = open(gsTmpBuffer, 0); + // Check file existence + if(length == -1) { + Print("Unknown Command: `");Print(saArgs[1]);Print("'\n"); // Error Message + continue; + } + // Check if the file is a directory + finfo( length, &info ); + close( length ); + if(info.flags & FILEFLAG_DIRECTORY) { + Print("`");Print(saArgs[1]); // Error Message + Print("' is a directory.\n"); + continue; + } + pid = clone(CLONE_VM, 0); + if(pid == 0) execve(gsTmpBuffer, &saArgs[1], NULL); + if(pid <= 0) { + Print("Unablt to create process: `");Print(gsTmpBuffer);Print("'\n"); // Error Message + //SysDebug("pid = %i\n", pid); + } + else { + //waitpid(pid, K_WAITPID_DIE); } } }