* sysdeps/unix/sysv/linux/sleep.c (__sleep): Use nanosleep syscall
	directly to avoid cancellation in the regular nanosleep
	implementation.
This commit is contained in:
Ulrich Drepper 2003-06-06 17:34:54 +00:00
parent 3a370de88f
commit c3f90e26a5
4 changed files with 28 additions and 12 deletions

View File

@ -1,5 +1,9 @@
2003-06-06 Ulrich Drepper <drepper@redhat.com> 2003-06-06 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/sleep.c (__sleep): Use nanosleep syscall
directly to avoid cancellation in the regular nanosleep
implementation.
* sysdeps/unix/sysv/linux/i386/sysdep.h (ASMFMT_2): Only allow * sysdeps/unix/sysv/linux/i386/sysdep.h (ASMFMT_2): Only allow
%edx for first parameter. This means no pushl and therefore the %edx for first parameter. This means no pushl and therefore the
unwind info isn't screwed up. unwind info isn't screwed up.

View File

@ -1,3 +1,9 @@
2003-06-06 Ulrich Drepper <drepper@redhat.com>
* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h: New sequences for
5+ arg syscalls only needed for PIC.
Patch by Ralph Siemsen <ralphs@netwinder.org>.
2003-06-05 Richard Henderson <rth@redhat.com> 2003-06-05 Richard Henderson <rth@redhat.com>
* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Use * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Use

View File

@ -26,12 +26,14 @@
/* We push lr onto the stack, so we have to use ldmib instead of ldmia /* We push lr onto the stack, so we have to use ldmib instead of ldmia
to find the saved arguments. */ to find the saved arguments. */
#undef DOARGS_5 # ifdef PIC
#undef DOARGS_6 # undef DOARGS_5
#undef DOARGS_7 # undef DOARGS_6
#define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8]; # undef DOARGS_7
#define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5}; # define DOARGS_5 str r4, [sp, $-4]!; ldr r4, [sp, $8];
#define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6}; # define DOARGS_6 mov ip, sp; stmfd sp!, {r4, r5}; ldmib ip, {r4, r5};
# define DOARGS_7 mov ip, sp; stmfd sp!, {r4, r5, r6}; ldmib ip, {r4, r5, r6};
# endif
# undef PSEUDO_RET # undef PSEUDO_RET
# define PSEUDO_RET \ # define PSEUDO_RET \

View File

@ -1,5 +1,5 @@
/* Implementation of the POSIX sleep function using nanosleep. /* Implementation of the POSIX sleep function using nanosleep.
Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. Copyright (C) 1996, 1997, 1998, 1999, 2003 Free Software Foundation, Inc.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@ -24,8 +24,12 @@
#include <unistd.h> #include <unistd.h>
/* We are going to use the `nanosleep' syscall of the kernel. But the /* We are going to use the `nanosleep' syscall of the kernel. But the
kernel does not implement the sstupid SysV SIGCHLD vs. SIG_IGN kernel does not implement the stupid SysV SIGCHLD vs. SIG_IGN
behaviour for this syscall. Therefore we have to emulate it here. */ behaviour for this syscall. Therefore we have to emulate it here.
Also note that we use the syscall directly instead of using the
__nanosleep function. The reason is that nanosleep() is a cancellation
point while sleep() isn't. */
unsigned int unsigned int
__sleep (unsigned int seconds) __sleep (unsigned int seconds)
{ {
@ -67,7 +71,7 @@ __sleep (unsigned int seconds)
if (oact.sa_handler == SIG_IGN) if (oact.sa_handler == SIG_IGN)
{ {
/* We should leave SIGCHLD blocked. */ /* We should leave SIGCHLD blocked. */
result = __nanosleep (&ts, &ts); result = INLINE_SYSCALL (nanosleep, 2, &ts, &ts);
saved_errno = errno; saved_errno = errno;
/* Restore the original signal mask. */ /* Restore the original signal mask. */
@ -78,11 +82,11 @@ __sleep (unsigned int seconds)
{ {
/* We should unblock SIGCHLD. Restore the original signal mask. */ /* We should unblock SIGCHLD. Restore the original signal mask. */
(void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL); (void) __sigprocmask (SIG_SETMASK, &oset, (sigset_t *) NULL);
result = __nanosleep (&ts, &ts); result = INLINE_SYSCALL (nanosleep, 2, &ts, &ts);
} }
} }
else else
result = __nanosleep (&ts, &ts); result = INLINE_SYSCALL (nanosleep, 2, &ts, &ts);
if (result != 0) if (result != 0)
/* Round remaining time. */ /* Round remaining time. */