96 lines
3.4 KiB
C
96 lines
3.4 KiB
C
#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;
|
|
|
|
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;
|
|
|
|
/**
|
|
* 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);
|