* sysdeps/unix/sysv/linux/alpha/syscalls.list (msgrcv, msgsnd):
	Make cancelable.
	* sysdeps/unix/sysv/linux/hppa/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/ia64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/x86_64/syscalls.list (msgrcv, msgsnd):
	Likewise.
	* sysdeps/unix/sysv/linux/ia64/sigsuspend.c (__sigsuspend): Likewise.
This commit is contained in:
Ulrich Drepper 2002-12-18 01:38:17 +00:00
parent f077a4a9f0
commit 82f81a9086
36 changed files with 1381 additions and 541 deletions

View File

@ -1,5 +1,17 @@
2002-12-17 Jakub Jelinek <jakub@redhat.com>
* sysdeps/unix/sysv/linux/alpha/syscalls.list (msgrcv, msgsnd):
Make cancelable.
* sysdeps/unix/sysv/linux/hppa/syscalls.list (msgrcv, msgsnd):
Likewise.
* sysdeps/unix/sysv/linux/ia64/syscalls.list (msgrcv, msgsnd):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/syscalls.list (msgrcv, msgsnd):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/syscalls.list (msgrcv, msgsnd):
Likewise.
* sysdeps/unix/sysv/linux/ia64/sigsuspend.c (__sigsuspend): Likewise.
* malloc/thread-m.h (mutex_init, mutex_lock, mutex_trylock,
mutex_unlock): If not building NPTL, use __libc_maybe_call2 if
available, otherwise __libc_maybe_call.

View File

@ -1,3 +1,122 @@
2002-12-18 Jakub Jelinek <jakub@redhat.com>
* internals.h (__pthread_thread_self): New prototype.
(struct pthread_functions): Add ptr_pthread_thread_self field.
* pthread.c (pthread_functions): Initialize ptr_pthread_thread_self.
(__pthread_thread_self): New function.
* libc-cancellation.c (__pthread_thread_self): Add weak_extern.
(__libc_enable_asynccancel, __libc_disable_asynccancel): Don't
use thread_self() directly if not FLOATING_STACKS.
2002-12-18 Jakub Jelinek <jakub@redhat.com>
* sysdeps/x86_64/pt-machine.h: Guard most of the header
with #ifndef __ASSEMBLER__.
* pthread.c (pthread_functions): Use SHLIB_COMPAT around
pthread_attr_init_2_0 use.
2002-12-17 Jakub Jelinek <jakub@redhat.com>
* wrapsyscall.c: Removed.
* weaks.c: Removed.
* Makefile (distribute): Add tst-cancel-wrappers.sh.
(routines): Remove weaks. Add forward,
libc_pthread_init, libc-cancellation.
(shared-only-routines): Remove weaks. Add forward.
(libpthread-routines): Remove wrapsyscall.
Add ptw-write, ptw-read, ptw-close, ptw-fcntl, ptw-accept,
ptw-connect, ptw-recv, ptw-recvfrom, ptw-recvmsg, ptw-send,
ptw-sendmsg, ptw-sendto, ptw-fsync, ptw-lseek, ptw-lseek64,
ptw-llseek, ptw-msync, ptw-nanosleep, ptw-open, ptw-open64,
ptw-pause, ptw-pread, ptw-pread64, ptw-pwrite, ptw-pwrite64,
ptw-tcdrain, ptw-wait, ptw-waitpid, pt-system, pt-allocrtsig.
(libpthread-shared-only-routines): Add pt-allocrtsig.
(tests): Depend on $(objpfx)tst-cancel-wrappers.out.
($(objpfx)tst-cancel-wrappers.out): New rule.
* sysdeps/pthread/bits/libc-lock.h: Include linuxthreads/internals.h
if in libc.
(__libc_maybe_call): In libpthread.* don't check for existance
of the function.
(__libc_maybe_call2): Define.
(__libc_lock_init, __libc_lock_fini, __libc_lock_lock,
__libc_lock_trylock, __libc_lock_unlock): Use it.
* sysdeps/pthread/flockfile.c: New file.
* sysdeps/pthread/ftrylockfile.c: New file.
* sysdeps/pthread/funlockfile.c: New file.
* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h: New file.
* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h: New file.
* sysdeps/unix/sysv/linux/allocrtsig.c: New file.
* libc-cancellation.c: New file.
* forward.c: New file.
* libc_pthread_init.c: New file.
* pt-system.c: New file.
* pthread.c: Remove locale.h.
(__pthread_manager_thread): Initialize multiple_threads.
(__pthread_multiple_threads): Declare.
(pthread_functions): New variable.
(__pthread_initialize_minimal): Remove __uselocale call.
Call __libc_pthread_init.
(__pthread_initialize_manager): Initialize __pthread_multiple_threads,
initial thread's multiple_threads and __libc_multiple_threads.
Check MULTIPLE_THREADS_OFFSET value. Initialize manager thread's
multiple_threads.
(pthread_setschedparam, pthread_getschedparam): Rename to __
prefixed variants. Add strong_alias.
(current_rtmin, current_rtmax, __libc_current_sigrtmin,
__libc_current_sigrtmax, __libc_allocate_rtsig): Remove.
(init_rtsigs): Use __libc_current_sigrtmin_private.
(pthread_initialize): Only call init_rtsigs if
!__ASSUME_REALTIME_SIGNALS.
(__pthread_require_wrappers, __pthread_require_lockfile): Remove.
* internals.h (__pthread_attr_destroy, __pthread_attr_setdetachstate,
__pthread_attr_getdetachstate, __pthread_attr_setschedparam,
__pthread_attr_getschedparam, __pthread_attr_setschedpolicy,
__pthread_attr_getschedpolicy, __pthread_attr_setinheritsched,
__pthread_attr_getinheritsched, __pthread_attr_setscope,
__pthread_attr_getscope, __pthread_cond_init,
__pthread_cond_destroy, __pthread_cond_wait,
__pthread_cond_signal, __pthread_cond_broadcast,
__pthread_condattr_init, __pthread_condattr_destroy,
__pthread_equal, __pthread_getschedparam,
__pthread_setschedparam, __pthread_setcancelstate,
__pthread_setcanceltype, __pthread_enable_asynccancel,
__libc_enable_asynccancel, __libc_pthread_init): New prototype.
(__pthread_mutex_init, __pthread_mutex_destroy,
__pthread_mutex_lock, __pthread_mutex_unlock,
__pthread_mutex_trylock): Likewise.
Add hidden_proto.
(struct pthread_functions): New type.
(__libc_pthread_functions): New variable.
(LIBC_CANCEL_ASYNC, LIBC_CANCEL_RESET): Define.
* descr.h (struct _pthread_descr_struct): Add
p_header.data.multiple_threads field.
* manager.c (pthread_handle_create): Initialize multiple_threads.
* cancel.c (__pthread_enable_asynccancel,
__pthread_disable_asynccancel): New functions.
(__pthread_provide_wrappers): Remove.
(pthread_setcancelstate, pthread_setcanceltype): Rename to __
prefixed variants. Add strong_alias.
* condvar.c (pthread_cond_init, pthread_cond_destroy,
pthread_cond_wait, pthread_cond_signal, pthread_cond_broadcast,
pthread_condattr_init, pthread_condattr_destroy): Likewise.
* join.c (pthread_exit): Likewise.
* attr.c (pthread_attr_destroy, pthread_attr_setdetachstate,
pthread_attr_getdetachstate, pthread_attr_setschedparam,
pthread_attr_getschedparam, pthread_attr_setschedpolicy,
pthread_attr_getschedpolicy, pthread_attr_setinheritsched,
pthread_attr_getinheritsched, pthread_attr_setscope,
pthread_attr_getscope): Likewise.
* mutex.c (__pthread_mutex_init, __pthread_mutex_destroy,
__pthread_mutex_lock, __pthread_mutex_unlock,
__pthread_mutex_trylock): Add hidden_def.
* Versions (libc): Add __libc_pthread_init,
__libc_current_sigrtmin_private, __libc_current_sigrtmax_private,
__libc_allocate_rtsig_private @@GLIBC_PRIVATE.
* lockfile.c: Remove some USE_IN_LIBIO guards.
(__pthread_provide_lockfile): Remove.
* pt-allocrtsig.c: New file.
* tst-cancel-wrappers.sh: New test.
2002-12-15 Ulrich Drepper <drepper@redhat.com>
* Versions [libpthread: GLIBC_2.3.2]: Remove creat, poll, pselect,

View File

@ -26,20 +26,29 @@ linuxthreads-version := $(shell sed -n 's/^.*$(subdir)-\([0-9.]*\).*$$/\1/p' \
headers := pthread.h semaphore.h
distribute := internals.h queue.h restart.h spinlock.h smp.h tst-signal.sh \
libc-tsd.c
tst-cancel-wrappers.sh libc-tsd.c
routines := weaks no-tsd
shared-only-routines = weaks
routines := forward no-tsd libc-cancellation libc_pthread_init
shared-only-routines = forward
extra-libs := libpthread
extra-libs-others := $(extra-libs)
libpthread-routines := attr cancel condvar join manager mutex ptfork \
ptlongjmp pthread signals specific errno lockfile \
semaphore spinlock wrapsyscall rwlock pt-machine \
semaphore spinlock rwlock pt-machine \
oldsemaphore events getcpuclockid pspinlock barrier \
ptclock_gettime ptclock_settime sighandler \
pthandles libc-tls-loc
pthandles libc-tls-loc pt-allocrtsig \
ptw-write ptw-read ptw-close ptw-fcntl ptw-accept \
ptw-connect ptw-recv ptw-recvfrom ptw-recvmsg \
ptw-send ptw-sendmsg ptw-sendto ptw-fsync ptw-lseek \
ptw-lseek64 ptw-llseek ptw-msync ptw-nanosleep \
ptw-open ptw-open64 ptw-pause ptw-pread ptw-pread64 \
ptw-pwrite ptw-pwrite64 ptw-tcdrain ptw-wait \
ptw-waitpid pt-system
libpthread-shared-only-routines = pt-allocrtsig
nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete
initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst
@ -194,8 +203,13 @@ endif
ifeq (no,$(cross-compiling))
ifeq (yes,$(build-shared))
tests: $(objpfx)tst-signal.out
tests: $(objpfx)tst-signal.out $(objpfx)tst-cancel-wrappers.out
$(objpfx)tst-signal.out: tst-signal.sh $(objpfx)tst-signal
$(SHELL) -e $< $(common-objpfx) > $@
$(objpfx)tst-cancel-wrappers.out: tst-cancel-wrappers.sh
$(SHELL) $< $(common-objpfx)/libc_pic.a \
$(common-objpfx)/libc.a \
$(objpfx)/libpthread_pic.a \
$(objpfx)/libpthread.a > $@
endif
endif

View File

@ -22,6 +22,9 @@ libc {
__libc_internal_tsd_address; __libc_alloca_cutoff;
__libc_dl_error_tsd;
__libc_pthread_init; __libc_current_sigrtmin_private;
__libc_current_sigrtmax_private; __libc_allocate_rtsig_private;
__libc_creat; __libc_poll; __libc_pselect; __libc_select;
__libc_sigpause; __libc_sigsuspend; __libc_sigwait; __libc_sigwaitinfo;
__libc_waitid; __libc___xpg_sigpause;

View File

@ -56,12 +56,13 @@ compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init,
GLIBC_2_0);
#endif
int pthread_attr_destroy(pthread_attr_t *attr)
int __pthread_attr_destroy(pthread_attr_t *attr)
{
return 0;
}
strong_alias (__pthread_attr_destroy, pthread_attr_destroy);
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
int __pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
{
if (detachstate < PTHREAD_CREATE_JOINABLE ||
detachstate > PTHREAD_CREATE_DETACHED)
@ -69,14 +70,16 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
attr->__detachstate = detachstate;
return 0;
}
strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate);
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
int __pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
{
*detachstate = attr->__detachstate;
return 0;
}
strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate);
int pthread_attr_setschedparam(pthread_attr_t *attr,
int __pthread_attr_setschedparam(pthread_attr_t *attr,
const struct sched_param *param)
{
int max_prio = __sched_get_priority_max(attr->__schedpolicy);
@ -87,43 +90,49 @@ int pthread_attr_setschedparam(pthread_attr_t *attr,
memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
return 0;
}
strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam);
int pthread_attr_getschedparam(const pthread_attr_t *attr,
int __pthread_attr_getschedparam(const pthread_attr_t *attr,
struct sched_param *param)
{
memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
return 0;
}
strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam);
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
int __pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
{
if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
return EINVAL;
attr->__schedpolicy = policy;
return 0;
}
strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
int __pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
{
*policy = attr->__schedpolicy;
return 0;
}
strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
int __pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
{
if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
return EINVAL;
attr->__inheritsched = inherit;
return 0;
}
strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched);
int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
int __pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
{
*inherit = attr->__inheritsched;
return 0;
}
strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched);
int pthread_attr_setscope(pthread_attr_t *attr, int scope)
int __pthread_attr_setscope(pthread_attr_t *attr, int scope)
{
switch (scope) {
case PTHREAD_SCOPE_SYSTEM:
@ -135,12 +144,14 @@ int pthread_attr_setscope(pthread_attr_t *attr, int scope)
return EINVAL;
}
}
strong_alias (__pthread_attr_setscope, pthread_attr_setscope);
int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
int __pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
{
*scope = attr->__scope;
return 0;
}
strong_alias (__pthread_attr_getscope, pthread_attr_getscope);
int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
{

View File

@ -30,7 +30,7 @@
#endif
int pthread_setcancelstate(int state, int * oldstate)
int __pthread_setcancelstate(int state, int * oldstate)
{
pthread_descr self = thread_self();
if (state < PTHREAD_CANCEL_ENABLE || state > PTHREAD_CANCEL_DISABLE)
@ -43,8 +43,9 @@ int pthread_setcancelstate(int state, int * oldstate)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
return 0;
}
strong_alias (__pthread_setcancelstate, pthread_setcancelstate);
int pthread_setcanceltype(int type, int * oldtype)
int __pthread_setcanceltype(int type, int * oldtype)
{
pthread_descr self = thread_self();
if (type < PTHREAD_CANCEL_DEFERRED || type > PTHREAD_CANCEL_ASYNCHRONOUS)
@ -57,6 +58,33 @@ int pthread_setcanceltype(int type, int * oldtype)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
return 0;
}
strong_alias (__pthread_setcanceltype, pthread_setcanceltype);
/* The next two functions are similar to pthread_setcanceltype() but
more specialized for the use in the cancelable functions like write().
They do not need to check parameters etc. */
int
attribute_hidden
__pthread_enable_asynccancel (void)
{
pthread_descr self = thread_self();
int oldtype = THREAD_GETMEM(self, p_canceltype);
THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) &&
THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
__pthread_do_exit(PTHREAD_CANCELED, CURRENT_STACK_FRAME);
return oldtype;
}
void
internal_function attribute_hidden
__pthread_disable_asynccancel (int oldtype)
{
pthread_descr self = thread_self();
THREAD_SETMEM(self, p_canceltype, oldtype);
}
int pthread_cancel(pthread_t thread)
{
@ -210,14 +238,3 @@ void __pthread_perform_cleanup(char *currentframe)
__rpc_thread_destroy ();
#endif
}
#ifndef SHARED
/* We need a hook to force the cancelation wrappers and file locking
to be linked in when static libpthread is used. */
extern const int __pthread_provide_wrappers;
static const int *const __pthread_require_wrappers =
&__pthread_provide_wrappers;
extern const int __pthread_provide_lockfile;
static const int *const __pthread_require_lockfile =
&__pthread_provide_lockfile;
#endif

View File

@ -25,19 +25,21 @@
#include "queue.h"
#include "restart.h"
int pthread_cond_init(pthread_cond_t *cond,
int __pthread_cond_init(pthread_cond_t *cond,
const pthread_condattr_t *cond_attr)
{
__pthread_init_lock(&cond->__c_lock);
cond->__c_waiting = NULL;
return 0;
}
strong_alias (__pthread_cond_init, pthread_cond_init)
int pthread_cond_destroy(pthread_cond_t *cond)
int __pthread_cond_destroy(pthread_cond_t *cond)
{
if (cond->__c_waiting != NULL) return EBUSY;
return 0;
}
strong_alias (__pthread_cond_destroy, pthread_cond_destroy)
/* Function called by pthread_cancel to remove the thread from
waiting on a condition variable queue. */
@ -55,7 +57,7 @@ static int cond_extricate_func(void *obj, pthread_descr th)
return did_remove;
}
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
volatile pthread_descr self = thread_self();
pthread_extricate_if extr;
@ -132,6 +134,7 @@ int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
pthread_mutex_lock(mutex);
return 0;
}
strong_alias (__pthread_cond_wait, pthread_cond_wait)
static int
pthread_cond_timedwait_relative(pthread_cond_t *cond,
@ -234,7 +237,7 @@ int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
return pthread_cond_timedwait_relative(cond, mutex, abstime);
}
int pthread_cond_signal(pthread_cond_t *cond)
int __pthread_cond_signal(pthread_cond_t *cond)
{
pthread_descr th;
@ -248,8 +251,9 @@ int pthread_cond_signal(pthread_cond_t *cond)
}
return 0;
}
strong_alias (__pthread_cond_signal, pthread_cond_signal)
int pthread_cond_broadcast(pthread_cond_t *cond)
int __pthread_cond_broadcast(pthread_cond_t *cond)
{
pthread_descr tosignal, th;
@ -266,16 +270,19 @@ int pthread_cond_broadcast(pthread_cond_t *cond)
}
return 0;
}
strong_alias (__pthread_cond_broadcast, pthread_cond_broadcast)
int pthread_condattr_init(pthread_condattr_t *attr)
int __pthread_condattr_init(pthread_condattr_t *attr)
{
return 0;
}
strong_alias (__pthread_condattr_init, pthread_condattr_init)
int pthread_condattr_destroy(pthread_condattr_t *attr)
int __pthread_condattr_destroy(pthread_condattr_t *attr)
{
return 0;
}
strong_alias (__pthread_condattr_destroy, pthread_condattr_destroy)
int pthread_condattr_getpshared (const pthread_condattr_t *attr, int *pshared)
{

View File

@ -106,6 +106,7 @@ struct _pthread_descr_struct {
the address of this thread descriptor. */
union dtv *dtvp;
pthread_descr self; /* Pointer to this structure */
int multiple_threads;
} data;
void *__padding[16];
} p_header;

146
linuxthreads/forward.c Normal file
View File

@ -0,0 +1,146 @@
/* 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 <dlfcn.h>
#include "internals.h"
#include <stdlib.h>
#include <shlib-compat.h>
/* Pointers to the libc functions. */
struct pthread_functions __libc_pthread_functions attribute_hidden;
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3_2)
# define FORWARD4(name, export, rettype, decl, params, defaction, version) \
rettype \
__noexport_##name decl \
{ \
if (__libc_pthread_functions.ptr_##name == NULL) \
defaction; \
\
return __libc_pthread_functions.ptr_##name params; \
} \
compat_symbol (libc, __noexport_##name, export, version)
# define FORWARD3(name, rettype, decl, params, defaction, version) \
FORWARD4 (name, name, rettype, decl, params, defaction, version)
# define FORWARD2(name, decl, params, defretval, version) \
FORWARD3 (name, int, decl, params, return defretval, version)
# define FORWARD(name, decl, params, defretval) \
FORWARD2 (name, decl, params, defretval, GLIBC_2_0)
FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0);
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_1)
FORWARD4 (pthread_attr_init_2_0, pthread_attr_init, int,
(pthread_attr_t *attr), (attr), 0, GLIBC_2_0);
#endif
FORWARD4 (pthread_attr_init_2_1, pthread_attr_init, int,
(pthread_attr_t *attr), (attr), 0, GLIBC_2_1);
FORWARD (pthread_attr_getdetachstate,
(const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
0);
FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
(attr, detachstate), 0);
FORWARD (pthread_attr_getinheritsched,
(const pthread_attr_t *attr, int *inherit), (attr, inherit), 0);
FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
(attr, inherit), 0);
FORWARD (pthread_attr_getschedparam,
(const pthread_attr_t *attr, struct sched_param *param),
(attr, param), 0);
FORWARD (pthread_attr_setschedparam,
(pthread_attr_t *attr, const struct sched_param *param),
(attr, param), 0);
FORWARD (pthread_attr_getschedpolicy,
(const pthread_attr_t *attr, int *policy), (attr, policy), 0);
FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
(attr, policy), 0);
FORWARD (pthread_attr_getscope,
(const pthread_attr_t *attr, int *scope), (attr, scope), 0);
FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
(attr, scope), 0);
FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0);
FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0);
FORWARD (pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0);
FORWARD (pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0);
FORWARD (pthread_cond_init,
(pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
(cond, cond_attr), 0);
FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0);
FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
(cond, mutex), 0);
FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
(thread1, thread2), 1);
FORWARD3 (pthread_exit, void, (void *retval), (retval), exit (EXIT_SUCCESS),
GLIBC_2_0);
FORWARD (pthread_getschedparam,
(pthread_t target_thread, int *policy, struct sched_param *param),
(target_thread, policy, param), 0);
FORWARD (pthread_setschedparam,
(pthread_t target_thread, int policy,
const struct sched_param *param), (target_thread, policy, param), 0);
FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0);
FORWARD (pthread_mutex_init,
(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
(mutex, mutexattr), 0);
FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0);
FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0);
FORWARD3 (pthread_self, pthread_t, (void), (), return 0, GLIBC_2_0);
FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate),
0);
FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0);
#endif

View File

@ -245,6 +245,9 @@ static inline int nonexisting_handle(pthread_handle h, pthread_t id)
#define SPIN_SLEEP_DURATION 2000001
#endif
/* Defined and used in libc.so. */
extern int __libc_multiple_threads attribute_hidden;
/* Debugging */
#ifdef DEBUG
@ -294,6 +297,24 @@ extern int __pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr,
size_t __stacksize);
extern int __pthread_attr_getstack (const pthread_attr_t *__attr, void **__stackaddr,
size_t *__stacksize);
extern int __pthread_attr_destroy (pthread_attr_t *attr);
extern int __pthread_attr_setdetachstate (pthread_attr_t *attr,
int detachstate);
extern int __pthread_attr_getdetachstate (const pthread_attr_t *attr,
int *detachstate);
extern int __pthread_attr_setschedparam (pthread_attr_t *attr,
const struct sched_param *param);
extern int __pthread_attr_getschedparam (const pthread_attr_t *attr,
struct sched_param *param);
extern int __pthread_attr_setschedpolicy (pthread_attr_t *attr, int policy);
extern int __pthread_attr_getschedpolicy (const pthread_attr_t *attr,
int *policy);
extern int __pthread_attr_setinheritsched (pthread_attr_t *attr, int inherit);
extern int __pthread_attr_getinheritsched (const pthread_attr_t *attr,
int *inherit);
extern int __pthread_attr_setscope (pthread_attr_t *attr, int scope);
extern int __pthread_attr_getscope (const pthread_attr_t *attr, int *scope);
extern int __pthread_getconcurrency (void);
extern int __pthread_setconcurrency (int __level);
extern int __pthread_mutex_timedlock (pthread_mutex_t *__mutex,
@ -305,6 +326,37 @@ extern int __pthread_mutexattr_setpshared (pthread_mutexattr_t *__attr,
extern int __pthread_mutexattr_gettype (const pthread_mutexattr_t *__attr,
int *__kind);
extern void __pthread_kill_other_threads_np (void);
extern int __pthread_mutex_init (pthread_mutex_t *__mutex,
__const pthread_mutexattr_t *__mutex_attr);
extern int __pthread_mutex_destroy (pthread_mutex_t *__mutex);
extern int __pthread_mutex_lock (pthread_mutex_t *__mutex);
extern int __pthread_mutex_trylock (pthread_mutex_t *__mutex);
extern int __pthread_mutex_unlock (pthread_mutex_t *__mutex);
#if defined NOT_IN_libc && defined IS_IN_libpthread
hidden_proto (__pthread_mutex_init)
hidden_proto (__pthread_mutex_destroy)
hidden_proto (__pthread_mutex_lock)
hidden_proto (__pthread_mutex_trylock)
hidden_proto (__pthread_mutex_unlock)
#endif
extern int __pthread_cond_init (pthread_cond_t *cond,
const pthread_condattr_t *cond_attr);
extern int __pthread_cond_destroy (pthread_cond_t *cond);
extern int __pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);
extern int __pthread_cond_signal (pthread_cond_t *cond);
extern int __pthread_cond_broadcast (pthread_cond_t *cond);
extern int __pthread_condattr_init (pthread_condattr_t *attr);
extern int __pthread_condattr_destroy (pthread_condattr_t *attr);
extern pthread_t __pthread_self (void);
extern pthread_descr __pthread_thread_self (void);
extern int __pthread_equal (pthread_t thread1, pthread_t thread2);
extern void __pthread_exit (void *retval);
extern int __pthread_getschedparam (pthread_t thread, int *policy,
struct sched_param *param);
extern int __pthread_setschedparam (pthread_t thread, int policy,
const struct sched_param *param);
extern int __pthread_setcancelstate (int state, int * oldstate);
extern int __pthread_setcanceltype (int type, int * oldtype);
extern void __pthread_restart_old(pthread_descr th);
extern void __pthread_suspend_old(pthread_descr self);
@ -339,7 +391,6 @@ extern int __pthread_spin_destroy (pthread_spinlock_t *__lock);
extern int __pthread_clock_gettime (hp_timing_t freq, struct timespec *tp);
extern void __pthread_clock_settime (hp_timing_t offset);
/* Global pointers to old or new suspend functions */
extern void (*__pthread_restart)(pthread_descr);
@ -386,4 +437,77 @@ extern void __pthread_sighandler_rt(int signo, struct siginfo *si,
struct ucontext *uc);
extern void __pthread_null_sighandler(int sig);
/* Cancellation. */
extern int __pthread_enable_asynccancel (void) 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;
#if !defined NOT_IN_libc
# define LIBC_CANCEL_ASYNC() \
__libc_enable_asynccancel ()
# define LIBC_CANCEL_RESET(oldtype) \
__libc_disable_asynccancel (oldtype)
#elif defined NOT_IN_libc && defined IS_IN_libpthread
# define LIBC_CANCEL_ASYNC() \
__pthread_enable_asynccancel ()
# define LIBC_CANCEL_RESET(oldtype) \
__pthread_disable_asynccancel (oldtype)
#else
# define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
# define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
#endif
/* Data type shared with libc. The libc uses it to pass on calls to
the thread functions. */
struct pthread_functions
{
int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
int (*ptr_pthread_attr_init_2_0) (pthread_attr_t *);
int (*ptr_pthread_attr_init_2_1) (pthread_attr_t *);
int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
struct sched_param *);
int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
const struct sched_param *);
int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
int (*ptr_pthread_cond_broadcast) (pthread_cond_t *);
int (*ptr_pthread_cond_destroy) (pthread_cond_t *);
int (*ptr_pthread_cond_init) (pthread_cond_t *, const pthread_condattr_t *);
int (*ptr_pthread_cond_signal) (pthread_cond_t *);
int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
int (*ptr_pthread_equal) (pthread_t, pthread_t);
void (*ptr_pthread_exit) (void *);
int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
int (*ptr_pthread_setschedparam) (pthread_t, int,
const struct sched_param *);
int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
const pthread_mutexattr_t *);
int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);
int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
pthread_t (*ptr_pthread_self) (void);
int (*ptr_pthread_setcancelstate) (int, int *);
int (*ptr_pthread_setcanceltype) (int, int *);
void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
pthread_descr (*ptr_pthread_thread_self) (void);
};
/* Variable in libc.so. */
extern struct pthread_functions __libc_pthread_functions attribute_hidden;
extern int * __libc_pthread_init (const struct pthread_functions *functions);
#endif /* internals.h */

View File

@ -23,10 +23,11 @@
#include "spinlock.h"
#include "restart.h"
void pthread_exit(void * retval)
void __pthread_exit(void * retval)
{
__pthread_do_exit (retval, CURRENT_STACK_FRAME);
}
strong_alias (__pthread_exit, pthread_exit);
void __pthread_do_exit(void *retval, char *currentframe)
{

View File

@ -0,0 +1,75 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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 <rpc/rpc.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include "restart.h"
#include <bits/libc-lock.h>
#if !defined NOT_IN_libc
# ifndef SHARED
weak_extern (__pthread_do_exit)
weak_extern (__pthread_thread_self)
# endif
int __libc_multiple_threads attribute_hidden;
/* The next two functions are similar to pthread_setcanceltype() but
more specialized for the use in the cancelable functions like write().
They do not need to check parameters etc. */
int
attribute_hidden
__libc_enable_asynccancel (void)
{
#ifdef FLOATING_STACKS
pthread_descr self = thread_self();
#else
pthread_descr self = __libc_maybe_call2 (pthread_thread_self, (), NULL);
if (self == NULL)
return PTHREAD_CANCEL_DEFERRED;
#endif
int oldtype = THREAD_GETMEM(self, p_canceltype);
THREAD_SETMEM(self, p_canceltype, PTHREAD_CANCEL_ASYNCHRONOUS);
if (__builtin_expect (THREAD_GETMEM(self, p_canceled), 0) &&
THREAD_GETMEM(self, p_cancelstate) == PTHREAD_CANCEL_ENABLE)
__libc_maybe_call2 (pthread_do_exit,
(PTHREAD_CANCELED, CURRENT_STACK_FRAME), 0);
return oldtype;
}
void
internal_function attribute_hidden
__libc_disable_asynccancel (int oldtype)
{
#ifdef FLOATING_STACKS
pthread_descr self = thread_self();
#else
pthread_descr self = __libc_maybe_call2 (pthread_thread_self, (), NULL);
if (self != NULL)
#endif
THREAD_SETMEM(self, p_canceltype, oldtype);
}
#endif

View File

@ -0,0 +1,53 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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 <string.h>
#include <tls.h>
#include <locale.h>
#include "internals.h"
#include <sysdep-cancel.h>
int *
__libc_pthread_init (functions)
const struct pthread_functions *functions;
{
#ifdef SHARED
/* We copy the content of the variable pointed to by the FUNCTIONS
parameter to one in libc.so since this means access to the array
can be done with one memory access instead of two. */
memcpy (&__libc_pthread_functions, functions,
sizeof (__libc_pthread_functions));
#endif
#ifdef MULTIPLE_THREADS_OFFSET
/* We have a macro which is used in asm code describing data layout.
Make sure it does not get out of date. */
if (offsetof (struct _pthread_descr_struct, p_header.data.multiple_threads)
!= MULTIPLE_THREADS_OFFSET)
abort ();
#endif
#if !(USE_TLS && HAVE___THREAD)
/* Initialize thread-locale current locale to point to the global one.
With __thread support, the variable's initializer takes care of this. */
__uselocale (LC_GLOBAL_LOCALE);
#endif
return &__libc_multiple_threads;
}

View File

@ -21,80 +21,51 @@
#include <stdio.h>
#include <pthread.h>
#include "internals.h"
#ifdef USE_IN_LIBIO
#include "../libio/libioP.h"
#endif
#ifndef SHARED
/* We need a hook to force this file to be linked in when static
libpthread is used. */
const int __pthread_provide_lockfile = 0;
#endif
void
__flockfile (FILE *stream)
{
#ifdef USE_IN_LIBIO
__pthread_mutex_lock (stream->_lock);
#else
#endif
}
#ifdef USE_IN_LIBIO
#undef _IO_flockfile
strong_alias (__flockfile, _IO_flockfile)
#endif
weak_alias (__flockfile, flockfile);
void
__funlockfile (FILE *stream)
{
#ifdef USE_IN_LIBIO
__pthread_mutex_unlock (stream->_lock);
#else
#endif
}
#ifdef USE_IN_LIBIO
#undef _IO_funlockfile
strong_alias (__funlockfile, _IO_funlockfile)
#endif
weak_alias (__funlockfile, funlockfile);
int
__ftrylockfile (FILE *stream)
{
#ifdef USE_IN_LIBIO
return __pthread_mutex_trylock (stream->_lock);
#else
#endif
}
#ifdef USE_IN_LIBIO
strong_alias (__ftrylockfile, _IO_ftrylockfile)
#endif
weak_alias (__ftrylockfile, ftrylockfile);
void
__flockfilelist(void)
{
#ifdef USE_IN_LIBIO
_IO_list_lock();
#endif
}
void
__funlockfilelist(void)
{
#ifdef USE_IN_LIBIO
_IO_list_unlock();
#endif
}
void
__fresetlockfiles (void)
{
#ifdef USE_IN_LIBIO
_IO_ITER i;
pthread_mutexattr_t attr;
@ -108,5 +79,4 @@ __fresetlockfiles (void)
__pthread_mutexattr_destroy (&attr);
_IO_list_resetlock();
#endif
}

View File

@ -633,6 +633,7 @@ static int pthread_handle_create(pthread_t *thread, const pthread_attr_t *attr,
initialized to zero already have this value. */
new_thread->p_header.data.tcb = new_thread;
new_thread->p_header.data.self = new_thread;
new_thread->p_header.data.multiple_threads = 1;
new_thread->p_tid = new_thread_id;
new_thread->p_lock = &(__pthread_handles[sseg].h_lock);
new_thread->p_cancelstate = PTHREAD_CANCEL_ENABLE;

View File

@ -36,6 +36,7 @@ int __pthread_mutex_init(pthread_mutex_t * mutex,
return 0;
}
strong_alias (__pthread_mutex_init, pthread_mutex_init)
hidden_def (__pthread_mutex_init)
int __pthread_mutex_destroy(pthread_mutex_t * mutex)
{
@ -55,6 +56,7 @@ int __pthread_mutex_destroy(pthread_mutex_t * mutex)
}
}
strong_alias (__pthread_mutex_destroy, pthread_mutex_destroy)
hidden_def (__pthread_mutex_destroy)
int __pthread_mutex_trylock(pthread_mutex_t * mutex)
{
@ -91,6 +93,7 @@ int __pthread_mutex_trylock(pthread_mutex_t * mutex)
}
}
strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock)
hidden_def (__pthread_mutex_trylock)
int __pthread_mutex_lock(pthread_mutex_t * mutex)
{
@ -124,6 +127,7 @@ int __pthread_mutex_lock(pthread_mutex_t * mutex)
}
}
strong_alias (__pthread_mutex_lock, pthread_mutex_lock)
hidden_def (__pthread_mutex_lock)
int __pthread_mutex_timedlock (pthread_mutex_t *mutex,
const struct timespec *abstime)
@ -199,6 +203,7 @@ int __pthread_mutex_unlock(pthread_mutex_t * mutex)
}
}
strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock)
hidden_def (__pthread_mutex_unlock)
int __pthread_mutexattr_init(pthread_mutexattr_t *attr)
{

View 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 <signal.h>
/* These are defined in libc. We want to have only one definition
so we "forward" the calls. */
extern int __libc_current_sigrtmin_private (void);
extern int __libc_current_sigrtmax_private (void);
extern int __libc_allocate_rtsig_private (int high);
/* We reserve __SIGRTMIN for use as the cancelation signal. This
signal is used internally. */
int
__libc_current_sigrtmin (void)
{
return __libc_current_sigrtmin_private ();
}
int
__libc_current_sigrtmax (void)
{
return __libc_current_sigrtmax_private ();
}
int
__libc_allocate_rtsig (int high)
{
return __libc_allocate_rtsig_private (high);
}

32
linuxthreads/pt-system.c Normal file
View File

@ -0,0 +1,32 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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-cancel.h>
int
system (const char *line)
{
int oldtype = LIBC_CANCEL_ASYNC ();
int result = __libc_system (line);
LIBC_CANCEL_RESET (oldtype);
return result;
}

View File

@ -33,12 +33,11 @@
#include "smp.h"
#include <ldsodefs.h>
#include <tls.h>
#include <locale.h> /* for __uselocale */
#include <version.h>
/* Sanity check. */
#if __ASSUME_REALTIME_SIGNALS && !defined __SIGRTMIN
# error "This must not happen; new kernel assumed but old headers"
#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
# error "This must not happen"
#endif
#if !(USE_TLS && HAVE___THREAD)
@ -86,6 +85,7 @@ struct _pthread_descr_struct __pthread_initial_thread = {
#define manager_thread (&__pthread_manager_thread)
struct _pthread_descr_struct __pthread_manager_thread = {
.p_header.data.self = &__pthread_manager_thread,
.p_header.data.multiple_threads = 1,
.p_lock = &__pthread_handles[1].h_lock,
.p_start_args = PTHREAD_START_ARGS_INITIALIZER(__pthread_manager),
#if !(USE_TLS && HAVE___THREAD)
@ -116,6 +116,8 @@ char *__pthread_initial_thread_bos;
int __pthread_manager_request = -1;
int __pthread_multiple_threads attribute_hidden;
/* Other end of the pipe for sending requests to the thread manager. */
int __pthread_manager_reader;
@ -177,109 +179,38 @@ static void pthread_handle_sigdebug(int sig);
platform does not support any real-time signals we will define the
values to some unreasonable value which will signal failing of all
the functions below. */
#ifndef __SIGRTMIN
static int current_rtmin = -1;
static int current_rtmax = -1;
int __pthread_sig_restart = SIGUSR1;
int __pthread_sig_cancel = SIGUSR2;
int __pthread_sig_debug;
#else
static int current_rtmin;
static int current_rtmax;
#if __SIGRTMAX - __SIGRTMIN >= 3
int __pthread_sig_restart = __SIGRTMIN;
int __pthread_sig_cancel = __SIGRTMIN + 1;
int __pthread_sig_debug = __SIGRTMIN + 2;
#else
int __pthread_sig_restart = SIGUSR1;
int __pthread_sig_cancel = SIGUSR2;
int __pthread_sig_debug;
#endif
static int rtsigs_initialized;
extern int __libc_current_sigrtmin_private (void);
#if !__ASSUME_REALTIME_SIGNALS
# include "testrtsig.h"
#endif
static int rtsigs_initialized;
static void
init_rtsigs (void)
{
#if !__ASSUME_REALTIME_SIGNALS
if (__builtin_expect (!kernel_has_rtsig (), 0))
if (rtsigs_initialized)
return;
if (__builtin_expect (__libc_current_sigrtmin_private () == -1))
{
current_rtmin = -1;
current_rtmax = -1;
# if __SIGRTMAX - __SIGRTMIN >= 3
__pthread_sig_restart = SIGUSR1;
__pthread_sig_cancel = SIGUSR2;
__pthread_sig_debug = 0;
# endif
}
else
#endif /* __ASSUME_REALTIME_SIGNALS */
{
#if __SIGRTMAX - __SIGRTMIN >= 3
current_rtmin = __SIGRTMIN + 3;
# if !__ASSUME_REALTIME_SIGNALS
__pthread_restart = __pthread_restart_new;
__pthread_suspend = __pthread_wait_for_restart_signal;
__pthread_timedsuspend = __pthread_timedsuspend_new;
# endif /* __ASSUME_REALTIME_SIGNALS */
#else
current_rtmin = __SIGRTMIN;
#endif
current_rtmax = __SIGRTMAX;
}
rtsigs_initialized = 1;
}
#endif
/* Return number of available real-time signal with highest priority. */
int
__libc_current_sigrtmin (void)
{
#ifdef __SIGRTMIN
if (__builtin_expect (!rtsigs_initialized, 0))
init_rtsigs ();
#endif
return current_rtmin;
}
/* Return number of available real-time signal with lowest priority. */
int
__libc_current_sigrtmax (void)
{
#ifdef __SIGRTMIN
if (__builtin_expect (!rtsigs_initialized, 0))
init_rtsigs ();
#endif
return current_rtmax;
}
/* Allocate real-time signal with highest/lowest available
priority. Please note that we don't use a lock since we assume
this function to be called at program start. */
int
__libc_allocate_rtsig (int high)
{
#ifndef __SIGRTMIN
return -1;
#else
if (__builtin_expect (!rtsigs_initialized, 0))
init_rtsigs ();
if (__builtin_expect (current_rtmin == -1, 0)
|| __builtin_expect (current_rtmin > current_rtmax, 0))
/* We don't have anymore signal available. */
return -1;
return high ? current_rtmin++ : current_rtmax--;
#endif
}
/* Initialize the pthread library.
Initialization is split in two functions:
@ -299,6 +230,52 @@ extern void *__dso_handle __attribute__ ((weak));
extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
#endif
#ifdef SHARED
static struct pthread_functions pthread_functions =
{
.ptr_pthread_attr_destroy = __pthread_attr_destroy,
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
.ptr_pthread_attr_init_2_0 = __pthread_attr_init_2_0,
#endif
.ptr_pthread_attr_init_2_1 = __pthread_attr_init_2_1,
.ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
.ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
.ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
.ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
.ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
.ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
.ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
.ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
.ptr_pthread_attr_getscope = __pthread_attr_getscope,
.ptr_pthread_attr_setscope = __pthread_attr_setscope,
.ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
.ptr_pthread_condattr_init = __pthread_condattr_init,
.ptr_pthread_cond_broadcast = __pthread_cond_broadcast,
.ptr_pthread_cond_destroy = __pthread_cond_destroy,
.ptr_pthread_cond_init = __pthread_cond_init,
.ptr_pthread_cond_signal = __pthread_cond_signal,
.ptr_pthread_cond_wait = __pthread_cond_wait,
.ptr_pthread_equal = __pthread_equal,
.ptr_pthread_exit = __pthread_exit,
.ptr_pthread_getschedparam = __pthread_getschedparam,
.ptr_pthread_setschedparam = __pthread_setschedparam,
.ptr_pthread_mutex_destroy = __pthread_mutex_destroy,
.ptr_pthread_mutex_init = __pthread_mutex_init,
.ptr_pthread_mutex_lock = __pthread_mutex_lock,
.ptr_pthread_mutex_trylock = __pthread_mutex_trylock,
.ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
.ptr_pthread_self = __pthread_self,
.ptr_pthread_setcancelstate = __pthread_setcancelstate,
.ptr_pthread_setcanceltype = __pthread_setcanceltype,
.ptr_pthread_do_exit = __pthread_do_exit,
.ptr_pthread_thread_self = __pthread_thread_self
};
# define ptr_pthread_functions &pthread_functions
#else
# define ptr_pthread_functions NULL
#endif
static int *__libc_multiple_threads_ptr;
/* Do some minimal initialization which has to be done during the
startup of the C library. */
@ -413,11 +390,7 @@ cannot allocate TLS data structures for initial thread\n";
# endif
#endif
#if !(USE_TLS && HAVE___THREAD)
/* Initialize thread-locale current locale to point to the global one.
With __thread support, the variable's initializer takes care of this. */
__uselocale (LC_GLOBAL_LOCALE);
#endif
__libc_multiple_threads_ptr = __libc_pthread_init (ptr_pthread_functions);
}
@ -520,7 +493,7 @@ static void pthread_initialize(void)
/* Likewise for the resolver state _res. */
__pthread_initial_thread.p_resp = &_res;
#endif
#ifdef __SIGRTMIN
#if !__ASSUME_REALTIME_SIGNALS
/* Initialize real-time signals. */
init_rtsigs ();
#endif
@ -577,6 +550,15 @@ int __pthread_initialize_manager(void)
int report_events;
pthread_descr tcb;
__pthread_multiple_threads = 1;
__pthread_main_thread->p_header.data.multiple_threads = 1;
* __libc_multiple_threads_ptr = 1;
#ifdef MULTIPLE_THREADS_OFFSET
if (offsetof(struct _pthread_descr_struct, p_header.data.multiple_threads)
!= MULTIPLE_THREADS_OFFSET)
abort ();
#endif
#ifndef HAVE_Z_NODELETE
if (__builtin_expect (&__dso_handle != NULL, 1))
__cxa_atexit ((void (*) (void *)) pthread_atexit_retcode, NULL,
@ -613,6 +595,7 @@ int __pthread_initialize_manager(void)
/* Initialize the descriptor. */
tcb->p_header.data.tcb = tcb;
tcb->p_header.data.self = tcb;
tcb->p_header.data.multiple_threads = 1;
tcb->p_lock = &__pthread_handles[1].h_lock;
# ifndef HAVE___THREAD
tcb->p_errnop = &tcb->p_errno;
@ -797,16 +780,23 @@ compat_symbol (libpthread, __pthread_create_2_0, pthread_create, GLIBC_2_0);
/* Simple operations on thread identifiers */
pthread_t pthread_self(void)
pthread_descr __pthread_thread_self(void)
{
return thread_self();
}
pthread_t __pthread_self(void)
{
pthread_descr self = thread_self();
return THREAD_GETMEM(self, p_tid);
}
strong_alias (__pthread_self, pthread_self);
int pthread_equal(pthread_t thread1, pthread_t thread2)
int __pthread_equal(pthread_t thread1, pthread_t thread2)
{
return thread1 == thread2;
}
strong_alias (__pthread_equal, pthread_equal);
/* Helper function for thread_self in the case of user-provided stacks */
@ -849,7 +839,7 @@ static pthread_descr thread_self_stack(void)
/* Thread scheduling */
int pthread_setschedparam(pthread_t thread, int policy,
int __pthread_setschedparam(pthread_t thread, int policy,
const struct sched_param *param)
{
pthread_handle handle = thread_handle(thread);
@ -872,8 +862,9 @@ int pthread_setschedparam(pthread_t thread, int policy,
__pthread_manager_adjust_prio(th->p_priority);
return 0;
}
strong_alias (__pthread_setschedparam, pthread_setschedparam);
int pthread_getschedparam(pthread_t thread, int *policy,
int __pthread_getschedparam(pthread_t thread, int *policy,
struct sched_param *param)
{
pthread_handle handle = thread_handle(thread);
@ -892,6 +883,7 @@ int pthread_getschedparam(pthread_t thread, int *policy,
*policy = pol;
return 0;
}
strong_alias (__pthread_getschedparam, pthread_getschedparam);
int __pthread_yield (void)
{
@ -1319,15 +1311,3 @@ void __pthread_message(const char * fmt, ...)
}
#endif
#ifndef SHARED
/* We need a hook to force the cancelation wrappers and file locking
to be linked in when static libpthread is used. */
extern const int __pthread_provide_wrappers;
static const int *const __pthread_require_wrappers =
&__pthread_provide_wrappers;
extern const int __pthread_provide_lockfile;
static const int *const __pthread_require_lockfile =
&__pthread_provide_lockfile;
#endif

View File

@ -23,6 +23,10 @@
#include <pthread.h>
#if defined _LIBC && !defined NOT_IN_libc
#include <linuxthreads/internals.h>
#endif
/* Mutex type. */
#if defined(_LIBC) || defined(_IO_MTSAFE_IO)
typedef pthread_mutex_t __libc_lock_t;
@ -90,6 +94,9 @@ typedef pthread_key_t __libc_key_t;
#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
{PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP}
#if defined _LIBC && defined IS_IN_libpthread
# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS
#else
# ifdef __PIC__
# define __libc_maybe_call(FUNC, ARGS, ELSE) \
(__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \
@ -98,11 +105,19 @@ typedef pthread_key_t __libc_key_t;
# define __libc_maybe_call(FUNC, ARGS, ELSE) \
(FUNC != NULL ? FUNC ARGS : ELSE)
# endif
#endif
#if defined _LIBC && !defined NOT_IN_libc && defined __PIC__
# define __libc_maybe_call2(FUNC, ARGS, ELSE) \
({__libc_pthread_functions.ptr_##FUNC != NULL \
? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
#else
# define __libc_maybe_call2(FUNC, ARGS, ELSE) __libc_maybe_call (__##FUNC, ARGS, ELSE)
#endif
/* Initialize the named lock variable, leaving it in a consistent, unlocked
state. */
#define __libc_lock_init(NAME) \
(__libc_maybe_call (__pthread_mutex_init, (&(NAME), NULL), 0))
(__libc_maybe_call2 (pthread_mutex_init, (&(NAME), NULL), 0))
#define __libc_rwlock_init(NAME) \
(__libc_maybe_call (__pthread_rwlock_init, (&(NAME), NULL), 0));
@ -125,7 +140,7 @@ typedef pthread_key_t __libc_key_t;
used again until __libc_lock_init is called again on it. This must be
called on a lock variable before the containing storage is reused. */
#define __libc_lock_fini(NAME) \
(__libc_maybe_call (__pthread_mutex_destroy, (&(NAME)), 0));
(__libc_maybe_call2 (pthread_mutex_destroy, (&(NAME)), 0));
#define __libc_rwlock_fini(NAME) \
(__libc_maybe_call (__pthread_rwlock_destroy, (&(NAME)), 0));
@ -135,7 +150,7 @@ typedef pthread_key_t __libc_key_t;
/* Lock the named lock variable. */
#define __libc_lock_lock(NAME) \
(__libc_maybe_call (__pthread_mutex_lock, (&(NAME)), 0));
(__libc_maybe_call2 (pthread_mutex_lock, (&(NAME)), 0));
#define __libc_rwlock_rdlock(NAME) \
(__libc_maybe_call (__pthread_rwlock_rdlock, (&(NAME)), 0));
#define __libc_rwlock_wrlock(NAME) \
@ -147,7 +162,7 @@ typedef pthread_key_t __libc_key_t;
/* Try to lock the named lock variable. */
#define __libc_lock_trylock(NAME) \
(__libc_maybe_call (__pthread_mutex_trylock, (&(NAME)), 0))
(__libc_maybe_call2 (pthread_mutex_trylock, (&(NAME)), 0))
#define __libc_rwlock_tryrdlock(NAME) \
(__libc_maybe_call (__pthread_rwlock_tryrdlock, (&(NAME)), 0))
#define __libc_rwlock_trywrlock(NAME) \
@ -160,7 +175,7 @@ typedef pthread_key_t __libc_key_t;
/* Unlock the named lock variable. */
#define __libc_lock_unlock(NAME) \
(__libc_maybe_call (__pthread_mutex_unlock, (&(NAME)), 0));
(__libc_maybe_call2 (pthread_mutex_unlock, (&(NAME)), 0));
#define __libc_rwlock_unlock(NAME) \
(__libc_maybe_call (__pthread_rwlock_unlock, (&(NAME)), 0));

View File

@ -0,0 +1,33 @@
/* 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 <pthread.h>
#include <stdio.h>
#include <libio.h>
#include <bits/stdio-lock.h>
void
__flockfile (stream)
FILE *stream;
{
_IO_lock_lock (*stream->_lock);
}
strong_alias (__flockfile, _IO_flockfile)
strong_alias (__flockfile, flockfile)

View File

@ -0,0 +1,33 @@
/* 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 <pthread.h>
#include <stdio.h>
#include <bits/stdio-lock.h>
int
__ftrylockfile (stream)
FILE *stream;
{
return _IO_lock_trylock (*stream->_lock);
}
strong_alias (__ftrylockfile, _IO_ftrylockfile)
weak_alias (__ftrylockfile, ftrylockfile)

View File

@ -0,0 +1,33 @@
/* 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 <pthread.h>
#include <stdio.h>
#include <libio.h>
#include <bits/stdio-lock.h>
void
__funlockfile (stream)
FILE *stream;
{
_IO_lock_unlock (*stream->_lock);
}
strong_alias (__funlockfile, _IO_funlockfile)
weak_alias (__funlockfile, funlockfile)

View File

@ -0,0 +1,85 @@
/* Handle real-time signal allocation.
Copyright (C) 1997,98,99,2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
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 <signal.h>
/* Sanity check. */
#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
# error "This must not happen"
#endif
static int current_rtmin;
static int current_rtmax;
static int initialized;
#include <testrtsig.h>
static void
init (void)
{
if (!kernel_has_rtsig ())
{
current_rtmin = -1;
current_rtmax = -1;
}
else
{
current_rtmin = __SIGRTMIN + 3;
current_rtmax = __SIGRTMAX;
}
initialized = 1;
}
/* Return number of available real-time signal with highest priority. */
int
__libc_current_sigrtmin (void)
{
if (!initialized)
init ();
return current_rtmin;
}
strong_alias (__libc_current_sigrtmin, __libc_current_sigrtmin_private);
/* Return number of available real-time signal with lowest priority. */
int
__libc_current_sigrtmax (void)
{
if (!initialized)
init ();
return current_rtmax;
}
strong_alias (__libc_current_sigrtmax, __libc_current_sigrtmax_private);
/* Allocate real-time signal with highest/lowest available
priority. Please note that we don't use a lock since we assume
this function to be called at program start. */
int
__libc_allocate_rtsig (int high)
{
if (!initialized)
init ();
if (current_rtmin == -1 || current_rtmin > current_rtmax)
/* We don't have anymore signal available. */
return -1;
return high ? current_rtmin++ : current_rtmax--;
}
strong_alias (__libc_allocate_rtsig, __libc_allocate_rtsig_private);

View File

@ -0,0 +1,124 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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>
#include <tls.h>
#include <pt-machine.h>
#ifndef ASSEMBLER
# include <linuxthreads/internals.h>
#endif
#if defined FLOATING_STACKS && USE___THREAD
# define MULTIPLE_THREADS_OFFSET 12
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
SINGLE_THREAD_P; \
jne L(pseudo_cancel); \
DO_CALL (syscall_name, args); \
cmpl $-4095, %eax; \
jae SYSCALL_ERROR_LABEL; \
ret; \
L(pseudo_cancel): \
CENABLE \
SAVE_OLDTYPE_##args \
PUSHARGS_##args \
DOCARGS_##args \
movl $SYS_ify (syscall_name), %eax; \
int $0x80 \
POPARGS_##args; \
POPCARGS_##args \
cmpl $-4095, %eax; \
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
# define SAVE_OLDTYPE_0 movl %eax, %edx;
# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
# define SAVE_OLDTYPE_2 pushl %eax;
# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
# define DOCARGS_0 DOARGS_0
# define DOCARGS_1 DOARGS_1
# define DOCARGS_2 _DOARGS_2 (12)
# define DOCARGS_3 _DOARGS_3 (20)
# define DOCARGS_4 _DOARGS_4 (28)
# define DOCARGS_5 _DOARGS_5 (36)
# ifdef IS_IN_libpthread
# define CENABLE call __pthread_enable_asynccancel;
# define CDISABLE call __pthread_disable_asynccancel
# else
# define CENABLE call __libc_enable_asynccancel;
# define CDISABLE call __libc_disable_asynccancel
# endif
# define POPCARGS_0 pushl %eax; movl %ecx, %eax; CDISABLE; popl %eax;
# define POPCARGS_1 POPCARGS_0
# define POPCARGS_2 xchgl (%esp), %eax; CDISABLE; popl %eax;
# define POPCARGS_3 POPCARGS_2
# define POPCARGS_4 POPCARGS_2
# define POPCARGS_5 POPCARGS_2
#if !defined NOT_IN_libc
# define __local_multiple_threads __libc_multiple_threads
#else
# define __local_multiple_threads __pthread_multiple_threads
#endif
# ifndef ASSEMBLER
# if defined MULTIPLE_THREADS_OFFSET && defined PIC
# define SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
p_header.data.multiple_threads) == 0, 1)
# else
extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
# endif
# else
# if !defined PIC
# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads
# elif defined MULTIPLE_THREADS_OFFSET
# define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
# else
# if !defined HAVE_HIDDEN || !USE___THREAD
# define SINGLE_THREAD_P \
SETUP_PIC_REG (cx); \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
cmpl $0, __local_multiple_threads@GOTOFF(%ecx)
# else
# define SINGLE_THREAD_P \
call __i686.get_pc_thunk.cx; \
addl $_GLOBAL_OFFSET_TABLE_, %ecx; \
cmpl $0, __local_multiple_threads@GOTOFF(%ecx)
# endif
# endif
# endif
#elif !defined ASSEMBLER
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -0,0 +1,118 @@
/* Copyright (C) 2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@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>
#include <tls.h>
#include <pt-machine.h>
#ifndef ASSEMBLER
# include <linuxthreads/internals.h>
#endif
#if !defined NOT_IN_libc || defined IS_IN_libpthread
# undef PSEUDO
# define PSEUDO(name, syscall_name, args) \
.text; \
ENTRY (name) \
SINGLE_THREAD_P; \
jne L(pseudo_cancel); \
DO_CALL (syscall_name, args); \
cmpq $-4095, %rax; \
jae SYSCALL_ERROR_LABEL; \
ret; \
L(pseudo_cancel): \
SAVESTK_##args \
PUSHARGS_##args \
CENABLE \
POPARGS_##args \
movq %rax, OLDTYPE_##args; \
movq $SYS_ify (syscall_name), %rax; \
syscall; \
xchgq %rax, OLDTYPE_##args; \
CDISABLE \
movq OLDTYPE_##args, %rax; \
RESTSTK_##args \
cmpq $-4095, %rax; \
jae SYSCALL_ERROR_LABEL; \
L(pseudo_end):
# define PUSHARGS_0 /* Nothing. */
# define PUSHARGS_1 PUSHARGS_0 movq %rdi, (%rsp);
# define PUSHARGS_2 PUSHARGS_1 movq %rsi, 8(%rsp);
# define PUSHARGS_3 PUSHARGS_2 movq %rdx, 16(%rsp);
# define PUSHARGS_4 PUSHARGS_3 movq %rcx, 24(%rsp);
# define PUSHARGS_5 PUSHARGS_4 movq %r8, 32(%rsp);
# define PUSHARGS_6 PUSHARGS_5 movq %r9, 40(%rsp);
# define POPARGS_0 /* Nothing. */
# define POPARGS_1 POPARGS_0 movq (%rsp), %rdi;
# define POPARGS_2 POPARGS_1 movq 8(%rsp), %rsi;
# define POPARGS_3 POPARGS_2 movq 16(%rsp), %rdx;
# define POPARGS_4 POPARGS_3 movq 24(%rsp), %r10;
# define POPARGS_5 POPARGS_4 movq 32(%rsp), %r8;
# define POPARGS_6 POPARGS_5 movq 40(%rsp), %r9;
# define SAVESTK_0 /* Nothing. */
# define SAVESTK_1 subq $16, %rsp;
# define SAVESTK_2 SAVESTK_1;
# define SAVESTK_3 subq $32, %rsp;
# define SAVESTK_4 SAVESTK_3;
# define SAVESTK_5 subq $48, %rsp;
# define SAVESTK_6 subq $64, %rsp;
# define RESTSTK_0 /* Nothing. */
# define RESTSTK_1 addq $16, %rsp;
# define RESTSTK_2 RESTSTK_1;
# define RESTSTK_3 addq $32, %rsp;
# define RESTSTK_4 RESTSTK_3;
# define RESTSTK_5 addq $48, %rsp;
# define RESTSTK_6 addq $64, %rsp;
# define OLDTYPE_0 %r9
# define OLDTYPE_1 OLDTYPE_0
# define OLDTYPE_2 OLDTYPE_0
# define OLDTYPE_3 OLDTYPE_0
# define OLDTYPE_4 OLDTYPE_0
# define OLDTYPE_5 OLDTYPE_0
# define OLDTYPE_6 48(%rsp)
# ifdef IS_IN_libpthread
# define CENABLE call __pthread_enable_asynccancel;
# define CDISABLE call __pthread_disable_asynccancel;
# define __local_multiple_threads __pthread_multiple_threads
# else
# define CENABLE call __libc_enable_asynccancel;
# define CDISABLE call __libc_disable_asynccancel;
# define __local_multiple_threads __libc_multiple_threads
# endif
# ifndef ASSEMBLER
extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P \
__builtin_expect (__local_multiple_threads == 0, 1)
# else
# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
# endif
#elif !defined ASSEMBLER
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
#endif

View File

@ -21,6 +21,7 @@
#ifndef _PT_MACHINE_H
#define _PT_MACHINE_H 1
#ifndef __ASSEMBLER__
# include <stddef.h> /* For offsetof. */
# include <stdlib.h> /* For abort(). */
# include <asm/prctl.h>
@ -210,6 +211,8 @@ extern int __arch_prctl (int __code, unsigned long __addr);
} \
})
#endif /* !__ASSEMBLER__ */
/* We want the OS to assign stack addresses. */
#define FLOATING_STACKS 1

View File

@ -0,0 +1,96 @@
#! /bin/sh
# Test whether all cancellable functions are cancellable.
# Copyright (C) 2002 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# Contributed by Jakub Jelinek <jakub@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.
while [ $# -gt 0 ]; do
( nm -P $1; echo 'end[end]:' ) | awk ' BEGIN {
C["accept"]=1
C["close"]=1
C["connect"]=1
C["creat"]=1
C["fcntl"]=1
C["fsync"]=1
C["llseek"]=1
C["lseek"]=1
C["msgrcv"]=1
C["msgsnd"]=1
C["msync"]=1
C["nanosleep"]=1
C["open"]=1
C["open64"]=1
C["pause"]=1
C["poll"]=1
C["pread"]=1
C["pread64"]=1
C["pselect"]=1
C["pwrite"]=1
C["pwrite64"]=1
C["read"]=1
C["readv"]=1
C["recv"]=1
C["recvfrom"]=1
C["recvmsg"]=1
C["select"]=1
C["send"]=1
C["sendmsg"]=1
C["sendto"]=1
C["sigpause"]=1
C["sigsuspend"]=1
C["sigwait"]=1
C["sigwaitinfo"]=1
C["system"]=1
C["tcdrain"]=1
C["wait"]=1
C["waitid"]=1
C["waitpid"]=1
C["write"]=1
C["writev"]=1
C["__xpg_sigpause"]=1
}
/:$/ {
if (seen)
{
# signals.c in linuxthreads does the cancellation checks not using
# *_{enable,disable}_asynccancel.
if ((!seen_enable || !seen_disable) && !(object ~ /^signals.o/))
{
printf "in '$1'(%s) %s'\''s cancellation missing\n", object, seen
ret = 1
}
}
seen=""
seen_enable=""
seen_disable=""
object=gensub(/^.*\[(.*)\]:$/,"\\1","",$0)
next
}
{
if (C[$1] && $2 ~ /^[TW]$/)
seen=$1
else if ($1 ~ /^__(libc|pthread)_enable_asynccancel$/ && $2 == "U")
seen_enable=1
else if ($1 ~ /^__(libc|pthread)_disable_asynccancel$/ && $2 == "U")
seen_disable=1
}
END {
exit ret
}' || exit
shift
done

View File

@ -1,97 +0,0 @@
/* The weak pthread functions for Linux.
Copyright (C) 1996,97,98,99,2000,01,02 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; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <limits.h>
#include <stdlib.h>
#include <shlib-compat.h>
#include <bp-sym.h>
extern int __pthread_return_0 (void);
extern int __pthread_return_1 (void);
extern void __pthread_return_void (void);
extern void weak_function pthread_exit (void *__retval)
__attribute__ ((noreturn));
/* Those are pthread functions which return 0 if successful. */
weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_1))
versioned_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_1),
BP_SYM (pthread_attr_init), GLIBC_2_1);
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
weak_alias (__pthread_return_0, BP_SYM (__libc_pthread_attr_init_2_0))
compat_symbol (libpthread, BP_SYM (__libc_pthread_attr_init_2_0),
BP_SYM (pthread_attr_init), GLIBC_2_0);
#endif
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_destroy))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setdetachstate))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getdetachstate))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedparam))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedparam))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setschedpolicy))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getschedpolicy))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setinheritsched))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getinheritsched))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setscope))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_getscope))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstackaddr))
weak_alias (__pthread_return_0, BP_SYM (pthread_attr_setstacksize))
weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_init))
weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_destroy))
weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_lock))
weak_alias (__pthread_return_0, BP_SYM (pthread_mutex_unlock))
weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_init))
weak_alias (__pthread_return_0, BP_SYM (pthread_condattr_destroy))
weak_alias (__pthread_return_0, BP_SYM (pthread_setschedparam))
weak_alias (__pthread_return_0, BP_SYM (pthread_getschedparam))
weak_alias (__pthread_return_0, BP_SYM (pthread_setcancelstate))
weak_alias (__pthread_return_0, BP_SYM (pthread_setcanceltype))
weak_alias (__pthread_return_0, pthread_self)
weak_alias (__pthread_return_0, BP_SYM (pthread_cond_init))
weak_alias (__pthread_return_0, BP_SYM (pthread_cond_destroy))
weak_alias (__pthread_return_0, BP_SYM (pthread_cond_wait))
weak_alias (__pthread_return_0, BP_SYM (pthread_cond_signal))
weak_alias (__pthread_return_0, BP_SYM (pthread_cond_broadcast))
/* Those are pthread functions which return 1 if successful. */
weak_alias (__pthread_return_1, pthread_equal)
/* pthread_exit () is a special case. */
void
weak_function
pthread_exit (void *retval)
{
exit (EXIT_SUCCESS);
}
int
__pthread_return_0 (void)
{
return 0;
}
int
__pthread_return_1 (void)
{
return 1;
}
void
__pthread_return_void (void)
{
}

View File

@ -1,233 +0,0 @@
/* Wrapper arpund system calls to provide cancelation points.
Copyright (C) 1996-1999,2000-2002 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
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; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <fcntl.h>
#include <sys/mman.h>
#include <pthread.h>
#include <unistd.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdlib.h>
#include <termios.h>
#include <sys/poll.h>
#include <sys/resource.h>
#include <sys/select.h>
#include <sys/uio.h>
#include <sys/wait.h>
#include <sys/socket.h>
#ifndef SHARED
/* We need a hook to force this file to be linked in when static
libpthread is used. */
const int __pthread_provide_wrappers = 0;
#endif
#define CANCELABLE_SYSCALL(res_type, name, param_list, params) \
extern res_type __libc_##name param_list; \
res_type \
name param_list \
{ \
res_type result; \
int oldtype; \
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \
result = __libc_##name params; \
pthread_setcanceltype (oldtype, NULL); \
return result; \
}
#define CANCELABLE_SYSCALL_VA(res_type, name, param_list, params, last_arg) \
res_type __libc_##name param_list; \
res_type \
name param_list \
{ \
res_type result; \
int oldtype; \
va_list ap; \
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype); \
va_start (ap, last_arg); \
result = __libc_##name params; \
va_end (ap); \
pthread_setcanceltype (oldtype, NULL); \
return result; \
}
#define PROMOTE_INTEGRAL_TYPE(type) __typeof__ ((type) 0 + 0)
/* close(2). */
CANCELABLE_SYSCALL (int, close, (int fd), (fd))
strong_alias (close, __close)
/* fcntl(2). */
CANCELABLE_SYSCALL_VA (int, fcntl, (int fd, int cmd, ...),
(fd, cmd, va_arg (ap, long int)), cmd)
strong_alias (fcntl, __fcntl)
/* fsync(2). */
CANCELABLE_SYSCALL (int, fsync, (int fd), (fd))
/* lseek(2). */
CANCELABLE_SYSCALL (off_t, lseek, (int fd, off_t offset, int whence),
(fd, offset, whence))
strong_alias (lseek, __lseek)
/* lseek64(2). */
CANCELABLE_SYSCALL (off64_t, lseek64, (int fd, off64_t offset, int whence),
(fd, offset, whence))
/* msync(2). */
CANCELABLE_SYSCALL (int, msync, (__ptr_t addr, size_t length, int flags),
(addr, length, flags))
/* nanosleep(2). */
CANCELABLE_SYSCALL (int, nanosleep, (const struct timespec *requested_time,
struct timespec *remaining),
(requested_time, remaining))
strong_alias (nanosleep, __nanosleep)
/* open(2). */
CANCELABLE_SYSCALL_VA (int, open, (const char *pathname, int flags, ...),
(pathname, flags,
va_arg (ap, PROMOTE_INTEGRAL_TYPE (mode_t))),
flags)
strong_alias (open, __open)
/* open64(3). */
CANCELABLE_SYSCALL_VA (int, open64, (const char *pathname, int flags, ...),
(pathname, flags,
va_arg (ap, PROMOTE_INTEGRAL_TYPE (mode_t))),
flags)
strong_alias (open64, __open64)
/* pause(2). */
CANCELABLE_SYSCALL (int, pause, (void), ())
/* pread(3). */
CANCELABLE_SYSCALL (ssize_t, pread, (int fd, void *buf, size_t count,
off_t offset),
(fd, buf, count, offset))
/* pread64(3). */
CANCELABLE_SYSCALL (ssize_t, pread64, (int fd, void *buf, size_t count,
off64_t offset),
(fd, buf, count, offset))
strong_alias (pread64, __pread64)
/* pwrite(3). */
CANCELABLE_SYSCALL (ssize_t, pwrite, (int fd, const void *buf, size_t n,
off_t offset),
(fd, buf, n, offset))
/* pwrite64(3). */
CANCELABLE_SYSCALL (ssize_t, pwrite64, (int fd, const void *buf, size_t n,
off64_t offset),
(fd, buf, n, offset))
strong_alias (pwrite64, __pwrite64)
/* read(2). */
CANCELABLE_SYSCALL (ssize_t, read, (int fd, void *buf, size_t count),
(fd, buf, count))
strong_alias (read, __read)
/* system(3). */
CANCELABLE_SYSCALL (int, system, (const char *line), (line))
/* tcdrain(2). */
CANCELABLE_SYSCALL (int, tcdrain, (int fd), (fd))
/* wait(2). */
CANCELABLE_SYSCALL (__pid_t, wait, (__WAIT_STATUS_DEFN stat_loc), (stat_loc))
strong_alias (wait, __wait)
/* waitpid(2). */
CANCELABLE_SYSCALL (__pid_t, waitpid, (__pid_t pid, int *stat_loc,
int options),
(pid, stat_loc, options))
/* write(2). */
CANCELABLE_SYSCALL (ssize_t, write, (int fd, const void *buf, size_t n),
(fd, buf, n))
strong_alias (write, __write)
/* The following system calls are thread cancellation points specified
in XNS. */
/* accept(2). */
CANCELABLE_SYSCALL (int, accept, (int fd, __SOCKADDR_ARG addr,
socklen_t *addr_len),
(fd, addr, addr_len))
/* connect(2). */
CANCELABLE_SYSCALL (int, connect, (int fd, __CONST_SOCKADDR_ARG addr,
socklen_t len),
(fd, addr, len))
strong_alias (connect, __connect)
/* recv(2). */
CANCELABLE_SYSCALL (ssize_t, recv, (int fd, __ptr_t buf, size_t n, int flags),
(fd, buf, n, flags))
/* recvfrom(2). */
CANCELABLE_SYSCALL (ssize_t, recvfrom, (int fd, __ptr_t buf, size_t n, int flags,
__SOCKADDR_ARG addr, socklen_t *addr_len),
(fd, buf, n, flags, addr, addr_len))
/* recvmsg(2). */
CANCELABLE_SYSCALL (ssize_t, recvmsg, (int fd, struct msghdr *message, int flags),
(fd, message, flags))
/* send(2). */
CANCELABLE_SYSCALL (ssize_t, send, (int fd, const __ptr_t buf, size_t n,
int flags),
(fd, buf, n, flags))
strong_alias (send, __send)
/* sendmsg(2). */
CANCELABLE_SYSCALL (ssize_t, sendmsg, (int fd, const struct msghdr *message,
int flags),
(fd, message, flags))
/* sendto(2). */
CANCELABLE_SYSCALL (ssize_t, sendto, (int fd, const __ptr_t buf, size_t n,
int flags, __CONST_SOCKADDR_ARG addr,
socklen_t addr_len),
(fd, buf, n, flags, addr, addr_len))

View File

@ -2,8 +2,8 @@
oldmsgctl EXTRA msgctl 3 __old_msgctl msgctl@GLIBC_2.0
msgget - msgget 2 __msgget msgget
msgrcv - msgrcv 5 __msgrcv msgrcv
msgsnd - msgsnd 4 __msgsnd msgsnd
msgrcv - msgrcv C:5 __msgrcv msgrcv
msgsnd - msgsnd C:4 __msgsnd msgsnd
shmat - osf_shmat 3 __shmat shmat
oldshmctl EXTRA shmctl 3 __old_shmctl shmctl@GLIBC_2.0
shmdt - shmdt 1 __shmdt shmdt

View File

@ -3,8 +3,8 @@
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
msgrcv - msgrcv i:ibnii __msgrcv msgrcv
msgsnd - msgsnd i:ibni __msgsnd msgsnd
msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt

View File

@ -20,7 +20,7 @@
#include <signal.h>
#include <unistd.h>
#include <sysdep.h>
#include <sysdep-cancel.h>
#include <sys/syscall.h>
#include <bp-checks.h>
@ -35,7 +35,16 @@ __sigsuspend (set)
{
/* XXX The size argument hopefully will have to be changed to the
real size of the user-level sigset_t. */
if (SINGLE_THREAD_P)
return INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
int oldtype = LIBC_CANCEL_ASYNC ();
int result = INLINE_SYSCALL (rt_sigsuspend, 2, CHECK_SIGSET (set), _NSIG / 8);
LIBC_CANCEL_RESET (oldtype);
return result;
}
libc_hidden_def (__sigsuspend)
weak_alias (__sigsuspend, sigsuspend)

View File

@ -22,8 +22,8 @@ sendfile - sendfile i:iipi sendfile sendfile64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
msgrcv - msgrcv i:ibnii __msgrcv msgrcv
msgsnd - msgsnd i:ibni __msgsnd msgsnd
msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt

View File

@ -15,8 +15,8 @@ setrlimit - setrlimit 2 __setrlimit setrlimit setrlimit64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
msgrcv - msgrcv i:ibnii __msgrcv msgrcv
msgsnd - msgsnd i:ibni __msgsnd msgsnd
msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt

View File

@ -18,8 +18,8 @@ sendfile - sendfile i:iipi sendfile sendfile64
# semaphore and shm system calls
msgctl - msgctl i:iip __msgctl msgctl
msgget - msgget i:ii __msgget msgget
msgrcv - msgrcv i:ibnii __msgrcv msgrcv
msgsnd - msgsnd i:ibni __msgsnd msgsnd
msgrcv - msgrcv Ci:ibnii __msgrcv msgrcv
msgsnd - msgsnd Ci:ibni __msgsnd msgsnd
shmat - shmat i:ipi __shmat shmat
shmctl - shmctl i:iip __shmctl shmctl
shmdt - shmdt i:s __shmdt shmdt