summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/KernelKit/HardwareThreadScheduler.h
blob: 6ee55226ec5545e4c6068023fa144192ff4aadb0 (plain)
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* -------------------------------------------

	Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.

------------------------------------------- */

#ifndef __INC_MP_MANAGER_H__
#define __INC_MP_MANAGER_H__

#include <ArchKit/ArchKit.h>
#include <CompilerKit/CompilerKit.h>
#include <NewKit/Ref.h>

/// @note Last Rev Sun 28 Jul CET 2024
/// @note Last Rev Thu, Aug  1, 2024  9:07:38 AM

#define kMaxAPInsideSched (8U)

namespace Kernel
{
	class HardwareThread;
	class HardwareThreadScheduler;

	using ThreadID = UInt32;

	enum ThreadKind
	{
		kAPInvalid,
		kAPSystemReserved, // System reserved thread, well user can't use it
		kAPStandard,	   // user thread, cannot be used by Kernel
		kAPRealTime,	   // fallback thread, cannot be used by user if not clear or
						   // used by Kernel.
		kAPBoot,		   // The core we booted from, the mama.
		kAPCount,
	};

	typedef enum ThreadKind ThreadKind;
	typedef ThreadID		ThreadID;

	/***********************************************************************************/
	///
	/// \name HardwareThread
	/// \brief Abstraction over the CPU's core, used to run processes or threads.
	///
	/***********************************************************************************/

	class HardwareThread final
	{
	public:
		explicit HardwareThread();
		~HardwareThread();

	public:
		NE_COPY_DEFAULT(HardwareThread)

	public:
		operator bool();

	public:
		void Wake(const bool wakeup = false) noexcept;
		void Busy(const bool busy = false) noexcept;

	public:
		bool Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid);
		bool IsWakeup() noexcept;

	public:
		HAL::StackFramePtr StackFrame() noexcept;
		const ThreadKind&  Kind() noexcept;
		bool			   IsBusy() noexcept;
		const ThreadID&	   ID() noexcept;

	private:
		HAL::StackFramePtr fStack{nullptr};
		ThreadKind		   fKind{ThreadKind::kAPStandard};
		ThreadID		   fID{0};
		ThreadID		   fPID{0};
		Bool			   fWakeup{NO};
		Bool			   fBusy{NO};
		UInt64			   fPTime{0};

	private:
		friend class HardwareThreadScheduler;
		friend class UserProcessHelper;
	};

	///
	/// \name HardwareThreadScheduler
	/// \brief Class to manage the thread scheduling.
	///

	class HardwareThreadScheduler final : public ISchedulable
	{
	private:
		friend class UserProcessHelper;

	public:
		explicit HardwareThreadScheduler();
		~HardwareThreadScheduler();
		NE_COPY_DEFAULT(HardwareThreadScheduler);

	public:
		HAL::StackFramePtr Leak() noexcept;

	public:
		Ref<HardwareThread*> operator[](const SizeT& idx);
		bool				 operator!() noexcept;
							 operator bool() noexcept;

		const Bool IsUser() override
		{
			return Yes;
		}

		const Bool IsKernel() override
		{
			return No;
		}

		const Bool HasMP() override
		{
			return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
		}

	public:
		/// @brief Shared instance of the MP Mgr.
		/// @return the reference to the mp manager class.
		STATIC HardwareThreadScheduler& The();

	public:
		/// @brief Returns the amount of threads present in the system.
		/// @returns SizeT the amount of cores present.
		SizeT Capacity() noexcept;

	private:
		Array<HardwareThread, kMaxAPInsideSched> fThreadList;
		ThreadID								 fCurrentThread{0};
	};

	/// @brief wakes up thread.
	/// wakes up thread from hang.
	Void mp_wakeup_thread(HAL::StackFramePtr stack);

	/// @brief makes thread sleep.
	/// hooks and hangs thread to prevent code from executing.
	Void mp_hang_thread(HAL::StackFramePtr stack);
} // namespace Kernel

#endif // !__INC_MP_MANAGER_H__