SimpleKernel 1.17.0
Loading...
Searching...
No Matches
syscall.cpp File Reference
#include "syscall.hpp"
#include "kernel.h"
#include "kernel_log.hpp"
#include "spinlock.hpp"
#include "task_manager.hpp"
Include dependency graph for syscall.cpp:

Go to the source code of this file.

Functions

auto syscall_dispatcher (int64_t syscall_id, uint64_t args[6]) -> int
 
auto sys_write (int fd, const char *buf, size_t len) -> int
 向文件描述符写入数据
 
auto sys_exit (int code) -> int
 退出当前进程或线程
 
auto sys_yield () -> int
 主动放弃CPU,让出时间片
 
auto sys_sleep (uint64_t ms) -> int
 休眠指定毫秒数
 
auto sys_clone (uint64_t flags, void *stack, int *parent_tid, int *child_tid, void *tls) -> int
 创建新线程(或进程)
 
auto sys_fork () -> int
 创建新进程(fork)
 
auto sys_gettid () -> int
 获取当前线程ID
 
auto sys_set_tid_address (int *tidptr) -> int
 设置线程ID地址(用于线程退出时的清理)
 
auto sys_futex (int *uaddr, int op, int val, const void *timeout, int *uaddr2, int val3) -> int
 快速用户空间互斥锁操作(futex)
 
auto sys_sched_getaffinity (int pid, size_t cpusetsize, uint64_t *mask) -> int
 获取线程的CPU亲和性
 
auto sys_sched_setaffinity (int pid, size_t cpusetsize, const uint64_t *mask) -> int
 设置线程的CPU亲和性
 

Function Documentation

◆ sys_clone()

auto sys_clone ( uint64_t  flags,
void *  stack,
int *  parent_tid,
int *  child_tid,
void *  tls 
) -> int

创建新线程(或进程)

Parameters
flags克隆标志(CLONE_VM、CLONE_THREAD、CLONE_SIGHAND 等)
stack新线程的栈指针(用户空间)
parent_tid父线程TID存储地址(可选)
child_tid子线程TID存储地址(可选)
tls线程本地存储指针
Returns
成功返回新线程TID,失败返回负数
Note
使用场景:
  • pthread_create 底层实现
  • fork() 实现(不带 CLONE_VM)
  • 创建轻量级线程

    flags 常用组合:

    • CLONE_VM | CLONE_THREAD | CLONE_SIGHAND: 创建共享地址空间的线程
    • 0: 创建独立进程(类似 fork)

Definition at line 95 of file syscall.cpp.

96 {
97 auto& task_manager = TaskManagerSingleton::instance();
98 auto current = task_manager.GetCurrentTask();
99
100 if (!current || !current->trap_context_ptr) {
101 klog::Err("[Syscall] sys_clone: Invalid current task or trap context");
102 return -1;
103 }
104
105 // 调用 TaskManager 的 Clone 方法
106 auto result = task_manager.Clone(flags, stack, parent_tid, child_tid, tls,
107 *current->trap_context_ptr);
108
109 if (!result.has_value()) {
110 // 失败返回 -1
111 klog::Err("[Syscall] sys_clone failed: {}", result.error().message());
112 return -1;
113 }
114
115 Pid child_pid = result.value();
116 if (child_pid == 0) {
117 // 子进程/线程返回 0
118 return 0;
119 } else {
120 // 父进程返回子进程 PID
121 return static_cast<int>(child_pid);
122 }
123}
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
size_t Pid
进程 ID 类型
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_exit()

auto sys_exit ( int  code) -> int

退出当前进程或线程

Parameters
code退出码
Returns
不返回
Note
使用场景:
  • 进程正常/异常终止
  • 线程退出(clone 创建的线程调用时只退出当前线程)

    行为取决于线程创建方式:

    • 普通进程:退出整个进程
    • CLONE_THREAD 线程:仅退出当前线程

Definition at line 75 of file syscall.cpp.

75 {
76 klog::Info("[Syscall] Process {} exited with code {}",
77 TaskManagerSingleton::instance().GetCurrentTask()->pid, code);
78 // 调用 TaskManager 的 Exit 方法处理线程退出
79 TaskManagerSingleton::instance().Exit(code);
80 // 不会执行到这里,因为 Exit 会触发调度切换
81 klog::Err("[Syscall] sys_exit should not return!");
82 return 0;
83}
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_fork()

auto sys_fork ( ) -> int

创建新进程(fork)

Returns
父进程返回子进程 PID,子进程返回 0,失败返回 -1
Note
使用场景:
  • 进程创建
  • 完全复制父进程的地址空间和资源

    fork 创建的子进程:

    • 拥有独立的地址空间(页表被复制)
    • 拥有独立的进程 ID (PID)
    • 继承父进程的文件描述符、信号处理器等
    • 父子进程独立运行,互不影响

Definition at line 125 of file syscall.cpp.

125 {
126 auto& task_manager = TaskManagerSingleton::instance();
127 auto current = task_manager.GetCurrentTask();
128
129 if (!current || !current->trap_context_ptr) {
130 klog::Err("[Syscall] sys_fork: Invalid current task or trap context");
131 return -1;
132 }
133
134 // fork = clone with flags=0 (完全复制,不共享任何资源)
135 auto result = task_manager.Clone(0, nullptr, nullptr, nullptr, nullptr,
136 *current->trap_context_ptr);
137
138 if (!result.has_value()) {
139 // 失败返回 -1
140 klog::Err("[Syscall] sys_fork failed: {}", result.error().message());
141 return -1;
142 }
143
144 Pid child_pid = result.value();
145 if (child_pid == 0) {
146 // 子进程返回 0
147 return 0;
148 } else {
149 // 父进程返回子进程 PID
150 return static_cast<int>(child_pid);
151 }
152}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_futex()

auto sys_futex ( int *  uaddr,
int  op,
int  val,
const void *  timeout,
int *  uaddr2,
int  val3 
) -> int

快速用户空间互斥锁操作(futex)

Parameters
uaddr用户空间的futex地址
op操作类型(FUTEX_WAIT、FUTEX_WAKE 等)
val操作参数
timeout超时时间(可选)
uaddr2第二个futex地址(部分操作使用)
val3第三个参数(部分操作使用)
Returns
依操作类型而定,失败返回负数
Note
使用场景:
  • 实现互斥锁(mutex)
  • 实现条件变量(condition variable)
  • 实现读写锁(rwlock)
  • 实现信号量(semaphore)
  • 实现 pthread_join(等待线程退出)
  • 实现 pthread_detach(线程状态管理)

    常用操作:

    • FUTEX_WAIT: 等待futex值变化
    • FUTEX_WAKE: 唤醒等待的线程
    • FUTEX_REQUEUE: 重新排队等待的线程
Todo:
应该返回实际唤醒的线程数
Todo:
实现 FUTEX_REQUEUE

Definition at line 178 of file syscall.cpp.

181 {
182 // Futex 常量定义
183 static constexpr int kFutexWait = 0;
184 static constexpr int kFutexWake = 1;
185 static constexpr int kFutexRequeue = 3;
186
187 // 提取操作类型(低位)
188 int cmd = op & 0x7F;
189
190 auto& task_manager = TaskManagerSingleton::instance();
191
192 switch (cmd) {
193 case kFutexWait: {
194 klog::Debug("[Syscall] FUTEX_WAIT on {:#x} (val={})",
195 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(uaddr)),
196 val);
197
199 reinterpret_cast<uintptr_t>(uaddr));
200 {
201 LockGuard<SpinLock> guard(futex_lock_);
202 if (*uaddr != val) {
203 return 0;
204 }
205 }
206 // futex_lock_ released before Block() — SpinLock must NOT be held
207 // across context switch boundaries (Block → Schedule → switch_to).
208 // A narrow race exists: FUTEX_WAKE between lock release and Block()
209 // can miss this thread. Production kernels solve this with a two-phase
210 // API (add-to-waitqueue under lock, schedule after release). This is
211 // still far safer than the original completely-unprotected check.
212 task_manager.Block(futex_id);
213 return 0;
214 }
215
216 case kFutexWake: {
217 klog::Debug("[Syscall] FUTEX_WAKE on {:#x} (count={})",
218 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(uaddr)),
219 val);
220
222 reinterpret_cast<uintptr_t>(uaddr));
223 {
224 LockGuard<SpinLock> guard(futex_lock_);
225 task_manager.Wakeup(futex_id);
226 }
227
229 return val;
230 }
231
232 case kFutexRequeue: {
233 // 将等待 uaddr 的线程重新排队到 uaddr2
235 klog::Warn("[Syscall] FUTEX_REQUEUE not implemented");
236 return -1;
237 }
238
239 default:
240 klog::Err("[Syscall] Unknown futex operation: {}", cmd);
241 return -1;
242 }
243}
RAII 风格的锁守卫模板类
Definition spinlock.hpp:131
资源 ID
auto Debug(etl::format_string< Args... > fmt, Args &&... args) -> void
以 DEBUG 级别记录日志(SIMPLEKERNEL_MIN_LOG_LEVEL > 0 时编译期消除)
auto Warn(etl::format_string< Args... > fmt, Args &&... args) -> void
以 WARN 级别记录日志
@ kFutex
Futex (快速用户空间互斥锁)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_gettid()

auto sys_gettid ( ) -> int

获取当前线程ID

Returns
当前线程的TID
Note
使用场景:
  • 线程标识
  • 调试信息输出
  • 线程本地数据索引

Definition at line 154 of file syscall.cpp.

154 {
155 auto current = TaskManagerSingleton::instance().GetCurrentTask();
156 if (!current) {
157 klog::Err("[Syscall] sys_gettid: No current task");
158 return -1;
159 }
160 return static_cast<int>(current->pid);
161}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_sched_getaffinity()

auto sys_sched_getaffinity ( int  pid,
size_t  cpusetsize,
uint64_t *  mask 
) -> int

获取线程的CPU亲和性

Parameters
pid线程ID(0 表示当前线程)
cpusetsizeCPU集合大小
maskCPU亲和性掩码
Returns
成功返回 0,失败返回负数

Definition at line 245 of file syscall.cpp.

246 {
247 auto& task_manager = TaskManagerSingleton::instance();
248
249 TaskControlBlock* target;
250 if (pid == 0) {
251 // pid=0 表示当前线程
252 target = task_manager.GetCurrentTask();
253 } else {
254 // 查找指定 PID 的任务
255 target = task_manager.FindTask(static_cast<Pid>(pid));
256 if (!target) {
257 klog::Err("[Syscall] sys_sched_getaffinity: Task {} not found", pid);
258 return -1;
259 }
260 }
261
262 if (!target) {
263 return -1;
264 }
265
266 // 简单实现:将 cpu_affinity 复制到用户空间
267 if (cpusetsize < sizeof(uint64_t)) {
268 return -1;
269 }
270
271 *mask = target->aux->cpu_affinity;
272 return 0;
273}
CpuAffinity cpu_affinity
CPU 亲和性位掩码
任务控制块,管理进程/线程的核心数据结构
TaskAuxData * aux
非调度热路径的辅助数据
Here is the call graph for this function:

◆ sys_sched_setaffinity()

auto sys_sched_setaffinity ( int  pid,
size_t  cpusetsize,
const uint64_t *  mask 
) -> int

设置线程的CPU亲和性

Parameters
pid线程ID(0 表示当前线程)
cpusetsizeCPU集合大小
maskCPU亲和性掩码
Returns
成功返回 0,失败返回负数
Note
使用场景:
  • CPU绑定优化
  • 实时任务调度
  • NUMA优化
Todo:
如果当前任务不在允许的 CPU 上运行,应该触发迁移

Definition at line 275 of file syscall.cpp.

276 {
277 auto& task_manager = TaskManagerSingleton::instance();
278
279 TaskControlBlock* target;
280 if (pid == 0) {
281 target = task_manager.GetCurrentTask();
282 } else {
283 // 查找指定 PID 的任务
284 target = task_manager.FindTask(static_cast<Pid>(pid));
285 if (!target) {
286 klog::Err("[Syscall] sys_sched_setaffinity: Task {} not found", pid);
287 return -1;
288 }
289 }
290
291 if (!target) {
292 return -1;
293 }
294
295 // 简单实现:更新 cpu_affinity
296 if (cpusetsize < sizeof(uint64_t)) {
297 return -1;
298 }
299
300 target->aux->cpu_affinity = *mask;
301
302 klog::Debug("[Syscall] Set CPU affinity for task {} to {:#x}", target->pid,
303 *mask);
304
306
307 return 0;
308}
Pid pid
线程 ID (Task ID)
Here is the call graph for this function:

◆ sys_set_tid_address()

auto sys_set_tid_address ( int *  tidptr) -> int

设置线程ID地址(用于线程退出时的清理)

Parameters
tidptr线程ID存储地址
Returns
成功返回0,失败返回负数
Note
使用场景:
  • 线程库内部使用
  • 实现线程退出时的通知机制
Todo:
需要在 TaskControlBlock 中添加字段保存 tidptr

Definition at line 163 of file syscall.cpp.

163 {
164 auto current = TaskManagerSingleton::instance().GetCurrentTask();
165 if (!current) {
166 klog::Err("[Syscall] sys_set_tid_address: No current task");
167 return -1;
168 }
169
170 // 保存 tidptr,在线程退出时会清零该地址并执行 futex wake
172 // current->clear_child_tid = tidptr;
173
174 // 返回当前线程的 TID
175 return static_cast<int>(current->pid);
176}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_sleep()

auto sys_sleep ( uint64_t  ms) -> int

休眠指定毫秒数

Parameters
ms休眠时长(毫秒)
Returns
0 表示成功
Note
使用场景:定时任务、延迟执行

Definition at line 90 of file syscall.cpp.

90 {
91 TaskManagerSingleton::instance().Sleep(ms);
92 return 0;
93}
Here is the caller graph for this function:

◆ sys_write()

auto sys_write ( int  fd,
const char *  buf,
size_t  len 
) -> int

向文件描述符写入数据

Parameters
fd文件描述符
buf数据缓冲区
len数据长度
Returns
成功写入的字节数,失败返回负数
Note
使用场景:标准输出、日志输出等
Todo:
应该检查 buf 是否在用户空间合法范围内

Definition at line 63 of file syscall.cpp.

63 {
64 // 简单实现:仅支持向标准输出(1)和错误输出(2)打印
65 if (fd == 1 || fd == 2) {
67 for (size_t i = 0; i < len; ++i) {
68 etl_putchar(buf[i]);
69 }
70 return static_cast<int>(len);
71 }
72 return -1;
73}
auto etl_putchar(int c) -> void
早期控制台字符输出
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys_yield()

auto sys_yield ( ) -> int

主动放弃CPU,让出时间片

Returns
0 表示成功
Note
使用场景:协作式调度、忙等待优化

Definition at line 85 of file syscall.cpp.

85 {
86 TaskManagerSingleton::instance().Schedule();
87 return 0;
88}
Here is the caller graph for this function:

◆ syscall_dispatcher()

auto syscall_dispatcher ( int64_t  syscall_id,
uint64_t  args[6] 
) -> int

Definition at line 17 of file syscall.cpp.

17 {
18 int64_t ret = 0;
19 switch (syscall_id) {
20 case kSyscallWrite:
21 ret = sys_write(static_cast<int>(args[0]),
22 reinterpret_cast<const char*>(args[1]),
23 static_cast<size_t>(args[2]));
24 break;
25 case kSyscallExit:
26 ret = sys_exit(static_cast<int>(args[0]));
27 break;
28 case kSyscallYield:
29 ret = sys_yield();
30 break;
31 case kSyscallClone:
32 ret = sys_clone(args[0], reinterpret_cast<void*>(args[1]),
33 reinterpret_cast<int*>(args[2]),
34 reinterpret_cast<int*>(args[3]),
35 reinterpret_cast<void*>(args[4]));
36 break;
37 case kSyscallFork:
38 ret = sys_fork();
39 break;
40 case kSyscallGettid:
41 ret = sys_gettid();
42 break;
43 case kSyscallSetTidAddress:
44 ret = sys_set_tid_address(reinterpret_cast<int*>(args[0]));
45 break;
46 case kSyscallFutex:
47 ret = sys_futex(
48 reinterpret_cast<int*>(args[0]), static_cast<int>(args[1]),
49 static_cast<int>(args[2]), reinterpret_cast<const void*>(args[3]),
50 reinterpret_cast<int*>(args[4]), static_cast<int>(args[5]));
51 break;
52 case kSyscallSleep:
53 ret = sys_sleep(args[0]);
54 break;
55 default:
56 klog::Err("[Syscall] Unknown syscall id: {}", syscall_id);
57 ret = -1;
58 break;
59 }
60 return ret;
61}
auto sys_sleep(uint64_t ms) -> int
休眠指定毫秒数
Definition syscall.cpp:90
auto sys_set_tid_address(int *tidptr) -> int
设置线程ID地址(用于线程退出时的清理)
Definition syscall.cpp:163
auto sys_exit(int code) -> int
退出当前进程或线程
Definition syscall.cpp:75
auto sys_futex(int *uaddr, int op, int val, const void *timeout, int *uaddr2, int val3) -> int
快速用户空间互斥锁操作(futex)
Definition syscall.cpp:178
auto sys_gettid() -> int
获取当前线程ID
Definition syscall.cpp:154
auto sys_fork() -> int
创建新进程(fork)
Definition syscall.cpp:125
auto sys_yield() -> int
主动放弃CPU,让出时间片
Definition syscall.cpp:85
auto sys_write(int fd, const char *buf, size_t len) -> int
向文件描述符写入数据
Definition syscall.cpp:63
auto sys_clone(uint64_t flags, void *stack, int *parent_tid, int *child_tid, void *tls) -> int
创建新线程(或进程)
Definition syscall.cpp:95
Here is the call graph for this function:
Here is the caller graph for this function: