summaryrefslogtreecommitdiffhomepage
path: root/src/kernel/KernelKit/HardwareThreadScheduler.h
blob: ea74cc10e2211b63657ff471afa3f077eb129dd9 (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
/* ========================================

  Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license.

======================================== */

#ifndef __INC_MP_MANAGER_H__
#define __INC_MP_MANAGER_H__

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

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

#define kMaxAPInsideSched (4U)

namespace Kernel {
class HardwareThread;
class HardwareThreadScheduler;

using ThreadID = UInt32;

enum ThreadKind {
  kAPInvalid        = 0,
  kAPSystemReserved = 100,  // 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:
  explicit operator bool();

 public:
  Void Wake(const BOOL wakeup = false);
  Void Busy(const BOOL busy = false);

 public:
  BOOL Switch(HAL::StackFramePtr frame);
  BOOL IsWakeup();

 public:
  HAL::StackFramePtr        StackFrame();
  _Output const ThreadKind& Kind();
  BOOL                      IsBusy();
  _Output const ThreadID&   ID();

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

 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();

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

  Bool IsUser() override { return Yes; }

  Bool IsKernel() override { return No; }

  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();

 private:
  Array<HardwareThread, kMaxAPInsideSched> fThreadList;
  ThreadID                                 fCurrentThreadIdx{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__