Implement thread cancellation for aarch64

This commit is contained in:
Justine Tunney 2023-09-07 08:29:16 -07:00
parent dcda6f7d8d
commit 032b1f3449
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
54 changed files with 297 additions and 167 deletions

View file

@ -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) */

View file

@ -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.
*

View file

@ -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) {

View file

@ -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);
}
}

View file

@ -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

View file

@ -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);