matos/core/thread.h

98 lines
3.5 KiB
C

#pragma once
struct thread;
#include "cpu_context.h"
#include "mem.h"
#include "process.h"
#include "wait.h"
#define THREAD_NAME_MAX_LENGTH 32
#define THREAD_DEFAULT_STACK_SIZE PAGE_SIZE
typedef enum {
RUNNING,
READY,
SLEEPING,
WAITING,
EXITING
} thread_state;
typedef unsigned long int thread_id_t;
struct thread {
char name[THREAD_NAME_MAX_LENGTH];
thread_id_t tid;
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;
struct wait_queue *wqExit; // This will be signaled at thread exit (user only)
/**
* 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);
struct thread *threadCreateUser(const char *name, struct process *proc, uaddr_t startPc,
uint32_t arg1, uint32_t arg2, uaddr_t startSP);
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 threadUsleep(unsigned long usec);
int threadOnJieffiesTick();
struct thread *getCurrentThread();
int threadAddThread(struct thread *th);
int threadChangeCurrentContext(struct mmu_context *ctx);
int threadCount();
thread_id_t threadGetId(struct thread *th);