glibc 2.21 Linux
remite a la llamada nanosleep
sistema.
glibc es la implementación predeterminada para C stdlib en la mayoría de las distribuciones de escritorio de Linux.
¿Cómo encontrarlo: el primer reflejo es:
git ls-files | grep sleep
Este contiene:
sysdeps/unix/sysv/linux/sleep.c
y sabemos que:
sysdeps/unix/sysv/linux/
contiene los detalles de Linux.
En la parte superior de ese archivo que vemos:
/* 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)
Así que si confía en los comentarios, que se realizan básicamente.
En la parte inferior:
weak_alias (__sleep, sleep)
que básicamente dice __sleep
== sleep
.La función utiliza nanosleep
través de:
result = __nanosleep (&ts, &ts);
Después greppingg:
git grep nanosleep | grep -v abilist
tenemos una pequeña lista de sucesos interesantes, y creo __nanosleep
se define en:
sysdeps/unix/sysv/linux/syscalls.list
en la línea :
nanosleep - nanosleep Ci:pp __nanosleep nanosleep
la que se algún formato magia Super Dry analizado por:
sysdeps/unix/make-syscalls.sh
Luego, desde el directorio de construcción:
grep -r __nanosleep
nos lleva a: /sysd-syscalls
que es lo que make-syscalls.sh
genera y contiene:
#### 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
Parece parte de un Makefile. git grep sysd-syscalls
muestra que está incluido en:
sysdeps/unix/Makefile:23:-include $(common-objpfx)sysd-syscalls
compile-syscall
se parece a la parte clave, por lo que nos encontramos:
# 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 [email protected] -x assembler-with-cpp - \
$(compile-mkdep-flags)
Tenga en cuenta que -x assembler-with-cpp
es una opción gcc
.
Este #define
s parámetros como:
#define SYSCALL_NAME nanosleep
y luego usarlos en:
#include <syscall-template.S>
OK, esto es por lo que voy a entrar en el juego de expansión de la macro por ahora.
Creo que esto genera el archivo posix/nanosleep.o
que debe estar vinculado junto con todo.
Linux 4.2 x86_64 nanosleep syscall
Utiliza el planificador: no es un sueño ocupado.
ctags búsqueda:
sys_nanosleep
nos lleva a kernel/time/hrtimer.c
:
SYSCALL_DEFINE2(nanosleep, struct timespec __user *, rqtp,
hrtimer
alta la resolución del temporizador.A partir de ahí la línea principal se parece a:
hrtimer_nanosleep
do_nanosleep
set_current_state(TASK_INTERRUPTIBLE);
que es el sueño interrumpible
freezable_schedule();
que exige schedule()
y permite que otros procesos que se ejecuten
hrtimer_start_expires
hrtimer_start_range_ns
- TODO: alcanzar el nivel
arch/x86
tiempo
Unos artículos al respecto:
IIRC, 10 ms es un intervalo de tiempo típico para los procesos de Linux. Linux puede adelantarse a los procesos en el medio de su segmento de tiempo de 10 ms para lograr una precisión del temporizador mucho mejor que esa. (Antes de que Linux implementara el derecho preferente de compra, algunas personas compilaban su núcleo con 'HZ = 1000' en lugar de' HZ = 100', para obtener jips de 1ms. Véase, por ejemplo, http://serverfault.com/questions/377947/1000- hz-linux-kernel-necessary-if-i-have-tickless-and-high-resolution-timer. Las CPU multi-core han hecho que esto sea mucho menos importante, también, ya que el bloqueo necesario para SMP hace que el respaldo preventivo sea mucho más económico . Y a menudo hay un núcleo libre –
, esta es una buena respuesta, pero el lector también debe entender que solo porque está en la fila para dormir, no está obligado por el tiempo que pidió. Por ejemplo, si se ha suscrito a una señal y la señal se recibe mientras está en la cola de espera, el proceso puede recuperar el tiempo de CPU más rápido. Los eventos de espera de E/S (seleccione ...) tienen un efecto similar. Consulte EINTR errno, que puede devolver la suspensión de Linux. – Eric