alpha: Consolidate NPTL/non versions of vfork

This commit is contained in:
Richard Henderson 2014-05-21 20:31:38 -07:00
parent 279b24e2e5
commit e2fa4bc2bb
5 changed files with 70 additions and 59 deletions

View File

@ -1,5 +1,13 @@
2014-05-23 Richard Henderson <rth@twiddle.net>
* sysdeps/unix/sysv/linux/alpha/syscalls.list: Remove vfork.
* sysdeps/unix/sysv/linux/alpha/nptl/vfork.S: Move file ...
* sysdeps/unix/sysv/linux/alpha/vfork.S: ... here. Restore PID
before exiting on error.
(__libc_vfork): New strong alias.
* sysdeps/unix/sysv/linux/alpha/nptl/pt-vfork.S: Remove file.
* sysdeps/unix/sysv/linux/alpha/pt-vfork.S: New file.
* sysdeps/unix/sysv/linux/alpha/clone.S: Deconditionalize the code
that was previously under [RESET_PID].
* sysdeps/unix/sysv/linux/alpha/nptl/clone.S: File removed.

View File

@ -1,42 +0,0 @@
/* Copyright (C) 2003-2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */
#include <sysdep.h>
#include <tcb-offsets.h>
#undef PSEUDO_PREPARE_ARGS
#define PSEUDO_PREPARE_ARGS \
/* Load the current cached pid value across the vfork. */ \
rduniq; \
ldl a2, PID_OFFSET(v0); \
mov v0, a1; \
/* Write back its negation, to indicate that the pid value is \
uninitialized in the child, and in the window between \
here and the point at which we restore the value. */ \
negl a2, t0; \
stl t0, PID_OFFSET(v0);
PSEUDO (__vfork, vfork, 0)
/* If we're back in the parent, restore the saved pid. */
beq v0, 1f
stl a2, PID_OFFSET(a1)
1: ret
PSEUDO_END (__vfork)
weak_alias (__vfork, vfork)

View File

@ -0,0 +1,34 @@
/* vfork ABI-compatibility entry points for libpthread.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
#include <shlib-compat.h>
/* libpthread used to have its own vfork implementation that differed
from libc's only in having a pointless micro-optimization. There
is no longer any use to having a separate copy in libpthread, but
the historical ABI requires it. For static linking, there is no
need to provide anything here--the libc version will be linked in.
For shared library ABI compatibility, there must be __vfork and
vfork symbols in libpthread.so. */
#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \
|| SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20))
#include <vfork.S>
#endif

View File

@ -14,7 +14,6 @@ semget - semget i:iii __semget semget
oldsemctl EXTRA semctl i:iiii __old_semctl semctl@GLIBC_2.0
sigstack - sigstack 2 sigstack
vfork - vfork 0 __vfork vfork
getpriority - getpriority i:ii __getpriority getpriority

View File

@ -18,28 +18,40 @@
#include <sysdep.h>
#include <tcb-offsets.h>
#undef PSEUDO_PREPARE_ARGS
#define PSEUDO_PREPARE_ARGS \
/* Load the current cached pid value across the vfork. */ \
rduniq; \
ldl a2, PID_OFFSET(v0); \
mov v0, a1; \
/* If the cached value is initialized (nonzero), then write \
back its negation, or INT_MIN, to indicate that the pid \
value is uninitialized in the child, and in the window \
between here and the point at which we restore the value. */ \
ldah t0, -0x8000; \
negl a2, t1; \
cmovne a2, t1, t0; \
ENTRY(__vfork)
PSEUDO_PROLOGUE
/* Load the thread pointer value in A1 across the vfork. */
rduniq
mov v0, a1
/* Save the TCB-cached PID away in A2, and then negate the TCB
field. But if it's zero, set it to 0x80000000 instead. See
raise.c for the logic that relies on this value. */
ldl a2, PID_OFFSET(v0)
ldah t0, -0x8000
negl a2, t1
cmovne a2, t1, t0
stl t0, PID_OFFSET(v0);
PSEUDO (__vfork, vfork, 0)
lda v0, SYS_ify(vfork)
call_pal PAL_callsys
/* If we're back in the parent, restore the saved pid. */
/* Restore the original value of the TCB cache of the PID, if we're
the parent. But in the child (syscall return value equals zero),
leave things as they are. */
beq v0, 1f
stl a2, PID_OFFSET(a1)
1: ret
1:
/* Normal error check and return. */
bne a3, SYSCALL_ERROR_LABEL
ret
PSEUDO_END (__vfork)
libc_hidden_def (__vfork)
weak_alias (__vfork, vfork)
#if !NOT_IN_libc
strong_alias (__vfork, __libc_vfork)
#endif