forked from Bananymous/banan-os
				
			Kernel: Sleep now actually sleeps and allows idling
This commit is contained in:
		
							parent
							
								
									66a4b69a29
								
							
						
					
					
						commit
						1bd8b0fe5c
					
				| 
						 | 
					@ -129,6 +129,8 @@ found:
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			dprintln("no handler for irq 0x{2H}\n", irq);
 | 
								dprintln("no handler for irq 0x{2H}\n", irq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// NOTE: Scheduler sends PIT eoi's
 | 
				
			||||||
 | 
							if (irq != PIT_IRQ)
 | 
				
			||||||
			InterruptController::get().eoi(irq);
 | 
								InterruptController::get().eoi(irq);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,12 +11,11 @@ exit_thread_trampoline:
 | 
				
			||||||
	pushl %eax
 | 
						pushl %eax
 | 
				
			||||||
	ret
 | 
						ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# void start_thread(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t rsp, uint32_t rbp, uint32_t rip)
 | 
					# void start_thread(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3, uint32_t rsp, uint32_t rip)
 | 
				
			||||||
.global start_thread
 | 
					.global start_thread
 | 
				
			||||||
start_thread:
 | 
					start_thread:
 | 
				
			||||||
	movl %esp, %eax
 | 
						movl %esp, %eax
 | 
				
			||||||
	movl 28(%eax), %ecx
 | 
						movl 24(%eax), %ecx
 | 
				
			||||||
	movl 24(%eax), %ebp
 | 
					 | 
				
			||||||
	movl 20(%eax), %esp
 | 
						movl 20(%eax), %esp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pushl 16(%eax)
 | 
						pushl 16(%eax)
 | 
				
			||||||
| 
						 | 
					@ -25,14 +24,15 @@ start_thread:
 | 
				
			||||||
	pushl 4(%eax)
 | 
						pushl 4(%eax)
 | 
				
			||||||
	pushl $exit_thread_trampoline
 | 
						pushl $exit_thread_trampoline
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						movl $0, %ebp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sti
 | 
						sti
 | 
				
			||||||
	jmp *%ecx
 | 
						jmp *%ecx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# void continue_thread(uint32_t rsp, uint32_t rbp, uint32_t rip)
 | 
					# void continue_thread(uint32_t rsp, uint32_t rip)
 | 
				
			||||||
.global continue_thread
 | 
					.global continue_thread
 | 
				
			||||||
continue_thread:
 | 
					continue_thread:
 | 
				
			||||||
	movl 12(%esp), %ecx
 | 
						movl 8(%esp), %ecx
 | 
				
			||||||
	movl 8(%esp), %ebp
 | 
					 | 
				
			||||||
	movl 4(%esp), %esp
 | 
						movl 4(%esp), %esp
 | 
				
			||||||
	movl $0, %eax
 | 
						movl $0, %eax
 | 
				
			||||||
	jmp *%ecx
 | 
						jmp *%ecx
 | 
				
			||||||
| 
						 | 
					@ -126,6 +126,8 @@ namespace IDT
 | 
				
			||||||
			dprintln("no handler for irq 0x{2H}\n", irq);
 | 
								dprintln("no handler for irq 0x{2H}\n", irq);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// NOTE: Scheduler sends PIT eoi's
 | 
				
			||||||
 | 
							if (irq != PIT_IRQ)
 | 
				
			||||||
			InterruptController::get().eoi(irq);
 | 
								InterruptController::get().eoi(irq);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,20 +8,18 @@ exit_thread_trampoline:
 | 
				
			||||||
	movq 8(%rsp), %rdi
 | 
						movq 8(%rsp), %rdi
 | 
				
			||||||
	ret
 | 
						ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# void start_thread(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t rsp, uint64_t rbp, uint64_t rip)
 | 
					# void start_thread(uint64_t arg0, uint64_t arg1, uint64_t arg2, uint64_t arg3, uint64_t rsp, uint64_t rip)
 | 
				
			||||||
.global start_thread
 | 
					.global start_thread
 | 
				
			||||||
start_thread:
 | 
					start_thread:
 | 
				
			||||||
	movq 8(%rsp), %rcx
 | 
					 | 
				
			||||||
	movq %r8, %rsp
 | 
						movq %r8, %rsp
 | 
				
			||||||
	movq %r9, %rbp
 | 
						movq $0, %rbp
 | 
				
			||||||
	pushq $exit_thread_trampoline
 | 
						pushq $exit_thread_trampoline
 | 
				
			||||||
	sti
 | 
						sti
 | 
				
			||||||
	jmp *%rcx
 | 
						jmp *%r9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# void continue_thread(uint64_t rsp, uint64_t rbp, uint64_t rip)
 | 
					# void continue_thread(uint64_t rsp, uint64_t rip)
 | 
				
			||||||
.global continue_thread
 | 
					.global continue_thread
 | 
				
			||||||
continue_thread:
 | 
					continue_thread:
 | 
				
			||||||
	movq %rdi, %rsp
 | 
						movq %rdi, %rsp
 | 
				
			||||||
	movq %rsi, %rbp
 | 
					 | 
				
			||||||
	movq $0, %rax
 | 
						movq $0, %rax
 | 
				
			||||||
	jmp *%rdx
 | 
						jmp *%rsi
 | 
				
			||||||
| 
						 | 
					@ -19,27 +19,33 @@ namespace Kernel
 | 
				
			||||||
		const Thread& current_thread() const;
 | 
							const Thread& current_thread() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template<typename... Args>
 | 
							template<typename... Args>
 | 
				
			||||||
		void add_thread(const BAN::Function<void(Args...)>& func, Args... args)
 | 
							[[nodiscard]] BAN::ErrorOr<void> add_thread(const BAN::Function<void(Args...)>& func, Args... args)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			uintptr_t flags;
 | 
								uintptr_t flags;
 | 
				
			||||||
			asm volatile("pushf; pop %0" : "=r"(flags));
 | 
								asm volatile("pushf; pop %0" : "=r"(flags));
 | 
				
			||||||
			asm volatile("cli");
 | 
								asm volatile("cli");
 | 
				
			||||||
			MUST(m_threads.emplace_back(func, BAN::forward<Args>(args)...));
 | 
								TRY(m_threads.emplace_back(func, BAN::forward<Args>(args)...));
 | 
				
			||||||
			if (flags & (1 << 9))
 | 
								if (flags & (1 << 9))
 | 
				
			||||||
				asm volatile("sti");
 | 
									asm volatile("sti");
 | 
				
			||||||
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void switch_thread();
 | 
							void reschedule();
 | 
				
			||||||
 | 
							void set_current_thread_sleeping();
 | 
				
			||||||
		void start();
 | 
							void start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static constexpr size_t ms_between_switch = 1;
 | 
							static constexpr size_t ms_between_switch = 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		Scheduler() {}
 | 
							Scheduler() {}
 | 
				
			||||||
 | 
							void switch_thread();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		BAN::LinkedList<Thread>				m_threads;
 | 
							BAN::LinkedList<Thread>				m_threads;
 | 
				
			||||||
		BAN::LinkedList<Thread>::iterator	m_current_iterator;
 | 
							BAN::LinkedList<Thread>::iterator	m_current_iterator;
 | 
				
			||||||
 | 
							uint64_t							m_last_reschedule = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							friend class Thread;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,7 @@ namespace Kernel
 | 
				
			||||||
			NotStarted,
 | 
								NotStarted,
 | 
				
			||||||
			Running,
 | 
								Running,
 | 
				
			||||||
			Paused,
 | 
								Paused,
 | 
				
			||||||
 | 
								Sleeping,
 | 
				
			||||||
			Done,
 | 
								Done,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,11 +37,9 @@ namespace Kernel
 | 
				
			||||||
		uint32_t id() const { return m_id; }
 | 
							uint32_t id() const { return m_id; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void set_rsp(uintptr_t rsp) { m_rsp = rsp; }
 | 
							void set_rsp(uintptr_t rsp) { m_rsp = rsp; }
 | 
				
			||||||
		void set_rbp(uintptr_t rbp) { m_rbp = rbp; }
 | 
					 | 
				
			||||||
		void set_rip(uintptr_t rip) { m_rip = rip; }
 | 
							void set_rip(uintptr_t rip) { m_rip = rip; }
 | 
				
			||||||
		void set_state(State state) { m_state = state; }
 | 
							void set_state(State state) { m_state = state; }
 | 
				
			||||||
		uintptr_t rsp() const { return m_rsp; }
 | 
							uintptr_t rsp() const { return m_rsp; }
 | 
				
			||||||
		uintptr_t rbp() const { return m_rbp; }
 | 
					 | 
				
			||||||
		uintptr_t rip() const { return m_rip; }
 | 
							uintptr_t rip() const { return m_rip; }
 | 
				
			||||||
		State state() const { return m_state; }
 | 
							State state() const { return m_state; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,7 +54,6 @@ namespace Kernel
 | 
				
			||||||
		State			m_state			= State::NotStarted;
 | 
							State			m_state			= State::NotStarted;
 | 
				
			||||||
		uintptr_t		m_args[4]		= {};
 | 
							uintptr_t		m_args[4]		= {};
 | 
				
			||||||
		uintptr_t		m_rip			= 0;
 | 
							uintptr_t		m_rip			= 0;
 | 
				
			||||||
		uintptr_t		m_rbp			= 0;
 | 
					 | 
				
			||||||
		uintptr_t		m_rsp			= 0;
 | 
							uintptr_t		m_rsp			= 0;
 | 
				
			||||||
		const uint32_t	m_id			= 0;
 | 
							const uint32_t	m_id			= 0;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -28,7 +28,7 @@ namespace PIT
 | 
				
			||||||
	void irq_handler()
 | 
						void irq_handler()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		s_system_time++;
 | 
							s_system_time++;
 | 
				
			||||||
		Kernel::Scheduler::get().switch_thread();
 | 
							Kernel::Scheduler::get().reschedule();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t ms_since_boot()
 | 
						uint64_t ms_since_boot()
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ namespace PIT
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uint64_t end = s_system_time + ms;
 | 
							uint64_t end = s_system_time + ms;
 | 
				
			||||||
		while (s_system_time < end)
 | 
							while (s_system_time < end)
 | 
				
			||||||
			asm volatile("hlt");
 | 
								Kernel::Scheduler::get().set_current_thread_sleeping();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,14 +7,16 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static Scheduler* s_instance = nullptr;
 | 
						static Scheduler* s_instance = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	extern "C" void start_thread(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t rsp, uintptr_t rbp, uintptr_t rip);
 | 
						extern "C" void start_thread(uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t rsp, uintptr_t rip);
 | 
				
			||||||
	extern "C" void continue_thread(uintptr_t rsp, uintptr_t rbp, uintptr_t rip);
 | 
						extern "C" void continue_thread(uintptr_t rsp, uintptr_t rip);
 | 
				
			||||||
	extern "C" uintptr_t read_rip();
 | 
						extern "C" uintptr_t read_rip();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Scheduler::initialize()
 | 
						void Scheduler::initialize()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(!s_instance);
 | 
							ASSERT(!s_instance);
 | 
				
			||||||
		s_instance = new Scheduler();
 | 
							s_instance = new Scheduler();
 | 
				
			||||||
 | 
							ASSERT(s_instance);
 | 
				
			||||||
 | 
							MUST(s_instance->add_thread(BAN::Function<void()>([] { for(;;) asm volatile("hlt"); })));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Scheduler& Scheduler::get()
 | 
						Scheduler& Scheduler::get()
 | 
				
			||||||
| 
						 | 
					@ -28,72 +30,92 @@ namespace Kernel
 | 
				
			||||||
		return *m_current_iterator;
 | 
							return *m_current_iterator;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Scheduler::reschedule()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							ASSERT(InterruptController::get().is_in_service(PIT_IRQ));
 | 
				
			||||||
 | 
							InterruptController::get().eoi(PIT_IRQ);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint64_t current_time = PIT::ms_since_boot();
 | 
				
			||||||
 | 
							if (m_last_reschedule + ms_between_switch > current_time)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							m_last_reschedule = current_time;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (Thread& thread : m_threads)
 | 
				
			||||||
 | 
								if (thread.state() == Thread::State::Sleeping)
 | 
				
			||||||
 | 
									thread.set_state(Thread::State::Paused);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch_thread();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Scheduler::switch_thread()
 | 
						void Scheduler::switch_thread()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		uintptr_t rsp, rbp, rip;
 | 
							uintptr_t rsp, rip;
 | 
				
			||||||
 | 
							push_callee_saved();
 | 
				
			||||||
		if (!(rip = read_rip()))
 | 
							if (!(rip = read_rip()))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								pop_callee_saved();
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		read_rsp(rsp);
 | 
							read_rsp(rsp);
 | 
				
			||||||
		read_rbp(rbp);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static uint8_t cnt = 0;
 | 
							ASSERT(m_threads.size() > 1);
 | 
				
			||||||
		if (cnt++ % ms_between_switch)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ASSERT(InterruptController::get().is_in_service(PIT_IRQ));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ASSERT(m_threads.size() > 0);
 | 
					 | 
				
			||||||
		if (m_threads.size() == 1)
 | 
					 | 
				
			||||||
			return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ASSERT(m_current_iterator);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto next_iterator = m_current_iterator;
 | 
					 | 
				
			||||||
		if (++next_iterator == m_threads.end())
 | 
					 | 
				
			||||||
			next_iterator = m_threads.begin();
 | 
					 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		Thread& current = *m_current_iterator;
 | 
							Thread& current = *m_current_iterator;
 | 
				
			||||||
		Thread& next 	= *next_iterator;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ASSERT(next.state() == Thread::State::Paused || next.state() == Thread::State::NotStarted);
 | 
							//if (m_threads.size() == 2 && current.id() != 0 && current.state() == Thread::State::Running)
 | 
				
			||||||
 | 
							//	return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (current.state() == Thread::State::Done)
 | 
							if (current.state() == Thread::State::Done)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			// NOTE: this does not invalidate the next/next_iterator
 | 
					 | 
				
			||||||
			//       since we are working with linked list
 | 
					 | 
				
			||||||
			m_threads.remove(m_current_iterator);
 | 
								m_threads.remove(m_current_iterator);
 | 
				
			||||||
			m_current_iterator = decltype(m_threads)::iterator();
 | 
								m_current_iterator = m_threads.begin();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
		if (m_current_iterator)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			current.set_rsp(rsp);
 | 
								current.set_rsp(rsp);
 | 
				
			||||||
			current.set_rbp(rbp);
 | 
					 | 
				
			||||||
			current.set_rip(rip);
 | 
								current.set_rip(rip);
 | 
				
			||||||
 | 
								if (current.state() != Thread::State::Sleeping)
 | 
				
			||||||
				current.set_state(Thread::State::Paused);
 | 
									current.set_state(Thread::State::Paused);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto next_iterator = m_current_iterator;
 | 
				
			||||||
 | 
							if (++next_iterator == m_threads.end())
 | 
				
			||||||
 | 
								next_iterator = ++m_threads.begin();
 | 
				
			||||||
 | 
							if (next_iterator->state() == Thread::State::Sleeping)
 | 
				
			||||||
 | 
								next_iterator = m_threads.begin();
 | 
				
			||||||
 | 
							Thread& next = *next_iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_current_iterator = next_iterator;
 | 
							m_current_iterator = next_iterator;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (next.state() == Thread::State::NotStarted)
 | 
							switch (next.state())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			InterruptController::get().eoi(PIT_IRQ);
 | 
								case Thread::State::NotStarted:
 | 
				
			||||||
				next.set_state(Thread::State::Running);
 | 
									next.set_state(Thread::State::Running);
 | 
				
			||||||
			const uintptr_t* args = next.args();
 | 
									start_thread(next.args()[0], next.args()[1], next.args()[2], next.args()[3], next.rsp(), next.rip());
 | 
				
			||||||
			start_thread(args[0], args[1], args[2], args[3], next.rsp(), next.rbp(), next.rip());
 | 
									break;
 | 
				
			||||||
		}
 | 
								case Thread::State::Paused:
 | 
				
			||||||
		else if (next.state() == Thread::State::Paused)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
				next.set_state(Thread::State::Running);
 | 
									next.set_state(Thread::State::Running);
 | 
				
			||||||
			continue_thread(next.rsp(), next.rbp(), next.rip());
 | 
									continue_thread(next.rsp(), next.rip());
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
 | 
								case Thread::State::Sleeping:	ASSERT(false);
 | 
				
			||||||
 | 
								case Thread::State::Running:	ASSERT(false);
 | 
				
			||||||
 | 
								case Thread::State::Done:		ASSERT(false);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		ASSERT(false);
 | 
							ASSERT(false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
 | 
						void Scheduler::set_current_thread_sleeping()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							asm volatile("cli");
 | 
				
			||||||
 | 
							m_current_iterator->set_state(Thread::State::Sleeping);
 | 
				
			||||||
 | 
							switch_thread();
 | 
				
			||||||
 | 
							asm volatile("sti");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Scheduler::start()
 | 
						void Scheduler::start()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		ASSERT(m_threads.size() > 0);
 | 
							ASSERT(m_threads.size() > 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		m_current_iterator = m_threads.begin();
 | 
							m_current_iterator = m_threads.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,7 +124,7 @@ namespace Kernel
 | 
				
			||||||
		current.set_state(Thread::State::Running);
 | 
							current.set_state(Thread::State::Running);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		const uintptr_t* args = current.args();
 | 
							const uintptr_t* args = current.args();
 | 
				
			||||||
		start_thread(args[0], args[1], args[2], args[3], current.rsp(), current.rbp(), current.rip());
 | 
							start_thread(args[0], args[1], args[2], args[3], current.rsp(), current.rip());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ASSERT(false);
 | 
							ASSERT(false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,9 +10,9 @@
 | 
				
			||||||
namespace Kernel
 | 
					namespace Kernel
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static uint32_t s_next_id = 1;
 | 
						static uint32_t s_next_id = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static constexpr size_t thread_stack_size = PAGE_SIZE;
 | 
						static constexpr size_t thread_stack_size = 16384;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<size_t size, typename T>
 | 
						template<size_t size, typename T>
 | 
				
			||||||
	static void write_to_stack(uintptr_t& rsp, const T& value)
 | 
						static void write_to_stack(uintptr_t& rsp, const T& value)
 | 
				
			||||||
| 
						 | 
					@ -27,8 +27,7 @@ namespace Kernel
 | 
				
			||||||
		m_stack_base = kmalloc(thread_stack_size, PAGE_SIZE);
 | 
							m_stack_base = kmalloc(thread_stack_size, PAGE_SIZE);
 | 
				
			||||||
		ASSERT(m_stack_base);
 | 
							ASSERT(m_stack_base);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
		m_rbp = (uintptr_t)m_stack_base + thread_stack_size;
 | 
							m_rsp = (uintptr_t)m_stack_base + thread_stack_size;
 | 
				
			||||||
		m_rsp = m_rbp;
 | 
					 | 
				
			||||||
		m_rip = rip;
 | 
							m_rip = rip;
 | 
				
			||||||
		m_args[1] = arg1;
 | 
							m_args[1] = arg1;
 | 
				
			||||||
		m_args[2] = arg2;
 | 
							m_args[2] = arg2;
 | 
				
			||||||
| 
						 | 
					@ -54,8 +53,10 @@ namespace Kernel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Thread::on_exit()
 | 
						void Thread::on_exit()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							asm volatile("cli");
 | 
				
			||||||
		m_state = State::Done;
 | 
							m_state = State::Done;
 | 
				
			||||||
		for (;;) asm volatile("hlt");
 | 
							Scheduler::get().switch_thread();
 | 
				
			||||||
 | 
							ASSERT(false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -97,8 +97,8 @@ extern "C" void kernel_main()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Scheduler::initialize();
 | 
						Scheduler::initialize();
 | 
				
			||||||
	Scheduler& scheduler = Scheduler::get();
 | 
						Scheduler& scheduler = Scheduler::get();
 | 
				
			||||||
	scheduler.add_thread(BAN::Function<void()>([] { DiskIO::initialize(); }));
 | 
						MUST(scheduler.add_thread(BAN::Function<void()>([] { DiskIO::initialize(); })));
 | 
				
			||||||
	scheduler.add_thread(BAN::Function<void()>([tty1] { Shell(tty1).run(); }));
 | 
						MUST(scheduler.add_thread(BAN::Function<void()>([tty1] { Shell(tty1).run(); })));
 | 
				
			||||||
	scheduler.start();
 | 
						scheduler.start();
 | 
				
			||||||
	ASSERT(false);
 | 
						ASSERT(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue