mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
Update.
2002-12-13 Ulrich Drepper <drepper@redhat.com> * misc/syslog.c (log_cleanup): Don't use parameter in __libc_lock_unlock call, use syslog_lock directly. Adjust callers to pass NULL instead of a pointer to syslog_lock.
This commit is contained in:
@ -1,3 +1,9 @@
|
|||||||
|
2002-12-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* misc/syslog.c (log_cleanup): Don't use parameter in
|
||||||
|
__libc_lock_unlock call, use syslog_lock directly. Adjust callers to
|
||||||
|
pass NULL instead of a pointer to syslog_lock.
|
||||||
|
|
||||||
2002-12-12 Ulrich Drepper <drepper@redhat.com>
|
2002-12-12 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* iconvdata/Makefile: iconv-rules: Add definition to use gconv.map
|
* iconvdata/Makefile: iconv-rules: Add definition to use gconv.map
|
||||||
|
@ -333,7 +333,7 @@ openlog_internal(const char *ident, int logstat, int logfac)
|
|||||||
static void
|
static void
|
||||||
log_cleanup (void *arg)
|
log_cleanup (void *arg)
|
||||||
{
|
{
|
||||||
__libc_lock_unlock (*(__libc_lock_t *) arg);
|
__libc_lock_unlock (syslog_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -341,7 +341,7 @@ openlog (const char *ident, int logstat, int logfac)
|
|||||||
{
|
{
|
||||||
#ifdef _LIBC_REENTRANT
|
#ifdef _LIBC_REENTRANT
|
||||||
/* Protect against multiple users. */
|
/* Protect against multiple users. */
|
||||||
__libc_cleanup_region_start (1, log_cleanup, &syslog_lock);
|
__libc_cleanup_region_start (1, log_cleanup, NULL);
|
||||||
__libc_lock_lock (syslog_lock);
|
__libc_lock_lock (syslog_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ closelog ()
|
|||||||
{
|
{
|
||||||
#ifdef _LIBC_REENTRANT
|
#ifdef _LIBC_REENTRANT
|
||||||
/* Protect against multiple users. */
|
/* Protect against multiple users. */
|
||||||
__libc_cleanup_region_start (1, log_cleanup, &syslog_lock);
|
__libc_cleanup_region_start (1, log_cleanup, NULL);
|
||||||
__libc_lock_lock (syslog_lock);
|
__libc_lock_lock (syslog_lock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,3 +1,38 @@
|
|||||||
|
2002-12-13 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* Makefile (routines): Add libc-cancellation.
|
||||||
|
* libc-cancellation.c: New file.
|
||||||
|
* descr.h (struct pthread): Add multiple_threads field.
|
||||||
|
* allocatestack.c (allocate_stack): Initialize multiple_header field of
|
||||||
|
new thread descriptor to 1.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/createthread.c (create_thread):
|
||||||
|
Initialize multiple_thread field after successful thread creation.
|
||||||
|
* cancellation.c (__do_cancel): Move to pthreadP.h.
|
||||||
|
(__pthread_enable_asynccancel): Remove parameter from __do_cancel call.
|
||||||
|
(__pthread_disable_asynccancel): Add internal_function attribute.
|
||||||
|
* init.c (sigcancel_handler): Remove parameter from __do_cancel call.
|
||||||
|
* pthread_setcancelstate.c: Likewise.
|
||||||
|
* pthread_setcanceltype.c: Likewise.
|
||||||
|
* pthread_exit.c: Likewise.
|
||||||
|
* pthreadP.h (CANCELLATION_P): Likewise.
|
||||||
|
(__do_cancel): Define as static inline.
|
||||||
|
(LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): New #defines.
|
||||||
|
(__libc_enable_asynccancel, __libc_disable_asynccancel): New
|
||||||
|
declarations.
|
||||||
|
* sysdeps/i386/tls.h (tcbhead_t): Add list and multiple_threads
|
||||||
|
fields. Define MULTIPLE_THREADS_OFFSET.
|
||||||
|
* sysdeps/pthread/bits/libc-lock.h: Remove __libc_locking_needed
|
||||||
|
declaration.
|
||||||
|
* sysdeps/unix/sysv/linux/accept.S: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/read.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/write.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/pt-socket.S: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/libc_pthread_init.c: Remove definition and
|
||||||
|
initialization of __libc_locking_needed.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/lowlevellock.h: Don't use
|
||||||
|
__libc_locking_needed, use multiple_threads field in TCB.
|
||||||
|
* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Likewise.
|
||||||
|
|
||||||
2002-12-12 Ulrich Drepper <drepper@redhat.com>
|
2002-12-12 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486
|
* sysdeps/unix/sysv/linux/i386/i686/libc-lowlevellock.S: Use i486
|
||||||
|
@ -28,7 +28,7 @@ headers := pthread.h semaphore.h
|
|||||||
extra-libs := libpthread
|
extra-libs := libpthread
|
||||||
extra-libs-others := $(extra-libs)
|
extra-libs-others := $(extra-libs)
|
||||||
|
|
||||||
routines = alloca_cutoff forward libc-lowlevellock
|
routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
|
||||||
shared-only-routines = forward
|
shared-only-routines = forward
|
||||||
|
|
||||||
libpthread-routines = init events \
|
libpthread-routines = init events \
|
||||||
|
@ -272,6 +272,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
|||||||
/* This is a user-provided stack. */
|
/* This is a user-provided stack. */
|
||||||
pd->user_stack = true;
|
pd->user_stack = true;
|
||||||
|
|
||||||
|
/* There is at least one more thread. */
|
||||||
|
pd->header.data.multiple_threads = 1;
|
||||||
|
|
||||||
/* Allocate the DTV for this thread. */
|
/* Allocate the DTV for this thread. */
|
||||||
if (_dl_allocate_tls (pd) == NULL)
|
if (_dl_allocate_tls (pd) == NULL)
|
||||||
/* Something went wrong. */
|
/* Something went wrong. */
|
||||||
@ -337,6 +340,9 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp,
|
|||||||
/* Initialize the lock. */
|
/* Initialize the lock. */
|
||||||
pd->lock = LLL_LOCK_INITIALIZER;
|
pd->lock = LLL_LOCK_INITIALIZER;
|
||||||
|
|
||||||
|
/* There is at least one more thread. */
|
||||||
|
pd->header.data.multiple_threads = 1;
|
||||||
|
|
||||||
/* Allocate the DTV for this thread. */
|
/* Allocate the DTV for this thread. */
|
||||||
if (_dl_allocate_tls (pd) == NULL)
|
if (_dl_allocate_tls (pd) == NULL)
|
||||||
{
|
{
|
||||||
|
@ -23,35 +23,6 @@
|
|||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
|
|
||||||
|
|
||||||
/* This function is responsible for calling all registered cleanup
|
|
||||||
handlers and then terminate the thread. This includes dellocating
|
|
||||||
the thread-specific data. The implementation is complicated by the
|
|
||||||
fact that we have to handle to cancellation handler registration
|
|
||||||
methods: exceptions using try/finally and setjmp.
|
|
||||||
|
|
||||||
The setjmp method is always available. The user might compile some
|
|
||||||
code which uses this method because no modern compiler is
|
|
||||||
available. So we have to handle these first since we cannot call
|
|
||||||
the cleanup handlers if the stack frames are gone. At the same
|
|
||||||
time this opens a hole for the register exception handler blocks
|
|
||||||
since now they might be in danger of using an overwritten stack
|
|
||||||
frame. The advise is to only use new or only old style cancellation
|
|
||||||
handling. */
|
|
||||||
void
|
|
||||||
__do_cancel (char *currentframe)
|
|
||||||
{
|
|
||||||
struct pthread *self = THREAD_SELF;
|
|
||||||
|
|
||||||
/* Throw an exception. */
|
|
||||||
// XXX TBI
|
|
||||||
|
|
||||||
/* If throwing an exception didn't work try the longjmp. */
|
|
||||||
__libc_longjmp (self->cancelbuf, 1);
|
|
||||||
|
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* The next two functions are similar to pthread_setcanceltype() but
|
/* The next two functions are similar to pthread_setcanceltype() but
|
||||||
more specialized for the use in the cancelable functions like write().
|
more specialized for the use in the cancelable functions like write().
|
||||||
They do not need to check parameters etc. */
|
They do not need to check parameters etc. */
|
||||||
@ -76,7 +47,7 @@ __pthread_enable_asynccancel (void)
|
|||||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||||
{
|
{
|
||||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
__do_cancel (CURRENT_STACK_FRAME);
|
__do_cancel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -88,7 +59,7 @@ __pthread_enable_asynccancel (void)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
attribute_hidden
|
internal_function attribute_hidden
|
||||||
__pthread_disable_asynccancel (int oldtype)
|
__pthread_disable_asynccancel (int oldtype)
|
||||||
{
|
{
|
||||||
/* If asynchronous cancellation was enabled before we do not have
|
/* If asynchronous cancellation was enabled before we do not have
|
||||||
|
@ -58,6 +58,8 @@ struct pthread
|
|||||||
/* XXX Remove this union for IA-64 style TLS module */
|
/* XXX Remove this union for IA-64 style TLS module */
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
/* It is very important to always append new elements. The offsets
|
||||||
|
of some of the elements of the struct are used in assembler code. */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
void *tcb; /* Pointer to the TCB. This is not always
|
void *tcb; /* Pointer to the TCB. This is not always
|
||||||
@ -65,6 +67,7 @@ struct pthread
|
|||||||
union dtv *dtvp;
|
union dtv *dtvp;
|
||||||
struct pthread *self; /* Pointer to this structure */
|
struct pthread *self; /* Pointer to this structure */
|
||||||
list_t list;
|
list_t list;
|
||||||
|
int multiple_threads;
|
||||||
} data;
|
} data;
|
||||||
void *__padding[16];
|
void *__padding[16];
|
||||||
} header;
|
} header;
|
||||||
|
@ -84,7 +84,7 @@ sigcancel_handler (int sig __attribute ((unused)))
|
|||||||
|
|
||||||
/* Run the registered destructors and terminate the
|
/* Run the registered destructors and terminate the
|
||||||
thread. */
|
thread. */
|
||||||
__do_cancel (CURRENT_STACK_FRAME);
|
__do_cancel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -74,7 +74,7 @@ extern int __pthread_debug attribute_hidden;
|
|||||||
if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
|
if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
|
||||||
{ \
|
{ \
|
||||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
|
THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
|
||||||
__do_cancel (CURRENT_STACK_FRAME); \
|
__do_cancel (); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
@ -85,9 +85,41 @@ extern int __pthread_debug attribute_hidden;
|
|||||||
#define CANCEL_RESET(oldtype) \
|
#define CANCEL_RESET(oldtype) \
|
||||||
__pthread_disable_asynccancel (oldtype)
|
__pthread_disable_asynccancel (oldtype)
|
||||||
|
|
||||||
/* Function performing the cancellation. */
|
/* Same as CANCEL_ASYNC, but for use in libc.so. */
|
||||||
extern void __do_cancel (char *currentframe)
|
#define LIBC_CANCEL_ASYNC() \
|
||||||
__attribute ((visibility ("hidden"), noreturn, regparm (1)));
|
__libc_enable_asynccancel ()
|
||||||
|
/* Same as CANCEL_RESET, but for use in libc.so. */
|
||||||
|
#define LIBC_CANCEL_RESET(oldtype) \
|
||||||
|
__libc_disable_asynccancel (oldtype)
|
||||||
|
|
||||||
|
|
||||||
|
/* This function is responsible for calling all registered cleanup
|
||||||
|
handlers and then terminate the thread. This includes dellocating
|
||||||
|
the thread-specific data. The implementation is complicated by the
|
||||||
|
fact that we have to handle to cancellation handler registration
|
||||||
|
methods: exceptions using try/finally and setjmp.
|
||||||
|
|
||||||
|
The setjmp method is always available. The user might compile some
|
||||||
|
code which uses this method because no modern compiler is
|
||||||
|
available. So we have to handle these first since we cannot call
|
||||||
|
the cleanup handlers if the stack frames are gone. At the same
|
||||||
|
time this opens a hole for the register exception handler blocks
|
||||||
|
since now they might be in danger of using an overwritten stack
|
||||||
|
frame. The advise is to only use new or only old style cancellation
|
||||||
|
handling. */
|
||||||
|
static inline void
|
||||||
|
__do_cancel (void)
|
||||||
|
{
|
||||||
|
struct pthread *self = THREAD_SELF;
|
||||||
|
|
||||||
|
/* Throw an exception. */
|
||||||
|
// XXX TBI
|
||||||
|
|
||||||
|
/* If throwing an exception didn't work try the longjmp. */
|
||||||
|
__libc_longjmp (self->cancelbuf, 1);
|
||||||
|
|
||||||
|
/* NOTREACHED */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Test whether stackframe is still active. */
|
/* Test whether stackframe is still active. */
|
||||||
@ -186,7 +218,13 @@ extern int __pthread_atfork (void (*prepare) (void), void (*parent) (void),
|
|||||||
extern int __pthread_kill (pthread_t threadid, int signo);
|
extern int __pthread_kill (pthread_t threadid, int signo);
|
||||||
extern int __pthread_setcanceltype (int type, int *oldtype);
|
extern int __pthread_setcanceltype (int type, int *oldtype);
|
||||||
extern int __pthread_enable_asynccancel (void) attribute_hidden;
|
extern int __pthread_enable_asynccancel (void) attribute_hidden;
|
||||||
extern void __pthread_disable_asynccancel (int oldtype) attribute_hidden;
|
extern void __pthread_disable_asynccancel (int oldtype)
|
||||||
|
internal_function attribute_hidden;
|
||||||
|
|
||||||
|
/* The two functions are in libc.so and not exported. */
|
||||||
|
extern int __libc_enable_asynccancel (void) attribute_hidden;
|
||||||
|
extern void __libc_disable_asynccancel (int oldtype)
|
||||||
|
internal_function attribute_hidden;
|
||||||
|
|
||||||
#ifdef IS_IN_libpthread
|
#ifdef IS_IN_libpthread
|
||||||
/* Special versions which use non-exported functions. */
|
/* Special versions which use non-exported functions. */
|
||||||
|
@ -27,5 +27,5 @@ pthread_exit (value)
|
|||||||
{
|
{
|
||||||
THREAD_SETMEM (THREAD_SELF, result, value);
|
THREAD_SETMEM (THREAD_SELF, result, value);
|
||||||
|
|
||||||
__do_cancel (CURRENT_STACK_FRAME);
|
__do_cancel ();
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ pthread_setcancelstate (state, oldstate)
|
|||||||
oldval) == 0)
|
oldval) == 0)
|
||||||
{
|
{
|
||||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||||
__do_cancel (CURRENT_STACK_FRAME);
|
__do_cancel ();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ __pthread_setcanceltype (type, oldtype)
|
|||||||
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
|
||||||
{
|
{
|
||||||
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
THREAD_SETMEM (self, result, PTHREAD_CANCELED);
|
||||||
__do_cancel (CURRENT_STACK_FRAME);
|
__do_cancel ();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
|
# include <list.h>
|
||||||
|
|
||||||
|
|
||||||
/* Type for the dtv. */
|
/* Type for the dtv. */
|
||||||
@ -40,6 +41,8 @@ typedef struct
|
|||||||
thread descriptor used by libpthread. */
|
thread descriptor used by libpthread. */
|
||||||
dtv_t *dtv;
|
dtv_t *dtv;
|
||||||
void *self; /* Pointer to the thread descriptor. */
|
void *self; /* Pointer to the thread descriptor. */
|
||||||
|
list_t list;
|
||||||
|
int multiple_threads;
|
||||||
} tcbhead_t;
|
} tcbhead_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -52,10 +55,13 @@ typedef struct
|
|||||||
/* Signal that TLS support is available. */
|
/* Signal that TLS support is available. */
|
||||||
#define USE_TLS 1
|
#define USE_TLS 1
|
||||||
|
|
||||||
/* Alignment requirement for the stack. For IA-32 this is govern by
|
/* Alignment requirement for the stack. For IA-32 this is governed by
|
||||||
the SSE memory functions. */
|
the SSE memory functions. */
|
||||||
#define STACK_ALIGN 16
|
#define STACK_ALIGN 16
|
||||||
|
|
||||||
|
/* Offset of the MULTIPLE_THREADS element in tcbhead_t. */
|
||||||
|
#define MULTIPLE_THREADS_OFFSET 20
|
||||||
|
|
||||||
|
|
||||||
#ifndef __ASSEMBLER__
|
#ifndef __ASSEMBLER__
|
||||||
/* Get system call information. */
|
/* Get system call information. */
|
||||||
|
@ -25,12 +25,6 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined _LIBC && !defined NOT_IN_libc
|
|
||||||
/* Nonzero if locking is needed. */
|
|
||||||
extern int __libc_locking_needed attribute_hidden;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* 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
|
||||||
|
4
nptl/sysdeps/unix/sysv/linux/accept.S
Normal file
4
nptl/sysdeps/unix/sysv/linux/accept.S
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#define socket accept
|
||||||
|
#define __socket __libc_accept
|
||||||
|
#define NARGS 3
|
||||||
|
#include <pt-socket.S>
|
@ -82,6 +82,9 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
|
|||||||
/* Failed. */
|
/* Failed. */
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
|
/* We now have for sure more than one thread. */
|
||||||
|
pd->header.data.multiple_threads = 1;
|
||||||
|
|
||||||
/* Now fill in the information about the new thread in
|
/* Now fill in the information about the new thread in
|
||||||
the newly created thread's data structure. We cannot let
|
the newly created thread's data structure. We cannot let
|
||||||
the new thread do this since we don't know whether it was
|
the new thread do this since we don't know whether it was
|
||||||
@ -142,5 +145,8 @@ create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
|
|||||||
/* Failed. */
|
/* Failed. */
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
|
/* We now have for sure more than one thread. */
|
||||||
|
pd->header.data.multiple_threads = 1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
02111-1307 USA. */
|
02111-1307 USA. */
|
||||||
|
|
||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
#include <tls.h>
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
@ -48,13 +49,7 @@ __lll_lock_wait:
|
|||||||
|
|
||||||
orl $-1, %eax /* Load -1. */
|
orl $-1, %eax /* Load -1. */
|
||||||
#ifndef UP
|
#ifndef UP
|
||||||
# ifdef PIC
|
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
|
||||||
call __i686.get_pc_thunk.dx
|
|
||||||
addl $_GLOBAL_OFFSET_TABLE_, %edx
|
|
||||||
cmpl $0, __libc_locking_needed@GOTOFF(%edx)
|
|
||||||
# else
|
|
||||||
cmpl $0, __libc_locking_needed
|
|
||||||
# endif
|
|
||||||
je,pt 0f
|
je,pt 0f
|
||||||
lock
|
lock
|
||||||
0:
|
0:
|
||||||
@ -83,13 +78,7 @@ lll_unlock_wake_cb:
|
|||||||
|
|
||||||
movl 20(%esp), %ebx
|
movl 20(%esp), %ebx
|
||||||
#ifndef UP
|
#ifndef UP
|
||||||
# ifdef PIC
|
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
|
||||||
call __i686.get_pc_thunk.dx
|
|
||||||
addl $_GLOBAL_OFFSET_TABLE_, %edx
|
|
||||||
cmpl $0, __libc_locking_needed@GOTOFF(%edx)
|
|
||||||
# else
|
|
||||||
cmpl $0, __libc_locking_needed
|
|
||||||
# endif
|
|
||||||
je,pt 0f
|
je,pt 0f
|
||||||
lock
|
lock
|
||||||
0:
|
0:
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define _LOWLEVELLOCK_H 1
|
#define _LOWLEVELLOCK_H 1
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <sys/param.h>
|
||||||
#include <bits/pthreadtypes.h>
|
#include <bits/pthreadtypes.h>
|
||||||
|
|
||||||
#ifndef LOCK_INSTR
|
#ifndef LOCK_INSTR
|
||||||
@ -182,26 +183,27 @@ extern int lll_unlock_wake_cb (int *__futex) attribute_hidden;
|
|||||||
the lock prefix when the thread library is not used.
|
the lock prefix when the thread library is not used.
|
||||||
|
|
||||||
XXX In future we might even want to avoid it on UP machines. */
|
XXX In future we might even want to avoid it on UP machines. */
|
||||||
|
# include <tls.h>
|
||||||
|
|
||||||
/* Nonzero if locking is needed. */
|
/* Nonzero if locking is needed. */
|
||||||
extern int __libc_locking_needed attribute_hidden;
|
extern int __libc_locking_needed attribute_hidden;
|
||||||
|
|
||||||
# define lll_trylock(futex) \
|
# define lll_trylock(futex) \
|
||||||
({ unsigned char ret; \
|
({ unsigned char ret; \
|
||||||
__asm __volatile ("cmpl $0, %5\n\t" \
|
__asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
|
||||||
"je,pt 0f\n\t" \
|
"je,pt 0f\n\t" \
|
||||||
"lock\n" \
|
"lock\n" \
|
||||||
"0:\tcmpxchgl %2, %1; setne %0" \
|
"0:\tcmpxchgl %2, %1; setne %0" \
|
||||||
: "=a" (ret), "=m" (futex) \
|
: "=a" (ret), "=m" (futex) \
|
||||||
: "r" (0), "1" (futex), "0" (1), \
|
: "r" (0), "1" (futex), "0" (1), \
|
||||||
"m" (__libc_locking_needed) \
|
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||||
: "memory"); \
|
: "memory"); \
|
||||||
ret; })
|
ret; })
|
||||||
|
|
||||||
|
|
||||||
# define lll_lock(futex) \
|
# define lll_lock(futex) \
|
||||||
(void) ({ int ignore1, ignore2; \
|
(void) ({ int ignore1, ignore2; \
|
||||||
__asm __volatile ("cmpl $0, %5\n\t" \
|
__asm __volatile ("cmpl $0, %%gs:%P5\n\t" \
|
||||||
"je,pt 0f\n\t" \
|
"je,pt 0f\n\t" \
|
||||||
"lock\n" \
|
"lock\n" \
|
||||||
"0:\txaddl %0, %2\n\t" \
|
"0:\txaddl %0, %2\n\t" \
|
||||||
@ -214,13 +216,13 @@ extern int __libc_locking_needed attribute_hidden;
|
|||||||
"2:" \
|
"2:" \
|
||||||
: "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
|
: "=a" (ignore1), "=&c" (ignore2), "=m" (futex) \
|
||||||
: "0" (-1), "2" (futex), \
|
: "0" (-1), "2" (futex), \
|
||||||
"m" (__libc_locking_needed) \
|
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||||
: "memory"); })
|
: "memory"); })
|
||||||
|
|
||||||
|
|
||||||
# define lll_unlock(futex) \
|
# define lll_unlock(futex) \
|
||||||
(void) ({ int ignore; \
|
(void) ({ int ignore; \
|
||||||
__asm __volatile ("cmpl $0, %3\n\t" \
|
__asm __volatile ("cmpl $0, %%gs:%P3\n\t" \
|
||||||
"je,pt 0f\n\t" \
|
"je,pt 0f\n\t" \
|
||||||
"lock\n" \
|
"lock\n" \
|
||||||
"0:\tincl %0\n\t" \
|
"0:\tincl %0\n\t" \
|
||||||
@ -232,7 +234,8 @@ extern int __libc_locking_needed attribute_hidden;
|
|||||||
".previous\n" \
|
".previous\n" \
|
||||||
"2:" \
|
"2:" \
|
||||||
: "=m" (futex), "=&a" (ignore) \
|
: "=m" (futex), "=&a" (ignore) \
|
||||||
: "0" (futex), "m" (__libc_locking_needed) \
|
: "0" (futex), \
|
||||||
|
"i" (offsetof (tcbhead_t, multiple_threads)) \
|
||||||
: "memory"); })
|
: "memory"); })
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
80
nptl/sysdeps/unix/sysv/linux/i386/pt-socket.S
Normal file
80
nptl/sysdeps/unix/sysv/linux/i386/pt-socket.S
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* Copyright (C) 1995, 1996, 1997, 1998, 2002 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, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <socketcall.h>
|
||||||
|
|
||||||
|
#define P(a, b) P2(a, b)
|
||||||
|
#define P2(a, b) a##b
|
||||||
|
|
||||||
|
.text
|
||||||
|
/* The socket-oriented system calls are handled unusally in Linux.
|
||||||
|
They are all gated through the single `socketcall' system call number.
|
||||||
|
`socketcall' takes two arguments: the first is the subcode, specifying
|
||||||
|
which socket function is being called; and the second is a pointer to
|
||||||
|
the arguments to the specific function.
|
||||||
|
|
||||||
|
The .S files for the other calls just #define socket and #include this. */
|
||||||
|
|
||||||
|
#ifndef __socket
|
||||||
|
# error "__socket and socket must be defined"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
.globl __socket
|
||||||
|
ENTRY (__socket)
|
||||||
|
/* We need one more register. */
|
||||||
|
pushl %esi
|
||||||
|
|
||||||
|
/* Enable asynchronous cancellation. */
|
||||||
|
call __libc_enable_asynccancel /* No @plt */
|
||||||
|
movl %eax, %esi
|
||||||
|
|
||||||
|
/* Save registers. */
|
||||||
|
movl %ebx, %edx
|
||||||
|
|
||||||
|
movl $SYS_ify(socketcall), %eax /* System call number in %eax. */
|
||||||
|
|
||||||
|
/* Use ## so `socket' is a separate token that might be #define'd. */
|
||||||
|
movl $P(SOCKOP_,socket), %ebx /* Subcode is first arg to syscall. */
|
||||||
|
lea 8(%esp), %ecx /* Address of args is 2nd arg. */
|
||||||
|
|
||||||
|
/* Do the system call trap. */
|
||||||
|
int $0x80
|
||||||
|
|
||||||
|
/* Restore the cancellation. */
|
||||||
|
xchgl %esi, %eax
|
||||||
|
call __libc_disable_asynccancel /* No @plt */
|
||||||
|
|
||||||
|
/* Restore registers. */
|
||||||
|
movl %esi, %eax
|
||||||
|
movl %edx, %ebx
|
||||||
|
popl %esi
|
||||||
|
|
||||||
|
/* %eax is < 0 if there was an error. */
|
||||||
|
cmpl $-125, %eax
|
||||||
|
jae SYSCALL_ERROR_LABEL
|
||||||
|
|
||||||
|
/* Successful; return the syscall's value. */
|
||||||
|
L(pseudo_end):
|
||||||
|
ret
|
||||||
|
|
||||||
|
PSEUDO_END (__socket)
|
||||||
|
|
||||||
|
#ifndef NO_WEAK_ALIAS
|
||||||
|
weak_alias (__socket, socket)
|
||||||
|
#endif
|
@ -24,9 +24,6 @@
|
|||||||
|
|
||||||
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
|
||||||
__libc_pthread_init (ptr, reclaim)
|
__libc_pthread_init (ptr, reclaim)
|
||||||
@ -41,7 +38,4 @@ __libc_pthread_init (ptr, reclaim)
|
|||||||
|
|
||||||
/* The fork handler needed by libpthread. */
|
/* 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;
|
|
||||||
}
|
}
|
||||||
|
50
nptl/sysdeps/unix/sysv/linux/read.c
Normal file
50
nptl/sysdeps/unix/sysv/linux/read.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* 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 <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <nptl/pthreadP.h>
|
||||||
|
#include <tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
__libc_read (int fd, void *buf, size_t count)
|
||||||
|
{
|
||||||
|
#ifndef NOT_IN_libc
|
||||||
|
if (__builtin_expect (THREAD_GETMEM (THREAD_SELF,
|
||||||
|
header.data.multiple_threads) == 0, 1))
|
||||||
|
return INLINE_SYSCALL (read, 3, fd, buf, count);
|
||||||
|
|
||||||
|
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ssize_t result = INLINE_SYSCALL (read, 3, fd, buf, count);
|
||||||
|
|
||||||
|
#ifndef NOT_IN_libc
|
||||||
|
LIBC_CANCEL_RESET (oldtype);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
libc_hidden_def (__libc_read)
|
||||||
|
strong_alias (__libc_read, __read)
|
||||||
|
libc_hidden_weak (__read)
|
||||||
|
weak_alias (__libc_read, read)
|
50
nptl/sysdeps/unix/sysv/linux/write.c
Normal file
50
nptl/sysdeps/unix/sysv/linux/write.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/* 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 <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <nptl/pthreadP.h>
|
||||||
|
#include <tls.h>
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
__libc_write (int fd, const void *buf, size_t count)
|
||||||
|
{
|
||||||
|
#ifndef NOT_IN_libc
|
||||||
|
if (__builtin_expect (THREAD_GETMEM (THREAD_SELF,
|
||||||
|
header.data.multiple_threads) == 0, 1))
|
||||||
|
return INLINE_SYSCALL (write, 3, fd, buf, count);
|
||||||
|
|
||||||
|
int oldtype = LIBC_CANCEL_ASYNC ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ssize_t result = INLINE_SYSCALL (write, 3, fd, buf, count);
|
||||||
|
|
||||||
|
#ifndef NOT_IN_libc
|
||||||
|
LIBC_CANCEL_RESET (oldtype);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
libc_hidden_def (__libc_write)
|
||||||
|
strong_alias (__libc_write, __write)
|
||||||
|
libc_hidden_weak (__write)
|
||||||
|
weak_alias (__libc_write, write)
|
Reference in New Issue
Block a user