mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03: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:
@ -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>
|
2002-12-11 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* Makefile (tests): Add tst-cleanup1.
|
* Makefile (tests): Add tst-cleanup1.
|
||||||
|
@ -167,5 +167,5 @@ __pthread_initialize_minimal (void)
|
|||||||
__static_tls_size = roundup (__static_tls_size, __static_tls_align);
|
__static_tls_size = roundup (__static_tls_size, __static_tls_align);
|
||||||
|
|
||||||
/* Register the fork generation counter with the libc. */
|
/* 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>
|
#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
|
/* 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
|
safe without the aid of the thread library. We also need no fancy
|
||||||
options like error checking mutexes etc. We only need simple
|
options like error checking mutexes etc. We only need simple
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
# 02111-1307 USA. */
|
# 02111-1307 USA. */
|
||||||
|
|
||||||
ifeq ($(subdir),nptl)
|
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
|
libpthread-sysdep_routines += pt-fork
|
||||||
endif
|
endif
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
libc {
|
libc {
|
||||||
GLIBC_PRIVATE {
|
GLIBC_PRIVATE {
|
||||||
__register_atfork; __register_pthread_fork_handler;
|
__register_atfork; __libc_pthread_init;
|
||||||
__libc_current_sigrtmin_private; __libc_current_sigrtmax_private;
|
__libc_current_sigrtmin_private; __libc_current_sigrtmax_private;
|
||||||
__libc_allocate_rtsig_private;
|
__libc_allocate_rtsig_private;
|
||||||
}
|
}
|
||||||
|
@ -56,5 +56,5 @@ extern int __register_atfork (void (*__prepare) (void),
|
|||||||
void *dso_handle);
|
void *dso_handle);
|
||||||
|
|
||||||
/* Register the generation counter in the libpthread with the libc. */
|
/* Register the generation counter in the libpthread with the libc. */
|
||||||
extern void __register_pthread_fork_handler (unsigned long int *__ptr,
|
extern void __libc_pthread_int (unsigned long int *__ptr,
|
||||||
void (*reclaim) (void));
|
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,6 +139,7 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
|||||||
<0 - taken by more users */
|
<0 - taken by more users */
|
||||||
|
|
||||||
|
|
||||||
|
#if defined NOT_IN_libc || defined UP
|
||||||
# define lll_trylock(futex) \
|
# define lll_trylock(futex) \
|
||||||
({ unsigned char ret; \
|
({ unsigned char ret; \
|
||||||
__asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0" \
|
__asm __volatile (LOCK_INSTR "cmpxchgl %2, %1; setne %0" \
|
||||||
@ -176,6 +177,59 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
|||||||
: "=m" (futex), "=&a" (ignore) \
|
: "=m" (futex), "=&a" (ignore) \
|
||||||
: "0" (futex) \
|
: "0" (futex) \
|
||||||
: "memory"); })
|
: "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) \
|
#define lll_islocked(futex) \
|
||||||
|
@ -19,19 +19,29 @@
|
|||||||
|
|
||||||
#include <list.h>
|
#include <list.h>
|
||||||
#include "fork.h"
|
#include "fork.h"
|
||||||
|
#include <bits/libc-lock.h>
|
||||||
|
|
||||||
|
|
||||||
static struct fork_handler pthread_child_handler;
|
static struct fork_handler pthread_child_handler;
|
||||||
|
|
||||||
|
/* Global variable signalled when locking is needed. */
|
||||||
|
int __libc_locking_needed;
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
__register_pthread_fork_handler (ptr, reclaim)
|
__libc_pthread_init (ptr, reclaim)
|
||||||
unsigned long int *ptr;
|
unsigned long int *ptr;
|
||||||
void (*reclaim) (void);
|
void (*reclaim) (void);
|
||||||
{
|
{
|
||||||
|
/* Remember the pointer to the generation counter in libpthread. */
|
||||||
__fork_generation_pointer = ptr;
|
__fork_generation_pointer = ptr;
|
||||||
|
|
||||||
|
/* Called by a child after fork. */
|
||||||
pthread_child_handler.handler = reclaim;
|
pthread_child_handler.handler = reclaim;
|
||||||
|
|
||||||
|
/* The fork handler needed by libpthread. */
|
||||||
list_add_tail (&pthread_child_handler.list, &__fork_child_list);
|
list_add_tail (&pthread_child_handler.list, &__fork_child_list);
|
||||||
|
|
||||||
|
/* Signal the internal locking code that locking is needed now. */
|
||||||
|
__libc_locking_needed = 1;
|
||||||
}
|
}
|
Reference in New Issue
Block a user