mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-25 06:20:06 +00:00
Update.
2002-12-12 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/sysv/linux/fork-gen.c: Renamed to... * sysdeps/unix/sysv/linux/libc_pthread_init.c: ...this. Initialize __libc_locking_needed. * init.c (__pthread_initialize_minimal): Call __libc_pthread_init instead of __register_pthread_fork_handler. * sysdeps/pthread/bits/libc-lock.h: Declare __libc_locking_needed. * sysdeps/unix/sysv/linux/Makefile (sysdep_routimes): Replace fork-gen with libc_pthread_init. * sysdeps/unix/sysv/linux/Versions: Use __libc_pthread_init instead of __register_pthread_fork_handler. * sysdeps/unix/sysv/linux/fork.h: Declare __libc_pthread_init instead of __register_pthread_fork_handler. * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Use __libc_locking_needed to determine whether lock prefix can be avoided. * sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
This commit is contained in:
parent
688e7bfe2b
commit
14e7aeceff
@ -1,3 +1,21 @@
|
||||
2002-12-12 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* sysdeps/unix/sysv/linux/fork-gen.c: Renamed to...
|
||||
* sysdeps/unix/sysv/linux/libc_pthread_init.c: ...this.
|
||||
Initialize __libc_locking_needed.
|
||||
* init.c (__pthread_initialize_minimal): Call __libc_pthread_init
|
||||
instead of __register_pthread_fork_handler.
|
||||
* sysdeps/pthread/bits/libc-lock.h: Declare __libc_locking_needed.
|
||||
* sysdeps/unix/sysv/linux/Makefile (sysdep_routimes): Replace
|
||||
fork-gen with libc_pthread_init.
|
||||
* sysdeps/unix/sysv/linux/Versions: Use __libc_pthread_init instead
|
||||
of __register_pthread_fork_handler.
|
||||
* sysdeps/unix/sysv/linux/fork.h: Declare __libc_pthread_init instead
|
||||
of __register_pthread_fork_handler.
|
||||
* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Use
|
||||
__libc_locking_needed to determine whether lock prefix can be avoided.
|
||||
* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
|
||||
|
||||
2002-12-11 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* Makefile (tests): Add tst-cleanup1.
|
||||
|
@ -167,5 +167,5 @@ __pthread_initialize_minimal (void)
|
||||
__static_tls_size = roundup (__static_tls_size, __static_tls_align);
|
||||
|
||||
/* Register the fork generation counter with the libc. */
|
||||
__register_pthread_fork_handler (&__fork_generation, __reclaim_stacks);
|
||||
__libc_pthread_init (&__fork_generation, __reclaim_stacks);
|
||||
}
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
/* Nonzero if locking is needed. */
|
||||
extern int __libc_locking_needed attribute_hidden;
|
||||
|
||||
|
||||
/* Fortunately Linux now has a mean to do locking which is realtime
|
||||
safe without the aid of the thread library. We also need no fancy
|
||||
options like error checking mutexes etc. We only need simple
|
||||
|
@ -18,7 +18,7 @@
|
||||
# 02111-1307 USA. */
|
||||
|
||||
ifeq ($(subdir),nptl)
|
||||
sysdep_routines += register-atfork unregister-atfork fork-gen
|
||||
sysdep_routines += register-atfork unregister-atfork libc_pthread_init
|
||||
|
||||
libpthread-sysdep_routines += pt-fork
|
||||
endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
libc {
|
||||
GLIBC_PRIVATE {
|
||||
__register_atfork; __register_pthread_fork_handler;
|
||||
__register_atfork; __libc_pthread_init;
|
||||
__libc_current_sigrtmin_private; __libc_current_sigrtmax_private;
|
||||
__libc_allocate_rtsig_private;
|
||||
}
|
||||
|
@ -56,5 +56,5 @@ extern int __register_atfork (void (*__prepare) (void),
|
||||
void *dso_handle);
|
||||
|
||||
/* Register the generation counter in the libpthread with the libc. */
|
||||
extern void __register_pthread_fork_handler (unsigned long int *__ptr,
|
||||
void (*reclaim) (void));
|
||||
extern void __libc_pthread_int (unsigned long int *__ptr,
|
||||
void (*reclaim) (void));
|
||||
|
@ -1 +1,184 @@
|
||||
#include "lowlevellock.S"
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||
|
||||
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, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA. */
|
||||
|
||||
#include <sysdep.h>
|
||||
|
||||
.text
|
||||
|
||||
#define SYS_gettimeofday __NR_gettimeofday
|
||||
#define SYS_futex 240
|
||||
#define FUTEX_WAIT 0
|
||||
#define FUTEX_WAKE 1
|
||||
|
||||
#define ETIMEDOUT 110
|
||||
|
||||
|
||||
.globl __lll_lock_wait
|
||||
.type __lll_lock_wait,@function
|
||||
.hidden __lll_lock_wait
|
||||
.align 16
|
||||
__lll_lock_wait:
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
|
||||
movl %ecx, %ebx
|
||||
xorl %esi, %esi /* No timeout. */
|
||||
xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
|
||||
1:
|
||||
leal -1(%eax), %edx /* account for the preceeded xadd. */
|
||||
movl $SYS_futex, %eax
|
||||
int $0x80
|
||||
|
||||
orl $-1, %eax /* Load -1. */
|
||||
#ifndef UP
|
||||
cmpl $0, __libc_locking_needed
|
||||
je,pt 0f
|
||||
lock
|
||||
0:
|
||||
#endif
|
||||
xaddl %eax, (%ebx)
|
||||
jne 1b
|
||||
|
||||
movl $-1, (%ebx)
|
||||
|
||||
popl %edx
|
||||
popl %ebx
|
||||
popl %esi
|
||||
ret
|
||||
.size __lll_lock_wait,.-__lll_lock_wait
|
||||
|
||||
|
||||
.globl lll_unlock_wake_cb
|
||||
.type lll_unlock_wake_cb,@function
|
||||
.hidden lll_unlock_wake_cb
|
||||
.align 16
|
||||
lll_unlock_wake_cb:
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
movl 20(%esp), %ebx
|
||||
#ifndef UP
|
||||
cmpl $0, __libc_locking_needed
|
||||
je,pt 0f
|
||||
lock
|
||||
0:
|
||||
#endif
|
||||
incl (%ebx)
|
||||
jng 1f
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %esi
|
||||
ret
|
||||
.size lll_unlock_wake_cb,.-lll_unlock_wake_cb
|
||||
|
||||
|
||||
.globl __lll_unlock_wake
|
||||
.type __lll_unlock_wake,@function
|
||||
.hidden __lll_unlock_wake
|
||||
__lll_unlock_wake:
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
movl %eax, %ebx
|
||||
1: movl $FUTEX_WAKE, %ecx
|
||||
movl $1, %edx /* Wake one thread. */
|
||||
xorl %esi, %esi
|
||||
movl %edx, (%ebx) /* Stores '$1'. */
|
||||
movl $SYS_futex, %eax
|
||||
int $0x80
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %esi
|
||||
ret
|
||||
.size __lll_unlock_wake,.-__lll_unlock_wake
|
||||
|
||||
|
||||
.globl __lll_timedwait_tid
|
||||
.type __lll_timedwait_tid,@function
|
||||
.hidden __lll_timedwait_tid
|
||||
__lll_timedwait_tid:
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
pushl %ebx
|
||||
pushl %ebp
|
||||
|
||||
movl %eax, %ebp
|
||||
movl %edx, %edi
|
||||
subl $8, %esp
|
||||
|
||||
/* Get current time. */
|
||||
2: movl %esp, %ebx
|
||||
xorl %ecx, %ecx
|
||||
movl $SYS_gettimeofday, %eax
|
||||
int $0x80
|
||||
|
||||
/* Compute relative timeout. */
|
||||
movl 4(%esp), %eax
|
||||
movl $1000, %edx
|
||||
mul %edx /* Milli seconds to nano seconds. */
|
||||
movl (%edi), %ecx
|
||||
movl 4(%edi), %edx
|
||||
subl (%esp), %ecx
|
||||
subl %eax, %edx
|
||||
jns 5f
|
||||
addl $1000000000, %edx
|
||||
decl %ecx
|
||||
5: testl %ecx, %ecx
|
||||
js 6f /* Time is already up. */
|
||||
|
||||
movl %ecx, (%esp) /* Store relative timeout. */
|
||||
movl %edx, 4(%esp)
|
||||
|
||||
movl (%ebp), %edx
|
||||
testl %edx, %edx
|
||||
jz 4f
|
||||
|
||||
movl %esp, %esi
|
||||
xorl %ecx, %ecx /* movl $FUTEX_WAIT, %ecx */
|
||||
movl %ebp, %ebx
|
||||
movl $SYS_futex, %eax
|
||||
int $0x80
|
||||
|
||||
movl %eax, %edx
|
||||
|
||||
cmpl $0, (%ebx)
|
||||
jne 1f
|
||||
4: xorl %eax, %eax
|
||||
|
||||
3: addl $8, %esp
|
||||
popl %ebp
|
||||
popl %ebx
|
||||
popl %esi
|
||||
popl %edi
|
||||
ret
|
||||
|
||||
1: cmpl $-ETIMEDOUT, %edx
|
||||
jne 2b
|
||||
6: movl $ETIMEDOUT, %eax
|
||||
jmp 3b
|
||||
.size __lll_timedwait_tid,.-__lll_timedwait_tid
|
||||
|
@ -139,7 +139,8 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
||||
<0 - taken by more users */
|
||||
|
||||
|
||||
#define lll_trylock(futex) \
|
||||
#if defined NOT_IN_libc || defined UP
|
||||
# define lll_trylock(futex) \
|
||||
({ unsigned char ret; \
|
||||
__asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0" \
|
||||
: "=a" (ret), "=m" (futex) \
|
||||
@ -148,7 +149,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
||||
ret; })
|
||||
|
||||
|
||||
#define lll_lock(futex) \
|
||||
# define lll_lock(futex) \
|
||||
(void) ({ int ignore1, ignore2; \
|
||||
__asm __volatile (LOCK_INSTR "xaddl %0, %2\n\t" \
|
||||
"jne 1f\n\t" \
|
||||
@ -163,7 +164,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
||||
: "memory"); })
|
||||
|
||||
|
||||
#define lll_unlock(futex) \
|
||||
# define lll_unlock(futex) \
|
||||
(void) ({ int ignore; \
|
||||
__asm __volatile (LOCK_INSTR "incl %0\n\t" \
|
||||
"jng 1f\n\t" \
|
||||
@ -176,6 +177,59 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
||||
: "=m" (futex), "=&a" (ignore) \
|
||||
: "0" (futex) \
|
||||
: "memory"); })
|
||||
#else
|
||||
/* Special versions of the macros for use in libc itself. They avoid
|
||||
the lock prefix when the thread library is not used.
|
||||
|
||||
XXX In future we might even want to avoid it on UP machines. */
|
||||
|
||||
# define lll_trylock(futex) \
|
||||
({ unsigned char ret; \
|
||||
__asm __volatile ("cmpl $0, __libc_locking_needed\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\tcmpxchgl %2, %1; setne %0" \
|
||||
: "=a" (ret), "=m" (futex) \
|
||||
: "r" (0), "1" (futex), "0" (1) \
|
||||
: "memory"); \
|
||||
ret; })
|
||||
|
||||
|
||||
# define lll_lock(futex) \
|
||||
(void) ({ int ignore1, ignore2; \
|
||||
__asm __volatile ("cmpl $0, __libc_locking_needed\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\txaddl %0, %2\n\t" \
|
||||
"jne 1f\n\t" \
|
||||
".subsection 1\n" \
|
||||
"1:\tleal %2, %%ecx\n\t" \
|
||||
"call __lll_lock_wait\n\t" \
|
||||
"jmp 2f\n\t" \
|
||||
".previous\n" \
|
||||
"2:" \
|
||||
: "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
|
||||
: "0" (-1), "2" (futex) \
|
||||
: "memory"); })
|
||||
|
||||
|
||||
# define lll_unlock(futex) \
|
||||
(void) ({ int ignore; \
|
||||
__asm __volatile ("cmpl $0, __libc_locking_needed\n\t" \
|
||||
"je,pt 0f\n\t" \
|
||||
"lock\n" \
|
||||
"0:\tincl %0\n\t" \
|
||||
"jng 1f\n\t" \
|
||||
".subsection 1\n" \
|
||||
"1:\tleal %0, %%eax\n\t" \
|
||||
"call __lll_unlock_wake\n\t" \
|
||||
"jmp 2f\n\t" \
|
||||
".previous\n" \
|
||||
"2:" \
|
||||
: "=m" (futex), "=&a" (ignore) \
|
||||
: "0" (futex) \
|
||||
: "memory"); })
|
||||
#endif
|
||||
|
||||
|
||||
#define lll_islocked(futex) \
|
||||
|
@ -19,19 +19,29 @@
|
||||
|
||||
#include <list.h>
|
||||
#include "fork.h"
|
||||
#include <bits/libc-lock.h>
|
||||
|
||||
|
||||
static struct fork_handler pthread_child_handler;
|
||||
|
||||
/* Global variable signalled when locking is needed. */
|
||||
int __libc_locking_needed;
|
||||
|
||||
|
||||
void
|
||||
__register_pthread_fork_handler (ptr, reclaim)
|
||||
__libc_pthread_init (ptr, reclaim)
|
||||
unsigned long int *ptr;
|
||||
void (*reclaim) (void);
|
||||
{
|
||||
/* Remember the pointer to the generation counter in libpthread. */
|
||||
__fork_generation_pointer = ptr;
|
||||
|
||||
/* Called by a child after fork. */
|
||||
pthread_child_handler.handler = reclaim;
|
||||
|
||||
/* The fork handler needed by libpthread. */
|
||||
list_add_tail (&pthread_child_handler.list, &__fork_child_list);
|
||||
|
||||
/* Signal the internal locking code that locking is needed now. */
|
||||
__libc_locking_needed = 1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user