glibc 2.21 Linux
转发到nanosleep
系统调用。
glibc 是大多数 Linux 桌面发行版上 C 标准库的默认实现。
如何找到它:第一反应是:
git ls-files | grep sleep
这包含:
sysdeps/unix/sysv/linux/sleep.c
我们知道:
sysdeps/unix/sysv/linux/
包含 Linux 细节。
在该文件的顶部,我们看到:
/* We are going to use the `nanosleep' syscall of the kernel. But the
kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN
behaviour for this syscall. Therefore we have to emulate it here. */
unsigned int
__sleep (unsigned int seconds)
因此,如果您相信评论,我们基本上就完成了。
在底部:
weak_alias (__sleep, sleep)
这基本上说__sleep
== sleep
。该函数nanosleep
通过:
result = __nanosleep (&ts, &ts);
greppingg之后:
git grep nanosleep | grep -v abilist
我们得到了一小部分有趣的事件,我认为__nanosleep
定义在:
sysdeps/unix/sysv/linux/syscalls.list
在线上:
nanosleep - nanosleep Ci:pp __nanosleep nanosleep
这是一些由以下内容解析的超级 DRY 魔术格式:
sysdeps/unix/make-syscalls.sh
然后从构建目录:
grep -r __nanosleep
引导我们:/sysd-syscalls
这是make-syscalls.sh
生成和包含的内容:
#### CALL=nanosleep NUMBER=35 ARGS=i:pp SOURCE=-
ifeq (,$(filter nanosleep,$(unix-syscalls)))
unix-syscalls += nanosleep
$(foreach p,$(sysd-rules-targets),$(foreach o,$(object-suffixes),$(objpfx)$(patsubst %,$p,nanosleep)$o)): \
$(..)sysdeps/unix/make-syscalls.sh
$(make-target-directory)
(echo '#define SYSCALL_NAME nanosleep'; \
echo '#define SYSCALL_NARGS 2'; \
echo '#define SYSCALL_SYMBOL __nanosleep'; \
echo '#define SYSCALL_CANCELLABLE 1'; \
echo '#include <syscall-template.S>'; \
echo 'weak_alias (__nanosleep, nanosleep)'; \
echo 'libc_hidden_weak (nanosleep)'; \
) | $(compile-syscall) $(foreach p,$(patsubst %nanosleep,%,$(basename $(@F))),$($(p)CPPFLAGS))
endif
它看起来像是 Makefile 的一部分。git grep sysd-syscalls
表明它包含在:
sysdeps/unix/Makefile:23:-include $(common-objpfx)sysd-syscalls
compile-syscall
看起来像关键部分,所以我们发现:
# This is the end of the pipeline for compiling the syscall stubs.
# The stdin is assembler with cpp using sysdep.h macros.
compile-syscall = $(COMPILE.S) -o $@ -x assembler-with-cpp - \
$(compile-mkdep-flags)
请注意,这-x assembler-with-cpp
是一个gcc
选项。
这#define
s 参数如:
#define SYSCALL_NAME nanosleep
然后在以下位置使用它们:
#include <syscall-template.S>
好的,这就是我现在要进行的宏扩展游戏。
我认为这会生成posix/nanosleep.o
必须与所有内容链接在一起的文件。
Linux 4.2 x86_64 nanosleep 系统调用
使用调度程序:这不是一个忙碌的睡眠。
搜索标签:
sys_nanosleep
引导我们kernel/time/hrtimer.c
:
SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
hrtimer
代表高分辨率计时器。从那里主线看起来像:
hrtimer_nanosleep
do_nanosleep
set_current_state(TASK_INTERRUPTIBLE);
这是可中断的睡眠
freezable_schedule();
它调用schedule()
并允许其他进程运行
hrtimer_start_expires
hrtimer_start_range_ns
- TODO:达到
arch/x86
时序级别
- TODO:上述步骤是直接在系统调用中断处理程序中完成的,还是在常规内核线程中完成的?
关于它的几篇文章: