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:
Ulrich Drepper 2002-12-12 10:28:11 +00:00
parent 688e7bfe2b
commit 14e7aeceff
9 changed files with 279 additions and 10 deletions

View file

@ -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.

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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));

View file

@ -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

View file

@ -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) \

View file

@ -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;
}