cosmopolitan/libc/thread/posixthread.internal.h
Justine Tunney f2af97711b
Make improvements
- Improve compatibility with Blink virtual machine
- Add non-POSIX APIs for joining threads and signal masks
- Never ever use anything except 32-bit integers for atomics
- Add some `#undef` statements to workaround `ctags` problems
2022-11-10 21:52:47 -08:00

104 lines
3.6 KiB
C

#ifndef COSMOPOLITAN_LIBC_THREAD_POSIXTHREAD_INTERNAL_H_
#define COSMOPOLITAN_LIBC_THREAD_POSIXTHREAD_INTERNAL_H_
#include "libc/calls/struct/sched_param.h"
#include "libc/calls/struct/sigset.h"
#include "libc/runtime/runtime.h"
#include "libc/thread/thread.h"
#include "libc/thread/tls.h"
#include "third_party/nsync/dll.h"
#define PT_OWNSTACK 1
#define PT_STATIC 2
#define PT_ASYNC 4
#define PT_NOCANCEL 8
#define PT_MASKED 16
#define PT_INCANCEL 32
#define PT_OPENBSD_KLUDGE 64
#define PT_EXITING 128
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
// LEGAL TRANSITIONS ┌──> TERMINATED ─┐
// pthread_create ─┬─> JOINABLE ─┴┬─> DETACHED ───┴─> ZOMBIE
// └──────────────┘
enum PosixThreadStatus {
// this is a running thread that needs pthread_join()
//
// the following transitions are possible:
//
// - kPosixThreadJoinable -> kPosixThreadTerminated if start_routine()
// returns, or is longjmp'd out of by pthread_exit(), and the thread
// is waiting to be joined.
//
// - kPosixThreadJoinable -> kPosixThreadDetached if pthread_detach()
// is called on this thread.
kPosixThreadJoinable,
// this is a managed thread that'll be cleaned up by the library.
//
// the following transitions are possible:
//
// - kPosixThreadDetached -> kPosixThreadZombie if start_routine()
// returns, or is longjmp'd out of by pthread_exit(), and the thread
// is waiting to be joined.
kPosixThreadDetached,
// this is a joinable thread that terminated.
//
// the following transitions are possible:
//
// - kPosixThreadTerminated -> _pthread_free() will happen when
// pthread_join() is called by the user.
// - kPosixThreadTerminated -> kPosixThreadZombie will happen when
// pthread_detach() is called by the user.
kPosixThreadTerminated,
// this is a detached thread that terminated.
//
// the following transitions are possible:
//
// - kPosixThreadZombie -> _pthread_free() will happen whenever
// convenient, e.g. pthread_create() entry or atexit handler.
kPosixThreadZombie,
};
struct PosixThread {
int flags; // 0x00: see PT_* constants
_Atomic(int) cancelled; // 0x04: thread has bad beliefs
_Atomic(enum PosixThreadStatus) status;
_Atomic(int) ptid; // transitions 0 → tid
void *(*start)(void *); // creation callback
void *arg; // start's parameter
void *rc; // start's return value
char *altstack; // thread sigaltstack
char *tls; // bottom of tls allocation
struct CosmoTib *tib; // middle of tls allocation
nsync_dll_element_ list; // list of threads
jmp_buf exiter; // for pthread_exit
pthread_attr_t attr;
struct _pthread_cleanup_buffer *cleanup;
};
typedef void (*atfork_f)(void);
extern nsync_dll_list_ _pthread_list;
extern pthread_spinlock_t _pthread_lock;
extern _Atomic(pthread_key_dtor) _pthread_key_dtor[PTHREAD_KEYS_MAX] _Hide;
int _pthread_atfork(atfork_f, atfork_f, atfork_f) _Hide;
int _pthread_reschedule(struct PosixThread *) _Hide;
int _pthread_setschedparam_freebsd(int, int, const struct sched_param *) _Hide;
void _pthread_zombify(struct PosixThread *) _Hide;
void _pthread_free(struct PosixThread *) _Hide;
void _pthread_onfork_prepare(void) _Hide;
void _pthread_onfork_parent(void) _Hide;
void _pthread_onfork_child(void) _Hide;
void _pthread_ungarbage(void) _Hide;
int _pthread_cancel_sys(void) _Hide;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_THREAD_POSIXTHREAD_INTERNAL_H_ */