65 LOG_DEBUG(
"created tid=%d pid=%d\n", thread->
id, process->
id);
110 thread->
frame = *frame;
115 *frame = thread->
frame;
124 *frame = thread->
frame;
165 panic(
NULL,
"Failed to initialize boot thread");
232 if (thread ==
NULL || dest ==
NULL || userSrc ==
NULL || length == 0)
243 memcpy(dest, userSrc, length);
250 if (thread ==
NULL || dest ==
NULL || userSrc ==
NULL || length == 0)
261 memcpy(dest, userSrc, length);
269 if (thread ==
NULL || userArray ==
NULL || terminator ==
NULL || objectSize == 0 || maxCount == 0 ||
278 if (arraySize ==
ERR)
283 uint64_t elementCount = arraySize / objectSize;
284 uint64_t allocSize = (elementCount + 1) * objectSize;
286 void* kernelArray =
malloc(allocSize);
287 if (kernelArray ==
NULL)
294 memcpy(kernelArray, userArray, arraySize);
295 memcpy((
uint8_t*)kernelArray + arraySize, terminator, objectSize);
298 *outArray = kernelArray;
299 if (outCount !=
NULL)
301 *outCount = elementCount;
309 if (thread ==
NULL || pathname ==
NULL || userPath ==
NULL)
315 char terminator =
'\0';
318 if (pathLength ==
ERR)
324 memcpy(copy, userPath, pathLength);
325 copy[pathLength] =
'\0';
338 if (thread ==
NULL || userObj ==
NULL || outValue ==
NULL)
#define MAX_PATH
Maximum length of filepaths.
#define assert(expression)
#define INTERRUPT_FRAME_IN_USER_SPACE(frame)
Checks if a interrupt frame is from user space.
void simd_ctx_save(simd_ctx_t *ctx)
void simd_ctx_load(simd_ctx_t *ctx)
uint64_t simd_ctx_init(simd_ctx_t *ctx)
void simd_ctx_deinit(simd_ctx_t *ctx)
#define STACK_POINTER_GUARD_PAGES
The amount of guard pages to use for stacks.
uint64_t stack_pointer_init(stack_pointer_t *stack, uintptr_t maxAddress, uint64_t maxPages)
Initializes a stack pointer structure, does not allocate or map any memory.
bool stack_pointer_is_in_stack(stack_pointer_t *stack, uintptr_t addr, uint64_t length)
Check if an region is within the stack.
#define SYSCALL_DEFINE(num, returnType,...)
Macro to define a syscall.
void syscall_ctx_init(syscall_ctx_t *ctx, stack_pointer_t *kernelStack)
Initialize a per-thread syscall context.
void syscall_ctx_load(syscall_ctx_t *ctx)
Load a syscall context into the CPU.
uint64_t pathname_init(pathname_t *pathname, const char *string)
Initialize a pathname.
uint64_t note_queue_length(note_queue_t *queue)
Get the length of a note queue.
uint64_t note_queue_write(note_queue_t *queue, const void *buffer, uint64_t count)
Write a note to a note queue.
void note_queue_init(note_queue_t *queue)
Initialize a note queue.
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
#define LOG_INFO(format,...)
#define LOG_DEBUG(format,...)
void space_unpin(space_t *space, const void *address, uint64_t length)
Unpins pages in a region previously pinned with space_pin() or space_pin_string().
uint64_t space_pin_terminated(space_t *space, const void *address, const void *terminator, uint8_t objectSize, uint64_t maxCount, stack_pointer_t *userStack)
Pins a region of memory terminated by a terminator value.
uint64_t space_pin(space_t *space, const void *address, uint64_t length, stack_pointer_t *userStack)
Pins pages within a region of the address space.
void space_load(space_t *space)
Loads a virtual address space.
#define VMM_KERNEL_STACKS_MAX
The maximum address for kernel stacks.
void * vmm_alloc(space_t *space, void *virtAddr, uint64_t length, pml_flags_t pmlFlags, vmm_alloc_flags_t allocFlags)
Allocates and maps virtual memory in a given address space.
#define VMM_USER_SPACE_MAX
The maximum address for user space.
@ VMM_ALLOC_FAIL_IF_MAPPED
If set and any page is already mapped, fail and set errno to EEXIST.
process_t * process_get_kernel(void)
Gets the kernel process.
bool thread_is_note_pending(thread_t *thread)
Check if a thread has a note pending.
void thread_free(thread_t *thread)
Frees a thread structure.
uint64_t thread_send_note(thread_t *thread, const void *buffer, uint64_t count)
Send a note to a thread.
uint64_t thread_copy_from_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data from user space.
void thread_load(thread_t *thread, interrupt_frame_t *frame)
Load state from a thread.
uint64_t thread_copy_to_user(thread_t *thread, void *dest, const void *userSrc, uint64_t length)
Safely copy data to user space.
uint64_t thread_load_atomic_from_user(thread_t *thread, atomic_uint64_t *userObj, uint64_t *outValue)
Atomically load a 64-bit value from a user-space atomic variable.
uint64_t thread_copy_from_user_terminated(thread_t *thread, const void *userArray, const void *terminator, uint8_t objectSize, uint64_t maxCount, void **outArray, uint64_t *outCount)
Safely copy a null-terminated array of objects from user space.
thread_t * thread_get_boot(void)
Retrieves the boot thread.
uint64_t thread_copy_from_user_pathname(thread_t *thread, pathname_t *pathname, const char *userPath)
Safely copy a string from user space and use it to initialize a pathname.
thread_t * thread_new(process_t *process)
Creates a new thread structure.
uint64_t thread_handle_page_fault(const interrupt_frame_t *frame)
Handles a page fault that occurred in the currently running thread.
void thread_save(thread_t *thread, const interrupt_frame_t *frame)
Save state to a thread.
thread_state_t
Thread state enum.
void thread_get_interrupt_frame(thread_t *thread, interrupt_frame_t *frame)
Retrieve the interrupt frame from a thread.
@ THREAD_UNBLOCKING
Has started unblocking, used to prevent the same thread being unblocked multiple times.
@ THREAD_BLOCKED
Is blocking and waiting in one or multiple wait queues.
@ THREAD_PARKED
Is doing nothing, not in a queue, not blocking, think of it as "other".
void wait_thread_ctx_init(wait_thread_ctx_t *wait)
Initialize per-thread wait context.
void wait_unblock_thread(thread_t *thread, errno_t err)
Unblock a specific thread.
thread_t * sched_thread(void)
Retrieves the currently running thread.
void sched_thread_ctx_init(sched_thread_ctx_t *ctx)
Initializes a thread's scheduling context.
thread_t * sched_thread_unsafe(void)
Retrieves the currently running thread without disabling interrupts.
static void lock_release(lock_t *lock)
Releases a lock.
static void lock_acquire(lock_t *lock)
Acquires a lock, blocking until it is available.
#define REF(ptr)
Increment reference count.
#define DEREF(ptr)
Decrement reference count.
#define CONFIG_MAX_USER_STACK_PAGES
User stack configuration.
#define CONFIG_MAX_KERNEL_STACK_PAGES
Kernel stack configuration.
#define EEXIST
File exists.
#define EINVAL
Invalid argument.
#define EFAULT
Bad address.
#define EINTR
Interrupted system call.
#define ENOMEM
Out of memory.
#define errno
Error number variable.
static void list_remove(list_t *list, list_entry_t *entry)
Removes a list entry from its current list.
static void list_push(list_t *list, list_entry_t *entry)
Pushes an entry to the end of the list.
static void list_entry_init(list_entry_t *entry)
Initializes a list entry.
#define ROUND_DOWN(number, multiple)
#define PAGE_SIZE
Memory page size.
#define NULL
Pointer error value.
#define ERR
Integer error value.
__UINT64_TYPE__ tid_t
Thread Identifier.
static bool bootThreadInitalized
static uint64_t thread_init(thread_t *thread, process_t *process)
static uintptr_t thread_id_to_offset(tid_t tid, uint64_t maxPages)
static thread_t bootThread
EFI_PHYSICAL_ADDRESS buffer
static uint64_t cr2_read()
#define atomic_compare_exchange_strong(object, expected, desired)
#define atomic_load(object)
#define atomic_init(obj, value)
__UINTPTR_TYPE__ uintptr_t
_PUBLIC void * malloc(size_t size)
_PUBLIC void free(void *ptr)
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
_PUBLIC void * memset(void *s, int c, size_t n)
process_threads_t threads
Thread of execution structure.
list_entry_t processEntry
The entry for the parent process.
process_t * process
The parent process that the thread executes within.
list_entry_t entry
The entry for the scheduler and wait system.
stack_pointer_t kernelStack
The kernel stack of the thread.
stack_pointer_t userStack
The user stack of the thread.
tid_t id
The thread id, unique within a process_t.