mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 08:18:30 +00:00
Implement thread cancellation for aarch64
This commit is contained in:
parent
dcda6f7d8d
commit
032b1f3449
54 changed files with 297 additions and 167 deletions
|
@ -97,8 +97,8 @@ void _pthread_free(struct PosixThread *);
|
|||
void _pthread_onfork_prepare(void);
|
||||
void _pthread_onfork_parent(void);
|
||||
void _pthread_onfork_child(void);
|
||||
long _pthread_cancel_sys(void);
|
||||
void _pthread_ungarbage(void);
|
||||
int _pthread_cancel_sys(void);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -21,11 +21,13 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/calls/struct/ucontext.internal.h"
|
||||
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
|
@ -34,14 +36,13 @@
|
|||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
int systemfive_cancel(void);
|
||||
|
||||
extern const char systemfive_cancellable[];
|
||||
extern const char systemfive_cancellable_end[];
|
||||
|
||||
int _pthread_cancel_sys(void) {
|
||||
long _pthread_cancel_sys(void) {
|
||||
struct PosixThread *pt;
|
||||
pt = (struct PosixThread *)__get_tls()->tib_pthread;
|
||||
if (!(pt->flags & (PT_NOCANCEL | PT_MASKED)) || (pt->flags & PT_ASYNC)) {
|
||||
|
@ -60,9 +61,9 @@ static void OnSigThr(int sig, siginfo_t *si, void *ctx) {
|
|||
!(pt->flags & PT_NOCANCEL) &&
|
||||
atomic_load_explicit(&pt->cancelled, memory_order_acquire)) {
|
||||
sigaddset(&uc->uc_sigmask, sig);
|
||||
if (systemfive_cancellable <= (char *)uc->uc_mcontext.rip &&
|
||||
(char *)uc->uc_mcontext.rip < systemfive_cancellable_end) {
|
||||
uc->uc_mcontext.rip = (intptr_t)systemfive_cancel;
|
||||
if (systemfive_cancellable <= (char *)uc->uc_mcontext.PC &&
|
||||
(char *)uc->uc_mcontext.PC < systemfive_cancellable_end) {
|
||||
uc->uc_mcontext.PC = (intptr_t)systemfive_cancel;
|
||||
} else if (pt->flags & PT_ASYNC) {
|
||||
pthread_exit(PTHREAD_CANCELED);
|
||||
} else {
|
||||
|
@ -302,8 +303,6 @@ errno_t pthread_cancel(pthread_t thread) {
|
|||
return rc;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
/**
|
||||
* Creates cancellation point in calling thread.
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/calls/blocksigs.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaltstack.h"
|
||||
|
@ -28,6 +29,7 @@
|
|||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/intrin/popcnt.h"
|
||||
#include "libc/log/internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
@ -58,6 +60,7 @@ static unsigned long roundup2pow(unsigned long x) {
|
|||
}
|
||||
|
||||
void _pthread_free(struct PosixThread *pt) {
|
||||
static atomic_uint freed;
|
||||
if (pt->flags & PT_STATIC) return;
|
||||
free(pt->tls);
|
||||
if ((pt->flags & PT_OWNSTACK) && //
|
||||
|
@ -69,6 +72,9 @@ void _pthread_free(struct PosixThread *pt) {
|
|||
free(pt->altstack);
|
||||
}
|
||||
free(pt);
|
||||
if (popcnt(atomic_fetch_add_explicit(&freed, 1, memory_order_acq_rel)) == 1) {
|
||||
malloc_trim(0);
|
||||
}
|
||||
}
|
||||
|
||||
void pthread_kill_siblings_np(void) {
|
||||
|
|
|
@ -16,19 +16,18 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/atomic.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/intrin/dll.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/thread/tls.h"
|
||||
#include "third_party/dlmalloc/dlmalloc.h"
|
||||
|
||||
/**
|
||||
* Releases memory of detached threads that have terminated.
|
||||
*/
|
||||
void pthread_decimate_np(void) {
|
||||
bool empty;
|
||||
struct Dll *e;
|
||||
struct PosixThread *pt;
|
||||
enum PosixThreadStatus status;
|
||||
|
@ -46,9 +45,5 @@ StartOver:
|
|||
goto StartOver;
|
||||
}
|
||||
}
|
||||
empty = dll_is_empty(_pthread_list);
|
||||
pthread_spin_unlock(&_pthread_lock);
|
||||
if (empty) {
|
||||
dlmalloc_trim(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ LIBC_THREAD_A_DIRECTDEPS = \
|
|||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_NSYNC \
|
||||
THIRD_PARTY_NSYNC_MEM
|
||||
|
||||
|
|
|
@ -44,9 +44,15 @@ extern unsigned __tls_index;
|
|||
#ifdef __x86_64__
|
||||
extern bool __tls_enabled;
|
||||
#define __tls_enabled_set(x) __tls_enabled = x
|
||||
#else
|
||||
#define __tls_enabled true
|
||||
#elif defined(__aarch64__)
|
||||
#define __tls_enabled \
|
||||
({ \
|
||||
register struct CosmoTib *_t asm("x28"); \
|
||||
!!_t; \
|
||||
})
|
||||
#define __tls_enabled_set(x) (void)0
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
|
||||
void __require_tls(void);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue