Max OS 0.3
Loading...
Searching...
No Matches
process.cpp
Go to the documentation of this file.
1
9#include <processes/process.h>
10#include <common/logger.h>
11
12using namespace MaxOS;
13using namespace MaxOS::system;
14using namespace MaxOS::memory;
15using namespace MaxOS::processes;
16using namespace MaxOS::common;
17
26Thread::Thread(void (* _entry_point)(void*), void* args, int arg_amount, Process* parent) {
27
28 // Basic setup
29 thread_state = ThreadState::NEW;
30 wakeup_time = 0;
31 ticks = 0;
32
33 // Create the stack
34 m_stack_pointer = (uintptr_t) MemoryManager::malloc(STACK_SIZE);
35
36 // Create the TSS stack
37 if (parent->is_kernel) {
38
39 // Use the kernel stack
40 m_tss_stack_pointer = CPU::executing_core() -> tss.rsp0;
41
42 } else {
43 m_tss_stack_pointer = (uintptr_t) MemoryManager::kmalloc(STACK_SIZE) + STACK_SIZE;
44 }
45
46 // Mak sure there is a stack
47 ASSERT(m_stack_pointer != 0 && m_tss_stack_pointer != 0, "Failed to allocate stack for thread");
48
49 // Set up the execution state
50 execution_state = {};
52 execution_state.ss = parent->is_kernel ? 0x10 : 0x23;
53 execution_state.cs = parent->is_kernel ? 0x8 : 0x1B;
54 execution_state.rflags = 0x202;
55 execution_state.interrupt_number = 0;
56 execution_state.error_code = 0;
57 execution_state.rsp = m_stack_pointer;
58 execution_state.rbp = 0;
59
60 // Copy the args into userspace
62 void* argv = MemoryManager::malloc(arg_amount * sizeof(void*));
63 memcpy(argv, args, arg_amount * sizeof(void*));
64
67 //execution_state->rdx = (uint64_t)env_args;
68
69 parent_pid = parent->pid();
70}
71
75Thread::~Thread() = default;
76
83
84 // Update the state
85 thread_state = ThreadState::SLEEPING;
87}
88
93
94 // Ensure the state saving is enabled
95 if (!CPU::executing_core()->xsave_enabled)
96 return;
97
98 // Save the state
99 asm volatile("fxsave %0" : "=m" (m_sse_save_region));
100}
101
106
107 // Ensure the state saving is enabled
108 if (!CPU::executing_core()->xsave_enabled)
109 return;
110
111 // Restore the state
112 asm volatile("fxrstor %0" : : "m" (m_sse_save_region));
113}
114
119 asm volatile(
120 // Store return address before stack is modified
121 "movq (%%rsp), %%rax\n"
122
123 // Store RDI before stack is modified
124 "pushq %%rdi\n"
125 "movq %0, %%rdi\n"
126
127 // Store general purpose
128 "movq %%r15, 0x00(%%rdi)\n"
129 "movq %%r14, 0x08(%%rdi)\n"
130 "movq %%r13, 0x10(%%rdi)\n"
131 "movq %%r12, 0x18(%%rdi)\n"
132 "movq %%r11, 0x20(%%rdi)\n"
133 "movq %%r10, 0x28(%%rdi)\n"
134 "movq %%r9, 0x30(%%rdi)\n"
135 "movq %%r8, 0x38(%%rdi)\n"
136 "movq %%rdi, 0x40(%%rdi)\n"
137 "movq %%rsi, 0x48(%%rdi)\n"
138 "movq %%rbp, 0x50(%%rdi)\n"
139 "movq %%rdx, 0x58(%%rdi)\n"
140 "movq %%rcx, 0x60(%%rdi)\n"
141 "movq %%rbx, 0x68(%%rdi)\n"
142 "movq %%rax, 0x70(%%rdi)\n"
143
144 // Reserved
145 "movq $0, 0x78(%%rdi)\n"
146 "movq $0, 0x80(%%rdi)\n"
147
148 // RIP from earlier
149 "movq %%rax, 0x88(%%rdi)\n"
150
151 // Get cs
152 "xorq %%rax, %%rax\n"
153 "movw %%cs, %%ax\n"
154 "movq %%rax, 0x90(%%rdi)\n"
155
156 // Store flags
157 "pushfq\n"
158 "popq %%rax\n"
159 "movq %%rax, 0x98(%%rdi)\n"
160
161 // Get RSP and SS
162 "movq %%rsp, 0xA0(%%rdi)\n"
163 "xorq %%rax, %%rax\n"
164 "movw %%ss, %%ax\n"
165 "movq %%rax, 0xA8(%%rdi)\n"
166
167 // Restore RDI
168 "popq %%rdi\n"
169 :
170 : "r" (&execution_state)
171 : "rax", "cc", "memory"
172 );
173}
174
181Process::Process(const string& p_name, bool is_kernel)
182: is_kernel(is_kernel),
183 name(p_name)
184{
185 // If it is a kernel process then don't need a new memory manager
187}
188
198Process::Process(const string& p_name, void (* _entry_point)(void*), void* args, int arg_amount, bool is_kernel)
199: Process(p_name, is_kernel)
200{
201
202 // Create the main thread
203 auto* main_thread = new Thread(_entry_point, args, arg_amount, this);
204
205 // Add the thread
207}
208
218Process::Process(const string& p_name, void* args, int arg_amount, ELF64* elf, bool is_kernel)
219: Process(p_name, is_kernel)
220{
221
222 // Get the entry point
223 elf->load();
224 auto* entry_point = (void (*)(void*)) elf->header()->entry;
225
226 // Create the main thread
227 auto* main_thread = new Thread(entry_point, args, arg_amount, this);
229}
230
231
236
238
239 // Free the threads
240 for (auto thread: m_threads)
241 delete thread;
242
243 // Free the memory manager (only if it was created)
244 if (!is_kernel)
245 delete memory_manager;
246
247 // Log the cleanup
248 Logger::DEBUG() << "Process " << name.c_str() << " cleaned up, memory before: " << pages << " bytes, after cleanup: " << PhysicalMemoryManager::s_current_manager->memory_used() << " bytes\n";
249}
250
257
258 m_lock.lock();
259
260 // Store the thread
261 m_threads.push_back(thread);
262 thread->parent_pid = m_pid;
263
264 m_lock.unlock();
265}
266
273
274 // Find the thread
275 for (uint32_t i = 0; i < m_threads.size(); i++) {
276
277 // Thread is not what is being removed
278 if (m_threads[i]->tid != tid)
279 continue;
280
281 // Delete the thread
282 Thread* thread = m_threads[i];
283 delete thread;
284
285 // Remove the thread from the list
286 m_threads.erase(m_threads.begin() + i);
287 return;
288 }
289}
290
297
298 // Check if the pid is already set
299 if (m_pid != 0)
300 return;
301
302 // Set the pid
303 m_pid = pid;
304
305 // Assign the pid to the threads
306 for (auto thread: m_threads)
307 thread->parent_pid = pid;
308
309}
310
317
318 return m_threads;
319}
320
327
328 return m_pid;
329}
330
337
339 for (auto thread: m_threads)
340 total_ticks += thread->ticks;
341
342 return total_ticks;
343}
static Logger DEBUG()
Gets active logger set to DEBUG level.
Definition logger.cpp:193
Stores the left, top, width and height of a rectangle.
Definition rectangle.h:22
void lock()
Lock the spinlock once it is available.
Definition spinlock.cpp:24
void unlock()
Unlock the spinlock.
Definition spinlock.cpp:32
Handles memory allocation and deallocation.
static MemoryManager * s_kernel_memory_manager
The memory manager for any kernel processes and all kernel allocations.
static void * malloc(size_t size)
Allocates a block of memory in the current USERSPACE heap.
static void * kmalloc(size_t size)
Allocates a block of memory in the KERNEL space.
static PhysicalMemoryManager * s_current_manager
The current physical memory manager in use.
Definition physical.h:185
Handles the loading and parsing of 64-bit ELF files.
Definition elf.h:217
A process that can be scheduled by the Scheduler, wraps & manages threads as well as its own address ...
Definition process.h:85
uint64_t pid() const
Gets the pid of the process.
Definition process.cpp:326
uint64_t total_ticks()
Gets the total ticks of the threads in the process (not this does not include any past killed threads...
Definition process.cpp:336
string name
The name of the process.
Definition process.h:109
common::Vector< Thread * > threads()
Gets the threads of the process.
Definition process.cpp:316
void add_thread(Thread *thread)
Adds a thread to the process.
Definition process.cpp:256
~Process()
Destructor for the Process class.
Definition process.cpp:235
Process(const string &name, bool is_kernel=false)
Base Constructor for the Process.
Definition process.cpp:181
bool is_kernel
Whether this process is a kernel process.
Definition process.h:107
void set_pid(uint64_t pid)
Sets the pid of the process once added to the queue.
Definition process.cpp:296
void remove_thread(uint64_t tid)
Remove a thread by its tid (NOTE: this will not remove it from the scheduler)
Definition process.cpp:272
memory::MemoryManager * memory_manager
The manager for memory used by this process.
Definition process.h:112
The execution context of a sub-process thread.
Definition process.h:49
thread_state_t thread_state
The current state of the thread.
Definition process.h:68
Thread(void(*_entry_point)(void *), void *args, int arg_amount, Process *parent)
Constructor for the Thread class.
Definition process.cpp:26
uint64_t parent_pid
The parent process ID.
Definition process.h:65
void save_sse_state()
Saves the SSE, x87 FPU, and MMX states from memory to the thread.
Definition process.cpp:92
size_t wakeup_time
The time at which the thread should wake up (if sleeping)
Definition process.h:71
~Thread()
Destructor for the Thread class.
void save_cpu_state()
Saves the CPU state into the thread's execution_state structure.
Definition process.cpp:118
system::cpu_status_t execution_state
The CPU state of the thread.
Definition process.h:67
void restore_sse_state()
Restores the SSE, x87 FPU, and MMX states from the thread to memory.
Definition process.cpp:105
size_t ticks
The number of ticks the thread has run for.
Definition process.h:70
void sleep(size_t milliseconds)
Sleeps the thread for a certain amount of time.
Definition process.cpp:82
static Core * executing_core()
Gets the core that is currently executing.
Definition cpu.cpp:623
Defines a Logger class for logging messages with different severity levels to multiple output streams...
#define ASSERT(condition, format,...)
If the specified condition is not met then the kernel will crash with the specified message.
Definition logger.h:100
void * memcpy(void *destination, const void *source, uint64_t num)
Copies a block of memory from one location to another.
Definition memoryIO.cpp:165
Defines Process and Thread classes for managing processes and their execution contexts.
constexpr size_t STACK_SIZE
The size of the stack for each thread (4KB)
Definition process.h:43