/* Linuxthreads - a simple clone()-based implementation of Posix */
/* threads for Linux. */
/* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
/* */
/* This program is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Library General Public License */
/* as published by the Free Software Foundation; either version 2 */
/* of the License, or (at your option) any later version. */
/* */
/* This program 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 Library General Public License for more details. */
/* Thread creation, initialization, and basic low-level routines */
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/time.h>
#include <shlib-compat.h>
#include "pthread.h"
#include "internals.h"
#include "spinlock.h"
#include "restart.h"
#include "smp.h"
#include <ldsodefs.h>
#include <tls.h>
#include <version.h>
/* Sanity check. */
#if !defined __SIGRTMIN || (__SIGRTMAX - __SIGRTMIN) < 3
# error "This must not happen"
#endif
#if !(USE_TLS && HAVE___THREAD)
/* These variables are used by the setup code. */
extern int _errno;
extern int _h_errno;
/* We need the global/static resolver state here. */
# include <resolv.h>
# undef _res
extern struct __res_state _res;
#endif
#ifdef USE_TLS
/* We need only a few variables. */
static pthread_descr manager_thread;
#else
/* Descriptor of the initial thread */
struct _pthread_descr_struct __pthread_initial_thread = {
.p_header.data.self = &__pthread_initial_thread,
.p_nextlive = &__pthread_initial_thread,
.p_prevlive = &__pthread_initial_thread,
.p_tid = PTHREAD_THREADS_MAX,
.p_lock = &__pthread_handles[0].h_lock,
.p_start_args = PTHREAD_START_ARGS_INITIALIZER(NULL),
#if !(USE_TLS && HAVE___THREAD)
.p_errnop = &_errno,
.p_h_errnop = &_h_errno,
.p_resp = &_res,
#endif
.p_userstack = 1,
.p_resume_count = __ATOMIC_INITIALIZER,
.p_alloca_cutoff = __MAX_ALLOCA_CUTOFF
};
/* Descriptor of the manager thread; none of this is used but the error
variables, the p_pid and p_priority fields,
and the address for identification. */
#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)
.p_errnop = &__pthread_manager_thread.p_errno,
#endif
.p_nr = 1,
.p_resume_count = __ATOMIC_INITIALIZER,
.p_alloca_cutoff = PTHREAD_STACK_MIN / 4
};
#endif
/* Pointer to the main thread (the father of the thread manager thread) */
/* Originally, this is the initial thread, but this changes after fork() */
#ifdef USE_TLS
pthread_descr __pthread_main_thread;
#else
pthread_descr __pthread_main_thread = &__pthread_initial_thread;
#endif
/* Limit between the stack of the initial thread (above) and the
stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
char *__pthread_initial_thread_bos;
/* File descriptor for sending requests to the thread manager. */
/* Initially -1, meaning that the thread manager is not running. */
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;
/* Limits of the thread manager stack */
char *__pthread_manager_thread_bos;
char *__pthread_manager_thread_tos;
/* For process-wide exit() */
int __pthread_exit_requested;
int __pthread_exit_code;
/* Maximum stack size. */
size_t __pthread_max_stacksize;
/* Nozero if the machine has more than one processor. */
int __pthread_smp_kernel;
#if !__ASSUME_REALTIME_SIGNALS
/* Pointers that select new or old suspend/resume functions
based on availability of rt signals. */
void (*__pthread_restart)(pthread_descr) = __pthread_restart_old;
void (*__pthread_suspend)(pthread_descr) = __pthread_suspend_old;
int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_old;
#endif /* __ASSUME_REALTIME_SIGNALS */
/* Communicate relevant LinuxThreads constants to gdb */
const int __pthread_threads_max = PTHREAD_THREADS_MAX;
const int __pthread_sizeof_handle = sizeof(struct pthread_handle_struct);
const int __pthread_offsetof_descr = offsetof(struct pthread_handle_struct,
h_descr);
const int __pthread_offsetof_pid = offsetof(struct _pthread_descr_struct,
p_pid);
const int __linuxthreads_pthread_sizeof_descr
= sizeof(struct _pthread_descr_struct);
const int __linuxthreads_initial_report_events;
const char __linuxthreads_version[] = VERSION;
/* Forward declarations */
static void pthread_onexit_process(int retcode, void *arg);
#ifndef HAVE_Z_NODELETE
static void pthread_atexit_process(void *arg, int retcode);
static void pthread_atexit_retcode(void *arg, int retcode);
#endif
static void pthread_handle_sigcancel(int sig);
static void pthread_handle_sigrestart(int sig);
static void pthread_handle_sigdebug(int sig);
/* Signal numbers used for the communication.
In these variables we keep track of the used variables. If the
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. */
int __pthread_sig_restart = __SIGRTMIN;
int __pthread_sig_cancel = __SIGRTMIN + 1;
int __pthread_sig_debug = __SIGRTMIN + 2;
extern int __libc_current_sigrtmin_private (void);
#if !__ASSUME_REALTIME_SIGNALS
static int rtsigs_initialized;
static void
init_rtsigs (void)
{
if (rtsigs_initialized)
return;
if (__libc_current_sigrtmin_private () == -1)
{
__pthread_sig_restart = SIGUSR1;
__pthread_sig_cancel = SIGUSR2;
__pthread_sig_debug = 0;
}
else
{
__pthread_restart = __pthread_restart_new;
__pthread_suspend = __pthread_wait_for_restart_signal;
__pthread_timedsuspend = __pthread_timedsuspend_new;
}
rtsigs_initialized = 1;
}
#endif
/* Initialize the pthread library.
Initialization is split in two functions:
- a constructor function that blocks the __pthread_sig_restart signal
(must do this very early, since the program could capture the signal
mask with e.g. sigsetjmp before creating the first thread);
- a regular function called from pthread_create when needed. */
static void pthread_initialize(void) __attribute__((constructor));
#ifndef HAVE_Z_NODELETE
extern void *__dso_handle __attribute__ ((weak));
#endif
#if defined USE_TLS && !defined SHARED
extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
#endif
struct pthread_functions __pthread_functions =
{
#if !(USE_TLS && HAVE___THREAD)
.ptr_pthread_internal_tsd_set = __pthread_internal_tsd_set,
.ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get,
.ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address,
#endif
.ptr_pthread_fork = __pthread_fork,
.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 = __p
没有合适的资源?快使用搜索试试~ 我知道了~
glibc-linuxthreads-2.3.2.tar.gz
5星 · 超过95%的资源 需积分: 10 234 下载量 65 浏览量
2008-10-29
16:26:34
上传
评论 1
收藏 279KB GZ 举报
温馨提示
共315个文件
c:158个
h:70个
man:21个
glibc-linuxthreads-2.3.2.tar.gz
资源推荐
资源详情
资源评论
收起资源包目录
glibc-linuxthreads-2.3.2.tar.gz (315个子文件)
README.Xfree3.2 9KB
Banner 51B
Banner 34B
pthread.c 42KB
manager.c 36KB
spinlock.c 21KB
rwlock.c 16KB
timer_routines.c 16KB
mutex.c 11KB
condvar.c 10KB
attr.c 10KB
tst-cancel4.c 10KB
semaphore.c 8KB
cancel.c 8KB
oldsemaphore.c 7KB
join.c 7KB
specific.c 7KB
signals.c 6KB
forward.c 6KB
td_ta_thr_iter.c 5KB
td_ta_new.c 5KB
timer_create.c 5KB
ex3.c 4KB
td_ta_event_getmsg.c 4KB
tst-cancel.c 4KB
pt-initfini.c 4KB
pt-initfini.c 4KB
ecmutex.c 4KB
pt-initfini.c 4KB
timer_settime.c 4KB
ex11.c 4KB
pt-initfini.c 3KB
pt-initfini.c 3KB
barrier.c 3KB
ex13.c 3KB
pt-initfini.c 3KB
tst-cancel1.c 3KB
pt-initfini.c 3KB
pspinlock.c 3KB
ex4.c 3KB
tst-timer.c 3KB
pspinlock.c 3KB
pspinlock.c 3KB
ex2.c 3KB
ex14.c 3KB
td_thr_tsd.c 3KB
td_ta_map_lwp2thr.c 3KB
td_thr_get_info.c 3KB
ex10.c 3KB
pspinlock.c 3KB
sighandler.c 3KB
ex9.c 3KB
pspinlock.c 3KB
register-atfork.c 3KB
pspinlock.c 3KB
pspinlock.c 3KB
ptfork.c 2KB
allocrtsig.c 2KB
ex17.c 2KB
td_ta_map_id2thr.c 2KB
ex5.c 2KB
sigwait.c 2KB
td_thr_validate.c 2KB
pspinlock.c 2KB
pspinlock.c 2KB
td_thr_tls_get_addr.c 2KB
execve.c 2KB
tst-context.c 2KB
ptlongjmp.c 2KB
tst-cancel2.c 2KB
ex8.c 2KB
timer_delete.c 2KB
td_symbol_list.c 2KB
td_thr_event_getmsg.c 2KB
pspinlock.c 2KB
pspinlock.c 2KB
pspinlock.c 2KB
ex18.c 2KB
lockfile.c 2KB
pspinlock.c 2KB
pspinlock.c 2KB
tst-cancel3.c 2KB
td_thr_set_event.c 2KB
td_thr_clear_event.c 2KB
libc-cancellation.c 2KB
pspinlock.c 2KB
td_ta_tsd_iter.c 2KB
timer_gettime.c 2KB
td_thr_getgregs.c 2KB
tst-signal.c 2KB
tststack.c 2KB
td_ta_event_addr.c 2KB
tst-cancel6.c 2KB
td_thr_getfpregs.c 2KB
td_ta_clear_event.c 2KB
td_ta_set_event.c 2KB
td_thr_event_enable.c 2KB
unregister-atfork.c 2KB
td_ta_delete.c 2KB
pthread_atfork.c 2KB
共 315 条
- 1
- 2
- 3
- 4
morre
- 粉丝: 187
- 资源: 2337
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页