SimpleKernel 1.17.0
Loading...
Searching...
No Matches
main.cpp
Go to the documentation of this file.
1
5#include <MPMCQueue.hpp>
6#include <cerrno>
7#include <cstdint>
8#include <new>
9
10#include "arch.h"
11#include "basic_info.hpp"
12#include "expected.hpp"
13#include "interrupt.h"
14#include "kernel.h"
15#include "kernel_log.hpp"
16#include "kstd_cstdio"
17#include "kstd_cstring"
18#include "kstd_libcxx.h"
19#include "mutex.hpp"
20#include "per_cpu.hpp"
21#include "sk_stdlib.h"
22#include "syscall.hpp"
24#include "task_manager.hpp"
25#include "virtual_memory.hpp"
26
27namespace {
28
30std::atomic<uint64_t> global_counter{0};
31
33auto task1_func(void* arg) -> void {
34 klog::Info("Task1: arg = {:#x}",
35 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(arg)));
36 for (int i = 0; i < 5; ++i) {
37 klog::Info("Task1: iteration {}/5", i + 1);
38 (void)sys_sleep(1000);
39 }
40 klog::Info("Task1: exiting with code 0");
41 sys_exit(0);
42}
43
45auto task2_func(void* arg) -> void {
46 klog::Info("Task2: arg = {:#x}",
47 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(arg)));
48 uint64_t count = 0;
49 while (1) {
50 klog::Info("Task2: yield count={}", count++);
51 (void)sys_sleep(2000);
52 // 主动让出 CPU
53 (void)sys_yield();
54 }
55}
56
58auto task3_func(void* arg) -> void {
59 klog::Info("Task3: arg = {:#x}",
60 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(arg)));
61 while (1) {
62 uint64_t old_value = global_counter.fetch_add(1, std::memory_order_relaxed);
63 klog::Info("Task3: global_counter {} -> {}", old_value, old_value + 1);
64 (void)sys_sleep(3000);
65 }
66}
67
69auto task4_func(void* arg) -> void {
70 klog::Info("Task4: arg = {:#x}",
71 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(arg)));
72 uint64_t iteration = 0;
73 while (1) {
74 auto* cpu_sched = per_cpu::GetCurrentCore().sched_data;
75 auto start_tick = cpu_sched->local_tick;
76 klog::Info("Task4: sleeping for 4s (iteration {})", iteration++);
77 (void)sys_sleep(4000);
78 auto end_tick = cpu_sched->local_tick;
79 klog::Info("Task4: woke up (slept ~{} ticks)", end_tick - start_tick);
80 }
81}
82
84auto create_test_tasks() -> void {
86 auto& tm = TaskManagerSingleton::instance();
87
88 auto task1 = kstd::make_unique<TaskControlBlock>(
89 "Task1-Exit", 10, task1_func, reinterpret_cast<void*>(0x1111));
90 auto task2 = kstd::make_unique<TaskControlBlock>(
91 "Task2-Yield", 10, task2_func, reinterpret_cast<void*>(0x2222));
92 auto task3 = kstd::make_unique<TaskControlBlock>(
93 "Task3-Sync", 10, task3_func, reinterpret_cast<void*>(0x3333));
94 auto task4 = kstd::make_unique<TaskControlBlock>(
95 "Task4-Sleep", 10, task4_func, reinterpret_cast<void*>(0x4444));
96
97 // 设置 CPU 亲和性,绑定到当前核心
98 task1->aux->cpu_affinity = (1UL << core_id);
99 task2->aux->cpu_affinity = (1UL << core_id);
100 task3->aux->cpu_affinity = (1UL << core_id);
101 task4->aux->cpu_affinity = (1UL << core_id);
102
103 tm.AddTask(std::move(task1));
104 tm.AddTask(std::move(task2));
105 tm.AddTask(std::move(task3));
106 tm.AddTask(std::move(task4));
107
108 klog::Info("Created 4 test tasks");
109}
110
112auto main_smp(int argc, const char** argv) -> int {
114 ArchInitSMP(argc, argv);
116 InterruptInitSMP(argc, argv);
117 TaskManagerSingleton::instance().InitCurrentCore();
118 TimerInitSMP();
119
120 klog::Info("Hello SimpleKernel SMP");
121
122 // 为当前核心创建测试任务
123 create_test_tasks();
124
125 // 启动调度器
126 TaskManagerSingleton::instance().Schedule();
127
128 // UNREACHABLE: Schedule() 不应返回
129 __builtin_unreachable();
130}
131
132} // namespace
133
134auto _start(int argc, const char** argv) -> void {
135 if (argv != nullptr) {
136 CppInit();
137 main(argc, argv);
138 } else {
139 main_smp(argc, argv);
140 }
141
142 while (true) {
144 }
145}
146
147auto main(int argc, const char** argv) -> int {
148 // 初始化当前核心的 per_cpu 数据
149 per_cpu::PerCpuArraySingleton::create();
151
152 // 架构相关初始化
153 ArchInit(argc, argv);
154 // 内存相关初始化
155 MemoryInit();
156 // 中断相关初始化
157 InterruptInit(argc, argv);
158 // 设备管理器初始化
159 DeviceInit();
160 // 文件系统初始化
162 // 初始化任务管理器 (设置主线程)
163 TaskManagerSingleton::create();
164 TaskManagerSingleton::instance().InitCurrentCore();
165
166 TimerInit();
167
168 // 唤醒其余 core
170
171 DumpStack();
172
173 klog::Info("Hello SimpleKernel");
174
175 klog::Info("Initializing test tasks...");
176
177 // 为主核心创建测试任务
178 create_test_tasks();
179
180 klog::Info("Main: Starting scheduler...");
181
182 // 启动调度器,不再返回
183 TaskManagerSingleton::instance().Schedule();
184
185 // UNREACHABLE: Schedule() 不应返回
186 __builtin_unreachable();
187}
auto WakeUpOtherCores() -> void
唤醒其余 core
Definition arch_main.cpp:68
auto ArchInit(int argc, const char **argv) -> void
体系结构相关初始化
Definition arch_main.cpp:48
auto ArchInitSMP(int argc, const char **argv) -> void
从核的体系结构相关初始化
Definition arch_main.cpp:65
auto DumpStack() -> void
打印调用栈
Definition backtrace.cpp:34
auto InterruptInit(int, const char **) -> void
体系结构相关中断初始化
auto InterruptInitSMP(int, const char **) -> void
从核的体系结构相关中断初始化
auto TimerInitSMP() -> void
从核的定时器初始化
Definition timer.cpp:35
auto TimerInit() -> void
初始化定时器
Definition timer.cpp:47
auto DeviceInit() -> void
设备子系统初始化入口
Definition device.cpp:28
auto FileSystemInit() -> void
文件系统子系统初始化入口
auto MemoryInit() -> void
内存子系统初始化
Definition memory.cpp:71
auto MemoryInitSMP() -> void
多核内存子系统初始化
Definition memory.cpp:106
auto CppInit() -> void
构造 c++ 全局对象
auto GetCurrentCoreId() -> size_t
Definition cpu_io.h:26
void Pause()
Definition cpu_io.h:20
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
static __always_inline auto GetCurrentCore() -> PerCpu &
获取当前核心的 PerCpu 数据
Definition per_cpu.hpp:55
size_t core_id
核心 ID
Definition per_cpu.hpp:1
auto _start(int argc, const char **argv) -> void
负责 crtbegin 的工作
Definition main.cpp:134
每个 CPU 核心的局部数据
Definition per_cpu.hpp:23
auto sys_sleep(uint64_t ms) -> int
休眠指定毫秒数
Definition syscall.cpp:90
auto sys_exit(int code) -> int
退出当前进程或线程
Definition syscall.cpp:75
auto sys_yield() -> int
主动放弃CPU,让出时间片
Definition syscall.cpp:85
void main()
Definition main.cpp:33