-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththread.c
85 lines (70 loc) · 2.83 KB
/
thread.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "thread.h"
#include "kmalloc.h"
#include "scheduler.h"
// Current running thread.
static thread_t *current_thread;
// Global variable to assign unique thread IDs.
uint32_t next_tid = 0;
// Forward declaration for thread exit function.
void thread_exit();
// External assembly function to create a thread.
extern void _create_thread(int (*fn)(void*), void *arg, uint32_t *stack, thread_t *thread);
/**
* @brief Initializes threading by creating the first thread.
*
* Allocates memory for a new thread structure, assigns it a unique ID, and
* sets it as the current thread.
*
* @return A pointer to the initialized thread structure.
*/
thread_t *init_threading() {
// Allocate memory for the initial thread structure.
thread_t *thread = kmalloc(sizeof(thread_t));
thread->id = next_tid++; // Assign a unique thread ID.
// Set the current thread to the newly created thread.
current_thread = thread;
return thread;
}
/**
* @brief Creates a new thread.
*
* Allocates memory for a thread structure, sets up the stack, and initializes
* the thread's state. The thread is marked as ready to run.
*
* @param fn The function the thread will execute.
* @param arg The argument passed to the thread function.
* @param stack Pointer to the stack memory allocated for the thread.
* @return A pointer to the newly created thread structure.
*/
thread_t *create_thread(int (*fn)(void*), void *arg, uint32_t *stack) {
// Allocate memory for the new thread structure.
thread_t *thread = kmalloc(sizeof(thread_t));
memset(thread, 0, sizeof(thread_t)); // Clear the memory for initialization.
thread->id = next_tid++; // Assign a unique thread ID.
// Set up the thread's stack in reverse order: arguments, return address, function pointer.
*--stack = (uint32_t)arg; // Argument for the thread function.
*--stack = (uint32_t)&thread_exit; // Return address (thread exit function).
*--stack = (uint32_t)fn; // Thread function entry point.
// Set the thread's stack pointer and initial register values.
thread->esp = (uint32_t)stack; // Stack pointer.
thread->ebp = 0; // Base pointer (unused here).
thread->eflags = 0x200; // Interrupts enabled.
// Mark the thread as ready to be scheduled.
thread_is_ready(thread);
return thread;
}
/**
* @brief Terminates the current thread.
*
* This function is called when a thread finishes execution. It prints the
* exit value of the thread and enters an infinite loop to prevent further
* execution.
*/
void thread_exit() {
// Retrieve the exit value from the eax register.
register uint32_t val asm("eax");
// Print the exit value of the thread.
printk("Thread exited with value %d\n", val);
// Enter an infinite loop to prevent the thread from executing further.
for (;;) ;
}