-/* Internal defenitions for pthreads library.
- Copyright (C) 2000-2020 Free Software Foundation, Inc.
+/* Internal definitions for pthreads library.
+ Copyright (C) 2000-2023 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
PTHREAD_DETACHED,
/* A joinable thread exited and its return code is available. */
PTHREAD_EXITED,
- /* The thread structure is unallocated and available for reuse. */
- PTHREAD_TERMINATED
};
#ifndef PTHREAD_KEY_MEMBERS
int cancel_state;
int cancel_type;
int cancel_pending;
- struct __pthread_cancelation_handler *cancelation_handlers;
/* Thread stack. */
void *stackaddr;
enum pthread_state state;
pthread_mutex_t state_lock; /* Locks the state. */
pthread_cond_t state_cond; /* Signalled when the state changes. */
+ bool terminated; /* Whether the kernel thread is over
+ and we can reuse this structure. */
/* Resolver state. */
struct __res_state res_state;
+ /* Indicates whether is a C11 thread created by thrd_creat. */
+ bool c11;
+
+ /* Initial sigset for the thread. */
+ sigset_t init_sigset;
+
/* Thread context. */
struct pthread_mcontext mcontext;
/* The total number of threads currently active. */
extern unsigned int __pthread_total;
-
-/* The total number of thread IDs currently in use, or on the list of
- available thread IDs. */
-extern int __pthread_num_threads;
+libc_hidden_proto (__pthread_total)
/* Concurrency hint. */
extern int __pthread_concurrency;
-/* Array of __pthread structures and its lock. Indexed by the pthread
- id minus one. (Why not just use the pthread id? Because some
- brain-dead users of the pthread interface incorrectly assume that 0
- is an invalid pthread id.) */
-extern struct __pthread **__pthread_threads;
+/* The size of the thread ID lookup table. */
extern int __pthread_max_threads;
-extern pthread_rwlock_t __pthread_threads_lock;
#define __pthread_getid(thread) \
({ struct __pthread *__t = NULL; \
- __pthread_rwlock_rdlock (&__pthread_threads_lock); \
+ __libc_rwlock_rdlock (GL (dl_pthread_threads_lock)); \
if (thread <= __pthread_max_threads) \
- __t = __pthread_threads[thread - 1]; \
- __pthread_rwlock_unlock (&__pthread_threads_lock); \
+ __t = GL (dl_pthread_threads)[thread - 1]; \
+ __libc_rwlock_unlock (GL (dl_pthread_threads_lock)); \
__t; })
#define __pthread_setid(thread, pthread) \
- __pthread_rwlock_wrlock (&__pthread_threads_lock); \
- __pthread_threads[thread - 1] = pthread; \
- __pthread_rwlock_unlock (&__pthread_threads_lock);
+ __libc_rwlock_wrlock (GL (dl_pthread_threads_lock)); \
+ GL (dl_pthread_threads)[thread - 1] = pthread; \
+ __libc_rwlock_unlock (GL (dl_pthread_threads_lock));
/* Similar to pthread_self, but returns the thread descriptor instead
of the thread ID. */
#ifndef _pthread_self
extern struct __pthread *_pthread_self (void);
#endif
+
+/* Stores the stack of cleanup handlers for the thread. */
+extern __thread struct __pthread_cancelation_handler *__pthread_cleanup_stack;
\f
/* Initialize the pthreads library. */
kernel thread or a stack). THREAD has one reference. */
extern int __pthread_alloc (struct __pthread **thread);
-/* Deallocate the thread structure. This is the dual of
+/* Deallocate the content of the thread structure. This is the dual of
__pthread_alloc (N.B. it does not call __pthread_stack_dealloc nor
- __pthread_thread_terminate). THREAD loses one reference and is
- released if the reference counter drops to 0. */
+ __pthread_thread_terminate). THREAD loses one reference, and if
+ if the reference counter drops to 0 this returns 1, and the caller has
+ to call __pthread_dealloc_finish when it is really finished with using
+ THREAD. */
extern void __pthread_dealloc (struct __pthread *thread);
+/* Confirm deallocating the thread structure. Before calling this
+ the structure will not be reused yet. */
+extern void __pthread_dealloc_finish (struct __pthread *pthread);
+
/* Allocate a stack of size STACKSIZE. The stack base shall be
returned in *STACKADDR. */
const struct timespec *__restrict abstime,
clockid_t clock_id);
+/* Block THREAD with interrupts. */
+extern error_t __pthread_block_intr (struct __pthread *thread);
+
+/* Block THREAD until *ABSTIME is reached, with interrupts. */
+extern error_t __pthread_timedblock_intr (struct __pthread *__restrict thread,
+ const struct timespec *__restrict abstime,
+ clockid_t clock_id);
+
/* Wakeup THREAD. */
extern void __pthread_wakeup (struct __pthread *thread);
const sigset_t *__restrict set,
sigset_t *__restrict oset,
int clear_pending);
+
+/* If supported, check that MUTEX is locked by the caller. */
+extern int __pthread_mutex_checklocked (pthread_mutex_t *mtx);
\f
/* Default thread attributes. */
-extern const struct __pthread_attr __pthread_default_attr;
+extern struct __pthread_attr __pthread_default_attr;
/* Default barrier attributes. */
extern const struct __pthread_barrierattr __pthread_default_barrierattr;
-/* Default mutex attributes. */
-extern const struct __pthread_mutexattr __pthread_default_mutexattr;
-
/* Default rdlock attributes. */
extern const struct __pthread_rwlockattr __pthread_default_rwlockattr;
/* Default condition attributes. */
extern const struct __pthread_condattr __pthread_default_condattr;
+/* Semaphore encoding.
+ See nptl implementation for the details. */
+struct new_sem
+{
+#if __HAVE_64B_ATOMICS
+ /* The data field holds both value (in the least-significant 32 bits) and
+ nwaiters. */
+# if __BYTE_ORDER == __LITTLE_ENDIAN
+# define SEM_VALUE_OFFSET 0
+# elif __BYTE_ORDER == __BIG_ENDIAN
+# define SEM_VALUE_OFFSET 1
+# else
+# error Unsupported byte order.
+# endif
+# define SEM_NWAITERS_SHIFT 32
+# define SEM_VALUE_MASK (~(unsigned int)0)
+ uint64_t data;
+ int pshared;
+#define __SEMAPHORE_INITIALIZER(value, pshared) \
+ { (value), (pshared) }
+#else
+# define SEM_VALUE_SHIFT 1
+# define SEM_NWAITERS_MASK ((unsigned int)1)
+ unsigned int value;
+ unsigned int nwaiters;
+ int pshared;
+#define __SEMAPHORE_INITIALIZER(value, pshared) \
+ { (value) << SEM_VALUE_SHIFT, 0, (pshared) }
+#endif
+};
+
+extern int __sem_waitfast (struct new_sem *isem, int definitive_result);
+
#endif /* pt-internal.h */