Kernel: Thread is no longer RefCounted
This makes developement with Scheduler much easier against compiler optimizations. I could now remove the pragma GCC optimize stuff.
This commit is contained in:
		
							parent
							
								
									c2e3b422cc
								
							
						
					
					
						commit
						dcee92a6bc
					
				|  | @ -44,7 +44,7 @@ namespace Kernel | |||
| 		BAN::String working_directory() const; | ||||
| 		BAN::ErrorOr<void> set_working_directory(BAN::StringView); | ||||
| 
 | ||||
| 		static BAN::RefPtr<Process> current() { return Thread::current()->process(); } | ||||
| 		static BAN::RefPtr<Process> current() { return Thread::current().process(); } | ||||
| 
 | ||||
| 	private: | ||||
| 		Process(pid_t pid) : m_pid(pid) {} | ||||
|  | @ -70,7 +70,7 @@ namespace Kernel | |||
| 
 | ||||
| 		const pid_t m_pid = 0; | ||||
| 		BAN::String m_working_directory; | ||||
| 		BAN::Vector<BAN::RefPtr<Thread>> m_threads; | ||||
| 		BAN::Vector<Thread*> m_threads; | ||||
| 
 | ||||
| 		friend class BAN::RefPtr<Process>; | ||||
| 	}; | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ namespace Kernel | |||
| 		void start(); | ||||
| 		void reschedule(); | ||||
| 
 | ||||
| 		BAN::ErrorOr<void> add_thread(BAN::RefPtr<Thread>); | ||||
| 		BAN::ErrorOr<void> add_thread(Thread*); | ||||
| 
 | ||||
| 		void set_current_thread_sleeping(uint64_t); | ||||
| 		[[noreturn]] void set_current_thread_done(); | ||||
|  | @ -25,7 +25,7 @@ namespace Kernel | |||
| 		void block_current_thread(Semaphore*); | ||||
| 		void unblock_threads(Semaphore*); | ||||
| 
 | ||||
| 		BAN::RefPtr<Thread> current_thread(); | ||||
| 		Thread& current_thread(); | ||||
| 
 | ||||
| 	private: | ||||
| 		Scheduler() = default; | ||||
|  | @ -39,27 +39,27 @@ namespace Kernel | |||
| 	private: | ||||
| 		struct ActiveThread | ||||
| 		{ | ||||
| 			ActiveThread(const BAN::RefPtr<Thread>& thread) : thread(thread) {} | ||||
| 			BAN::RefPtr<Thread> thread; | ||||
| 			uint64_t padding = 0; | ||||
| 			ActiveThread(Thread* thread) : thread(thread) {} | ||||
| 			Thread* thread; | ||||
| 			uint64_t padding; | ||||
| 		}; | ||||
| 
 | ||||
| 		struct SleepingThread | ||||
| 		{ | ||||
| 			SleepingThread(const BAN::RefPtr<Thread>& thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} | ||||
| 			BAN::RefPtr<Thread> thread; | ||||
| 			SleepingThread(Thread* thread, uint64_t wake_time) : thread(thread), wake_time(wake_time) {} | ||||
| 			Thread* thread; | ||||
| 			uint64_t wake_time; | ||||
| 		}; | ||||
| 
 | ||||
| 		struct BlockingThread | ||||
| 		{ | ||||
| 			BlockingThread(const BAN::RefPtr<Thread>& thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} | ||||
| 			BAN::RefPtr<Thread> thread; | ||||
| 			BlockingThread(Thread* thread, Semaphore* semaphore) : thread(thread), semaphore(semaphore) {} | ||||
| 			Thread* thread; | ||||
| 			Semaphore* semaphore; | ||||
| 			uint8_t padding[sizeof(uint64_t) - sizeof(Semaphore*)]; | ||||
| 		}; | ||||
| 
 | ||||
| 		BAN::RefPtr<Thread> m_idle_thread; | ||||
| 		Thread* m_idle_thread { nullptr }; | ||||
| 		BAN::LinkedList<ActiveThread> m_active_threads; | ||||
| 		BAN::LinkedList<SleepingThread> m_sleeping_threads; | ||||
| 		BAN::LinkedList<BlockingThread> m_blocking_threads; | ||||
|  |  | |||
|  | @ -10,13 +10,16 @@ namespace Kernel | |||
| 
 | ||||
| 	class Process; | ||||
| 
 | ||||
| 	class Thread : public BAN::RefCounted<Thread> | ||||
| 	class Thread | ||||
| 	{ | ||||
| 		BAN_NON_COPYABLE(Thread); | ||||
| 		BAN_NON_MOVABLE(Thread); | ||||
| 		 | ||||
| 	public: | ||||
| 		using entry_t = void(*)(void*); | ||||
| 
 | ||||
| 	public: | ||||
| 		static BAN::ErrorOr<BAN::RefPtr<Thread>> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr); | ||||
| 		static BAN::ErrorOr<Thread*> create(entry_t, void* = nullptr, BAN::RefPtr<Process> = nullptr); | ||||
| 		~Thread(); | ||||
| 
 | ||||
| 		pid_t tid() const { return m_tid; } | ||||
|  | @ -29,7 +32,7 @@ namespace Kernel | |||
| 		void set_started() { m_started = true; } | ||||
| 		bool started() const { return m_started; } | ||||
| 
 | ||||
| 		static BAN::RefPtr<Thread> current() ; | ||||
| 		static Thread& current() ; | ||||
| 		BAN::RefPtr<Process> process(); | ||||
| 
 | ||||
| 	private: | ||||
|  | @ -45,8 +48,6 @@ namespace Kernel | |||
| 		const pid_t	m_tid			= 0; | ||||
| 		bool		m_started		= false; | ||||
| 		BAN::RefPtr<Process> m_process; | ||||
| 
 | ||||
| 		friend class BAN::RefPtr<Thread>; | ||||
| 	}; | ||||
| 	 | ||||
| } | ||||
|  | @ -22,7 +22,7 @@ namespace Kernel | |||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 
 | ||||
| 		auto thread = TRY(Thread::create(entry, data, this)); | ||||
| 		Thread* thread = TRY(Thread::create(entry, data, this)); | ||||
| 		TRY(m_threads.push_back(thread)); | ||||
| 		if (auto res = Scheduler::get().add_thread(thread); res.is_error()) | ||||
| 		{ | ||||
|  | @ -36,9 +36,8 @@ namespace Kernel | |||
| 	void Process::on_thread_exit(Thread& thread) | ||||
| 	{ | ||||
| 		LockGuard _(m_lock); | ||||
| 		dprintln("thread {} exit", thread.tid()); | ||||
| 		for (size_t i = 0; i < m_threads.size(); i++) | ||||
| 			if (m_threads[i].ptr() == &thread) | ||||
| 			if (m_threads[i] == &thread) | ||||
| 				m_threads.remove(i); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
|  | @ -46,9 +46,9 @@ namespace Kernel | |||
| 		ASSERT_NOT_REACHED(); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::RefPtr<Thread> Scheduler::current_thread() | ||||
| 	Thread& Scheduler::current_thread() | ||||
| 	{ | ||||
| 		return m_current_thread ? m_current_thread->thread : m_idle_thread; | ||||
| 		return m_current_thread ? *m_current_thread->thread : *m_idle_thread; | ||||
| 	} | ||||
| 
 | ||||
| 	void Scheduler::reschedule() | ||||
|  | @ -77,17 +77,16 @@ namespace Kernel | |||
| 		uint64_t current_time = PIT::ms_since_boot(); | ||||
| 		while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time) | ||||
| 		{ | ||||
| 			auto thread = m_sleeping_threads.front().thread; | ||||
| 			Thread* thread = m_sleeping_threads.front().thread; | ||||
| 			m_sleeping_threads.remove(m_sleeping_threads.begin()); | ||||
| 
 | ||||
| 			// This should work as we released enough memory from sleeping thread
 | ||||
| 			static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); | ||||
| 			MUST(m_active_threads.emplace_back(thread)); | ||||
| 			thread.clear(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<void> Scheduler::add_thread(BAN::RefPtr<Thread> thread) | ||||
| 	BAN::ErrorOr<void> Scheduler::add_thread(Thread* thread) | ||||
| 	{ | ||||
| 		Kernel::CriticalScope critical; | ||||
| 		TRY(m_active_threads.emplace_back(thread)); | ||||
|  | @ -141,9 +140,9 @@ namespace Kernel | |||
| 		} | ||||
| 		read_rsp(rsp); | ||||
| 
 | ||||
| 		auto current = current_thread(); | ||||
| 		current->set_rip(rip); | ||||
| 		current->set_rsp(rsp); | ||||
| 		Thread& current = current_thread(); | ||||
| 		current.set_rip(rip); | ||||
| 		current.set_rsp(rsp); | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
|  | @ -151,7 +150,7 @@ namespace Kernel | |||
| 	{ | ||||
| 		VERIFY_CLI(); | ||||
| 		 | ||||
| 		auto& current = *current_thread(); | ||||
| 		Thread& current = current_thread(); | ||||
| 
 | ||||
| 		if (current.started()) | ||||
| 		{ | ||||
|  | @ -166,8 +165,6 @@ namespace Kernel | |||
| 		ASSERT_NOT_REACHED(); | ||||
| 	} | ||||
| 
 | ||||
| #pragma GCC push_options | ||||
| #pragma GCC optimize("O0") | ||||
| 	void Scheduler::set_current_thread_sleeping(uint64_t wake_time) | ||||
| 	{ | ||||
| 		VERIFY_STI(); | ||||
|  | @ -175,7 +172,7 @@ namespace Kernel | |||
| 
 | ||||
| 		ASSERT(m_current_thread); | ||||
| 
 | ||||
| 		auto sleeping = m_current_thread->thread; | ||||
| 		Thread* sleeping = m_current_thread->thread; | ||||
| 
 | ||||
| 		if (save_current_thread()) | ||||
| 		{ | ||||
|  | @ -192,12 +189,10 @@ namespace Kernel | |||
| 		// This should work as we released enough memory from active thread
 | ||||
| 		static_assert(sizeof(ActiveThread) == sizeof(SleepingThread)); | ||||
| 		MUST(m_sleeping_threads.emplace(it, sleeping, wake_time)); | ||||
| 		sleeping.clear(); | ||||
| 
 | ||||
| 		execute_current_thread(); | ||||
| 		ASSERT_NOT_REACHED(); | ||||
| 	} | ||||
| #pragma GCC pop_options | ||||
| 
 | ||||
| 	void Scheduler::set_current_thread_done() | ||||
| 	{ | ||||
|  | @ -205,14 +200,15 @@ namespace Kernel | |||
| 		DISABLE_INTERRUPTS(); | ||||
| 
 | ||||
| 		ASSERT(m_current_thread); | ||||
| 
 | ||||
| 		Thread* thread = m_current_thread->thread; | ||||
| 		remove_and_advance_current_thread(); | ||||
| 		delete thread; | ||||
| 
 | ||||
| 		execute_current_thread(); | ||||
| 		ASSERT_NOT_REACHED(); | ||||
| 	} | ||||
| 
 | ||||
| #pragma GCC push_options | ||||
| #pragma GCC optimize("O0") | ||||
| 	void Scheduler::block_current_thread(Semaphore* semaphore) | ||||
| 	{ | ||||
| 		VERIFY_STI(); | ||||
|  | @ -220,7 +216,7 @@ namespace Kernel | |||
| 
 | ||||
| 		ASSERT(m_current_thread); | ||||
| 
 | ||||
| 		auto blocking = m_current_thread->thread; | ||||
| 		Thread* blocking = m_current_thread->thread; | ||||
| 
 | ||||
| 		if (save_current_thread()) | ||||
| 		{ | ||||
|  | @ -232,14 +228,12 @@ namespace Kernel | |||
| 		// This should work as we released enough memory from active thread
 | ||||
| 		static_assert(sizeof(ActiveThread) == sizeof(BlockingThread)); | ||||
| 		MUST(m_blocking_threads.emplace_back(blocking, semaphore)); | ||||
| 		blocking.clear(); | ||||
| 
 | ||||
| 		semaphore->m_blocked = true; | ||||
| 
 | ||||
| 		execute_current_thread(); | ||||
| 		ASSERT_NOT_REACHED(); | ||||
| 	} | ||||
| #pragma GCC pop_options | ||||
| 	 | ||||
| 	void Scheduler::unblock_threads(Semaphore* semaphore) | ||||
| 	{ | ||||
|  |  | |||
|  | @ -25,7 +25,7 @@ namespace Kernel | |||
| 	void RecursiveSpinLock::lock() | ||||
| 	{ | ||||
| 		// FIXME: is this thread safe?
 | ||||
| 		if (m_locker == Thread::current()->tid()) | ||||
| 		if (m_locker == Thread::current().tid()) | ||||
| 		{ | ||||
| 			m_lock_depth++; | ||||
| 		} | ||||
|  | @ -33,7 +33,7 @@ namespace Kernel | |||
| 		{ | ||||
| 			m_lock.lock(); | ||||
| 			ASSERT(m_locker == 0); | ||||
| 			m_locker = Thread::current()->tid(); | ||||
| 			m_locker = Thread::current().tid(); | ||||
| 			m_lock_depth = 1; | ||||
| 		} | ||||
| 	} | ||||
|  |  | |||
|  | @ -19,10 +19,12 @@ namespace Kernel | |||
| 		memcpy((void*)rsp, (void*)&value, size); | ||||
| 	} | ||||
| 
 | ||||
| 	BAN::ErrorOr<BAN::RefPtr<Thread>> Thread::create(entry_t entry, void* data, BAN::RefPtr<Process> process) | ||||
| 	BAN::ErrorOr<Thread*> Thread::create(entry_t entry, void* data, BAN::RefPtr<Process> process) | ||||
| 	{ | ||||
| 		static pid_t next_tid = 1; | ||||
| 		auto thread = TRY(BAN::RefPtr<Thread>::create(next_tid++, process)); | ||||
| 		auto* thread = new Thread(next_tid++, process); | ||||
| 		if (thread == nullptr) | ||||
| 			return BAN::Error::from_errno(ENOMEM); | ||||
| 		TRY(thread->initialize(entry, data)); | ||||
| 		return thread; | ||||
| 	} | ||||
|  | @ -31,7 +33,7 @@ namespace Kernel | |||
| 		: m_tid(tid), m_process(process) | ||||
| 	{} | ||||
| 
 | ||||
| 	BAN::RefPtr<Thread> Thread::current() | ||||
| 	Thread& Thread::current() | ||||
| 	{ | ||||
| 		return Scheduler::get().current_thread(); | ||||
| 	} | ||||
|  | @ -58,6 +60,7 @@ namespace Kernel | |||
| 
 | ||||
| 	Thread::~Thread() | ||||
| 	{ | ||||
| 		dprintln("thread {} exit", tid()); | ||||
| 		kfree(m_stack_base); | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue