#pragma once struct thread; #include "cpu_context.h" #include "mem.h" #include "process.h" #define THREAD_NAME_MAX_LENGTH 32 #define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE typedef enum { RUNNING, READY, SLEEPING, WAITING, EXITING } thread_state; struct thread { char name[THREAD_NAME_MAX_LENGTH]; struct cpu_state *cpuState; thread_state state; vaddr_t stackAddr; size_t stackSize; unsigned long jiffiesSleeping; int sleepHaveTimeouted; struct thread *next, *prev; struct thread *timeNext, *timePrev; // For User thread only struct thread *nextInProcess, *prevInProcess; struct process *process; /** * Address space currently "squatted" by the thread, or used to be * active when the thread was interrupted/preempted. This is the MMU * configuration expected before the cpu_state of the thread is * restored on CPU. * - For kernel threads: should normally be NULL, meaning that the * thread will squat the current mm_context currently set in the * MMU. Might be NON NULL when a kernel thread squats a given * process to manipulate its address space. * - For user threads: should normally be NULL. More precisely: * - in user mode: the thread->process.mm_context is ALWAYS * set on MMU. squatted_mm_context is ALWAYS NULL in this * situation, meaning that the thread in user mode uses its * process-space as expected * - in kernel mode: NULL means that we keep on using the * mm_context currently set on MMU, which might be the * mm_context of another process. This is natural since a * thread in kernel mode normally only uses data in kernel * space. BTW, this limits the number of TLB flushes. However, * there are exceptions where this squatted_mm_context will * NOT be NULL. One is the copy_from/to_user API, which can * force the effective mm_context so that the MMU will be * (re)configured upon every context to the thread to match * the squatted_mm_context. Another exception is when a parent * thread creates the address space of a child process, in * which case the parent thread might temporarilly decide to * switch to the child's process space. * * This is the SOS/matos implementation of the Linux "Lazy TLB" and * address-space loaning. */ struct mmu_context *squattedContext; }; int threadSetup(vaddr_t mainStack, size_t mainStackSize); void threadExit(); struct thread *threadCreate(const char *name, cpu_kstate_function_arg1_t func, void *args); void threadDelete(struct thread *thread); struct thread *threadSelectNext(); struct cpu_state *threadSwitch(struct cpu_state *prevCpu); int threadYield(); int threadWait(struct thread *current, struct thread *next, unsigned long msec); int threadUnsched(struct thread *th); int threadMsleep(unsigned long msec); int threadOnJieffiesTick(); struct thread *getCurrentThread(); int threadAddThread(struct thread *th); int threadChangeCurrentContext(struct mmu_context *ctx);