⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pthread.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 3 页
字号:
/* 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 */#define __FORCE_GLIBC#include <features.h>#define __USE_GNU#include <errno.h>#include <netdb.h>	/* for h_errno */#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 "pthread.h"#include "internals.h"#include "spinlock.h"#include "restart.h"#include "debug.h"      /* added to linuxthreads -StS *//* Mods for uClibc: Some includes */#include <signal.h>#include <sys/types.h>#include <sys/syscall.h>/* mods for uClibc: getpwd and getpagesize are the syscalls */#define __getpid getpid#define __getpagesize getpagesize/* mods for uClibc: __libc_sigaction is not in any standard headers */extern int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact);/* These variables are used by the setup code.  */extern int _errno;extern int _h_errno;/* Descriptor of the initial thread */struct _pthread_descr_struct __pthread_initial_thread = {  &__pthread_initial_thread,  /* pthread_descr p_nextlive */  &__pthread_initial_thread,  /* pthread_descr p_prevlive */  NULL,                       /* pthread_descr p_nextwaiting */  NULL,			      /* pthread_descr p_nextlock */  PTHREAD_THREADS_MAX,        /* pthread_t p_tid */  0,                          /* int p_pid */  0,                          /* int p_priority */  &__pthread_handles[0].h_lock, /* struct _pthread_fastlock * p_lock */  0,                          /* int p_signal */  NULL,                       /* sigjmp_buf * p_signal_buf */  NULL,                       /* sigjmp_buf * p_cancel_buf */  0,                          /* char p_terminated */  0,                          /* char p_detached */  0,                          /* char p_exited */  NULL,                       /* void * p_retval */  0,                          /* int p_retval */  NULL,                       /* pthread_descr p_joining */  NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */  0,                          /* char p_cancelstate */  0,                          /* char p_canceltype */  0,                          /* char p_canceled */  &_errno,                       /* int *p_errnop */  0,                          /* int p_errno */  &_h_errno,                       /* int *p_h_errnop */  0,                          /* int p_h_errno */  NULL,                       /* char * p_in_sighandler */  0,                          /* char p_sigwaiting */  PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */  {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */  {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */  0,                          /* int p_userstack */  NULL,                       /* void * p_guardaddr */  0,                          /* size_t p_guardsize */  &__pthread_initial_thread,  /* pthread_descr p_self */  0,                          /* Always index 0 */  0,                          /* int p_report_events */  {{{0, }}, 0, NULL},         /* td_eventbuf_t p_eventbuf */  __ATOMIC_INITIALIZER,         /* struct pthread_atomic p_resume_count */  0,                          /* char p_woken_by_cancel */  0,                          /* char p_condvar_avail */  0,                          /* char p_sem_avail */  NULL,                       /* struct pthread_extricate_if *p_extricate */  NULL,	                      /* pthread_readlock_info *p_readlock_list; */  NULL,                       /* pthread_readlock_info *p_readlock_free; */  0                           /* int p_untracked_readlock_count; */#ifdef __UCLIBC_HAS_XLOCALE__  ,  &__global_locale_data,      /* __locale_t locale; */#endif /* __UCLIBC_HAS_XLOCALE__ */};/* 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 = {  NULL,                       /* pthread_descr p_nextlive */  NULL,                       /* pthread_descr p_prevlive */  NULL,                       /* pthread_descr p_nextwaiting */  NULL,			      /* pthread_descr p_nextlock */  0,                          /* int p_tid */  0,                          /* int p_pid */  0,                          /* int p_priority */  &__pthread_handles[1].h_lock, /* struct _pthread_fastlock * p_lock */  0,                          /* int p_signal */  NULL,                       /* sigjmp_buf * p_signal_buf */  NULL,                       /* sigjmp_buf * p_cancel_buf */  0,                          /* char p_terminated */  0,                          /* char p_detached */  0,                          /* char p_exited */  NULL,                       /* void * p_retval */  0,                          /* int p_retval */  NULL,                       /* pthread_descr p_joining */  NULL,                       /* struct _pthread_cleanup_buffer * p_cleanup */  0,                          /* char p_cancelstate */  0,                          /* char p_canceltype */  0,                          /* char p_canceled */  &__pthread_manager_thread.p_errno, /* int *p_errnop */  0,                          /* int p_errno */  NULL,                       /* int *p_h_errnop */  0,                          /* int p_h_errno */  NULL,                       /* char * p_in_sighandler */  0,                          /* char p_sigwaiting */  PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */  {NULL},                     /* void ** p_specific[PTHREAD_KEY_1STLEVEL_SIZE] */  {NULL},                     /* void * p_libc_specific[_LIBC_TSD_KEY_N] */  0,                          /* int p_userstack */  NULL,                       /* void * p_guardaddr */  0,                          /* size_t p_guardsize */  &__pthread_manager_thread,  /* pthread_descr p_self */  1,                          /* Always index 1 */  0,                          /* int p_report_events */  {{{0, }}, 0, NULL},         /* td_eventbuf_t p_eventbuf */  __ATOMIC_INITIALIZER,         /* struct pthread_atomic p_resume_count */  0,                          /* char p_woken_by_cancel */  0,                          /* char p_condvar_avail */  0,                          /* char p_sem_avail */  NULL,                       /* struct pthread_extricate_if *p_extricate */  NULL,	                      /* pthread_readlock_info *p_readlock_list; */  NULL,                       /* pthread_readlock_info *p_readlock_free; */  0                           /* int p_untracked_readlock_count; */#ifdef __UCLIBC_HAS_XLOCALE__  ,  &__global_locale_data,      /* __locale_t locale; */#endif /* __UCLIBC_HAS_XLOCALE__ */};/* Pointer to the main thread (the father of the thread manager thread) *//* Originally, this is the initial thread, but this changes after fork() */pthread_descr __pthread_main_thread = &__pthread_initial_thread;/* 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 = NULL;/* For non-MMU systems also remember to stack top of the initial thread. * This is adapted when other stacks are malloc'ed since we don't know * the bounds a-priori. -StS */#ifndef __ARCH_HAS_MMU__char *__pthread_initial_thread_tos = NULL;#endif /* __ARCH_HAS_MMU__ *//* File descriptor for sending requests to the thread manager. *//* Initially -1, meaning that the thread manager is not running. */int __pthread_manager_request = -1;/* 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 = NULL;char *__pthread_manager_thread_tos = NULL;/* For process-wide exit() */int __pthread_exit_requested = 0;int __pthread_exit_code = 0;/* 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);static void pthread_handle_sigcancel(int sig);static void pthread_handle_sigrestart(int sig);static void pthread_handle_sigdebug(int sig);int __pthread_timedsuspend_new(pthread_descr self, const struct timespec *abstime);/* 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.  */#ifndef __NR_rt_sigactionstatic int current_rtmin = -1;static int current_rtmax = -1;int __pthread_sig_restart = SIGUSR1;int __pthread_sig_cancel = SIGUSR2;int __pthread_sig_debug;#else#if __SIGRTMAX - __SIGRTMIN >= 3static int current_rtmin = __SIGRTMIN + 3;static int current_rtmax = __SIGRTMAX;int __pthread_sig_restart = __SIGRTMIN;int __pthread_sig_cancel = __SIGRTMIN + 1;int __pthread_sig_debug = __SIGRTMIN + 2;void (*__pthread_restart)(pthread_descr) = __pthread_restart_new;void (*__pthread_suspend)(pthread_descr) = __pthread_wait_for_restart_signal;int (*__pthread_timedsuspend)(pthread_descr, const struct timespec *) = __pthread_timedsuspend_new;#elsestatic int current_rtmin = __SIGRTMIN;static int current_rtmax = __SIGRTMAX;int __pthread_sig_restart = SIGUSR1;int __pthread_sig_cancel = SIGUSR2;int __pthread_sig_debug;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/* Return number of available real-time signal with highest priority.  */int __libc_current_sigrtmin (void){    return current_rtmin;}/* Return number of available real-time signal with lowest priority.  */int __libc_current_sigrtmax (void){    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){    if (current_rtmin == -1 || current_rtmin > current_rtmax)	/* 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:   - 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)); /* Do some minimal initialization which has to be done during the    startup of the C library.  */void __pthread_initialize_minimal(void){    /* If we have special thread_self processing, initialize      * that for the main thread now.  */#ifdef INIT_THREAD_SELF    INIT_THREAD_SELF(&__pthread_initial_thread, 0);#endif}static void pthread_initialize(void){  struct sigaction sa;  sigset_t mask;  struct rlimit limit;  int max_stack;  /* If already done (e.g. by a constructor called earlier!), bail out */  if (__pthread_initial_thread_bos != NULL) return;#ifdef TEST_FOR_COMPARE_AND_SWAP  /* Test if compare-and-swap is available */  __pthread_has_cas = compare_and_swap_is_available();#endif  /* For the initial stack, reserve at least STACK_SIZE bytes of stack     below the current stack address, and align that on a     STACK_SIZE boundary. */  __pthread_initial_thread_bos =    (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));  /* Update the descriptor for the initial thread. */  __pthread_initial_thread.p_pid = __getpid();  /* If we have special thread_self processing, initialize that for the     main thread now.  */#ifdef INIT_THREAD_SELF  INIT_THREAD_SELF(&__pthread_initial_thread, 0);#endif  /* The errno/h_errno variable of the main thread are the global ones.  */  __pthread_initial_thread.p_errnop = &_errno;  __pthread_initial_thread.p_h_errnop = &_h_errno;#ifdef __UCLIBC_HAS_XLOCALE__  /* The locale of the main thread is the current locale in use. */  __pthread_initial_thread.locale = __curlocale_var;#endif /* __UCLIBC_HAS_XLOCALE__ */ {			   /* uClibc-specific stdio initialization for threads. */	 FILE *fp;	 	 _stdio_user_locking = 0;	/* 2 if threading not initialized */	 for (fp = _stdio_openlist; fp != NULL; fp = fp->__nextopen) {		 if (fp->__user_locking != 1) {			 fp->__user_locking = 0;		 }	 } }  /* Play with the stack size limit to make sure that no stack ever grows     beyond STACK_SIZE minus two pages (one page for the thread descriptor

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -