From b2ff2641d6d3acb0cdad7d2756e9d023566630f5 Mon Sep 17 00:00:00 2001 From: Georgii Date: Wed, 21 May 2025 21:46:07 +0300 Subject: [PATCH] Add musl_mutex from musl POSIX-library. --- Makefile | 10 +- Makefile.config | 53 +- ci-build.sh | 18 + include/muslmutex.h | 122 +++ src/Makefile | 4 +- src/empty.c | 9 + src/interpose.c | 4 +- src/interpose.h | 2 +- src/interpose.map | 5 + src/mcstp.c | 6 +- src/musl_mutex/Makefile | 48 ++ src/musl_mutex/__syscall_cp.c | 18 + src/musl_mutex/__syscall_cp.o | Bin 0 -> 1744 bytes src/musl_mutex/__timedwait.c | 84 ++ src/musl_mutex/__timedwait.o | Bin 0 -> 2552 bytes src/musl_mutex/__wait.c | 17 + src/musl_mutex/__wait.o | Bin 0 -> 1912 bytes src/musl_mutex/alltypes_make.h | 142 ++++ src/musl_mutex/atomic.h | 100 +++ src/musl_mutex/atomic_archx86_64.h | 72 ++ src/musl_mutex/clock_gettime.c | 112 +++ src/musl_mutex/clock_gettime.o | Bin 0 -> 2592 bytes src/musl_mutex/errno.h | 134 ++++ src/musl_mutex/features.h | 40 + src/musl_mutex/futex.h | 19 + src/musl_mutex/libc.h | 60 ++ src/musl_mutex/libmusl_mutex.a | Bin 0 -> 37854 bytes src/musl_mutex/limits.h | 165 ++++ src/musl_mutex/metrics_handlers.o | Bin 0 -> 4312 bytes src/musl_mutex/mman.h | 8 + src/musl_mutex/pthread_cond_broadcast.c | 10 + src/musl_mutex/pthread_cond_broadcast.o | Bin 0 -> 952 bytes src/musl_mutex/pthread_cond_destroy.c | 14 + src/musl_mutex/pthread_cond_destroy.o | Bin 0 -> 944 bytes src/musl_mutex/pthread_cond_init.c | 12 + src/musl_mutex/pthread_cond_init.o | Bin 0 -> 944 bytes src/musl_mutex/pthread_cond_signal.c | 11 + src/musl_mutex/pthread_cond_signal.o | Bin 0 -> 944 bytes src/musl_mutex/pthread_cond_timedwait.c | 214 ++++++ src/musl_mutex/pthread_cond_timedwait.o | Bin 0 -> 952 bytes src/musl_mutex/pthread_cond_wait.c | 7 + src/musl_mutex/pthread_cond_wait.o | Bin 0 -> 944 bytes src/musl_mutex/pthread_condattr_destroy.c | 6 + src/musl_mutex/pthread_condattr_init.c | 7 + src/musl_mutex/pthread_condattr_setclock.c | 9 + src/musl_mutex/pthread_condattr_setpshared.c | 9 + src/musl_mutex/pthread_impl.h | 93 +++ src/musl_mutex/pthread_musl.h | 86 +++ src/musl_mutex/pthread_mutex_init.c | 14 + src/musl_mutex/pthread_mutex_init.o | Bin 0 -> 1576 bytes src/musl_mutex/pthread_mutex_lock.c | 14 + src/musl_mutex/pthread_mutex_lock.o | Bin 0 -> 1608 bytes src/musl_mutex/pthread_mutex_timedlock.c | 100 +++ src/musl_mutex/pthread_mutex_timedlock.o | Bin 0 -> 3672 bytes src/musl_mutex/pthread_mutex_trylock.c | 102 +++ src/musl_mutex/pthread_mutex_trylock.o | Bin 0 -> 2288 bytes src/musl_mutex/pthread_mutex_unlock.c | 62 ++ src/musl_mutex/pthread_mutex_unlock.o | Bin 0 -> 2656 bytes src/musl_mutex/pthread_self_glibc.c | 7 + src/musl_mutex/pthread_self_glibc.h | 2 + src/musl_mutex/pthread_self_glibc.o | Bin 0 -> 1384 bytes src/musl_mutex/pthread_setcancelstate_glibc.c | 7 + src/musl_mutex/pthread_setcancelstate_glibc.h | 3 + src/musl_mutex/pthread_setcancelstate_glibc.o | Bin 0 -> 1440 bytes src/musl_mutex/stdint.h | 117 +++ src/musl_mutex/stdintx86_64.h | 20 + src/musl_mutex/syscall.h | 410 ++++++++++ src/musl_mutex/syscall_archx86_64.h | 70 ++ src/musl_mutex/syscall_make.h | 727 ++++++++++++++++++ src/musl_mutex/syscall_ret.c | 13 + src/musl_mutex/syscall_ret.o | Bin 0 -> 1264 bytes src/musl_mutex/test_build.sh | 23 + src/musl_mutex/time.h | 10 + src/musl_mutex/vdso.c | 93 +++ src/musl_mutex/vdso.o | Bin 0 -> 2760 bytes src/musl_mutex/vmlock.c | 23 + src/musl_mutex/vmlock.o | Bin 0 -> 2712 bytes src/muslmutex.c | 353 +++++++++ src/ticketepfl.c | 2 +- src/utils.h | 2 + test/Makefile | 15 + test/mutex_test_args.h | 6 + test/read_args.c | 47 ++ test/test_program.c | 36 + 84 files changed, 3973 insertions(+), 35 deletions(-) create mode 100755 ci-build.sh create mode 100644 include/muslmutex.h create mode 100644 src/musl_mutex/Makefile create mode 100644 src/musl_mutex/__syscall_cp.c create mode 100644 src/musl_mutex/__syscall_cp.o create mode 100644 src/musl_mutex/__timedwait.c create mode 100644 src/musl_mutex/__timedwait.o create mode 100644 src/musl_mutex/__wait.c create mode 100644 src/musl_mutex/__wait.o create mode 100644 src/musl_mutex/alltypes_make.h create mode 100644 src/musl_mutex/atomic.h create mode 100644 src/musl_mutex/atomic_archx86_64.h create mode 100644 src/musl_mutex/clock_gettime.c create mode 100644 src/musl_mutex/clock_gettime.o create mode 100644 src/musl_mutex/errno.h create mode 100644 src/musl_mutex/features.h create mode 100644 src/musl_mutex/futex.h create mode 100644 src/musl_mutex/libc.h create mode 100644 src/musl_mutex/libmusl_mutex.a create mode 100644 src/musl_mutex/limits.h create mode 100644 src/musl_mutex/metrics_handlers.o create mode 100644 src/musl_mutex/mman.h create mode 100644 src/musl_mutex/pthread_cond_broadcast.c create mode 100644 src/musl_mutex/pthread_cond_broadcast.o create mode 100644 src/musl_mutex/pthread_cond_destroy.c create mode 100644 src/musl_mutex/pthread_cond_destroy.o create mode 100644 src/musl_mutex/pthread_cond_init.c create mode 100644 src/musl_mutex/pthread_cond_init.o create mode 100644 src/musl_mutex/pthread_cond_signal.c create mode 100644 src/musl_mutex/pthread_cond_signal.o create mode 100644 src/musl_mutex/pthread_cond_timedwait.c create mode 100644 src/musl_mutex/pthread_cond_timedwait.o create mode 100644 src/musl_mutex/pthread_cond_wait.c create mode 100644 src/musl_mutex/pthread_cond_wait.o create mode 100644 src/musl_mutex/pthread_condattr_destroy.c create mode 100644 src/musl_mutex/pthread_condattr_init.c create mode 100644 src/musl_mutex/pthread_condattr_setclock.c create mode 100644 src/musl_mutex/pthread_condattr_setpshared.c create mode 100644 src/musl_mutex/pthread_impl.h create mode 100644 src/musl_mutex/pthread_musl.h create mode 100644 src/musl_mutex/pthread_mutex_init.c create mode 100644 src/musl_mutex/pthread_mutex_init.o create mode 100644 src/musl_mutex/pthread_mutex_lock.c create mode 100644 src/musl_mutex/pthread_mutex_lock.o create mode 100644 src/musl_mutex/pthread_mutex_timedlock.c create mode 100644 src/musl_mutex/pthread_mutex_timedlock.o create mode 100644 src/musl_mutex/pthread_mutex_trylock.c create mode 100644 src/musl_mutex/pthread_mutex_trylock.o create mode 100644 src/musl_mutex/pthread_mutex_unlock.c create mode 100644 src/musl_mutex/pthread_mutex_unlock.o create mode 100644 src/musl_mutex/pthread_self_glibc.c create mode 100644 src/musl_mutex/pthread_self_glibc.h create mode 100644 src/musl_mutex/pthread_self_glibc.o create mode 100644 src/musl_mutex/pthread_setcancelstate_glibc.c create mode 100644 src/musl_mutex/pthread_setcancelstate_glibc.h create mode 100644 src/musl_mutex/pthread_setcancelstate_glibc.o create mode 100644 src/musl_mutex/stdint.h create mode 100644 src/musl_mutex/stdintx86_64.h create mode 100644 src/musl_mutex/syscall.h create mode 100644 src/musl_mutex/syscall_archx86_64.h create mode 100644 src/musl_mutex/syscall_make.h create mode 100644 src/musl_mutex/syscall_ret.c create mode 100644 src/musl_mutex/syscall_ret.o create mode 100644 src/musl_mutex/test_build.sh create mode 100644 src/musl_mutex/time.h create mode 100644 src/musl_mutex/vdso.c create mode 100644 src/musl_mutex/vdso.o create mode 100644 src/musl_mutex/vmlock.c create mode 100644 src/musl_mutex/vmlock.o create mode 100644 src/muslmutex.c create mode 100644 test/Makefile create mode 100644 test/mutex_test_args.h create mode 100644 test/read_args.c create mode 100644 test/test_program.c diff --git a/Makefile b/Makefile index badb0de..c09dac9 100644 --- a/Makefile +++ b/Makefile @@ -16,12 +16,17 @@ export COND_VAR=1 .SECONDARY: $(OBJS) .PHONY: all clean format +all: +ifeq ($(BUILD_MUSL), 1) +all: musl_mutex $(DIR) include/topology.h $(SOS) $(SHS) +else all: $(DIR) include/topology.h $(SOS) $(SHS) +endif no_cond_var: COND_VAR=0 no_cond_var: all -%.so: obj/CLHT/libclht.a obj/ +%.so: musl_mutex obj/CLHT/libclht.a obj/ mkdir -p lib/ $(MAKE) -C src/ ../lib/$@ @@ -31,6 +36,9 @@ obj/: $(DIR): mkdir -p $@ +musl_mutex: + $(MAKE) -C src/musl_mutex + obj/CLHT: cd obj/ && ([ -d CLHT ] || git clone https://github.com/HugoGuiroux/CLHT.git) mkdir -p obj/CLHT/external/lib/ diff --git a/Makefile.config b/Makefile.config index fb4c970..dcb4da4 100644 --- a/Makefile.config +++ b/Makefile.config @@ -2,33 +2,34 @@ # A = algorithm name, lowercase, without space (must match the src/*.c and src/*.h name) # S = waiting strategy. original = hardcoded in the algorithm (see README), otherwise spinlock/spin_then_park/park -ALGORITHMS=mcs_spinlock \ -mcsepfl_original \ -mcs_spin_then_park \ -mcstp_original \ +ALGORITHMS=muslmutex_original \ spinlock_original \ -spinlockepfl_original \ -malthusian_spinlock \ -malthusian_spin_then_park \ -ttas_original \ -ttasepfl_original \ -ticket_original \ -ticketepfl_original \ -clh_spinlock \ -clh_spin_then_park \ -clhepfl_original \ -backoff_original \ empty_original \ +hmcs_original \ +mcs_spinlock \ pthreadinterpose_original \ pthreadadaptive_original \ -concurrency_original \ -htlockepfl_original \ -alockepfl_original \ -hmcs_original \ -hyshmcs_original \ -cbomcs_spinlock \ -cbomcs_spin_then_park \ -cptltkt_original \ -ctkttkt_original \ -partitioned_original \ -mutexee_original +#mcsepfl_original \ +#mcs_spin_then_park \ +#mcstp_original \ +#spinlockepfl_original \ +#malthusian_spinlock \ +#malthusian_spin_then_park \ +#ttas_original \ +#ttasepfl_original \ +#ticket_original \ +#ticketepfl_original \ +#clh_spinlock \ +#clh_spin_then_park \ +#clhepfl_original \ +#backoff_original \ +#concurrency_original \ +#htlockepfl_original \ +#alockepfl_original \ +#hyshmcs_original \ +#cbomcs_spinlock \ +#cbomcs_spin_then_park \ +#cptltkt_original \ +#ctkttkt_original \ +#partitioned_original \ +#mutexee_original diff --git a/ci-build.sh b/ci-build.sh new file mode 100755 index 0000000..91c2b98 --- /dev/null +++ b/ci-build.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +set -eux + +#Discard all uncommited changes +git checkout -f + +#Build LiTL +nproc="$(nproc)" +make BUILD_MUSL=1 no_cond_var -j "$nproc" + +#Delete source files, keep only .so libraries and .sh scripts for use those libraries +if [ "${1:-}" = "delete_sources" ]; then + find . -mindepth 1 ! -path "./.git/*" ! -name ".git" ! -name ".gitignore" ! -name ".clang-format" \ + ! -path "./lib/*" ! -name "lib" \ + ! -name "*.sh" \ + -exec rm -rf {} + +fi diff --git a/include/muslmutex.h b/include/muslmutex.h new file mode 100644 index 0000000..b5f30ad --- /dev/null +++ b/include/muslmutex.h @@ -0,0 +1,122 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016 Hugo Guiroux + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of his software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef __MUSL_MUTEX_H__ +#define __MUSL_MUTEX_H__ + +#define LOCK_ALGORITHM "MUSL" +#define NEED_CONTEXT 0 +#define SUPPORT_WAITING 0 + +// Define needed types before including alltypes_make.h +// #define __NEED_pthread_cond_t +// #define __NEED_pthread_condattr_t + +#include "../src/musl_mutex/alltypes_make.h" +#include "padding.h" // for glibc pthread_cond_t + +// typedef struct musl_mutex { +// // #if COND_VAR +// // pthread_mutex_t posix_lock; +// // char __pad[pad_to_cache_line(sizeof(pthread_mutex_t))]; +// // #endif +// __pthread_mutex_t lock; +// } musl_mutex_t __attribute__((aligned(L_CACHE_LINE_SIZE))); + +typedef __pthread_mutex_t musl_mutex_t; +typedef __pthread_cond_t musl_cond_t; +// typedef void *musl_context_t; // Unused, take the less space + // as possible +typedef void *musl_context_t; +typedef musl_mutex_t lock_mutex_t; +typedef musl_context_t lock_context_t; +typedef musl_cond_t lock_cond_t; + +// + +// typedef __pthread_mutex_t musl_mutex_t; +// typedef __pthread_mutexattr_t musl_mutexattr_t; + +// typedef pthread_mutex_t musl_mutex_t; +// typedef pthread_cond_t musl_cond_t; +// typedef void *musl_context_t; + +// typedef musl_mutex_t lock_mutex_t; +// typedef musl_context_t lock_context_t; + +// typedef void *musl_context_t; // Unused, take the less space as possible +// typedef void *lock_context_t; // Required for interpose.c + +//Decls +musl_mutex_t *musl_mutex_create(const __pthread_mutexattr_t *attr); +int musl_mutex_destroy(musl_mutex_t *lock); + + +// int musl_cond_init(musl_cond_t *cond, const pthread_condattr_t *attr); +// int __pthread_musl_cond_init(musl_cond_t *restrict c, const pthread_condattr_t *restrict a); +// // int musl_cond_timedwait(musl_cond_t *cond, musl_mutex_t *lock, +// // musl_context_t *me, const struct timespec *ts); +// int __pthread_musl_cond_timedwait(musl_cond_t *restrict c, musl_mutex_t *restrict m, musl_context_t *restrict me, const struct timespec *restrict ts); +// // int musl_cond_wait(musl_cond_t *cond, musl_mutex_t *lock, musl_context_t *me); +// int __pthread_musl_cond_wait(musl_cond_t *restrict c, musl_mutex_t *restrict m, musl_context_t *restrict me); + +// // int musl_cond_signal(musl_cond_t *cond); +// int __pthread_musl_cond_signal(musl_cond_t *cond); +// // int musl_cond_broadcast(musl_cond_t *cond); +// int __pthread_musl_cond_broadcast(musl_cond_t *cond); +// // int musl_cond_destroy(musl_cond_t *cond); +// int __pthread_musl_cond_destroy(musl_cond_t *c); + +void musl_thread_start(void); +void musl_thread_exit(void); +void musl_application_init(void); +void musl_application_exit(void); +//unused + + +//Defines +// From musl_mutex/pthread_musl.h +#define lock_mutex_lock __pthread_musl_mutex_lock +#define lock_mutex_trylock __pthread_musl_mutex_trylock +#define lock_mutex_unlock __pthread_musl_mutex_unlock +// #define musl_mutex_init __pthread_mutex_init + +// From here +#define lock_mutex_create musl_mutex_create +#define lock_mutex_destroy musl_mutex_destroy + +//Unused +#define lock_cond_init __pthread_musl_cond_init +#define lock_cond_timedwait __pthread_musl_cond_timedwait +#define lock_cond_wait __pthread_musl_cond_wait +#define lock_cond_signal __pthread_musl_cond_signal +#define lock_cond_broadcast __pthread_musl_cond_broadcast +#define lock_cond_destroy __pthread_musl_cond_destroy +#define lock_thread_start musl_thread_start +#define lock_thread_exit musl_thread_exit +#define lock_application_init musl_application_init +#define lock_application_exit musl_application_exit +#define lock_init_context musl_init_context +//unused + +#endif // __MUSL_MUTEX_H__ diff --git a/src/Makefile b/src/Makefile index 4ab46cb..2f4afd4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ include ../Makefile.config LDFLAGS=-L../obj/CLHT/external/lib -L../obj/CLHT -Wl,--whole-archive -Wl,--version-script=interpose.map -lsspfd -lssmem -lclht -Wl,--no-whole-archive -lrt -lm -ldl -lpapi -m64 -pthread -CFLAGS=-I../include/ -I../obj/CLHT/include/ -I../obj/CLHT/external/include/ -fPIC -Wall -Werror -O3 -g +CFLAGS=-I../include/ -I../obj/CLHT/include/ -I../obj/CLHT/external/include/ -fPIC -Wall -O3 -g -Wno-flexible-array-member-not-at-end # Keep objects files .PRECIOUS: %.o @@ -19,4 +19,4 @@ CFLAGS=-I../include/ -I../obj/CLHT/include/ -I../obj/CLHT/external/include/ -fPI .SECONDEXPANSION: ../lib/lib%.so: ../obj/%/interpose.o ../obj/%/utils.o $$(subst algo,%,../obj/algo/algo.o) - $(CC) -shared -o $@ $^ $(LDFLAGS) + $(CC) -shared -o $@ $^ -L ./musl_mutex -lmusl_mutex $(LDFLAGS) diff --git a/src/empty.c b/src/empty.c index bd93620..f19331c 100644 --- a/src/empty.c +++ b/src/empty.c @@ -49,39 +49,48 @@ int empty_mutex_lock(empty_mutex_t *impl, empty_context_t *UNUSED(me)) { } int empty_mutex_trylock(empty_mutex_t *impl, empty_context_t *UNUSED(me)) { + // fprintf(stderr, "empty_mutex_trylock\n"); return REAL(pthread_mutex_trylock)(impl); } void empty_mutex_unlock(empty_mutex_t *impl, empty_context_t *UNUSED(me)) { + // fprintf(stderr, "empty_mutex_unlock\n"); REAL(pthread_mutex_unlock)(impl); } int empty_mutex_destroy(empty_mutex_t *lock) { + // fprintf(stderr, "empty_mutex_destroy\n"); return REAL(pthread_mutex_destroy)(lock); } int empty_cond_init(empty_cond_t *cond, const pthread_condattr_t *attr) { + // fprintf(stderr, "empty_cond_init\n"); return REAL(pthread_cond_init)(cond, attr); } int empty_cond_timedwait(empty_cond_t *cond, empty_mutex_t *lock, empty_context_t *me, const struct timespec *ts) { + // fprintf(stderr, "empty_cond_timedwait\n"); return REAL(pthread_cond_timedwait)(cond, lock, ts); } int empty_cond_wait(empty_cond_t *cond, empty_mutex_t *lock, empty_context_t *UNUSED(me)) { + // fprintf(stderr, "empty_cond_wait\n"); return REAL(pthread_cond_wait)(cond, lock); } int empty_cond_signal(empty_cond_t *cond) { + // fprintf(stderr, "empty_cond_signal\n"); return REAL(pthread_cond_signal)(cond); } int empty_cond_broadcast(empty_cond_t *cond) { + // fprintf(stderr, "empty_cond_broadcast\n"); return REAL(pthread_cond_broadcast)(cond); } int empty_cond_destroy(empty_cond_t *cond) { + // fprintf(stderr, "empty_cond_destroy\n"); return REAL(pthread_cond_destroy)(cond); } diff --git a/src/interpose.c b/src/interpose.c index 1e65e77..77a4b3d 100644 --- a/src/interpose.c +++ b/src/interpose.c @@ -87,6 +87,8 @@ #include #elif defined(MUTEXEE) #include +#elif defined(MUSLMUTEX) +#include #else #error "No lock algorithm known" #endif @@ -697,4 +699,4 @@ int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) { #else assert(0 && "rwlock not supported without indirection"); #endif -} +} \ No newline at end of file diff --git a/src/interpose.h b/src/interpose.h index 08eb99c..ecb5426 100644 --- a/src/interpose.h +++ b/src/interpose.h @@ -97,4 +97,4 @@ extern int (*REAL(pthread_rwlock_trywrlock))(pthread_rwlock_t *lock); extern int (*REAL(pthread_rwlock_unlock))(pthread_rwlock_t *lock); // rdwr locks -#endif // __INTERPOSE_H__ +#endif // __INTERPOSE_H__ \ No newline at end of file diff --git a/src/interpose.map b/src/interpose.map index 9a75060..e6160ef 100644 --- a/src/interpose.map +++ b/src/interpose.map @@ -35,3 +35,8 @@ GLIBC_2.3.2 { pthread_cond_wait; pthread_cond_timedwait; } GLIBC_2.2.5; + +GLIBC_2.39 { + global: + pthread_create; +} GLIBC_2.3.2; diff --git a/src/mcstp.c b/src/mcstp.c index 7d4fbbf..3cf3dd3 100644 --- a/src/mcstp.c +++ b/src/mcstp.c @@ -39,7 +39,7 @@ * is preempted. * Indeed, a thread A can overtake another thread B behind which it has been * waiting for a long time. - * The waiting thread A will first yield its CPU (via pthread_yield) in order to + * The waiting thread A will first yield its CPU (via sched_yield) in order to * create an opportunity for the preempted thread (lock holder or B) to make * progress. * If this is not enough, T will overtake the predecessor thread (B) by marking @@ -144,7 +144,7 @@ int mcs_tp_mutex_trylock(mcs_tp_mutex_t *impl, mcs_tp_node_t *me) { goto success; } else if (me->status == FAILED) { if (GET_TIME() - impl->cs_start_time > MAX_CS_TIME) - pthread_yield(); + sched_yield(); me->last_lock = impl; return EBUSY; @@ -164,7 +164,7 @@ int mcs_tp_mutex_trylock(mcs_tp_mutex_t *impl, mcs_tp_node_t *me) { } if (GET_TIME() - impl->cs_start_time > MAX_CS_TIME) - pthread_yield(); + sched_yield(); me->last_lock = impl; return EBUSY; diff --git a/src/musl_mutex/Makefile b/src/musl_mutex/Makefile new file mode 100644 index 0000000..7eeb480 --- /dev/null +++ b/src/musl_mutex/Makefile @@ -0,0 +1,48 @@ +# Compiler and flags +CC = musl-gcc +CFLAGS = -Wall -Wextra -fPIC -I. -D__NEED_struct_timespec + +# Source files +SRCS = pthread_mutex_lock.c \ + pthread_mutex_timedlock.c \ + pthread_mutex_trylock.c \ + pthread_mutex_unlock.c \ + pthread_mutex_init.c \ + pthread_self_glibc.c \ + pthread_setcancelstate_glibc.c \ + pthread_cond_wait.c \ + pthread_cond_timedwait.c \ + pthread_cond_signal.c \ + pthread_cond_broadcast.c \ + pthread_cond_destroy.c \ + pthread_cond_init.c \ + __timedwait.c \ + __wait.c \ + vmlock.c \ + __syscall_cp.c \ + clock_gettime.c \ + syscall_ret.c \ + # vdso.c \ + +# Object files +OBJS = $(SRCS:.c=.o) + +# Output library +TARGET = libmusl_mutex.a + +# Default target +all: $(TARGET) + +# Link shared library +$(TARGET): $(OBJS) + ar rcs $@ $^ + +# Compile sources +%.o: %.c + $(CC) $(CFLAGS) -c $< -o $@ + +# Clean up +clean: + rm -f $(OBJS) $(TARGET) + +.PHONY: all clean diff --git a/src/musl_mutex/__syscall_cp.c b/src/musl_mutex/__syscall_cp.c new file mode 100644 index 0000000..1976180 --- /dev/null +++ b/src/musl_mutex/__syscall_cp.c @@ -0,0 +1,18 @@ +#include "pthread_impl.h" +#include "syscall.h" + +long __syscall_cp_c(); +long __syscall_cp_c(syscall_arg_t nr, + syscall_arg_t u, syscall_arg_t v, syscall_arg_t w, + syscall_arg_t x, syscall_arg_t y, syscall_arg_t z) +{ + return __syscall(nr, u, v, w, x, y, z); +} + +weak_alias(sccp, __syscall_cp_c); +long (__syscall_cp)(syscall_arg_t nr, + syscall_arg_t u, syscall_arg_t v, syscall_arg_t w, + syscall_arg_t x, syscall_arg_t y, syscall_arg_t z) +{ + return __syscall_cp_c(nr, u, v, w, x, y, z); +} diff --git a/src/musl_mutex/__syscall_cp.o b/src/musl_mutex/__syscall_cp.o new file mode 100644 index 0000000000000000000000000000000000000000..8b18f52399ce3c7ab7b5b1a9c996916c82b8ffbf GIT binary patch literal 1744 zcmbtS&ubGw6n=^QrM5PT2caT4iHaT4A5 zru4Io@j>aOT0mPXd%wo7{Z=|V#|db)p!EY<(99e{s|l?JbQ<7;n}G&uK6=1zyRnS- z>5&K0m!nF%-IhC_M-EOUDR+)XPRR1-LN<1=M~e#!^YI(myjynM_|%M;5sAq;SEbW$ zr)NcC_NIo_8xak_$FK&m7MHUWC8{%Kp7Szdw#b{u6xoPHCPs%xb}@jfz<9Ae;O+i} z*!$?h*w8i_kaF!VIq#C&XoN?Gw-n#YWjsRmJ#kc!QU3` z!_{4ZO<-LDZgO=;V7D~>5uQ!mje}gSwplA!#bU0oE(*PLt{0+`>#HCo`pR6`fL?#_ z3$Vo*gyFr_QVF)C4h(MYw;I6B{Yca{OOBO?cd8w~W}>QHw1i`CI3!+JjzuD0tC1*F zN+r7ttXy$yftgR%9INnJ=da4HSg%&r?W(g$LMhm5xtCR|Wa}H8&c#9JDGdc=k~;q$ zz=IRzx$#>j1ATRVFxZujqjT`g<$saQ;MWl|ZvJnsv5DY89a#11P`TUKS@VDSQ{eJZ z39NoI=d*slnQIw8kD`hD`<{h?A-zk$hOzW>btP6cKi)+;fq6dz=MivgkpE8eH%z1U zLH-Kxu=zE$pwv8`A9D@g%rES0rnL0=yPUwzWAQmb{#jtb*#V*t`usbb^qH3JA{P;b O@#7jSb~`&kkpCBg$>oy( literal 0 HcmV?d00001 diff --git a/src/musl_mutex/__timedwait.c b/src/musl_mutex/__timedwait.c new file mode 100644 index 0000000..ca1d9b2 --- /dev/null +++ b/src/musl_mutex/__timedwait.c @@ -0,0 +1,84 @@ +#include "pthread_musl.h" +#include "errno.h" +#include "futex.h" +#include "syscall.h" +#include "pthread_impl.h" +#include + +#include "pthread_setcancelstate_glibc.h" // pthread_setcancelstate +#include + +#define IS32BIT(x) !((x)+0x80000000ULL>>32) +#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) + +static int __futex4_cp(volatile void *addr, int op, int val, const struct timespec *to) +{ + // fprintf(stderr, "Error __futex4_cp.\n"); + int r; +#ifdef SYS_futex_time64 + time_t s = to ? to->tv_sec : 0; + long ns = to ? to->tv_nsec : 0; + r = -ENOSYS; + if (SYS_futex == SYS_futex_time64 || !IS32BIT(s)) + r = __syscall_cp(SYS_futex_time64, addr, op, val, + to ? ((long long[]){s, ns}) : 0); + if (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r; + to = to ? (void *)(long[]){CLAMP(s), ns} : 0; +#endif + // fprintf(stderr, "Error __futex4_cp 1.\n"); + r = __syscall_cp(SYS_futex, addr, op, val, to); + // fprintf(stderr, "Error __futex4_cp 2.\n"); + if (r != -ENOSYS) return r; + // fprintf(stderr, "Error __futex4_cp 3.\n"); + return __syscall_cp(SYS_futex, addr, op & ~FUTEX_PRIVATE, val, to); +} + +static volatile int __eintr_valid_flag = 0; + +int __timedwait_cp(volatile int *addr, int val, + clockid_t clk, const struct timespec *at, int priv) +{ + // fprintf(stderr, "Error __timedwait_cp.\n"); + int r; + struct timespec to, *top=0; + + if (priv) priv = FUTEX_PRIVATE; + + if (at) { + if (at->tv_nsec >= 1000000000UL) return EINVAL; + if (clock_gettime(clk, &to)) return EINVAL; + // clock_gettime(clk, &to); + to.tv_sec = at->tv_sec - to.tv_sec; + if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) { + to.tv_sec--; + to.tv_nsec += 1000000000; + } + if (to.tv_sec < 0) return ETIMEDOUT; + top = &to; + } + // fprintf(stderr, "Error __timedwait_cp 1.\n"); + r = -__futex4_cp(addr, FUTEX_WAIT|priv, val, top); + // fprintf(stderr, "Error __timedwait_cp 2.\n"); + if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0; + /* Mitigate bug in old kernels wrongly reporting EINTR for non- + * interrupting (SA_RESTART) signal handlers. This is only practical + * when NO interrupting signal handlers have been installed, and + * works by sigaction tracking whether that's the case. */ + if (r == EINTR && !__eintr_valid_flag) r = 0; + // fprintf(stderr, "Error __timedwait_cp return.\n"); + return r; +} + + +int __timedwait(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv) +{ + // fprintf(stderr, "Error __timedwait.\n"); + int cs, r; + pthread_setcancelstate_glibc(PTHREAD_CANCEL_DISABLE, &cs); + // fprintf(stderr, "Error __timedwait 1.\n"); + r = __timedwait_cp(addr, val, clk, at, priv); + // fprintf(stderr, "Error __timedwait 2.\n"); + pthread_setcancelstate_glibc(cs, 0); + // fprintf(stderr, "Error __timedwait return.\n"); + return r; +} diff --git a/src/musl_mutex/__timedwait.o b/src/musl_mutex/__timedwait.o new file mode 100644 index 0000000000000000000000000000000000000000..43c1e545a01b65040b130ac2ba1e4e452a0cf6b6 GIT binary patch literal 2552 zcmb_dUuYaf7@xf)O{|T%Y7wz2_n?wuyCiKW*r;5Ila7C?rEubdW!>A`YWFoi4ip<=-x!SnlOXOhiwfj;=b?0nzv z`+eWceBbQu75e&g!Z3&ygS`j3%4U4T7p1pZo(X~3T9F9&or$3*`#qqtx|x5gW6owjiKT6LB1 z!F9U&F}iBiIvM%oOH>7|Gm#!*FLtkAo4kCm{wRRAZ=z=<(-su+{t~R$!48kH+~A7y zHF9Kh5~emg_5;JxNaVs0%$*SGNOiff^thzeItJ_vc^x)DZd{uL3n^^|l)-utvfg=% zt$-a+DDwH1$gBx}6&M>VSntgJ+wK0{3TU%dZT9m=;92Cu@T}tDnz&7L_=m*+>dOsZ z!-6)M$ZX}(~*7{Nf>y_ zb8lowf{+GceK1gtgcC77xJZn}q;d4n;Lugr^b>&NK=}e6^r7UZiK*cO2?31I_X6S| zZ{i`fzi-+=0>-|BPLO4MXn*2E8IMpe!BqX^&u%YYU(YuZ&w?k~DdN& zB77Zb0*-Zx%On5~Lxhf(X9et47`^y!?}Haqp5O6+AhISf`!IUtA(q7p^KR~ayTDBc ztQnuXixZYp0^KbXdD*&bdxe}eh( z*`jZj$_pj8%$JBMGq`zcrffqm{|`w)5-fS-w1S?_9$=oK4DMNJ4mRE z;s*yr{!?H+2m@pB4xl_1PUKmb5!c@%1(UC0>uNl{{&8?%&i&%``>o^S_Bc2&=a?p_ zS+9@zqoUW>^BHhzJ<4m|=l=0Kg7-E~Zz&)ZO$xfMpN6xb;QI0SEd?xUqMGCJmjLh8 zKYbyXio^b4td7_H>$Nt9lvG1fsyO%#;vI{}<2xAd9YEx&YSiawL?mA8!{F-`&(wwX KBC)8(7%14rQ^iY=9&!-_^-!rukm5SCd9PWQc+r7*GxN>N`^kHo$MVp1 zzt0Ckd~g+Nk)QzS#+n~-+z7P6K2VtXnVFd~GgBpIDn(`vuMe5>+K{EJF-tBpD^p@t zs>m#5JM!8*=q%E2rBzbhZO0emafWuVJyMsce|T#Z`G{0(X_o z6u~&TDi;?p*gQrXu;7xs5m;P8u#5`jCEK+C5k;T?&-hO8`X1;s-o@V|2%eGmz@+lQ|3jZki@P-!NEiF*# zVxA^(HfOx5E*L=KEcgQpHhsCm3JeYmTn>em@l?V{h0gU#y;67Ag_INaJnHF_y8BLZ zOe>JkH3d=(AUw{(wf5yKaQM~HSWUwovZDW5t^YaCZ;_Sx`u;D~0-p04daI4_&GvGN z8|u8|y~zD8?wl3bVa`SDoB>$}=ObuI1n)$j=Al81*3XI6)NWEaXI^_tj}b zilL*=>oIj^rVrHUbRvf1ghr!2H=W>R03qr@!TWR632=yTM{u#=z_`K5nSvXpLmmP6^M@(gsKqs-c23uInJhX5(=!fh;j=Xc9iRF5OUL_jo*+NJ(?a z**Ps~%!8EFW>iU=ir!7Cag8tjABOIQ?!MVGM})^?lyr$Fgig#66W@g>ec>(S2`@f{ zoW6^H?LULPG-o%eTg3X5cZ*nG*z=eazPqka57w!bk+q=GJ95i9?+>{l`gB&ejA1~f z-u^A#zw9nX-`jr+8T~IsP~Gy3|Db6O>ARwRivFXV*IS!Xula`ZypF#2di^x7_wJ}= cio>%MxP%{Tm$ai-uRlnKLYb_Z-O=0s8(a((QUCw| literal 0 HcmV?d00001 diff --git a/src/musl_mutex/alltypes_make.h b/src/musl_mutex/alltypes_make.h new file mode 100644 index 0000000..6a268db --- /dev/null +++ b/src/musl_mutex/alltypes_make.h @@ -0,0 +1,142 @@ +#pragma once + +#define _Addr long +#define _Int64 long +#define _Reg long + +#define __BYTE_ORDER 1234 +#define __LONG_MAX 0x7fffffffffffffffL + + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __USE_TIME_BITS64 1 + +//#if defined(__NEED_size_t) && !defined(__DEFINED_size_t) +typedef unsigned _Addr size_t; +//#define __DEFINED_size_t +//#endif + +//#if defined(__NEED_uintptr_t) && !defined(__DEFINED_uintptr_t) +typedef unsigned _Addr uintptr_t; +//#define __DEFINED_uintptr_t +//#endif + +//#if defined(__NEED_intptr_t) && !defined(__DEFINED_intptr_t) +typedef _Addr intptr_t; +//#define __DEFINED_intptr_t +//#endif + +//#if defined(__NEED_time_t) && !defined(__DEFINED_time_t) +typedef _Int64 time_t; +//#define __DEFINED_time_t +//#endif + + +//#if defined(__NEED_int8_t) && !defined(__DEFINED_int8_t) +typedef signed char int8_t; +//#define __DEFINED_int8_t +//#endif + +//#if defined(__NEED_int16_t) && !defined(__DEFINED_int16_t) +typedef signed short int16_t; +//#define __DEFINED_int16_t +//#endif + +//#if defined(__NEED_int32_t) && !defined(__DEFINED_int32_t) +typedef signed int int32_t; +//#define __DEFINED_int32_t +//#endif + +//#if defined(__NEED_int64_t) && !defined(__DEFINED_int64_t) +typedef signed _Int64 int64_t; +//#define __DEFINED_int64_t +//#endif + +//#if defined(__NEED_intmax_t) && !defined(__DEFINED_intmax_t) +typedef signed _Int64 intmax_t; +//#define __DEFINED_intmax_t +//#endif + +//#if defined(__NEED_uint8_t) && !defined(__DEFINED_uint8_t) +typedef unsigned char uint8_t; +//#define __DEFINED_uint8_t +//#endif + +//#if defined(__NEED_uint16_t) && !defined(__DEFINED_uint16_t) +typedef unsigned short uint16_t; +//#define __DEFINED_uint16_t +//#endif + +//#if defined(__NEED_uint32_t) && !defined(__DEFINED_uint32_t) +typedef unsigned int uint32_t; +//#define __DEFINED_uint32_t +//#endif + +//#if defined(__NEED_uint64_t) && !defined(__DEFINED_uint64_t) +typedef unsigned _Int64 uint64_t; +//#define __DEFINED_uint64_t +//#endif + +//#if defined(__NEED_uintmax_t) && !defined(__DEFINED_uintmax_t) +typedef unsigned _Int64 uintmax_t; +//#define __DEFINED_uintmax_t +//#endif + +#if defined(__NEED_wctype_t) && !defined(__DEFINED_wctype_t) +typedef unsigned long wctype_t; +#define __DEFINED_wctype_t +#endif + + +#//if defined(__NEED_clockid_t) && !defined(__DEFINED_clockid_t) +typedef int clockid_t; +#define __DEFINED_clockid_t +//#endif + +#if defined(__NEED_struct_timespec) && !defined(__DEFINED_struct_timespec) +struct timespec { time_t tv_sec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER==4321); long tv_nsec; int :8*(sizeof(time_t)-sizeof(long))*(__BYTE_ORDER!=4321); }; +#define __DEFINED_struct_timespec +#endif + +#ifdef __cplusplus +#if defined(__NEED_pthread_t) && !defined(__DEFINED_pthread_t) +typedef unsigned long pthread_t; +#define __DEFINED_pthread_t +#endif + +#endif + +//#if defined(__NEED_pthread_mutexattr_t) && !defined(__DEFINED_pthread_mutexattr_t) +typedef struct { unsigned __attr; } __pthread_mutexattr_t; +#define __DEFINED_pthread_mutexattr_t +//#endif + +#if defined(__NEED_locale_t) && !defined(__DEFINED_locale_t) +typedef struct __locale_struct * locale_t; +#define __DEFINED_locale_t +#endif + +#if defined(__NEED_pthread_attr_t) && !defined(__DEFINED_pthread_attr_t) +typedef struct { union { int __i[sizeof(long)==8?14:9]; volatile int __vi[sizeof(long)==8?14:9]; unsigned long __s[sizeof(long)==8?7:9]; } __u; } pthread_attr_t; +#define __DEFINED_pthread_attr_t +#endif + +//#if defined(__NEED_pthread_mutex_t) && !defined(__DEFINED_pthread_mutex_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } __pthread_mutex_t; +#define __DEFINED_pthread_mutex_t +//#endif + +typedef struct { union { int __i[12]; volatile int __vi[12]; void *__p[12*sizeof(int)/sizeof(void*)]; } __u; } __pthread_cond_t; + +typedef struct { unsigned __attr; } __pthread_condattr_t; + +#if defined(__NEED_mtx_t) && !defined(__DEFINED_mtx_t) +typedef struct { union { int __i[sizeof(long)==8?10:6]; volatile int __vi[sizeof(long)==8?10:6]; volatile void *volatile __p[sizeof(long)==8?5:6]; } __u; } mtx_t; +#define __DEFINED_mtx_t +#endif + + +#undef _Addr +#undef _Int64 +#undef _Reg diff --git a/src/musl_mutex/atomic.h b/src/musl_mutex/atomic.h new file mode 100644 index 0000000..62642d8 --- /dev/null +++ b/src/musl_mutex/atomic.h @@ -0,0 +1,100 @@ +#ifndef _ATOMIC_H +#define _ATOMIC_H + +#include "stdint.h" +#include "atomic_archx86_64.h" + +#ifndef a_pre_llsc +#define a_pre_llsc() +#endif + +#ifndef a_post_llsc +#define a_post_llsc() +#endif + +#ifndef a_cas +#define a_cas a_cas +static inline int a_cas(volatile int *p, int t, int s) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (old==t && !a_sc(p, s)); + a_post_llsc(); + return old; +} +#endif + +#ifndef a_swap +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + int old; + a_pre_llsc(); + do old = a_ll(p); + while (!a_sc(p, v)); + a_post_llsc(); + return old; +} +#endif + +#endif + + +#ifndef a_cas +#error missing definition of a_cas +#endif + +#ifndef a_swap +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + int old; + do old = *p; + while (a_cas(p, old, v) != old); + return old; +} +#endif + +#ifndef a_inc +#define a_inc a_inc +static inline void a_inc(volatile int *p) +{ + a_fetch_add(p, 1); +} +#endif + +#ifndef a_dec +#define a_dec a_dec +static inline void a_dec(volatile int *p) +{ + a_fetch_add(p, -1); +} +#endif + +#ifndef a_store +#define a_store a_store +static inline void a_store(volatile int *p, int v) +{ +#ifdef a_barrier + a_barrier(); + *p = v; + a_barrier(); +#else + a_swap(p, v); +#endif +} +#endif + +#ifndef a_barrier +#define a_barrier a_barrier +static void a_barrier() +{ + volatile int tmp = 0; + a_cas(&tmp, 0, 0); +} +#endif + +#ifndef a_spin +#define a_spin a_barrier +#endif \ No newline at end of file diff --git a/src/musl_mutex/atomic_archx86_64.h b/src/musl_mutex/atomic_archx86_64.h new file mode 100644 index 0000000..423684b --- /dev/null +++ b/src/musl_mutex/atomic_archx86_64.h @@ -0,0 +1,72 @@ +#define a_cas a_cas +static inline int a_cas(volatile int *p, int t, int s) +{ + __asm__ __volatile__ ( + "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*p) : "a"(t), "r"(s) : "memory" ); + return t; +} + +#define a_cas_p a_cas_p +static inline void *a_cas_p(volatile void *p, void *t, void *s) +{ + __asm__( "lock ; cmpxchg %3, %1" + : "=a"(t), "=m"(*(void *volatile *)p) + : "a"(t), "r"(s) : "memory" ); + return t; +} + +#define a_swap a_swap +static inline int a_swap(volatile int *p, int v) +{ + __asm__ __volatile__( + "xchg %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + +#define a_fetch_add a_fetch_add +static inline int a_fetch_add(volatile int *p, int v) +{ + __asm__ __volatile__( + "lock ; xadd %0, %1" + : "=r"(v), "=m"(*p) : "0"(v) : "memory" ); + return v; +} + + +#define a_inc a_inc +static inline void a_inc(volatile int *p) +{ + __asm__ __volatile__( + "lock ; incl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +#define a_dec a_dec +static inline void a_dec(volatile int *p) +{ + __asm__ __volatile__( + "lock ; decl %0" + : "=m"(*p) : "m"(*p) : "memory" ); +} + +#define a_store a_store +static inline void a_store(volatile int *p, int x) +{ + __asm__ __volatile__( + "mov %1, %0 ; lock ; orl $0,(%%rsp)" + : "=m"(*p) : "r"(x) : "memory" ); +} + +#define a_barrier a_barrier +static inline void a_barrier() +{ + __asm__ __volatile__( "" : : : "memory" ); +} + +#define a_spin a_spin +static inline void a_spin() +{ + __asm__ __volatile__( "pause" : : : "memory" ); +} diff --git a/src/musl_mutex/clock_gettime.c b/src/musl_mutex/clock_gettime.c new file mode 100644 index 0000000..4ccbea2 --- /dev/null +++ b/src/musl_mutex/clock_gettime.c @@ -0,0 +1,112 @@ +#include "time.h" +#include "errno.h" +#include "stdint.h" +#include "syscall.h" +#include "atomic.h" + +#ifdef VDSO_CGT_SYM + +static void *volatile vdso_func; + +#ifdef VDSO_CGT32_SYM +static void *volatile vdso_func_32; +static int cgt_time32_wrap(clockid_t clk, struct timespec *ts) +{ + long ts32[2]; + int (*f)(clockid_t, long[2]) = + (int (*)(clockid_t, long[2]))vdso_func_32; + int r = f(clk, ts32); + if (!r) { + /* Fallback to syscalls if time32 overflowed. Maybe + * we lucked out and somehow migrated to a kernel with + * time64 syscalls available. */ + if (ts32[0] < 0) { + a_cas_p(&vdso_func, (void *)cgt_time32_wrap, 0); + return -ENOSYS; + } + ts->tv_sec = ts32[0]; + ts->tv_nsec = ts32[1]; + } + return r; +} +#endif + +static int cgt_init(clockid_t clk, struct timespec *ts) +{ + void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM); +#ifdef VDSO_CGT32_SYM + if (!p) { + void *q = __vdsosym(VDSO_CGT32_VER, VDSO_CGT32_SYM); + if (q) { + a_cas_p(&vdso_func_32, 0, q); + p = cgt_time32_wrap; + } + } +#ifdef VDSO_CGT_WORKAROUND + if (!__vdsosym(VDSO_CGT32_VER, VDSO_CGT32_SYM)) p = 0; +#endif +#endif + int (*f)(clockid_t, struct timespec *) = + (int (*)(clockid_t, struct timespec *))p; + a_cas_p(&vdso_func, (void *)cgt_init, p); + return f ? f(clk, ts) : -ENOSYS; +} + +static void *volatile vdso_func = (void *)cgt_init; + +#endif + +int __clock_gettime(clockid_t clk, struct timespec *ts) +{ + int r; + +#ifdef VDSO_CGT_SYM + int (*f)(clockid_t, struct timespec *) = + (int (*)(clockid_t, struct timespec *))vdso_func; + if (f) { + r = f(clk, ts); + if (!r) return r; + if (r == -EINVAL) return __syscall_ret(r); + /* Fall through on errors other than EINVAL. Some buggy + * vdso implementations return ENOSYS for clocks they + * can't handle, rather than making the syscall. This + * also handles the case where cgt_init fails to find + * a vdso function to use. */ + } +#endif + +#ifdef SYS_clock_gettime64 + r = -ENOSYS; + if (sizeof(time_t) > 4) + r = __syscall(SYS_clock_gettime64, clk, ts); + if (SYS_clock_gettime == SYS_clock_gettime64 || r!=-ENOSYS) + return __syscall_ret(r); + long ts32[2]; + r = __syscall(SYS_clock_gettime, clk, ts32); +#ifdef SYS_gettimeofday + if (r==-ENOSYS && clk==CLOCK_REALTIME) { + r = __syscall(SYS_gettimeofday, ts32, 0); + ts32[1] *= 1000; + } +#endif + if (!r) { + ts->tv_sec = ts32[0]; + ts->tv_nsec = ts32[1]; + return r; + } + return __syscall_ret(r); +#else + r = __syscall(SYS_clock_gettime, clk, ts); +#ifdef SYS_gettimeofday + if (r == -ENOSYS) { + if (clk == CLOCK_REALTIME) { + __syscall(SYS_gettimeofday, ts, 0); + ts->tv_nsec = (int)ts->tv_nsec * 1000; + return 0; + } + r = -EINVAL; + } +#endif + return __syscall_ret(r); +#endif +} diff --git a/src/musl_mutex/clock_gettime.o b/src/musl_mutex/clock_gettime.o new file mode 100644 index 0000000000000000000000000000000000000000..fbbc3703cb7f832d1ad88d9b750bdb01e227001b GIT binary patch literal 2592 zcmb_dPiPcp6o0!hCZ*L~OAdn4?xFM#twT&CiWFH1qf@ZK7Pj?JnM}q>3~qMQ-5D{` z)j~>PSPC9<>Y=AzdlR83h9-C^_R@-nl7lTR>4R_Id%ySh zd*3(TUboMj%4Ra8DMKe{Thk~}VfVINRAQ0xl%tXp|KY@qmJ>&7PF#B6H0_qtEUh`s z=z$aemg{$7dkf&!`DJn4f@>SDaQl!gZMe7EPVR?&aD`&G&o4j8z4lbOFK!g##)eA% zO+S});uS|rtE~h{qNET~--XAmPN&oD+hAm|u|?q!H`uf{R0Hv^@oMLn_5Pa=VZYb2 za#Jc}BP#ybzvE+jbFr~W(O}cw{Oc>U1?_Q^gXSzbank5|RmTBZx%~)UtskFvI!Wxq zXne7;LD3i{uy!li*vjomc3OfHqfWCpID4nnhbj2?6%d~tyveTXL#y`YV{D+S;JszG zCFHu7FVw59U#|L>+?gN@XXgSs^T9;voI7HT5uF|%KVEpdG!<3CsBn1H8nuQGjYUcw zxi)gd8b0!lz)8McV0kPa&FP5}Wr^-EhUOFv3C~>pm@-%LnFFs34Bo)SItZK>)4Tk0 za&P|Y?D(GD({O;ww)Yta?PUKfG1FD%w!~*YR|z=&3$g#)W&bHDAU2cno!>=&cTAl1 zz8+u1KH%9Du6hN=^%>W?=75n$T_hG?&>N64DV%4(WMOfhPn1TbXxq;Ar5RPo853EkPsYzQv~ z>kD&`x-x9XyR{%BDoY=@FT{I&hD*zI*}!?eOxF^Ivmts3OZ$H(IOpN1YW&X~@VDeq z<2)~?{FipXB@HIW=Rhycp&$mvcxft%pmBZflLoHO^GgHQ=R+2T7zB9o2 zwKLt12~dzY&Gi1YejNhmG~>?+u%sP@oALY~(`)|2GXF`5= 199901L +#define __restrict restrict +#elif !defined(__GNUC__) +#define __restrict +#endif + +#if __STDC_VERSION__ >= 199901L || defined(__cplusplus) +#define __inline inline +#elif !defined(__GNUC__) +#define __inline +#endif + +#if __STDC_VERSION__ >= 201112L +#elif defined(__GNUC__) +#define _Noreturn __attribute__((__noreturn__)) +#else +#define _Noreturn +#endif + +#define __REDIR(x,y) __typeof__(x) x __asm__(#y) + +#endif diff --git a/src/musl_mutex/futex.h b/src/musl_mutex/futex.h new file mode 100644 index 0000000..dafbc24 --- /dev/null +++ b/src/musl_mutex/futex.h @@ -0,0 +1,19 @@ +#ifndef _INTERNAL_FUTEX_H +#define _INTERNAL_FUTEX_H + +#define FUTEX_WAIT 0 +#define FUTEX_WAKE 1 +#define FUTEX_FD 2 +#define FUTEX_REQUEUE 3 +#define FUTEX_CMP_REQUEUE 4 +#define FUTEX_WAKE_OP 5 +#define FUTEX_LOCK_PI 6 +#define FUTEX_UNLOCK_PI 7 +#define FUTEX_TRYLOCK_PI 8 +#define FUTEX_WAIT_BITSET 9 + +#define FUTEX_PRIVATE 128 + +#define FUTEX_CLOCK_REALTIME 256 + +#endif diff --git a/src/musl_mutex/libc.h b/src/musl_mutex/libc.h new file mode 100644 index 0000000..3ead57e --- /dev/null +++ b/src/musl_mutex/libc.h @@ -0,0 +1,60 @@ +#ifndef LIBC_H +#define LIBC_H + +#include +#include +#include + +#define hidden __attribute__((visibility("hidden"))) + +struct __locale_map; + +struct __locale_struct { + const struct __locale_map *cat[6]; +}; + +struct tls_module { + struct tls_module *next; + void *image; + size_t len, size, align, offset; +}; + +struct __libc { + char can_do_threads; + char threaded; + char secure; + volatile signed char need_locks; + int threads_minus_1; + size_t *auxv; + struct tls_module *tls_head; + size_t tls_size, tls_align, tls_cnt; + size_t page_size; + struct __locale_struct global_locale; +}; + +#ifndef PAGE_SIZE +#define PAGE_SIZE libc.page_size +#endif + +extern hidden struct __libc __libc; +#define libc __libc + +void __init_libc(char **, char *); +void __init_tls(size_t *); +void __init_ssp(void *); +void __libc_start_init(void); +void __funcs_on_exit(void); +void __funcs_on_quick_exit(void); +void __libc_exit_fini(void); +void __fork_handler(int); + +extern size_t __hwcap; +extern size_t __sysinfo; +extern char *__progname, *__progname_full; + +extern hidden const char __libc_version[]; + +hidden void __synccall(void (*)(void *), void *); +hidden int __setxid(int, int, int, int); + +#endif diff --git a/src/musl_mutex/libmusl_mutex.a b/src/musl_mutex/libmusl_mutex.a new file mode 100644 index 0000000000000000000000000000000000000000..abf4080e0ebce0faa1614d1b47d99bae7010a5b3 GIT binary patch literal 37854 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 pi3sh@Cg6_ literal 0 HcmV?d00001 diff --git a/src/musl_mutex/limits.h b/src/musl_mutex/limits.h new file mode 100644 index 0000000..403b240 --- /dev/null +++ b/src/musl_mutex/limits.h @@ -0,0 +1,165 @@ +#ifndef _LIMITS_H +#define _LIMITS_H + +#include "features.h" + +#include "alltypes_make.h" /* __LONG_MAX */ + +/* Support signed or unsigned plain-char */ + +#if '\xff' > 0 +#define CHAR_MIN 0 +#define CHAR_MAX 255 +#else +#define CHAR_MIN (-128) +#define CHAR_MAX 127 +#endif + +#define CHAR_BIT 8 +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 +#define UCHAR_MAX 255 +#define SHRT_MIN (-1-0x7fff) +#define SHRT_MAX 0x7fff +#define USHRT_MAX 0xffff +#define INT_MIN (-1-0x7fffffff) +#define INT_MAX 0x7fffffff +#define UINT_MAX 0xffffffffU +#define LONG_MIN (-LONG_MAX-1) +#define LONG_MAX __LONG_MAX +#define ULONG_MAX (2UL*LONG_MAX+1) +#define LLONG_MIN (-LLONG_MAX-1) +#define LLONG_MAX 0x7fffffffffffffffLL +#define ULLONG_MAX (2ULL*LLONG_MAX+1) + +#define MB_LEN_MAX 4 + +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + + +#define PIPE_BUF 4096 +#define FILESIZEBITS 64 +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif +#define PATH_MAX 4096 +#define NGROUPS_MAX 32 +#define ARG_MAX 131072 +#define IOV_MAX 1024 +#define SYMLOOP_MAX 40 +#define WORD_BIT 32 +#define SSIZE_MAX LONG_MAX +#define TZNAME_MAX 6 +#define TTY_NAME_MAX 32 +#define HOST_NAME_MAX 255 + +#if LONG_MAX == 0x7fffffffL +#define LONG_BIT 32 +#else +#define LONG_BIT 64 +#endif + +/* Implementation choices... */ + +#define PTHREAD_KEYS_MAX 128 +#define PTHREAD_STACK_MIN 2048 +#define PTHREAD_DESTRUCTOR_ITERATIONS 4 +#define SEM_VALUE_MAX 0x7fffffff +#define SEM_NSEMS_MAX 256 +#define DELAYTIMER_MAX 0x7fffffff +#define MQ_PRIO_MAX 32768 +#define LOGIN_NAME_MAX 256 + +/* Arbitrary numbers... */ + +#define BC_BASE_MAX 99 +#define BC_DIM_MAX 2048 +#define BC_SCALE_MAX 99 +#define BC_STRING_MAX 1000 +#define CHARCLASS_NAME_MAX 14 +#define COLL_WEIGHTS_MAX 2 +#define EXPR_NEST_MAX 32 +#define LINE_MAX 4096 +#define RE_DUP_MAX 255 + +#define NL_ARGMAX 9 +#define NL_MSGMAX 32767 +#define NL_SETMAX 255 +#define NL_TEXTMAX 2048 + +#endif + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_XOPEN_SOURCE) + +#ifdef PAGESIZE +#define PAGE_SIZE PAGESIZE +#endif +#define NZERO 20 +#define NL_LANGMAX 32 + +#endif + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) \ + || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700) + +#define NL_NMAX 16 + +#endif + +/* POSIX/SUS requirements follow. These numbers come directly + * from SUS and have nothing to do with the host system. */ + +#define _POSIX_AIO_LISTIO_MAX 2 +#define _POSIX_AIO_MAX 1 +#define _POSIX_ARG_MAX 4096 +#define _POSIX_CHILD_MAX 25 +#define _POSIX_CLOCKRES_MIN 20000000 +#define _POSIX_DELAYTIMER_MAX 32 +#define _POSIX_HOST_NAME_MAX 255 +#define _POSIX_LINK_MAX 8 +#define _POSIX_LOGIN_NAME_MAX 9 +#define _POSIX_MAX_CANON 255 +#define _POSIX_MAX_INPUT 255 +#define _POSIX_MQ_OPEN_MAX 8 +#define _POSIX_MQ_PRIO_MAX 32 +#define _POSIX_NAME_MAX 14 +#define _POSIX_NGROUPS_MAX 8 +#define _POSIX_OPEN_MAX 20 +#define _POSIX_PATH_MAX 256 +#define _POSIX_PIPE_BUF 512 +#define _POSIX_RE_DUP_MAX 255 +#define _POSIX_RTSIG_MAX 8 +#define _POSIX_SEM_NSEMS_MAX 256 +#define _POSIX_SEM_VALUE_MAX 32767 +#define _POSIX_SIGQUEUE_MAX 32 +#define _POSIX_SSIZE_MAX 32767 +#define _POSIX_STREAM_MAX 8 +#define _POSIX_SS_REPL_MAX 4 +#define _POSIX_SYMLINK_MAX 255 +#define _POSIX_SYMLOOP_MAX 8 +#define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 +#define _POSIX_THREAD_KEYS_MAX 128 +#define _POSIX_THREAD_THREADS_MAX 64 +#define _POSIX_TIMER_MAX 32 +#define _POSIX_TRACE_EVENT_NAME_MAX 30 +#define _POSIX_TRACE_NAME_MAX 8 +#define _POSIX_TRACE_SYS_MAX 8 +#define _POSIX_TRACE_USER_EVENT_MAX 32 +#define _POSIX_TTY_NAME_MAX 9 +#define _POSIX_TZNAME_MAX 6 +#define _POSIX2_BC_BASE_MAX 99 +#define _POSIX2_BC_DIM_MAX 2048 +#define _POSIX2_BC_SCALE_MAX 99 +#define _POSIX2_BC_STRING_MAX 1000 +#define _POSIX2_CHARCLASS_NAME_MAX 14 +#define _POSIX2_COLL_WEIGHTS_MAX 2 +#define _POSIX2_EXPR_NEST_MAX 32 +#define _POSIX2_LINE_MAX 2048 +#define _POSIX2_RE_DUP_MAX 255 + +#define _XOPEN_IOV_MAX 16 +#define _XOPEN_NAME_MAX 255 +#define _XOPEN_PATH_MAX 1024 + +#endif diff --git a/src/musl_mutex/metrics_handlers.o b/src/musl_mutex/metrics_handlers.o new file mode 100644 index 0000000000000000000000000000000000000000..5ef03404b4932023105668ab9223ff02e83e3dc4 GIT binary patch literal 4312 zcmb_eU2IfE6rSx5EC_Tp5J@m*6H`*6EL*@Iz@G(jVMx$4B#pdnx7*uxZFjrby(_H> zLe{Ifx!$-jVj6w%p$~oFp)Vv2v9Ku8)fltB_05e5NeO)@(L`dv})Nx-qhiY$bnmJ^Ob*b?(sON|rk3 zr>RpY4N)t`?zB%n0Gc;MH zPL<71G{A-x^YS+z>(|_gC`73Mf zgmiuO9e_Oem6pN1J_v4eEf`*@3_;lpfhuGYghiC;qA>?3!2NUJD$`FwKH{n( zc8rQ9tUR8O&sx>QRey1`(1sU|$Y~YKr_^J@?zx>%?>$(!TpNF0}4w zSW4$NjBQtOZdWuQw+C=}E^i!riM!b*c209ijbprNmMp81SuR=S7;l;-4^#Kga}@!z)k1B3_TZ~Lrtc3(0dPn%XQ1#NehFevfvNW2j~kw}f3Lt$$o zJdrgs;b9mZ4tM7_6YMd}93sR@rOmvRNM~Q`9xrT47IN`(iIipL@@$O#RAwZOtayfF z=A@a#srYcSNVPEzW~0WDV?7q)P4P}1KYlpe(?3|qScP!!fyjYKbnik$?+eKmtUO7MPk;)-VR>^AzUJ3jbB1y|22Eat&H#gQ^3 zrs49QkVt+iZ6yYwwQ{^2mA#xfo`^uzStK%)uo5IPn9q|)Zh{Yz6X~=GwHnDxSY`y? zs=cfx#dsuBh-7n6c{yteG#JSojSuG%P9s{TBtGtXpk#OqVGl1h#_58C!9~L^< z=waUh2gcO(B|$tZg`(B;D5W1iCT+ literal 0 HcmV?d00001 diff --git a/src/musl_mutex/mman.h b/src/musl_mutex/mman.h new file mode 100644 index 0000000..1aa9ecb --- /dev/null +++ b/src/musl_mutex/mman.h @@ -0,0 +1,8 @@ +#ifndef SYS_MMAN_H +#define SYS_MMAN_H + +void __vm_wait(void); +void __vm_lock(void); +void __vm_unlock(void); + +#endif \ No newline at end of file diff --git a/src/musl_mutex/pthread_cond_broadcast.c b/src/musl_mutex/pthread_cond_broadcast.c new file mode 100644 index 0000000..b79573f --- /dev/null +++ b/src/musl_mutex/pthread_cond_broadcast.c @@ -0,0 +1,10 @@ +// #include "pthread_impl.h" + +// int __pthread_musl_cond_broadcast(musl_cond_t *c) +// { +// if (!c->_c_shared) return __private_cond_signal(c, -1); +// if (!c->_c_waiters) return 0; +// a_inc(&c->_c_seq); +// __wake(&c->_c_seq, -1, 0); +// return 0; +// } diff --git a/src/musl_mutex/pthread_cond_broadcast.o b/src/musl_mutex/pthread_cond_broadcast.o new file mode 100644 index 0000000000000000000000000000000000000000..25fcbc4de6767048bb45a39bc94fd16fa08a1903 GIT binary patch literal 952 zcmbVK%}T>S5T4Zfd(xZeC7x8UOKhu%2MLtgi+C$|E1MrIXp@jkz+UPr_(**Y-@+%* znPgYD8}QJ9nQ!Nt`Sxen_u<2R%W*)P19$M3X%^tdApMH=VGnizMuWkvdo~Wr1WWg_ zCwju`T$feaU3B}x>z^ySQne}WlW&rb9>>rESTeUk{-5#jZTR|b^kg{AV;N1tG>Ilb zp2{ec1&RxWIbEG0FH%TbA6na-ACEuc#A>%-M7Et7yZMYSQoG8F3#Y+hGm-^Bc3{ c(vkz&Q4PP*zW)JL?Adekr&2sA)L`p>0H6RrMF0Q* literal 0 HcmV?d00001 diff --git a/src/musl_mutex/pthread_cond_destroy.c b/src/musl_mutex/pthread_cond_destroy.c new file mode 100644 index 0000000..e9e336d --- /dev/null +++ b/src/musl_mutex/pthread_cond_destroy.c @@ -0,0 +1,14 @@ +// #include "pthread_impl.h" + +// int __pthread_musl_cond_destroy(musl_cond_t *c) +// { +// if (c->_c_shared && c->_c_waiters) { +// int cnt; +// a_or(&c->_c_waiters, 0x80000000); +// a_inc(&c->_c_seq); +// __wake(&c->_c_seq, -1, 0); +// while ((cnt = c->_c_waiters) & 0x7fffffff) +// __wait(&c->_c_waiters, 0, cnt, 0); +// } +// return 0; +// } diff --git a/src/musl_mutex/pthread_cond_destroy.o b/src/musl_mutex/pthread_cond_destroy.o new file mode 100644 index 0000000000000000000000000000000000000000..a3487ae5d32c0da7e98a9628ab43eec79cfb42d9 GIT binary patch literal 944 zcmbVK%}T>S5T4Zfd(xZWC7x8UOKhtL4-zP~7x7l`R`Ro0(EN~0z+Chde55{xui+Eu zOtOpH4G20gGy8q>O*S*^+w|_X=QyCvfgAWing#F-(r;)V_FxxaHkn+zr}MB%v2rg) zVkEr5Rn@@Z>u@Z*@tLBVu0F+m@=fyD{TzA#E9N%He>1+m51(HhO^(Y#2Js@w(s&We z5{s-B5r8P`1cQ(=7HwYY6Ur9^5eFE62+I;glqHEwiAyt-f_`gIVh}wk{FqiEFS1+~ zSa+`fD{({(Jj<5V=v!DrW9_c_clock = a->__attr & 0x7fffffff; +// // if (a->__attr>>31) c->_c_shared = (void *)-1; +// // } +// // return 0; +// // } diff --git a/src/musl_mutex/pthread_cond_init.o b/src/musl_mutex/pthread_cond_init.o new file mode 100644 index 0000000000000000000000000000000000000000..41541fbefb3de93ede658169aa55a09a821987d0 GIT binary patch literal 944 zcmbVK%}T>S5T4Zfd(wj-c!?(!>=N7R!Gi=!?M1v5yp{Z6i*^%|3D}Fif{)af@Iib6 zok@0ey8#a!nE7_TnQwoFeIMT6wHybuIdBVqnPvezgY+xfhdtN@7!3wD?%6mjC6?}G zPxOS>xh|`;`_}CXuYa!SO4X*gPrgY$dKg0sV9DGD`G3a8x8du%(UajcPl9+7r81t( zNtPnZ(=5qx z(Kvez;+Qo2mMu%`Te(h+u~*ayMds{z`Bk+UZ2c*5-e}tAy*O>GL&S zQBkkWz85nw)^_iZYTM-WZ&oZ*nY+T)Z#602&(?DNLpAAl@r<~Sk?p7k{_&03acRkc Y?68L4Xy5;UD)#KT`BNz#6>6~cKc0X+Gynhq literal 0 HcmV?d00001 diff --git a/src/musl_mutex/pthread_cond_signal.c b/src/musl_mutex/pthread_cond_signal.c new file mode 100644 index 0000000..3a852f9 --- /dev/null +++ b/src/musl_mutex/pthread_cond_signal.c @@ -0,0 +1,11 @@ +// #include "pthread_impl.h" + + +// int __pthread_musl_cond_signal(musl_cond_t *c) +// { +// if (!c->_c_shared) return __private_cond_signal(c, 1); +// if (!c->_c_waiters) return 0; +// a_inc(&c->_c_seq); +// __wake(&c->_c_seq, 1, 0); +// return 0; +// } diff --git a/src/musl_mutex/pthread_cond_signal.o b/src/musl_mutex/pthread_cond_signal.o new file mode 100644 index 0000000000000000000000000000000000000000..28ccc0c0004484effee2cb93865b697711d5a334 GIT binary patch literal 944 zcmbVK%}T>S5T4Zfd(xAFmv~aaF0rj1JV>C_Uc_6$TiN{3ip?e@8?cx93O-Wb!sqY_ zbSBx=?FIxLnE7_TnQwoFeI4H4wHybuIdBU37kLsE?5Bs0RA+joDFY aMFH)whVN+K{{SoY?5X)(DIOJSu=QW1@je0o literal 0 HcmV?d00001 diff --git a/src/musl_mutex/pthread_cond_timedwait.c b/src/musl_mutex/pthread_cond_timedwait.c new file mode 100644 index 0000000..3c63838 --- /dev/null +++ b/src/musl_mutex/pthread_cond_timedwait.c @@ -0,0 +1,214 @@ +// #include "pthread_impl.h" + + +// /* +// * struct waiter +// * +// * Waiter objects have automatic storage on the waiting thread, and +// * are used in building a linked list representing waiters currently +// * waiting on the condition variable or a group of waiters woken +// * together by a broadcast or signal; in the case of signal, this is a +// * degenerate list of one member. +// * +// * Waiter lists attached to the condition variable itself are +// * protected by the lock on the cv. Detached waiter lists are never +// * modified again, but can only be traversed in reverse order, and are +// * protected by the "barrier" locks in each node, which are unlocked +// * in turn to control wake order. +// * +// * Since process-shared cond var semantics do not necessarily allow +// * one thread to see another's automatic storage (they may be in +// * different processes), the waiter list is not used for the +// * process-shared case, but the structure is still used to store data +// * needed by the cancellation cleanup handler. +// */ + +// struct waiter { +// struct waiter *prev, *next; +// volatile int state, barrier; +// volatile int *notify; +// }; + +// /* Self-synchronized-destruction-safe lock functions */ + +// static inline void lock(volatile int *l) +// { +// if (a_cas(l, 0, 1)) { +// a_cas(l, 1, 2); +// do __wait(l, 0, 2, 1); +// while (a_cas(l, 0, 2)); +// } +// } + +// static inline void unlock(volatile int *l) +// { +// if (a_swap(l, 0)==2) +// __wake(l, 1, 1); +// } + +// static inline void unlock_requeue(volatile int *l, volatile int *r, int w) +// { +// a_store(l, 0); +// if (w) __wake(l, 1, 1); +// else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS +// || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); +// } + +// enum { +// WAITING, +// SIGNALED, +// LEAVING, +// }; + +// int __pthread_musl_cond_timedwait(musl_cond_t *restrict c, musl_mutex_t *restrict m, musl_context_t *restrict me, const struct timespec *restrict ts) +// { +// struct waiter node = { 0 }; +// int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp; +// volatile int *fut; + +// if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid) +// return EPERM; + +// if (ts && ts->tv_nsec >= 1000000000UL) +// return EINVAL; + +// __pthread_testcancel(); + +// if (c->_c_shared) { +// shared = 1; +// fut = &c->_c_seq; +// seq = c->_c_seq; +// a_inc(&c->_c_waiters); +// } else { +// lock(&c->_c_lock); + +// seq = node.barrier = 2; +// fut = &node.barrier; +// node.state = WAITING; +// node.next = c->_c_head; +// c->_c_head = &node; +// if (!c->_c_tail) c->_c_tail = &node; +// else node.next->prev = &node; + +// unlock(&c->_c_lock); +// } + +// __pthread_musl_mutex_unlock(m); + +// __pthread_musl_setcancelstate(PTHREAD_CANCEL_MASKED, &cs); +// if (cs == PTHREAD_CANCEL_DISABLE) __pthread_musl_setcancelstate(cs, 0); + +// do e = __timedwait_cp(fut, seq, clock, ts, !shared); +// while (*fut==seq && (!e || e==EINTR)); +// if (e == EINTR) e = 0; + +// if (shared) { +// /* Suppress cancellation if a signal was potentially +// * consumed; this is a legitimate form of spurious +// * wake even if not. */ +// if (e == ECANCELED && c->_c_seq != seq) e = 0; +// if (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff) +// __wake(&c->_c_waiters, 1, 0); +// oldstate = WAITING; +// goto relock; +// } + +// oldstate = a_cas(&node.state, WAITING, LEAVING); + +// if (oldstate == WAITING) { +// /* Access to cv object is valid because this waiter was not +// * yet signaled and a new signal/broadcast cannot return +// * after seeing a LEAVING waiter without getting notified +// * via the futex notify below. */ + +// lock(&c->_c_lock); + +// if (c->_c_head == &node) c->_c_head = node.next; +// else if (node.prev) node.prev->next = node.next; +// if (c->_c_tail == &node) c->_c_tail = node.prev; +// else if (node.next) node.next->prev = node.prev; + +// unlock(&c->_c_lock); + +// if (node.notify) { +// if (a_fetch_add(node.notify, -1)==1) +// __wake(node.notify, 1, 1); +// } +// } else { +// /* Lock barrier first to control wake order. */ +// lock(&node.barrier); +// } + +// relock: +// /* Errors locking the mutex override any existing error or +// * cancellation, since the caller must see them to know the +// * state of the mutex. */ +// if ((tmp = pthread_mutex_lock(m))) e = tmp; + +// if (oldstate == WAITING) goto done; + +// if (!node.next && !(m->_m_type & 8)) +// a_inc(&m->_m_waiters); + +// /* Unlock the barrier that's holding back the next waiter, and +// * either wake it or requeue it to the mutex. */ +// if (node.prev) { +// int val = m->_m_lock; +// if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); +// unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128)); +// } else if (!(m->_m_type & 8)) { +// a_dec(&m->_m_waiters); +// } + +// /* Since a signal was consumed, cancellation is not permitted. */ +// if (e == ECANCELED) e = 0; + +// done: +// __pthread_setcancelstate(cs, 0); + +// if (e == ECANCELED) { +// __pthread_testcancel(); +// __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); +// } + +// return e; +// } + +// int __private_cond_signal(pthread_cond_t *c, int n) +// { +// struct waiter *p, *first=0; +// volatile int ref = 0; +// int cur; + +// lock(&c->_c_lock); +// for (p=c->_c_tail; n && p; p=p->prev) { +// if (a_cas(&p->state, WAITING, SIGNALED) != WAITING) { +// ref++; +// p->notify = &ref; +// } else { +// n--; +// if (!first) first=p; +// } +// } +// /* Split the list, leaving any remainder on the cv. */ +// if (p) { +// if (p->next) p->next->prev = 0; +// p->next = 0; +// } else { +// c->_c_head = 0; +// } +// c->_c_tail = p; +// unlock(&c->_c_lock); + +// /* Wait for any waiters in the LEAVING state to remove +// * themselves from the list before returning or allowing +// * signaled threads to proceed. */ +// while ((cur = ref)) __wait(&ref, 0, cur, 1); + +// /* Allow first signaled waiter, if any, to proceed. */ +// if (first) unlock(&first->barrier); + +// return 0; +// } + +// weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait); diff --git a/src/musl_mutex/pthread_cond_timedwait.o b/src/musl_mutex/pthread_cond_timedwait.o new file mode 100644 index 0000000000000000000000000000000000000000..c1ba78feb5cd2af26f9a325299d73e7109a489bb GIT binary patch literal 952 zcmbVK%}T>S5T4Zfd(xZeC7x8UOKhu%2MLtgi+C$|E1P7oMe{?lL3`0x@R9l)zJ*Vq zGs&)QH{hWIGvCfP^X<>D@58&>mg9gn2X5dm(=5Q1LHZT#!wzf%j0S^i_hcNDi7ego z9_ul$b6Hkt_pRG!UjJ0lm8y+#7kwRlbU%g`z=F6n^#6>GZ^PGjqbHNoT<~ZTrb#rB zvsgqgd?r~4z>0Y+d4MSM8mD?C#j6Asamj%NMFA{K<5(ofC8-n)FV-m}51&;2n3OEb z(@f-Y-nhVO#39P)O&gZnw{o2tS5T4Zfd(wj-c!?(!>=N7R!Gi=!?M1v5yp_!lR4AQS?A9i3HU^Ez9xhLbGOt5s% zd!i@2&ShDp-M4OEc>PmFSE@F}UGjDE(cKtY01M{U$p14wz71dBjh+mrc`Tzzm?qKW zMLwbk0YovMp$rHyuW_nZ7{4NjNTLK06a|Pdoz3EexFp3`(49I3%J50$4@oJqJk8=9 z=Z&*hAPz~xZ`rW4zLo3L7<)w>QDn}ZmtR$z!PXyB%NF^n`ZLn__attr &= 0x80000000; + a->__attr |= clk; + return 0; +} diff --git a/src/musl_mutex/pthread_condattr_setpshared.c b/src/musl_mutex/pthread_condattr_setpshared.c new file mode 100644 index 0000000..bc98315 --- /dev/null +++ b/src/musl_mutex/pthread_condattr_setpshared.c @@ -0,0 +1,9 @@ +#include "pthread_impl.h" + +int __pthread_musl_condattr_setpshared(__pthread_condattr_t *a, int pshared) +{ + if (pshared > 1U) return EINVAL; + a->__attr &= 0x7fffffff; + a->__attr |= (unsigned)pshared<<31; + return 0; +} diff --git a/src/musl_mutex/pthread_impl.h b/src/musl_mutex/pthread_impl.h new file mode 100644 index 0000000..23eb272 --- /dev/null +++ b/src/musl_mutex/pthread_impl.h @@ -0,0 +1,93 @@ +#ifndef _PTHREAD_IMPL_H +#define _PTHREAD_IMPL_H + +#include "pthread_musl.h" +#include "syscall.h" +#include "mman.h" +#include "atomic.h" +#include "futex.h" +#include "errno.h" +#include "limits.h" +#include "alltypes_make.h" + +#define pthread __pthread + +enum { + DT_EXITED = 0, + DT_EXITING, + DT_JOINABLE, + DT_DETACHED, +}; + +#define __SU (sizeof(size_t)/sizeof(int)) + +#define _a_stacksize __u.__s[0] +#define _a_guardsize __u.__s[1] +#define _a_stackaddr __u.__s[2] +#define _a_detach __u.__i[3*__SU+0] +#define _a_sched __u.__i[3*__SU+1] +#define _a_policy __u.__i[3*__SU+2] +#define _a_prio __u.__i[3*__SU+3] +#define _m_type __u.__i[0] +#define _m_lock __u.__vi[1] +#define _m_waiters __u.__vi[2] +#define _m_prev __u.__p[3] +#define _m_next __u.__p[4] +#define _m_count __u.__i[5] +#define _c_shared __u.__p[0] +#define _c_seq __u.__vi[2] +#define _c_waiters __u.__vi[3] +#define _c_clock __u.__i[4] +#define _c_lock __u.__vi[8] +#define _c_head __u.__p[1] +#define _c_tail __u.__p[5] +#define _rw_lock __u.__vi[0] +#define _rw_waiters __u.__vi[1] +#define _rw_shared __u.__i[2] +#define _b_lock __u.__vi[0] +#define _b_waiters __u.__vi[1] +#define _b_limit __u.__i[2] +#define _b_count __u.__vi[3] +#define _b_waiters2 __u.__vi[4] +#define _b_inst __u.__p[3] + +#ifndef TP_OFFSET +#define TP_OFFSET 0 +#endif + +#ifndef DTP_OFFSET +#define DTP_OFFSET 0 +#endif + +#ifndef tls_mod_off_t +#define tls_mod_off_t size_t +#endif + +#define SIGTIMER 32 +#define SIGCANCEL 33 +#define SIGSYNCCALL 34 + + +// __timedwait(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv) +int __timedwait(volatile int *addr, int val, clockid_t clk, const struct timespec *at, int priv); +// void __wait(volatile void *, volatile int *, int, int); +void __wait(volatile int *addr, volatile int *waiters, int val, int priv); + +static inline void __wake(volatile void *addr, int cnt, int priv) +{ + if (priv) priv = FUTEX_PRIVATE; + if (cnt<0) cnt = INT_MAX; + __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS || + __syscall(SYS_futex, addr, FUTEX_WAKE, cnt); +} + +static inline void __futexwait(volatile void *addr, int val, int priv) +{ + if (priv) priv = FUTEX_PRIVATE; + __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS || + __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0); +} + + +#endif + \ No newline at end of file diff --git a/src/musl_mutex/pthread_musl.h b/src/musl_mutex/pthread_musl.h new file mode 100644 index 0000000..17849a9 --- /dev/null +++ b/src/musl_mutex/pthread_musl.h @@ -0,0 +1,86 @@ +// #ifndef _PTHREAD_H +// #define _PTHREAD_H +#pragma once +//#ifdef __cplusplus +//extern "C" { +//#endif + +#include "features.h" +#include "alltypes_make.h" + +#define __NEED_clockid_t +#define __NEED_struct_timespec +#define __NEED_pthread_t +#define __NEED_pthread_attr_t +#define __NEED_pthread_mutexattr_t +#define __NEED_pthread_mutex_t +#define __NEED_size_t + + +//#include +#include "time.h" + +#define PTHREAD_CREATE_JOINABLE 0 +#define PTHREAD_CREATE_DETACHED 1 + +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_DEFAULT 0 +#define PTHREAD_MUTEX_RECURSIVE 1 +#define PTHREAD_MUTEX_ERRORCHECK 2 + +#define PTHREAD_MUTEX_STALLED 0 +#define PTHREAD_MUTEX_ROBUST 1 + +#define PTHREAD_PRIO_NONE 0 +#define PTHREAD_PRIO_INHERIT 1 +#define PTHREAD_PRIO_PROTECT 2 + +#define PTHREAD_INHERIT_SCHED 0 +#define PTHREAD_EXPLICIT_SCHED 1 + +#define PTHREAD_SCOPE_SYSTEM 0 +#define PTHREAD_SCOPE_PROCESS 1 + +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +#define PTHREAD_MUTEX_INITIALIZER {{{0}}} +#define PTHREAD_RWLOCK_INITIALIZER {{{0}}} +#define PTHREAD_COND_INITIALIZER {{{0}}} +#define PTHREAD_ONCE_INIT 0 + +#define PTHREAD_CANCEL_ENABLE 0 +#define PTHREAD_CANCEL_DISABLE 1 +#define PTHREAD_CANCEL_MASKED 2 + +#define PTHREAD_CANCEL_DEFERRED 0 +#define PTHREAD_CANCEL_ASYNCHRONOUS 1 + +#define PTHREAD_CANCELED ((void *)-1) + +#define PTHREAD_BARRIER_SERIAL_THREAD (-1) + +#define PTHREAD_NULL ((pthread_t)0) + + +#ifdef __GNUC__ +__attribute__((const)) +#endif + +typedef void *musl_context_t; + +int __pthread_musl_mutex_lock(__pthread_mutex_t *impl, musl_context_t *me); +int __pthread_musl_mutex_unlock(__pthread_mutex_t *impl, musl_context_t *me); +int __pthread_musl_mutex_trylock(__pthread_mutex_t *, musl_context_t *me); +int __pthread_musl_mutex_timedlock(__pthread_mutex_t *restrict m, const struct timespec *restrict at, musl_context_t *me); +int __pthread_musl_mutex_init(__pthread_mutex_t *restrict m, const __pthread_mutexattr_t *restrict a); + +#ifdef _GNU_SOURCE +struct cpu_set_t; +#endif + +//#ifdef __cplusplus +//} +//#endif + +// #endif diff --git a/src/musl_mutex/pthread_mutex_init.c b/src/musl_mutex/pthread_mutex_init.c new file mode 100644 index 0000000..ab41595 --- /dev/null +++ b/src/musl_mutex/pthread_mutex_init.c @@ -0,0 +1,14 @@ +#include "pthread_impl.h" +#include +#include "assert.h" + +int __pthread_musl_mutex_init(__pthread_mutex_t *restrict m, const __pthread_mutexattr_t *restrict a) +{ + // fprintf(stderr, "Error __pthread_musl_mutex_init.\n"); + // assert(0); + // return 0; + + *m = (__pthread_mutex_t){0}; + if (a) m->_m_type = a->__attr; + return 0; +} \ No newline at end of file diff --git a/src/musl_mutex/pthread_mutex_init.o b/src/musl_mutex/pthread_mutex_init.o new file mode 100644 index 0000000000000000000000000000000000000000..478fc816090e862328d32086f19ce85b42dea696 GIT binary patch literal 1576 zcmbtT&1(};5T8xb){j)91Q9B-hbk5ABWa7)9wZQA7YQOl(2J~_WNSjRNyxs1)Pt=A zg(WCGc=V6(A{3!g^dR0ndKGdgh5G2~n)@UF>g_CS9rm^7`;Y+8I`LV^-~8_U)H?h3G|@>Uc+Qf1Bk((`m@m%@Q3F@&rxxSvF{o7nL} zx`l(Xb~Wjh;}c%m*Uzw;&910(g`!jEj+$O%i!3#N-SLhK&lZ+gYUzrgA%e^vRt{yo_Y0CnH^qAR-(z+Zg=n zhk2tRlRt-nXMMca3%L{u-8+aINQCjwAK +#include + +int __pthread_musl_mutex_lock(__pthread_mutex_t *m, musl_context_t *me) +{ + // fprintf(stderr, "Error __pthread_musl_mutex_lock.\n"); + + if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL + && !a_cas(&m->_m_lock, 0, EBUSY)) + return 0; + + return __pthread_musl_mutex_timedlock(m, 0, me); +} diff --git a/src/musl_mutex/pthread_mutex_lock.o b/src/musl_mutex/pthread_mutex_lock.o new file mode 100644 index 0000000000000000000000000000000000000000..a5652fbf0562e99e71df73a77877e80280f02596 GIT binary patch literal 1608 zcmbtTOKTHR6uuKC~#Ly4;(>~iO zl{WJiw2Iesz5L1=U*m=44KFZPpRTU+!upbc5s;>XDhKIo-PBl$u^uq_^Ny1aQ6Al9 z%1%yMoXgDa(LhcUh66c^>&nsG%T#H8MkfN9@Ld8g2P5mOO7=!G!UKSsE;gB}Rmpo8B#C2hBEn?_ByJlEXO8?EX?US)<}H5{hv6Q|RN zFp@p)1Iw%-0ct!Jg)mdh_zx`+k{3A58#523C^U)7{uy_6E!U{f>)PYDE;ZY17@WFx z8Lt_x!Fa`S7_YW0%WM+XY`G?<-7Y(>K~0VA`%RCx?N-~g-Cf3m3}#)wXB(Co_VPbU zo`SKhnOKsdu%E~9_+}T$kC_!?yjx;erv!eOUc};?gGl^5>A>Z83?Jmf_?f!n^)C_w zIsY|&g<_GjKqo4)KJrIJ)|c-lIi()u{fHV7JHG literal 0 HcmV?d00001 diff --git a/src/musl_mutex/pthread_mutex_timedlock.c b/src/musl_mutex/pthread_mutex_timedlock.c new file mode 100644 index 0000000..a4a902c --- /dev/null +++ b/src/musl_mutex/pthread_mutex_timedlock.c @@ -0,0 +1,100 @@ +#include "pthread_impl.h" +#include "pthread_self_glibc.h" +#include + +#define IS32BIT(x) !((x)+0x80000000ULL>>32) +#define CLAMP(x) (int)(IS32BIT(x) ? (x) : 0x7fffffffU+((0ULL+(x))>>63)) + +static int __futex4(volatile void *addr, int op, int val, const struct timespec *to) +{ +#ifdef SYS_futex_time64 + time_t s = to ? to->tv_sec : 0; + long ns = to ? to->tv_nsec : 0; + int r = -ENOSYS; + if (SYS_futex == SYS_futex_time64 || !IS32BIT(s)) + r = __syscall(SYS_futex_time64, addr, op, val, + to ? ((long long[]){s, ns}) : 0); + if (SYS_futex == SYS_futex_time64 || r!=-ENOSYS) return r; + to = to ? (void *)(long[]){CLAMP(s), ns} : 0; +#endif + return __syscall(SYS_futex, addr, op, val, to); +} + +static int pthread_musl_mutex_timedlock_pi(__pthread_mutex_t *restrict m, const struct timespec *restrict at, musl_context_t *me) +{ + // fprintf(stderr, "Error pthread_musl_mutex_timedlock_pi.\n"); + + int type = m->_m_type; + int priv = (type & 128) ^ 128; + unsigned long self = pthread_self_glibc(); + int e; + + //if (!priv) self->robust_list.pending = &m->_m_next; + + do e = -__futex4(&m->_m_lock, FUTEX_LOCK_PI|priv, 0, at); + while (e==EINTR); + //if (e) self->robust_list.pending = 0; + + switch (e) { + case 0: + /* Catch spurious success for non-robust mutexes. */ + if (!(type&4) && ((m->_m_lock & 0x40000000) || m->_m_waiters)) { + a_store(&m->_m_waiters, -1); + __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); + //self->robust_list.pending = 0; + break; + } + /* Signal to trylock that we already have the lock. */ + m->_m_count = -1; + return __pthread_musl_mutex_trylock(m, me); + case ETIMEDOUT: + return e; + case EDEADLK: + if ((type&3) == PTHREAD_MUTEX_ERRORCHECK) return e; + } + do e = __timedwait(&(int){0}, 0, CLOCK_REALTIME, at, 1); + while (e != ETIMEDOUT); + return e; +} + +int __pthread_musl_mutex_timedlock(__pthread_mutex_t *restrict m, const struct timespec *restrict at, musl_context_t *me) +{ + // fprintf(stderr, "Error __pthread_musl_mutex_timedlock.\n"); + + if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL + && !a_cas(&m->_m_lock, 0, EBUSY)) + return 0; + + int type = m->_m_type; + int r, t, priv = (type & 128) ^ 128; + + r = __pthread_musl_mutex_trylock(m, me); + if (r != EBUSY) return r; + + if (type&8) return pthread_musl_mutex_timedlock_pi(m, at, me); + + int spins = 100; + while (spins-- && m->_m_lock && !m->_m_waiters) a_spin(); + + while ((r=__pthread_musl_mutex_trylock(m, me)) == EBUSY) { + r = m->_m_lock; + int own = r & 0x3fffffff; + if (!own && (!r || (type&4))) + continue; + // fprintf(stderr, "own: %d\n", own); + // fprintf(stderr, "pthread_self_glibc(): %ul\n", pthread_self_glibc()); + if ((type&3) == PTHREAD_MUTEX_ERRORCHECK + && own == pthread_self_glibc()) + // fprintf(stderr, "return EDEADLK 10;\n"); + return EDEADLK; + + a_inc(&m->_m_waiters); + t = r | 0x80000000; + a_cas(&m->_m_lock, r, t); + r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, priv); + a_dec(&m->_m_waiters); + if (r && r != EINTR) break; + } + // fprintf(stderr, "return r 98:\n"); + return r; +} diff --git a/src/musl_mutex/pthread_mutex_timedlock.o b/src/musl_mutex/pthread_mutex_timedlock.o new file mode 100644 index 0000000000000000000000000000000000000000..5cdc76ec15cbbf8eebd0c05fdf80516cfc50a0b9 GIT binary patch literal 3672 zcmbtWU2IcT96#MU7;MmC&@6%I5}3gt4TFh7P)g>7D=?#I;{%e?bscNyx~099O`R^e zo95(ZI*kuJs2HC#zG!@KAqER1tVo0z4fJ6TeE{vUJ=8EmW6=8hpLNy~e0k(!Uv!Kpz>wL7J^K@S4!JKYs1>Fkf zbt|3I`AuJg&b1Q2((z0G5ar#oN4SXYr&EpPi4$WdK7GEmN0 zjBB?n?bhAd_AxNHR+z@d3ba6~h>Duo75p;E>XXA>>@aoVoDg~u-tOkOwrGwndX1m4 zCVb-`gC$Pyer}(b;lq8CZ=B;k{{a^GGxOewOgbn+2zc8825@h(?~M}~V~_A?W*X1K zNm=JJg$sX`%OaeW`Wcitr<)hOI{#7U7j=HkPJiLga(Uq~(wqsb7kYMkQGpv|0&dvC zVM|+FI3QxEH%oQt2D(elKF;aPoB%kQ72L43PAD2JCzj=^vm+?e5jLt`}7` z8ia#t{a?_{MI8;uq5&B+U>cESEoSC@$aM={bTi{U*8=Mm4;E4YceQB4{8>a{D{(Dv zY57WDE3cmOT)jsH@)lI5%OH!6280)Xpw6n-BD$s8@PbSola zzVR<1B%&b`6Q8P^sQ*LstBvFwbGQ2v^4|oZ`LohE>eNU`AY$XgUaOnxltH8RbL4F|lV28XLa;(iTJDA##cHg=>P@#Vc&3&wv2T1e zl7tAn>elhnl}qekSJ$4lEy132!brDu?DX&SZ{M~nEv`G>*wN|V-uZ}x8S^51YI*~{ zgU<$89b*~7>hTe+w>Rc_^(gZUw|F)*uWXz`r#1qok7z3```5O-RoAs}#ecfW zzbE+t+BKQq=_-FC>OeF`yW-cM_K*bSv{&-)IQg1cUw>POkm|BTDqi+mxt2hEjlWDA zAXw+XMNfb|EOB)gy#UrB@d$Pz(F5#{<0Ct769^Ku#r`Bd!apJqr0_1B3IAH4)tNXf z@#_*7HOBd<#B&l4$o-haTV>70q1E3cE#WMIe%ivky_aXi>7@7r z{mE#!H#CqoqQfC0HW2NN4@OS;BP?CW zn*TNzuI4}B!qt2-e`;jF2=`z&lJ?%OPRVFI?8k^1%-`F~p*)G3t}E;9jnw`5-xTc)k9 zjNUa82~-gKP@+FFpo~}YWXIWVL4D|r2i&h^p3do$&I^rfLMzZ{FN>aa;3x8 SfmciaGa5Kh+} +#include + +int __pthread_musl_mutex_trylock_owner(__pthread_mutex_t *m) +{ + // fprintf(stderr, "Error pthread_musl_mutex_trylock_owner.\n"); + int old, own; + int type = m->_m_type; + // pthread_t self = pthread_self(); + unsigned long tid = pthread_self_glibc(); + + old = m->_m_lock; + own = old & 0x3fffffff; + if (own == tid) { + if ((type&8) && m->_m_count<0) { + old &= 0x40000000; + m->_m_count = 0; + goto success; + } + if ((type&3) == PTHREAD_MUTEX_RECURSIVE) { + if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN; + m->_m_count++; + return 0; + } + } + if (own == 0x3fffffff) { + // fprintf(stderr, "return ENOTRECOVERABLE 29;\n"); + return ENOTRECOVERABLE; + } + if (own || (old && !(type & 4))) { + // fprintf(stderr, "return EBUSY 33;\n"); + return EBUSY; + } + + //Work with robust_list + /* + if (type & 128) { + if (!self->robust_list.off) { + self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next; + __syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long)); + } + if (m->_m_waiters) tid |= 0x80000000; + self->robust_list.pending = &m->_m_next; + } + */ + tid |= old & 0x40000000; + + if (a_cas(&m->_m_lock, old, tid) != old) { + //self->robust_list.pending = 0; + if ((type&12)==12 && m->_m_waiters) { + // fprintf(stderr, "return ENOTRECOVERABLE 53;\n"); + return ENOTRECOVERABLE; + } + // fprintf(stderr, "return EBUSY 56;\n"); + return EBUSY; + } + +success: + if ((type&8) && m->_m_waiters) { + int priv = (type & 128) ^ 128; + __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); + //self->robust_list.pending = 0; + // fprintf(stderr, "return (type&4) ? ENOTRECOVERABLE : EBUSY;\n"); + return (type&4) ? ENOTRECOVERABLE : EBUSY; + } + + /* + volatile void *next = self->robust_list.head; + m->_m_next = next; + m->_m_prev = &self->robust_list.head; + if (next != &self->robust_list.head) *(volatile void *volatile *) + ((char *)next - sizeof(void *)) = &m->_m_next; + self->robust_list.head = &m->_m_next; + self->robust_list.pending = 0; + */ + + if (old) { + m->_m_count = 0; + // fprintf(stderr, "return EOWNERDEAD 81;\n"); + return EOWNERDEAD; + } + + // fprintf(stderr, "return 0;\n"); + return 0; +} + +int __pthread_musl_mutex_trylock(__pthread_mutex_t *m, musl_context_t *me) +{ + // fprintf(stderr, "Error __pthread_musl_mutex_trylock.\n"); + // fprintf(stderr, "Error cond_var not supported."); + // assert(1); + // return 0; + if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL) { + // fprintf(stderr, "return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;\n"); + return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY; + } + + // fprintf(stderr, "return __pthread_mutex_trylock_owner(m);\n"); + return __pthread_musl_mutex_trylock_owner(m); +} diff --git a/src/musl_mutex/pthread_mutex_trylock.o b/src/musl_mutex/pthread_mutex_trylock.o new file mode 100644 index 0000000000000000000000000000000000000000..c16f6b213d2673aea412208d09bd8fea0111f2a2 GIT binary patch literal 2288 zcmbtTO>7%Q6dpTH)21$Qt00QXPlQ_jyK<8XiBe!uv~)nUR3P7ooVB}Yp#F*MU8n)m zmQ|2Ot4clg&Xq$sAXyy1G!ms8_&H&2z96~82P0C|f)w+;@l5QljD+BmX5PH-{ms0$ zd(L|0#b_kLG$QOdHqbQ7*p>0Y*_20Hbkn!gX7)6+6Ype&eW&71y0t+!rJds5Bwqh{B{y)DP1FA!s^th zW{WnsO4f`Cs~uSF1HE4Fc@#m7XRHnHt-$K|&F!mo_o2Sq^lH6w&jqKAP?MNz<}{_b z@f9}dJLY#I-kfrN_OD*=+}o42o#e6?olyM6lMyT8BMB_HVJ#eId*p{YUVNJQk$z^tSk#i|<=Mqx#cU+kHgF#{F*G zySsk@dXTE~Ari=p>+fCKdhF{1H=H`RemHO*Zo=9OtWE!$34R$vX>k8)jEf(+xXQ(M zU($VAM^RB<)SZwIS>NB!e!qOi9!jiwR-@AEuc=T{QQxbM^hQE;CeHM=8QQbdGIMusUwmTwC5-bvaI^?d(DuSz ziI1Z5yS6RC0V>&!5)bUBP21B0`y0dqpCBKzRQ%Y-5%Qq;_sIyHpiSGORzCr8BS5KQ z?6=+s6W&DDJ8>`6=nya80*>xX{IE`uk7Mlt|0*efygTG^Eb3zziy+AVPgPpJg`8I0 z<&tBcO6NV-Ih%G%m0U4<#>ldCx?Cw|?Obk_+3BoZ1~G6g=kD}R7vCv3rLA0LC%2S7 zoqIDwY5qBi$`@z@Xx7`XHt`1%=J5d#h^KEt^D{UT$gEtXZpwYY>wYbUc-^n_Azt@| z8RbgewKI@zsV|rHspRBr16^{NamsdWW@O4`W@L-`yi)*ID7ub;Z}(u?wX + +int __pthread_musl_mutex_unlock(__pthread_mutex_t *m, musl_context_t *me) +{ + // fprintf(stderr, "Error __pthread_musl_mutex_unlock.\n"); + unsigned long self; + int waiters = m->_m_waiters; + int cont; + int type = m->_m_type & 15; + int priv = (m->_m_type & 128) ^ 128; + int new = 0; + int old; + + if (type != PTHREAD_MUTEX_NORMAL) { + // fprintf(stderr, "type != PTHREAD_MUTEX_NORMAL\n"); + // self = __pthread_self(); + old = m->_m_lock; + int own = old & 0x3fffffff; + // if (own != self->tid) + // return EPERM; + if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count) { + // fprintf(stderr, "type&3 == PTHREAD_MUTEX_RECURSIVE && m->_m_count\n"); + return m->_m_count--, 0; + } + if ((type&4) && (old&0x40000000)) { + new = 0x7fffffff; + } + if (!priv) { + // self->robust_list.pending = &m->_m_next; + // fprintf(stderr, "!priv\n"); + __vm_lock(); + } + // volatile void *prev = m->_m_prev; + // volatile void *next = m->_m_next; + // *(volatile void *volatile *)prev = next; + // if (next != &self->robust_list.head) *(volatile void *volatile *) + // ((char *)next - sizeof(void *)) = prev; + } + if (type&8) { + if (old<0 || a_cas(&m->_m_lock, old, new)!=old) { + if (new) a_store(&m->_m_waiters, -1); + __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); + } + cont = 0; + waiters = 0; + } else { + cont = a_swap(&m->_m_lock, new); + } + if (type != PTHREAD_MUTEX_NORMAL && !priv) { + // self->robust_list.pending = 0; + // fprintf(stderr, "type != PTHREAD_MUTEX_NORMAL && !priv\n"); + __vm_unlock(); + } + if (waiters || cont<0) + __wake(&m->_m_lock, 1, priv); + + // fprintf(stderr, "return 0 58;\n"); + return 0; +} + +// weak_alias(__pthread_musl_mutex_unlock, pthread_mutex_unlock); diff --git a/src/musl_mutex/pthread_mutex_unlock.o b/src/musl_mutex/pthread_mutex_unlock.o new file mode 100644 index 0000000000000000000000000000000000000000..a7ef54706ab4ce0f043ddcfa62df04f3a8bb324b GIT binary patch literal 2656 zcmbtWUuauZ7(YqVHg28mw8F3|LANo{UAnf2PMMK%-9g+aLQv2VZ?n`wlQbsx+Ex}j zxNLH`4EiYOgO5I{2#UxoEv%gnu6tS$!8}xmn1_ggU1S=6-?`@`@h-mT2j_g>`F(%S z_uUh+YQFqpG!kK&BJ33FoHWWv zT-+M&=fd;>`sX(9G8Jcb0`p2>?xl8m*!#k1id2JpXME3WdZ|WZ__KoolG$v>BpYNU zgZHC7b*As7nqs8k4jpD|%FnHjpmY`Atu&ZDxMemj;&yJO$yRV^wpy)K1m&4+&uqBc z5uTxveJ-wj`yK3R$6&x+{|Dz$X{D4mzor(pjrz#w()!x<&EJO~`9rqBt&bx$I^>Yc zu9u7pb5Baltq$V`fqZ-C2$h2tZkcrmvM{?4xWt6nKvhQ&{dr;DK>=>H&-EkD(Lg_X zY26-E;+2^eNn&R7D+=?=ZEVsZ2BZ5a3VlZruHwXtErcLY99sLEuK@_X4f3>6kh;Y!q>AwloY>BvzA1%oMtYAx5S#_FF3i%VS@UUzS7AM7wa=D`1Z)T%To+fEfyZ9h^w^27C&O z;;a$~l6MAw7K`u?2?S|;8ZzNuN|XgXfcz5HeZUR62uR)?d=87ggD@2V^uk%uo-bvs z^Xa@}XP47XA-9-WFfuHiF0Yg`RxUTu5ht0I&RAva4hbN`43 z-8=a-MGmAOi!AXcRX=^J`>^iNO9Z+2fQbm-kEQVhWFk^46M0U`y@Ts{ycxpvJT8WC zJ&%t=xSq#)2-owdhHyO(W|UX*wlxcGmjXVorBXI$8R)jnjPsUlF=Mt|W=3W)pU)P6 z6&CHRfj4}-Y+LA9aDJ=c7{$_JF6eg+8UvxJc zm>OH#dJGcHD%nN?VV8c8K>A(KjLDaNTZrgg5go-MT>oAXM$`=D4bZ#uKM4iJ{IC8e z;7j>+oe(AI{1m^N^!+tI38j|1?GoXFlrn5f@0tF(gs-dp6Ut9B-9LSvg+MXG{z;YJ z*M^FR{m%jKHNUv}AU;ukG(Ymy{(64Ba+Ax`6cm(D7pAv-4_4TpuwJctO?^KXpzo$| T{|-Xg%l}hVf3DjZa@hZGlv4NY literal 0 HcmV?d00001 diff --git a/src/musl_mutex/pthread_self_glibc.c b/src/musl_mutex/pthread_self_glibc.c new file mode 100644 index 0000000..a11cce1 --- /dev/null +++ b/src/musl_mutex/pthread_self_glibc.c @@ -0,0 +1,7 @@ +#include + +#include "pthread_self_glibc.h" + +unsigned long int pthread_self_glibc () { + return pthread_self(); +} diff --git a/src/musl_mutex/pthread_self_glibc.h b/src/musl_mutex/pthread_self_glibc.h new file mode 100644 index 0000000..00a677b --- /dev/null +++ b/src/musl_mutex/pthread_self_glibc.h @@ -0,0 +1,2 @@ + +unsigned long int pthread_self_glibc (); \ No newline at end of file diff --git a/src/musl_mutex/pthread_self_glibc.o b/src/musl_mutex/pthread_self_glibc.o new file mode 100644 index 0000000000000000000000000000000000000000..777b835e1e6205436736533244e75a2d387c63de GIT binary patch literal 1384 zcmbtTOG_L<5UyFDF&bBqAQ-}&L?Jfo0}&6hu=qei5`;axG!dUVO3C1Vs7~f z{tSsrQfK*WI+=y<{cOl3NDJ~Hz# z1cPut{Q04{@$>FCaoabrUMMWPQ$@d3H!XK|Ud^lA%wj8Y=T7DpRBmCK>8J^GBV_&ct9}|1aF&C*(;1_(lnJodpo62S9eQ$)qTIL%J7TT))l){d4X7Q@c%b|+1XXU-YPybGy + +int pthread_setcancelstate_glibc(int state, int *oldstate) { + return pthread_setcancelstate(state, oldstate); +} diff --git a/src/musl_mutex/pthread_setcancelstate_glibc.h b/src/musl_mutex/pthread_setcancelstate_glibc.h new file mode 100644 index 0000000..c80d54b --- /dev/null +++ b/src/musl_mutex/pthread_setcancelstate_glibc.h @@ -0,0 +1,3 @@ + + +int pthread_setcancelstate_glibc(int state, int *oldstate); diff --git a/src/musl_mutex/pthread_setcancelstate_glibc.o b/src/musl_mutex/pthread_setcancelstate_glibc.o new file mode 100644 index 0000000000000000000000000000000000000000..cbd72ae5b775c2c8551e264240c00bb19f107e1f GIT binary patch literal 1440 zcmbtSPiqrV5T8wJtF_fA9)uRzlUT5i^baBhB@kkRhzBvp5_h++O)=So-M5em>Y-2w zy@)42ipPQn@e7DwpwNSdh&L(JncbOm`%FFP!0d14H~-$gd2g#v9u*u1L>zbsr=G9? zFAAr2IW@~L1Jm&H>aAb(TK}-N`@PtIeO&7&gW7(5uwO;kh7@3f8QBbq3~ zrdW|~dCKUX0kz>750oFrpn^`jtwZF(j?oHtv4AHJUb4RxCaN2Cx;ipDpwbSy+1QM{ zw#Lc-FD|yA-Aq`m%IwR%OW1z9vlyUzDN6$50Vm#Me+rQ(c_YG8f8yocp_$627#7;| z?_!*K{%idr)>6+BYF=bM_0NmU7hJ`l*!jHoc_(MvxsNe6iF)P@q5pwvTt)%8Kk 0 +#define WCHAR_MAX (0xffffffffu+L'\0') +#define WCHAR_MIN (0+L'\0') +#else +#define WCHAR_MAX (0x7fffffff+L'\0') +#define WCHAR_MIN (-1-0x7fffffff+L'\0') +#endif + +#define SIG_ATOMIC_MIN INT32_MIN +#define SIG_ATOMIC_MAX INT32_MAX + +#include "stdintx86_64.h" + +#define INT8_C(c) c +#define INT16_C(c) c +#define INT32_C(c) c + +#define UINT8_C(c) c +#define UINT16_C(c) c +#define UINT32_C(c) c ## U + +#if UINTPTR_MAX == UINT64_MAX +#define INT64_C(c) c ## L +#define UINT64_C(c) c ## UL +#define INTMAX_C(c) c ## L +#define UINTMAX_C(c) c ## UL +#else +#define INT64_C(c) c ## LL +#define UINT64_C(c) c ## ULL +#define INTMAX_C(c) c ## LL +#define UINTMAX_C(c) c ## ULL +#endif + +#endif diff --git a/src/musl_mutex/stdintx86_64.h b/src/musl_mutex/stdintx86_64.h new file mode 100644 index 0000000..1bb147f --- /dev/null +++ b/src/musl_mutex/stdintx86_64.h @@ -0,0 +1,20 @@ +typedef int32_t int_fast16_t; +typedef int32_t int_fast32_t; +typedef uint32_t uint_fast16_t; +typedef uint32_t uint_fast32_t; + +#define INT_FAST16_MIN INT32_MIN +#define INT_FAST32_MIN INT32_MIN + +#define INT_FAST16_MAX INT32_MAX +#define INT_FAST32_MAX INT32_MAX + +#define UINT_FAST16_MAX UINT32_MAX +#define UINT_FAST32_MAX UINT32_MAX + +#define INTPTR_MIN INT64_MIN +#define INTPTR_MAX INT64_MAX +#define UINTPTR_MAX UINT64_MAX +#define PTRDIFF_MIN INT64_MIN +#define PTRDIFF_MAX INT64_MAX +#define SIZE_MAX UINT64_MAX diff --git a/src/musl_mutex/syscall.h b/src/musl_mutex/syscall.h new file mode 100644 index 0000000..3f47186 --- /dev/null +++ b/src/musl_mutex/syscall.h @@ -0,0 +1,410 @@ +#ifndef _INTERNAL_SYSCALL_H +#define _INTERNAL_SYSCALL_H + +#include +#include +#include +#include "syscall_archx86_64.h" + +#ifndef SYSCALL_RLIM_INFINITY +#define SYSCALL_RLIM_INFINITY (~0ULL) +#endif + +#ifndef SYSCALL_MMAP2_UNIT +#define SYSCALL_MMAP2_UNIT 4096ULL +#endif + +#ifndef __SYSCALL_LL_PRW +#define __SYSCALL_LL_PRW(x) __SYSCALL_LL_O(x) +#endif + +#ifndef __scc +#define __scc(X) ((long) (X)) +typedef long syscall_arg_t; +#endif + +long __syscall_ret(unsigned long), + __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t, + syscall_arg_t, syscall_arg_t, syscall_arg_t); + +#define __syscall1(n,a) __syscall1(n,__scc(a)) +#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b)) +#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c)) +#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d)) +#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e)) +#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) +#define __syscall7(n,a,b,c,d,e,f,g) __syscall7(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g)) + +#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n +#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,) +#define __SYSCALL_CONCAT_X(a,b) a##b +#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b) +#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) + +#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__) +#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__)) + +#define socketcall(nm,a,b,c,d,e,f) __syscall_ret(__socketcall(nm,a,b,c,d,e,f)) +#define socketcall_cp(nm,a,b,c,d,e,f) __syscall_ret(__socketcall_cp(nm,a,b,c,d,e,f)) + +#define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0) +#define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0) +#define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0) +#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),0,0,0) +#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),0,0) +#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),0) +#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f)) + +#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__) +#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__)) + +static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f) +{ + long r; + if (cp) r = __syscall_cp(sys, a, b, c, d, e, f); + else r = __syscall(sys, a, b, c, d, e, f); + if (r != -ENOSYS) return r; +#ifdef SYS_socketcall + if (cp) r = __syscall_cp(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f})); + else r = __syscall(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f})); +#endif + return r; +} +#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \ + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) +#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \ + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f)) + +/* fixup legacy 16-bit junk */ + +#ifdef SYS_getuid32 +#undef SYS_lchown +#undef SYS_getuid +#undef SYS_getgid +#undef SYS_geteuid +#undef SYS_getegid +#undef SYS_setreuid +#undef SYS_setregid +#undef SYS_getgroups +#undef SYS_setgroups +#undef SYS_fchown +#undef SYS_setresuid +#undef SYS_getresuid +#undef SYS_setresgid +#undef SYS_getresgid +#undef SYS_chown +#undef SYS_setuid +#undef SYS_setgid +#undef SYS_setfsuid +#undef SYS_setfsgid +#define SYS_lchown SYS_lchown32 +#define SYS_getuid SYS_getuid32 +#define SYS_getgid SYS_getgid32 +#define SYS_geteuid SYS_geteuid32 +#define SYS_getegid SYS_getegid32 +#define SYS_setreuid SYS_setreuid32 +#define SYS_setregid SYS_setregid32 +#define SYS_getgroups SYS_getgroups32 +#define SYS_setgroups SYS_setgroups32 +#define SYS_fchown SYS_fchown32 +#define SYS_setresuid SYS_setresuid32 +#define SYS_getresuid SYS_getresuid32 +#define SYS_setresgid SYS_setresgid32 +#define SYS_getresgid SYS_getresgid32 +#define SYS_chown SYS_chown32 +#define SYS_setuid SYS_setuid32 +#define SYS_setgid SYS_setgid32 +#define SYS_setfsuid SYS_setfsuid32 +#define SYS_setfsgid SYS_setfsgid32 +#endif + + +/* fixup legacy 32-bit-vs-lfs64 junk */ + +#ifdef SYS_fcntl64 +#undef SYS_fcntl +#define SYS_fcntl SYS_fcntl64 +#endif + +#ifdef SYS_getdents64 +#undef SYS_getdents +#define SYS_getdents SYS_getdents64 +#endif + +#ifdef SYS_ftruncate64 +#undef SYS_ftruncate +#undef SYS_truncate +#define SYS_ftruncate SYS_ftruncate64 +#define SYS_truncate SYS_truncate64 +#endif + +#ifdef SYS_stat64 +#undef SYS_stat +#define SYS_stat SYS_stat64 +#endif + +#ifdef SYS_fstat64 +#undef SYS_fstat +#define SYS_fstat SYS_fstat64 +#endif + +#ifdef SYS_lstat64 +#undef SYS_lstat +#define SYS_lstat SYS_lstat64 +#endif + +#ifdef SYS_statfs64 +#undef SYS_statfs +#define SYS_statfs SYS_statfs64 +#endif + +#ifdef SYS_fstatfs64 +#undef SYS_fstatfs +#define SYS_fstatfs SYS_fstatfs64 +#endif + +#if defined(SYS_newfstatat) +#undef SYS_fstatat +#define SYS_fstatat SYS_newfstatat +#elif defined(SYS_fstatat64) +#undef SYS_fstatat +#define SYS_fstatat SYS_fstatat64 +#endif + +#ifdef SYS_ugetrlimit +#undef SYS_getrlimit +#define SYS_getrlimit SYS_ugetrlimit +#endif + +#ifdef SYS__newselect +#undef SYS_select +#define SYS_select SYS__newselect +#endif + +#ifdef SYS_pread64 +#undef SYS_pread +#undef SYS_pwrite +#define SYS_pread SYS_pread64 +#define SYS_pwrite SYS_pwrite64 +#endif + +#ifdef SYS_fadvise64_64 +#undef SYS_fadvise +#define SYS_fadvise SYS_fadvise64_64 +#elif defined(SYS_fadvise64) +#undef SYS_fadvise +#define SYS_fadvise SYS_fadvise64 +#endif + +#ifdef SYS_sendfile64 +#undef SYS_sendfile +#define SYS_sendfile SYS_sendfile64 +#endif + +#ifdef SYS_timer_settime32 +#define SYS_timer_settime SYS_timer_settime32 +#endif + +#ifdef SYS_timer_gettime32 +#define SYS_timer_gettime SYS_timer_gettime32 +#endif + +#ifdef SYS_timerfd_settime32 +#define SYS_timerfd_settime SYS_timerfd_settime32 +#endif + +#ifdef SYS_timerfd_gettime32 +#define SYS_timerfd_gettime SYS_timerfd_gettime32 +#endif + +#ifdef SYS_clock_settime32 +#define SYS_clock_settime SYS_clock_settime32 +#endif + +#ifdef SYS_clock_gettime32 +#define SYS_clock_gettime SYS_clock_gettime32 +#endif + +#ifdef SYS_clock_getres_time32 +#define SYS_clock_getres SYS_clock_getres_time32 +#endif + +#ifdef SYS_clock_nanosleep_time32 +#define SYS_clock_nanosleep SYS_clock_nanosleep_time32 +#endif + +#ifdef SYS_gettimeofday_time32 +#define SYS_gettimeofday SYS_gettimeofday_time32 +#endif + +#ifdef SYS_settimeofday_time32 +#define SYS_settimeofday SYS_settimeofday_time32 +#endif + +/* Ensure that the plain syscall names are defined even for "time64-only" + * archs. These facilitate callers passing null time arguments, and make + * tests for establishing which to use/fallback-to more consistent when + * they do need to be called with time arguments. */ + +#ifndef SYS_clock_gettime +#define SYS_clock_gettime SYS_clock_gettime64 +#endif + +#ifndef SYS_clock_settime +#define SYS_clock_settime SYS_clock_settime64 +#endif + +#ifndef SYS_clock_adjtime +#define SYS_clock_adjtime SYS_clock_adjtime64 +#endif + +#ifndef SYS_clock_getres +#define SYS_clock_getres SYS_clock_getres_time64 +#endif + +#ifndef SYS_clock_nanosleep +#define SYS_clock_nanosleep SYS_clock_nanosleep_time64 +#endif + +#ifndef SYS_timer_gettime +#define SYS_timer_gettime SYS_timer_gettime64 +#endif + +#ifndef SYS_timer_settime +#define SYS_timer_settime SYS_timer_settime64 +#endif + +#ifndef SYS_timerfd_gettime +#define SYS_timerfd_gettime SYS_timerfd_gettime64 +#endif + +#ifndef SYS_timerfd_settime +#define SYS_timerfd_settime SYS_timerfd_settime64 +#endif + +#ifndef SYS_utimensat +#define SYS_utimensat SYS_utimensat_time64 +#endif + +#ifndef SYS_pselect6 +#define SYS_pselect6 SYS_pselect6_time64 +#endif + +#ifndef SYS_ppoll +#define SYS_ppoll SYS_ppoll_time64 +#endif + +#ifndef SYS_recvmmsg +#define SYS_recvmmsg SYS_recvmmsg_time64 +#endif + +#ifndef SYS_mq_timedsend +#define SYS_mq_timedsend SYS_mq_timedsend_time64 +#endif + +#ifndef SYS_mq_timedreceive +#define SYS_mq_timedreceive SYS_mq_timedreceive_time64 +#endif + +/* SYS_semtimedop omitted because SYS_ipc may provide it */ + +#ifndef SYS_rt_sigtimedwait +#define SYS_rt_sigtimedwait SYS_rt_sigtimedwait_time64 +#endif + +#ifndef SYS_futex +#define SYS_futex SYS_futex_time64 +#endif + +#ifndef SYS_sched_rr_get_interval +#define SYS_sched_rr_get_interval SYS_sched_rr_get_interval_time64 +#endif + + + + +/* socketcall calls */ + +#define __SC_socket 1 +#define __SC_bind 2 +#define __SC_connect 3 +#define __SC_listen 4 +#define __SC_accept 5 +#define __SC_getsockname 6 +#define __SC_getpeername 7 +#define __SC_socketpair 8 +#define __SC_send 9 +#define __SC_recv 10 +#define __SC_sendto 11 +#define __SC_recvfrom 12 +#define __SC_shutdown 13 +#define __SC_setsockopt 14 +#define __SC_getsockopt 15 +#define __SC_sendmsg 16 +#define __SC_recvmsg 17 +#define __SC_accept4 18 +#define __SC_recvmmsg 19 +#define __SC_sendmmsg 20 + +/* This is valid only because all socket syscalls are made via + * socketcall, which always fills unused argument slots with zeros. */ +#ifndef SYS_accept +#define SYS_accept SYS_accept4 +#endif + +#ifndef SO_RCVTIMEO_OLD +#define SO_RCVTIMEO_OLD 20 +#endif +#ifndef SO_SNDTIMEO_OLD +#define SO_SNDTIMEO_OLD 21 +#endif + +#define SO_TIMESTAMP_OLD 29 +#define SO_TIMESTAMPNS_OLD 35 +#define SO_TIMESTAMPING_OLD 37 +#define SCM_TIMESTAMP_OLD SO_TIMESTAMP_OLD +#define SCM_TIMESTAMPNS_OLD SO_TIMESTAMPNS_OLD +#define SCM_TIMESTAMPING_OLD SO_TIMESTAMPING_OLD + +#ifndef SIOCGSTAMP_OLD +#define SIOCGSTAMP_OLD 0x8906 +#endif +#ifndef SIOCGSTAMPNS_OLD +#define SIOCGSTAMPNS_OLD 0x8907 +#endif + +#ifdef SYS_open +#define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE) +#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo) +#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_open, pn, (fl)|O_LARGEFILE) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_open, pn, (fl)|O_LARGEFILE, mo) +#else +#define __sys_open2(x,pn,fl) __syscall3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) +#define __sys_open3(x,pn,fl,mo) __syscall4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) +#define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE) +#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo) +#endif + +#define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__) +#define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__)) + +#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__) +#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__)) + +#ifdef SYS_wait4 +#define __sys_wait4(a,b,c,d) __syscall(SYS_wait4,a,b,c,d) +#define __sys_wait4_cp(a,b,c,d) __syscall_cp(SYS_wait4,a,b,c,d) +#else +hidden long __emulate_wait4(int, int *, int, void *, int); +#define __sys_wait4(a,b,c,d) __emulate_wait4(a,b,c,d,0) +#define __sys_wait4_cp(a,b,c,d) __emulate_wait4(a,b,c,d,1) +#endif + +#define sys_wait4(a,b,c,d) __syscall_ret(__sys_wait4(a,b,c,d)) +#define sys_wait4_cp(a,b,c,d) __syscall_ret(__sys_wait4_cp(a,b,c,d)) + +void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned); + +void *__vdsosym(const char *, const char *); + +#endif diff --git a/src/musl_mutex/syscall_archx86_64.h b/src/musl_mutex/syscall_archx86_64.h new file mode 100644 index 0000000..92d5c17 --- /dev/null +++ b/src/musl_mutex/syscall_archx86_64.h @@ -0,0 +1,70 @@ +#define __SYSCALL_LL_E(x) (x) +#define __SYSCALL_LL_O(x) (x) + +static __inline long __syscall0(long n) +{ + unsigned long ret; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n) : "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall1(long n, long a1) +{ + unsigned long ret; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1) : "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall2(long n, long a1, long a2) +{ + unsigned long ret; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2) + : "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall3(long n, long a1, long a2, long a3) +{ + unsigned long ret; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), + "d"(a3) : "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall4(long n, long a1, long a2, long a3, long a4) +{ + unsigned long ret; + register long r10 __asm__("r10") = a4; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), + "d"(a3), "r"(r10): "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall5(long n, long a1, long a2, long a3, long a4, long a5) +{ + unsigned long ret; + register long r10 __asm__("r10") = a4; + register long r8 __asm__("r8") = a5; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), + "d"(a3), "r"(r10), "r"(r8) : "rcx", "r11", "memory"); + return ret; +} + +static __inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a5, long a6) +{ + unsigned long ret; + register long r10 __asm__("r10") = a4; + register long r8 __asm__("r8") = a5; + register long r9 __asm__("r9") = a6; + __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2), + "d"(a3), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); + return ret; +} + +#define VDSO_USEFUL +#define VDSO_CGT_SYM "__vdso_clock_gettime" +#define VDSO_CGT_VER "LINUX_2.6" +#define VDSO_GETCPU_SYM "__vdso_getcpu" +#define VDSO_GETCPU_VER "LINUX_2.6" + +#define IPC_64 0 diff --git a/src/musl_mutex/syscall_make.h b/src/musl_mutex/syscall_make.h new file mode 100644 index 0000000..25ccb44 --- /dev/null +++ b/src/musl_mutex/syscall_make.h @@ -0,0 +1,727 @@ +#define __NR_read 0 +#define __NR_write 1 +#define __NR_open 2 +#define __NR_close 3 +#define __NR_stat 4 +#define __NR_fstat 5 +#define __NR_lstat 6 +#define __NR_poll 7 +#define __NR_lseek 8 +#define __NR_mmap 9 +#define __NR_mprotect 10 +#define __NR_munmap 11 +#define __NR_brk 12 +#define __NR_rt_sigaction 13 +#define __NR_rt_sigprocmask 14 +#define __NR_rt_sigreturn 15 +#define __NR_ioctl 16 +#define __NR_pread64 17 +#define __NR_pwrite64 18 +#define __NR_readv 19 +#define __NR_writev 20 +#define __NR_access 21 +#define __NR_pipe 22 +#define __NR_select 23 +#define __NR_sched_yield 24 +#define __NR_mremap 25 +#define __NR_msync 26 +#define __NR_mincore 27 +#define __NR_madvise 28 +#define __NR_shmget 29 +#define __NR_shmat 30 +#define __NR_shmctl 31 +#define __NR_dup 32 +#define __NR_dup2 33 +#define __NR_pause 34 +#define __NR_nanosleep 35 +#define __NR_getitimer 36 +#define __NR_alarm 37 +#define __NR_setitimer 38 +#define __NR_getpid 39 +#define __NR_sendfile 40 +#define __NR_socket 41 +#define __NR_connect 42 +#define __NR_accept 43 +#define __NR_sendto 44 +#define __NR_recvfrom 45 +#define __NR_sendmsg 46 +#define __NR_recvmsg 47 +#define __NR_shutdown 48 +#define __NR_bind 49 +#define __NR_listen 50 +#define __NR_getsockname 51 +#define __NR_getpeername 52 +#define __NR_socketpair 53 +#define __NR_setsockopt 54 +#define __NR_getsockopt 55 +#define __NR_clone 56 +#define __NR_fork 57 +#define __NR_vfork 58 +#define __NR_execve 59 +#define __NR_exit 60 +#define __NR_wait4 61 +#define __NR_kill 62 +#define __NR_uname 63 +#define __NR_semget 64 +#define __NR_semop 65 +#define __NR_semctl 66 +#define __NR_shmdt 67 +#define __NR_msgget 68 +#define __NR_msgsnd 69 +#define __NR_msgrcv 70 +#define __NR_msgctl 71 +#define __NR_fcntl 72 +#define __NR_flock 73 +#define __NR_fsync 74 +#define __NR_fdatasync 75 +#define __NR_truncate 76 +#define __NR_ftruncate 77 +#define __NR_getdents 78 +#define __NR_getcwd 79 +#define __NR_chdir 80 +#define __NR_fchdir 81 +#define __NR_rename 82 +#define __NR_mkdir 83 +#define __NR_rmdir 84 +#define __NR_creat 85 +#define __NR_link 86 +#define __NR_unlink 87 +#define __NR_symlink 88 +#define __NR_readlink 89 +#define __NR_chmod 90 +#define __NR_fchmod 91 +#define __NR_chown 92 +#define __NR_fchown 93 +#define __NR_lchown 94 +#define __NR_umask 95 +#define __NR_gettimeofday 96 +#define __NR_getrlimit 97 +#define __NR_getrusage 98 +#define __NR_sysinfo 99 +#define __NR_times 100 +#define __NR_ptrace 101 +#define __NR_getuid 102 +#define __NR_syslog 103 +#define __NR_getgid 104 +#define __NR_setuid 105 +#define __NR_setgid 106 +#define __NR_geteuid 107 +#define __NR_getegid 108 +#define __NR_setpgid 109 +#define __NR_getppid 110 +#define __NR_getpgrp 111 +#define __NR_setsid 112 +#define __NR_setreuid 113 +#define __NR_setregid 114 +#define __NR_getgroups 115 +#define __NR_setgroups 116 +#define __NR_setresuid 117 +#define __NR_getresuid 118 +#define __NR_setresgid 119 +#define __NR_getresgid 120 +#define __NR_getpgid 121 +#define __NR_setfsuid 122 +#define __NR_setfsgid 123 +#define __NR_getsid 124 +#define __NR_capget 125 +#define __NR_capset 126 +#define __NR_rt_sigpending 127 +#define __NR_rt_sigtimedwait 128 +#define __NR_rt_sigqueueinfo 129 +#define __NR_rt_sigsuspend 130 +#define __NR_sigaltstack 131 +#define __NR_utime 132 +#define __NR_mknod 133 +#define __NR_uselib 134 +#define __NR_personality 135 +#define __NR_ustat 136 +#define __NR_statfs 137 +#define __NR_fstatfs 138 +#define __NR_sysfs 139 +#define __NR_getpriority 140 +#define __NR_setpriority 141 +#define __NR_sched_setparam 142 +#define __NR_sched_getparam 143 +#define __NR_sched_setscheduler 144 +#define __NR_sched_getscheduler 145 +#define __NR_sched_get_priority_max 146 +#define __NR_sched_get_priority_min 147 +#define __NR_sched_rr_get_interval 148 +#define __NR_mlock 149 +#define __NR_munlock 150 +#define __NR_mlockall 151 +#define __NR_munlockall 152 +#define __NR_vhangup 153 +#define __NR_modify_ldt 154 +#define __NR_pivot_root 155 +#define __NR__sysctl 156 +#define __NR_prctl 157 +#define __NR_arch_prctl 158 +#define __NR_adjtimex 159 +#define __NR_setrlimit 160 +#define __NR_chroot 161 +#define __NR_sync 162 +#define __NR_acct 163 +#define __NR_settimeofday 164 +#define __NR_mount 165 +#define __NR_umount2 166 +#define __NR_swapon 167 +#define __NR_swapoff 168 +#define __NR_reboot 169 +#define __NR_sethostname 170 +#define __NR_setdomainname 171 +#define __NR_iopl 172 +#define __NR_ioperm 173 +#define __NR_create_module 174 +#define __NR_init_module 175 +#define __NR_delete_module 176 +#define __NR_get_kernel_syms 177 +#define __NR_query_module 178 +#define __NR_quotactl 179 +#define __NR_nfsservctl 180 +#define __NR_getpmsg 181 +#define __NR_putpmsg 182 +#define __NR_afs_syscall 183 +#define __NR_tuxcall 184 +#define __NR_security 185 +#define __NR_gettid 186 +#define __NR_readahead 187 +#define __NR_setxattr 188 +#define __NR_lsetxattr 189 +#define __NR_fsetxattr 190 +#define __NR_getxattr 191 +#define __NR_lgetxattr 192 +#define __NR_fgetxattr 193 +#define __NR_listxattr 194 +#define __NR_llistxattr 195 +#define __NR_flistxattr 196 +#define __NR_removexattr 197 +#define __NR_lremovexattr 198 +#define __NR_fremovexattr 199 +#define __NR_tkill 200 +#define __NR_time 201 +#define __NR_futex 202 +#define __NR_sched_setaffinity 203 +#define __NR_sched_getaffinity 204 +#define __NR_set_thread_area 205 +#define __NR_io_setup 206 +#define __NR_io_destroy 207 +#define __NR_io_getevents 208 +#define __NR_io_submit 209 +#define __NR_io_cancel 210 +#define __NR_get_thread_area 211 +#define __NR_lookup_dcookie 212 +#define __NR_epoll_create 213 +#define __NR_epoll_ctl_old 214 +#define __NR_epoll_wait_old 215 +#define __NR_remap_file_pages 216 +#define __NR_getdents64 217 +#define __NR_set_tid_address 218 +#define __NR_restart_syscall 219 +#define __NR_semtimedop 220 +#define __NR_fadvise64 221 +#define __NR_timer_create 222 +#define __NR_timer_settime 223 +#define __NR_timer_gettime 224 +#define __NR_timer_getoverrun 225 +#define __NR_timer_delete 226 +#define __NR_clock_settime 227 +#define __NR_clock_gettime 228 +#define __NR_clock_getres 229 +#define __NR_clock_nanosleep 230 +#define __NR_exit_group 231 +#define __NR_epoll_wait 232 +#define __NR_epoll_ctl 233 +#define __NR_tgkill 234 +#define __NR_utimes 235 +#define __NR_vserver 236 +#define __NR_mbind 237 +#define __NR_set_mempolicy 238 +#define __NR_get_mempolicy 239 +#define __NR_mq_open 240 +#define __NR_mq_unlink 241 +#define __NR_mq_timedsend 242 +#define __NR_mq_timedreceive 243 +#define __NR_mq_notify 244 +#define __NR_mq_getsetattr 245 +#define __NR_kexec_load 246 +#define __NR_waitid 247 +#define __NR_add_key 248 +#define __NR_request_key 249 +#define __NR_keyctl 250 +#define __NR_ioprio_set 251 +#define __NR_ioprio_get 252 +#define __NR_inotify_init 253 +#define __NR_inotify_add_watch 254 +#define __NR_inotify_rm_watch 255 +#define __NR_migrate_pages 256 +#define __NR_openat 257 +#define __NR_mkdirat 258 +#define __NR_mknodat 259 +#define __NR_fchownat 260 +#define __NR_futimesat 261 +#define __NR_newfstatat 262 +#define __NR_unlinkat 263 +#define __NR_renameat 264 +#define __NR_linkat 265 +#define __NR_symlinkat 266 +#define __NR_readlinkat 267 +#define __NR_fchmodat 268 +#define __NR_faccessat 269 +#define __NR_pselect6 270 +#define __NR_ppoll 271 +#define __NR_unshare 272 +#define __NR_set_robust_list 273 +#define __NR_get_robust_list 274 +#define __NR_splice 275 +#define __NR_tee 276 +#define __NR_sync_file_range 277 +#define __NR_vmsplice 278 +#define __NR_move_pages 279 +#define __NR_utimensat 280 +#define __NR_epoll_pwait 281 +#define __NR_signalfd 282 +#define __NR_timerfd_create 283 +#define __NR_eventfd 284 +#define __NR_fallocate 285 +#define __NR_timerfd_settime 286 +#define __NR_timerfd_gettime 287 +#define __NR_accept4 288 +#define __NR_signalfd4 289 +#define __NR_eventfd2 290 +#define __NR_epoll_create1 291 +#define __NR_dup3 292 +#define __NR_pipe2 293 +#define __NR_inotify_init1 294 +#define __NR_preadv 295 +#define __NR_pwritev 296 +#define __NR_rt_tgsigqueueinfo 297 +#define __NR_perf_event_open 298 +#define __NR_recvmmsg 299 +#define __NR_fanotify_init 300 +#define __NR_fanotify_mark 301 +#define __NR_prlimit64 302 +#define __NR_name_to_handle_at 303 +#define __NR_open_by_handle_at 304 +#define __NR_clock_adjtime 305 +#define __NR_syncfs 306 +#define __NR_sendmmsg 307 +#define __NR_setns 308 +#define __NR_getcpu 309 +#define __NR_process_vm_readv 310 +#define __NR_process_vm_writev 311 +#define __NR_kcmp 312 +#define __NR_finit_module 313 +#define __NR_sched_setattr 314 +#define __NR_sched_getattr 315 +#define __NR_renameat2 316 +#define __NR_seccomp 317 +#define __NR_getrandom 318 +#define __NR_memfd_create 319 +#define __NR_kexec_file_load 320 +#define __NR_bpf 321 +#define __NR_execveat 322 +#define __NR_userfaultfd 323 +#define __NR_membarrier 324 +#define __NR_mlock2 325 +#define __NR_copy_file_range 326 +#define __NR_preadv2 327 +#define __NR_pwritev2 328 +#define __NR_pkey_mprotect 329 +#define __NR_pkey_alloc 330 +#define __NR_pkey_free 331 +#define __NR_statx 332 +#define __NR_io_pgetevents 333 +#define __NR_rseq 334 +#define __NR_pidfd_send_signal 424 +#define __NR_io_uring_setup 425 +#define __NR_io_uring_enter 426 +#define __NR_io_uring_register 427 +#define __NR_open_tree 428 +#define __NR_move_mount 429 +#define __NR_fsopen 430 +#define __NR_fsconfig 431 +#define __NR_fsmount 432 +#define __NR_fspick 433 +#define __NR_pidfd_open 434 +#define __NR_clone3 435 +#define __NR_close_range 436 +#define __NR_openat2 437 +#define __NR_pidfd_getfd 438 +#define __NR_faccessat2 439 +#define __NR_process_madvise 440 +#define __NR_epoll_pwait2 441 +#define __NR_mount_setattr 442 +#define __NR_landlock_create_ruleset 444 +#define __NR_landlock_add_rule 445 +#define __NR_landlock_restrict_self 446 +#define __NR_memfd_secret 447 +#define __NR_process_mrelease 448 +#define __NR_futex_waitv 449 +#define __NR_set_mempolicy_home_node 450 +#define __NR_cachestat 451 +#define __NR_fchmodat2 452 + +#define SYS_read 0 +#define SYS_write 1 +#define SYS_open 2 +#define SYS_close 3 +#define SYS_stat 4 +#define SYS_fstat 5 +#define SYS_lstat 6 +#define SYS_poll 7 +#define SYS_lseek 8 +#define SYS_mmap 9 +#define SYS_mprotect 10 +#define SYS_munmap 11 +#define SYS_brk 12 +#define SYS_rt_sigaction 13 +#define SYS_rt_sigprocmask 14 +#define SYS_rt_sigreturn 15 +#define SYS_ioctl 16 +#define SYS_pread64 17 +#define SYS_pwrite64 18 +#define SYS_readv 19 +#define SYS_writev 20 +#define SYS_access 21 +#define SYS_pipe 22 +#define SYS_select 23 +#define SYS_sched_yield 24 +#define SYS_mremap 25 +#define SYS_msync 26 +#define SYS_mincore 27 +#define SYS_madvise 28 +#define SYS_shmget 29 +#define SYS_shmat 30 +#define SYS_shmctl 31 +#define SYS_dup 32 +#define SYS_dup2 33 +#define SYS_pause 34 +#define SYS_nanosleep 35 +#define SYS_getitimer 36 +#define SYS_alarm 37 +#define SYS_setitimer 38 +#define SYS_getpid 39 +#define SYS_sendfile 40 +#define SYS_socket 41 +#define SYS_connect 42 +#define SYS_accept 43 +#define SYS_sendto 44 +#define SYS_recvfrom 45 +#define SYS_sendmsg 46 +#define SYS_recvmsg 47 +#define SYS_shutdown 48 +#define SYS_bind 49 +#define SYS_listen 50 +#define SYS_getsockname 51 +#define SYS_getpeername 52 +#define SYS_socketpair 53 +#define SYS_setsockopt 54 +#define SYS_getsockopt 55 +#define SYS_clone 56 +#define SYS_fork 57 +#define SYS_vfork 58 +#define SYS_execve 59 +#define SYS_exit 60 +#define SYS_wait4 61 +#define SYS_kill 62 +#define SYS_uname 63 +#define SYS_semget 64 +#define SYS_semop 65 +#define SYS_semctl 66 +#define SYS_shmdt 67 +#define SYS_msgget 68 +#define SYS_msgsnd 69 +#define SYS_msgrcv 70 +#define SYS_msgctl 71 +#define SYS_fcntl 72 +#define SYS_flock 73 +#define SYS_fsync 74 +#define SYS_fdatasync 75 +#define SYS_truncate 76 +#define SYS_ftruncate 77 +#define SYS_getdents 78 +#define SYS_getcwd 79 +#define SYS_chdir 80 +#define SYS_fchdir 81 +#define SYS_rename 82 +#define SYS_mkdir 83 +#define SYS_rmdir 84 +#define SYS_creat 85 +#define SYS_link 86 +#define SYS_unlink 87 +#define SYS_symlink 88 +#define SYS_readlink 89 +#define SYS_chmod 90 +#define SYS_fchmod 91 +#define SYS_chown 92 +#define SYS_fchown 93 +#define SYS_lchown 94 +#define SYS_umask 95 +#define SYS_gettimeofday 96 +#define SYS_getrlimit 97 +#define SYS_getrusage 98 +#define SYS_sysinfo 99 +#define SYS_times 100 +#define SYS_ptrace 101 +#define SYS_getuid 102 +#define SYS_syslog 103 +#define SYS_getgid 104 +#define SYS_setuid 105 +#define SYS_setgid 106 +#define SYS_geteuid 107 +#define SYS_getegid 108 +#define SYS_setpgid 109 +#define SYS_getppid 110 +#define SYS_getpgrp 111 +#define SYS_setsid 112 +#define SYS_setreuid 113 +#define SYS_setregid 114 +#define SYS_getgroups 115 +#define SYS_setgroups 116 +#define SYS_setresuid 117 +#define SYS_getresuid 118 +#define SYS_setresgid 119 +#define SYS_getresgid 120 +#define SYS_getpgid 121 +#define SYS_setfsuid 122 +#define SYS_setfsgid 123 +#define SYS_getsid 124 +#define SYS_capget 125 +#define SYS_capset 126 +#define SYS_rt_sigpending 127 +#define SYS_rt_sigtimedwait 128 +#define SYS_rt_sigqueueinfo 129 +#define SYS_rt_sigsuspend 130 +#define SYS_sigaltstack 131 +#define SYS_utime 132 +#define SYS_mknod 133 +#define SYS_uselib 134 +#define SYS_personality 135 +#define SYS_ustat 136 +#define SYS_statfs 137 +#define SYS_fstatfs 138 +#define SYS_sysfs 139 +#define SYS_getpriority 140 +#define SYS_setpriority 141 +#define SYS_sched_setparam 142 +#define SYS_sched_getparam 143 +#define SYS_sched_setscheduler 144 +#define SYS_sched_getscheduler 145 +#define SYS_sched_get_priority_max 146 +#define SYS_sched_get_priority_min 147 +#define SYS_sched_rr_get_interval 148 +#define SYS_mlock 149 +#define SYS_munlock 150 +#define SYS_mlockall 151 +#define SYS_munlockall 152 +#define SYS_vhangup 153 +#define SYS_modify_ldt 154 +#define SYS_pivot_root 155 +#define SYS__sysctl 156 +#define SYS_prctl 157 +#define SYS_arch_prctl 158 +#define SYS_adjtimex 159 +#define SYS_setrlimit 160 +#define SYS_chroot 161 +#define SYS_sync 162 +#define SYS_acct 163 +#define SYS_settimeofday 164 +#define SYS_mount 165 +#define SYS_umount2 166 +#define SYS_swapon 167 +#define SYS_swapoff 168 +#define SYS_reboot 169 +#define SYS_sethostname 170 +#define SYS_setdomainname 171 +#define SYS_iopl 172 +#define SYS_ioperm 173 +#define SYS_create_module 174 +#define SYS_init_module 175 +#define SYS_delete_module 176 +#define SYS_get_kernel_syms 177 +#define SYS_query_module 178 +#define SYS_quotactl 179 +#define SYS_nfsservctl 180 +#define SYS_getpmsg 181 +#define SYS_putpmsg 182 +#define SYS_afs_syscall 183 +#define SYS_tuxcall 184 +#define SYS_security 185 +#define SYS_gettid 186 +#define SYS_readahead 187 +#define SYS_setxattr 188 +#define SYS_lsetxattr 189 +#define SYS_fsetxattr 190 +#define SYS_getxattr 191 +#define SYS_lgetxattr 192 +#define SYS_fgetxattr 193 +#define SYS_listxattr 194 +#define SYS_llistxattr 195 +#define SYS_flistxattr 196 +#define SYS_removexattr 197 +#define SYS_lremovexattr 198 +#define SYS_fremovexattr 199 +#define SYS_tkill 200 +#define SYS_time 201 +#define SYS_futex 202 +#define SYS_sched_setaffinity 203 +#define SYS_sched_getaffinity 204 +#define SYS_set_thread_area 205 +#define SYS_io_setup 206 +#define SYS_io_destroy 207 +#define SYS_io_getevents 208 +#define SYS_io_submit 209 +#define SYS_io_cancel 210 +#define SYS_get_thread_area 211 +#define SYS_lookup_dcookie 212 +#define SYS_epoll_create 213 +#define SYS_epoll_ctl_old 214 +#define SYS_epoll_wait_old 215 +#define SYS_remap_file_pages 216 +#define SYS_getdents64 217 +#define SYS_set_tid_address 218 +#define SYS_restart_syscall 219 +#define SYS_semtimedop 220 +#define SYS_fadvise64 221 +#define SYS_timer_create 222 +#define SYS_timer_settime 223 +#define SYS_timer_gettime 224 +#define SYS_timer_getoverrun 225 +#define SYS_timer_delete 226 +#define SYS_clock_settime 227 +#define SYS_clock_gettime 228 +#define SYS_clock_getres 229 +#define SYS_clock_nanosleep 230 +#define SYS_exit_group 231 +#define SYS_epoll_wait 232 +#define SYS_epoll_ctl 233 +#define SYS_tgkill 234 +#define SYS_utimes 235 +#define SYS_vserver 236 +#define SYS_mbind 237 +#define SYS_set_mempolicy 238 +#define SYS_get_mempolicy 239 +#define SYS_mq_open 240 +#define SYS_mq_unlink 241 +#define SYS_mq_timedsend 242 +#define SYS_mq_timedreceive 243 +#define SYS_mq_notify 244 +#define SYS_mq_getsetattr 245 +#define SYS_kexec_load 246 +#define SYS_waitid 247 +#define SYS_add_key 248 +#define SYS_request_key 249 +#define SYS_keyctl 250 +#define SYS_ioprio_set 251 +#define SYS_ioprio_get 252 +#define SYS_inotify_init 253 +#define SYS_inotify_add_watch 254 +#define SYS_inotify_rm_watch 255 +#define SYS_migrate_pages 256 +#define SYS_openat 257 +#define SYS_mkdirat 258 +#define SYS_mknodat 259 +#define SYS_fchownat 260 +#define SYS_futimesat 261 +#define SYS_newfstatat 262 +#define SYS_unlinkat 263 +#define SYS_renameat 264 +#define SYS_linkat 265 +#define SYS_symlinkat 266 +#define SYS_readlinkat 267 +#define SYS_fchmodat 268 +#define SYS_faccessat 269 +#define SYS_pselect6 270 +#define SYS_ppoll 271 +#define SYS_unshare 272 +#define SYS_set_robust_list 273 +#define SYS_get_robust_list 274 +#define SYS_splice 275 +#define SYS_tee 276 +#define SYS_sync_file_range 277 +#define SYS_vmsplice 278 +#define SYS_move_pages 279 +#define SYS_utimensat 280 +#define SYS_epoll_pwait 281 +#define SYS_signalfd 282 +#define SYS_timerfd_create 283 +#define SYS_eventfd 284 +#define SYS_fallocate 285 +#define SYS_timerfd_settime 286 +#define SYS_timerfd_gettime 287 +#define SYS_accept4 288 +#define SYS_signalfd4 289 +#define SYS_eventfd2 290 +#define SYS_epoll_create1 291 +#define SYS_dup3 292 +#define SYS_pipe2 293 +#define SYS_inotify_init1 294 +#define SYS_preadv 295 +#define SYS_pwritev 296 +#define SYS_rt_tgsigqueueinfo 297 +#define SYS_perf_event_open 298 +#define SYS_recvmmsg 299 +#define SYS_fanotify_init 300 +#define SYS_fanotify_mark 301 +#define SYS_prlimit64 302 +#define SYS_name_to_handle_at 303 +#define SYS_open_by_handle_at 304 +#define SYS_clock_adjtime 305 +#define SYS_syncfs 306 +#define SYS_sendmmsg 307 +#define SYS_setns 308 +#define SYS_getcpu 309 +#define SYS_process_vm_readv 310 +#define SYS_process_vm_writev 311 +#define SYS_kcmp 312 +#define SYS_finit_module 313 +#define SYS_sched_setattr 314 +#define SYS_sched_getattr 315 +#define SYS_renameat2 316 +#define SYS_seccomp 317 +#define SYS_getrandom 318 +#define SYS_memfd_create 319 +#define SYS_kexec_file_load 320 +#define SYS_bpf 321 +#define SYS_execveat 322 +#define SYS_userfaultfd 323 +#define SYS_membarrier 324 +#define SYS_mlock2 325 +#define SYS_copy_file_range 326 +#define SYS_preadv2 327 +#define SYS_pwritev2 328 +#define SYS_pkey_mprotect 329 +#define SYS_pkey_alloc 330 +#define SYS_pkey_free 331 +#define SYS_statx 332 +#define SYS_io_pgetevents 333 +#define SYS_rseq 334 +#define SYS_pidfd_send_signal 424 +#define SYS_io_uring_setup 425 +#define SYS_io_uring_enter 426 +#define SYS_io_uring_register 427 +#define SYS_open_tree 428 +#define SYS_move_mount 429 +#define SYS_fsopen 430 +#define SYS_fsconfig 431 +#define SYS_fsmount 432 +#define SYS_fspick 433 +#define SYS_pidfd_open 434 +#define SYS_clone3 435 +#define SYS_close_range 436 +#define SYS_openat2 437 +#define SYS_pidfd_getfd 438 +#define SYS_faccessat2 439 +#define SYS_process_madvise 440 +#define SYS_epoll_pwait2 441 +#define SYS_mount_setattr 442 +#define SYS_landlock_create_ruleset 444 +#define SYS_landlock_add_rule 445 +#define SYS_landlock_restrict_self 446 +#define SYS_memfd_secret 447 +#define SYS_process_mrelease 448 +#define SYS_futex_waitv 449 +#define SYS_set_mempolicy_home_node 450 +#define SYS_cachestat 451 +#define SYS_fchmodat2 452 diff --git a/src/musl_mutex/syscall_ret.c b/src/musl_mutex/syscall_ret.c new file mode 100644 index 0000000..ba7ebcc --- /dev/null +++ b/src/musl_mutex/syscall_ret.c @@ -0,0 +1,13 @@ +#include "syscall.h" +#include +// #include + +long __syscall_ret(unsigned long r) +{ + // fprintf(stderr, "Error __syscall_ret.\n"); + if (r > -4096UL) { + // errno = -r; + return -1; + } + return r; +} diff --git a/src/musl_mutex/syscall_ret.o b/src/musl_mutex/syscall_ret.o new file mode 100644 index 0000000000000000000000000000000000000000..51dfb567895eb1abfef967c39b7e27cbf8cb6aa0 GIT binary patch literal 1264 zcmbVLJ4*vW5T1+C_=pL|GQ2+=Dx&vx>-Ezv^X;XM_Te}06SdSUY{cWM;pt?iT;S#K`~q8Gk-6ov z2cwtKMHX3{5wx7>$0UT_j=rRuZ)ac$^iLyZ8&`3@LoA!8&M=zPF4jv`M^Hc3mO zFLdLJ_jc@I1K~f6KF<%I^;YG!7B|w5je`pB%_6Z|akEw~mv(Hn3t!N{FPJeC=^&p5CHi(9}lt_v(%%;)U_a)lzd8D7tv%dPB*z(<8LD>=oI z?eGdP$Ie;IK29GxR^Dz-`*$*eO1i5KZHJh^&3h1-dR3c1K%9I>S^Mi~x_$};^p5}4 z&!U$0jG(I~=TluZIbX&lEXrK%dsKmv>%9rA1<>jJReKU3tdf}Pzu6RWw5P6r7P=J? zWzhAzSfKw=Og4yE5(ga?xC +#include +#include "limits.h" +#include "stdint.h" +#include +#include "libc.h" +#include "syscall.h" + +#ifdef VDSO_USEFUL + +#if ULONG_MAX == 0xffffffff +typedef Elf32_Ehdr Ehdr; +typedef Elf32_Phdr Phdr; +typedef Elf32_Sym Sym; +typedef Elf32_Verdef Verdef; +typedef Elf32_Verdaux Verdaux; +#else +typedef Elf64_Ehdr Ehdr; +typedef Elf64_Phdr Phdr; +typedef Elf64_Sym Sym; +typedef Elf64_Verdef Verdef; +typedef Elf64_Verdaux Verdaux; +#endif + +static int checkver(Verdef *def, int vsym, const char *vername, char *strings) +{ + vsym &= 0x7fff; + for (;;) { + if (!(def->vd_flags & VER_FLG_BASE) + && (def->vd_ndx & 0x7fff) == vsym) + break; + if (def->vd_next == 0) + return 0; + def = (Verdef *)((char *)def + def->vd_next); + } + Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux); + return !strcmp(vername, strings + aux->vda_name); +} + +#define OK_TYPES (1<e_phoff); + size_t *dynv=0, base=-1; + for (i=0; ie_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) { + if (ph->p_type == PT_LOAD) + base = (size_t)eh + ph->p_offset - ph->p_vaddr; + else if (ph->p_type == PT_DYNAMIC) + dynv = (void *)((char *)eh + ph->p_offset); + } + if (!dynv || base==(size_t)-1) return 0; + + char *strings = 0; + Sym *syms = 0; + Elf_Symndx *hashtab = 0; + uint16_t *versym = 0; + Verdef *verdef = 0; + + for (i=0; dynv[i]; i+=2) { + void *p = (void *)(base + dynv[i+1]); + switch(dynv[i]) { + case DT_STRTAB: strings = p; break; + case DT_SYMTAB: syms = p; break; + case DT_HASH: hashtab = p; break; + case DT_VERSYM: versym = p; break; + case DT_VERDEF: verdef = p; break; + } + } + + if (!strings || !syms || !hashtab) return 0; + if (!verdef) versym = 0; + + for (i=0; i>4) & OK_BINDS)) continue; + if (!syms[i].st_shndx) continue; + if (strcmp(name, strings+syms[i].st_name)) continue; + if (versym && !checkver(verdef, versym[i], vername, strings)) + continue; + return (void *)(base + syms[i].st_value); + } + + return 0; +} + +#endif diff --git a/src/musl_mutex/vdso.o b/src/musl_mutex/vdso.o new file mode 100644 index 0000000000000000000000000000000000000000..003f4297ad5ffd8368e2a1eaeaaff3b636f86709 GIT binary patch literal 2760 zcmbtWU1%It6uz_BX49B_MY4Tc5K6$8MIvk%A5!#Tsp9&bJNG7&NsOQe?woVK zbIv{Io^$T9cg#0mk7*iHq_GQZYo}1gK1*!LX(6WB0oK8O(~mtJuA z#@)eH?q05bY^^o#Fvg2!U0+DY^aZa_(`G&A1&PFgyh0Y|%r*NsfyHzZ`otog?_ZLL z>v7Gj`-`Pu-{CHkz_luO%?89qkqM~EHPRsTWA3ih>5N%V|I*X%dygK5(wst?bKG@G ze8nt_NL{?Rj|5&EEc2zGTj=Z}<4C1lq_RHW0%gH0$96X?G>$vphgF4TZP#-~>6}ok z?RKuYf&8)FP6;kms+Z92)jmeCB)Kc-A$ z&hy(%sfdeoHH}=+rZZ>?>J4|XJxkkjW;yo-FU%}5I|1f3RbA#{xX+4N5ye|EtCFuu zUXxt(Lgl^w9Z;NJ<^@mVpC9@`7!{EPRXqs};;Y`4cNj3<|7Wu~X%7W_`W@cCLHi2< zpMHZE8m;zG`cC)b8@FG?cc0UXgB!SP#Xl*fs{fLdR(+}pX>0y|Db-7|;Yc)^B#nkX zdzP9}n5i)PAXqi1%_>v1`2ep7c%3lF`}Qb>9BQhO-(B+COMar{ z$4kB@+CxLTiaClSCo!h_C*SM~t=pnl}FmOKAIXL1>*iNeVv~k+#=|1C#?Wqq> z^%*^VT@q#t#bQY;`XRXZ)*!=VdxYV|3OXdY_Wl*7-AZalIudOqwDBl#T14N{$2^$) zG&XRcHTE?u0^MtbgMO#Ol)lAp5e7oD^FzPEarUISQ$snCb~_;ya^Av4F2J6}qI*T@ zFo5S^uk1u_z+T2m;_^G_=C%B!k!9IYD|_Rnm1B83mmQyC!^5P=-yVlF_TETV`F$k? zsv#{rT0s?wQ;1fnBj^czKvBFyUMY(A{R7@c!9dZtDS-y(hp(58;Hny`{ty?xTu4U{DGe+`xW@IPF$E^uq6O*=OV1~N$b|!m6?%$nojH%q@l$En@ zGeewUjSgSWWyUR;!T)0^xKl}}reR9U%{^HcrQ4d60679iCh1_i`5lr6mL$>+PQEm6 zL^MZ4C$I=t?}ad;pCWMsG_X}N@mI0v%>U}&3tx)ggB2zfpUw}Hy1(M*p;U6%E+PII zgpojw+Fk;jzzWY6S++_46m3GJ>ZhO)2y|xDzf<}TDMQJl{#SwT*1x*!pQ;P>k9?KC z>fdg$DbzpVUiKF#KIy4WjonyP04quuOyPwUmib-zJ}VK}eY?DX_&*%$Nk ze%14{Cnv2*YvRO|uiaDEPMx+UPQPTZ&e)4OgThtMp3SSYQXR5AD6}WSMy0NvQ>m3q zYW%?HBWu|BQE(R81gkTLG9Ra>5AIun04`&%lf#a&lKA;y{5^8mQ>-NZ&M^KVIqV86 ziKpvY!0|sJhn-<%oB3CU`CpL3o?#{N$oM~#!)94Y{92e#lw`c~z3PuaQfyD+7sIpU zi9TqL!A(c>`V7IIG+carc3{sMeikiFpBdWYC>&>j5T?%xt%Z_`%*#8W@$nwkx2;_z zdr9p9?WA@8?F0%lr8>#^pV9VqEThE5_yCmDO0Scn)@@Z)=Ho4I11lX4kc!QwUJ{U-M5QH);QC`fpMx*(di;B=ZY@ z6O8lAdq!8=x>-N>7d3-*4*5A0VNqQ#2_|Ug!A4P{-x|m1oBS-Dh{^f|T}6k|c>WOs z`XV%KJl_XTI=|cI{BD~(o*(~HBwx-iX>O)u%!SUGeH;XPG$EfXe)mA?f_c9cIuSF& V?UKXjCFReV59*^`W!Q=5{|i+WghBuS literal 0 HcmV?d00001 diff --git a/src/muslmutex.c b/src/muslmutex.c new file mode 100644 index 0000000..94ba1d4 --- /dev/null +++ b/src/muslmutex.c @@ -0,0 +1,353 @@ +#include +#include +#include +#include +#include +#include "interpose.h" +#include "utils.h" +#include "musl_mutex/pthread_musl.h" +#include "musl_mutex/pthread_impl.h" +#include "musl_mutex/pthread_self_glibc.h" +#include "musl_mutex/pthread_setcancelstate_glibc.h" + +musl_mutex_t *musl_mutex_create(const __pthread_mutexattr_t *attr) { + musl_mutex_t *impl = (musl_mutex_t*) calloc(1, sizeof(musl_mutex_t)); + + // #if COND_VAR + // REAL(__pthread_mutex_init)(&impl->lock, attr); + // #endif + + return impl; +} + +int musl_mutex_destroy(musl_mutex_t *lock) { + // #if COND_VAR + // REAL(__pthread_mutex_destroy)(lock); + // #endif + free(lock); + return 0; +} + +// int musl_cond_init(musl_cond_t *cond, const pthread_condattr_t *attr) { +// fprintf(stderr, "musl_cond_init\n"); +// #if COND_VAR +// return REAL(pthread_cond_init)(cond, attr); +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +// int musl_cond_timedwait(musl_cond_t *cond, musl_mutex_t *lock, musl_context_t *UNUSED(me), +// const struct timespec *ts) { +// fprintf(stderr, "musl_cond_timedwait\n"); +// #if COND_VAR +// int res; +// if (ts) +// res = REAL(pthread_cond_timedwait)(cond, &lock->lock, ts); +// else +// res = REAL(pthread_cond_wait)(cond, &lock->lock); + +// return res; +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +// int musl_cond_wait(musl_cond_t *cond, musl_mutex_t *lock, musl_context_t *UNUSED(me)) { +// fprintf(stderr, "musl_cond_wait\n"); +// #if COND_VAR +// int res = REAL(pthread_cond_wait)(cond, &lock->lock); +// return res; +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +// int musl_cond_signal(musl_cond_t *cond) { +// fprintf(stderr, "musl_cond_signal\n"); +// #if COND_VAR +// return REAL(pthread_cond_signal)(cond); +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +// int musl_cond_broadcast(musl_cond_t *cond) { +// fprintf(stderr, "musl_cond_broadcast\n"); +// #if COND_VAR +// return REAL(pthread_cond_broadcast)(cond); +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +// int musl_cond_destroy(musl_cond_t *cond) { +// fprintf(stderr, "musl_cond_destroy\n"); +// #if COND_VAR +// return REAL(pthread_cond_destroy)(cond); +// #else +// fprintf(stderr, "Error cond_var not supported."); +// assert(0); +// #endif +// } + +void musl_thread_start(void) { +} + +void musl_thread_exit(void) { +} + +void musl_application_init(void) { +} + +void musl_application_exit(void) { +} + +void musl_init_context(lock_mutex_t *impl, + lock_context_t *context, + int number) { +} + +int __pthread_musl_cond_wait(pthread_cond_t *restrict c, __pthread_mutex_t *restrict m, musl_context_t *restrict me) +{ + return __pthread_musl_cond_timedwait(c, m, me, 0); +} + +struct waiter { + struct waiter *prev, *next; + volatile int state, barrier; + volatile int *notify; +}; + +/* Self-synchronized-destruction-safe lock functions */ + +static inline void lock(volatile int *l) +{ + if (a_cas(l, 0, 1)) { + a_cas(l, 1, 2); + do __wait(l, 0, 2, 1); + while (a_cas(l, 0, 2)); + } +} + +static inline void unlock(volatile int *l) +{ + if (a_swap(l, 0)==2) + __wake(l, 1, 1); +} + +static inline void unlock_requeue(volatile int *l, volatile int *r, int w) +{ + a_store(l, 0); + if (w) __wake(l, 1, 1); + else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS + || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r); +} + +enum { + WAITING, + SIGNALED, + LEAVING, +}; + +int __pthread_musl_cond_timedwait(musl_cond_t *restrict c, musl_mutex_t *restrict m, musl_context_t *restrict me, const struct timespec *restrict ts) +{ + struct waiter node = { 0 }; + int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp; + volatile int *fut; + + if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != pthread_self_glibc()) + return EPERM; + + if (ts && ts->tv_nsec >= 1000000000UL) + return EINVAL; + + // fprintf(stderr, "__pthread_testcancel 170\n"); + pthread_testcancel(); // TODO: Add this back + + if (c->_c_shared) { + shared = 1; + fut = &c->_c_seq; + seq = c->_c_seq; + a_inc(&c->_c_waiters); + } else { + lock(&c->_c_lock); + + seq = node.barrier = 2; + fut = &node.barrier; + node.state = WAITING; + node.next = c->_c_head; + c->_c_head = &node; + if (!c->_c_tail) c->_c_tail = &node; + else node.next->prev = &node; + + unlock(&c->_c_lock); + } + + __pthread_musl_mutex_unlock(m, me); + + pthread_setcancelstate_glibc(PTHREAD_CANCEL_MASKED, &cs); + if (cs == PTHREAD_CANCEL_DISABLE) pthread_setcancelstate_glibc(cs, 0); + + do e = __timedwait_cp(fut, seq, clock, ts, !shared); + while (*fut==seq && (!e || e==EINTR)); + if (e == EINTR) e = 0; + + if (shared) { + /* Suppress cancellation if a signal was potentially + * consumed; this is a legitimate form of spurious + * wake even if not. */ + if (e == ECANCELED && c->_c_seq != seq) e = 0; + if (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff) + __wake(&c->_c_waiters, 1, 0); + oldstate = WAITING; + goto relock; + } + + oldstate = a_cas(&node.state, WAITING, LEAVING); + + if (oldstate == WAITING) { + /* Access to cv object is valid because this waiter was not + * yet signaled and a new signal/broadcast cannot return + * after seeing a LEAVING waiter without getting notified + * via the futex notify below. */ + + lock(&c->_c_lock); + + if (c->_c_head == &node) c->_c_head = node.next; + else if (node.prev) node.prev->next = node.next; + if (c->_c_tail == &node) c->_c_tail = node.prev; + else if (node.next) node.next->prev = node.prev; + + unlock(&c->_c_lock); + + if (node.notify) { + if (a_fetch_add(node.notify, -1)==1) + __wake(node.notify, 1, 1); + } + } else { + /* Lock barrier first to control wake order. */ + lock(&node.barrier); + } + +relock: + /* Errors locking the mutex override any existing error or + * cancellation, since the caller must see them to know the + * state of the mutex. */ + if ((tmp = __pthread_musl_mutex_lock(m, me))) e = tmp; + + if (oldstate == WAITING) goto done; + + if (!node.next && !(m->_m_type & 8)) + a_inc(&m->_m_waiters); + + /* Unlock the barrier that's holding back the next waiter, and + * either wake it or requeue it to the mutex. */ + if (node.prev) { + int val = m->_m_lock; + if (val>0) a_cas(&m->_m_lock, val, val|0x80000000); + unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128)); + } else if (!(m->_m_type & 8)) { + a_dec(&m->_m_waiters); + } + + /* Since a signal was consumed, cancellation is not permitted. */ + if (e == ECANCELED) e = 0; + +done: + pthread_setcancelstate_glibc(cs, 0); + + if (e == ECANCELED) { + fprintf(stderr, "__pthread_testcancel 266\n"); + // __pthread_testcancel(); // TODO: Add this back + pthread_testcancel(); + pthread_setcancelstate_glibc(PTHREAD_CANCEL_DISABLE, 0); + } + + return e; +} + +int __private_cond_signal(musl_cond_t *c, int n) +{ + struct waiter *p, *first=0; + volatile int ref = 0; + int cur; + + lock(&c->_c_lock); + for (p=c->_c_tail; n && p; p=p->prev) { + if (a_cas(&p->state, WAITING, SIGNALED) != WAITING) { + ref++; + p->notify = &ref; + } else { + n--; + if (!first) first=p; + } + } + /* Split the list, leaving any remainder on the cv. */ + if (p) { + if (p->next) p->next->prev = 0; + p->next = 0; + } else { + c->_c_head = 0; + } + c->_c_tail = p; + unlock(&c->_c_lock); + + /* Wait for any waiters in the LEAVING state to remove + * themselves from the list before returning or allowing + * signaled threads to proceed. */ + while ((cur = ref)) __wait(&ref, 0, cur, 1); + + /* Allow first signaled waiter, if any, to proceed. */ + if (first) unlock(&first->barrier); + + return 0; +} + +weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait); + +int __pthread_musl_cond_signal(musl_cond_t *c) +{ + if (!c->_c_shared) return __private_cond_signal(c, 1); + if (!c->_c_waiters) return 0; + a_inc(&c->_c_seq); + __wake(&c->_c_seq, 1, 0); + return 0; +} + +int __pthread_musl_cond_broadcast(musl_cond_t *c) +{ + if (!c->_c_shared) return __private_cond_signal(c, -1); + if (!c->_c_waiters) return 0; + a_inc(&c->_c_seq); + __wake(&c->_c_seq, -1, 0); + return 0; +} + +int __pthread_musl_cond_destroy(musl_cond_t *c) +{ + if (c->_c_shared && c->_c_waiters) { + int cnt; + a_or(&c->_c_waiters, 0x80000000); + a_inc(&c->_c_seq); + __wake(&c->_c_seq, -1, 0); + while ((cnt = c->_c_waiters) & 0x7fffffff) + __wait(&c->_c_waiters, 0, cnt, 0); + } + return 0; +} + +int __pthread_musl_cond_init(musl_cond_t *restrict c, const __pthread_condattr_t *restrict a) +{ + *c = (musl_cond_t){0}; + if (a) { + c->_c_clock = a->__attr & 0x7fffffff; + if (a->__attr>>31) c->_c_shared = (void *)-1; + } + return 0; +} diff --git a/src/ticketepfl.c b/src/ticketepfl.c index d322541..2360df3 100644 --- a/src/ticketepfl.c +++ b/src/ticketepfl.c @@ -96,7 +96,7 @@ int ticketepfl_mutex_lock(ticketepfl_mutex_t *impl, if (distance > 20) { sched_yield(); - /* pthread_yield(); */ + /* sched_yield(); */ } } diff --git a/src/utils.h b/src/utils.h index 5514bdf..0a7ce9f 100644 --- a/src/utils.h +++ b/src/utils.h @@ -109,9 +109,11 @@ static inline uint64_t rdtsc(void) { return low | ((uint64_t)high) << 32; } +#if !defined(__GLIBC__) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 30) static inline int gettid() { return syscall(SYS_gettid); } +#endif // EPFL libslock #define my_random xorshf96 diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..eb9d0af --- /dev/null +++ b/test/Makefile @@ -0,0 +1,15 @@ +LDFLAGS= -lpthread + +all: test + +test: test_program.o read_args.o + gcc read_args.o test_program.o -o test_program $(LDFLAGS) + +test_program.o: test_program.c + gcc -c -ggdb test_program.c + +read_args.o: read_args.c mutex_test_args.h + gcc -c read_args.c + +clean: + rm -rf *.o diff --git a/test/mutex_test_args.h b/test/mutex_test_args.h new file mode 100644 index 0000000..fa2a5f0 --- /dev/null +++ b/test/mutex_test_args.h @@ -0,0 +1,6 @@ +struct mutex_test_args { + int thread_num; + int iter_num; +} typedef mutex_test_args; + +mutex_test_args read_args(int argc, char *argv[]); diff --git a/test/read_args.c b/test/read_args.c new file mode 100644 index 0000000..ef0173b --- /dev/null +++ b/test/read_args.c @@ -0,0 +1,47 @@ +#include +#include +#include "mutex_test_args.h" +#include + +void check_args(mutex_test_args *args) { + if (args->iter_num < 1) { + printf("Wrong iteration number: %d, setting it to the default: 1\n", args->iter_num); + args->iter_num = 1; + } + if (args->thread_num < 1) { + printf("Wrong thread number: %d, setting it to the default: 1\n", args->thread_num); + args->thread_num = 1; + } +} + +mutex_test_args read_args(int argc, char *argv[]) { + struct option long_opts[] = { + {"threads", required_argument, NULL, 't'}, + {"iterations", required_argument, NULL, 'i'}, + {NULL, 0, NULL, 0}}; + + char *opts = "t:i"; + int opt; + mutex_test_args args = {-1, -1}; + + int long_index; + opt = getopt_long(argc, argv, opts, long_opts, &long_index); + + while (opt != -1) { + switch (opt) { + case 't': { + sscanf(optarg, "%d", &args.thread_num); + break; + } + case 'i': { + sscanf(optarg, "%d", &args.iter_num); + break; + } + } + opt = getopt_long(argc, argv, opts, long_opts, &long_index); + } + + check_args(&args); + + return args; +} diff --git a/test/test_program.c b/test/test_program.c new file mode 100644 index 0000000..6755482 --- /dev/null +++ b/test/test_program.c @@ -0,0 +1,36 @@ +#include +#include +#include +#include "mutex_test_args.h" + +__uint64_t shared_num = 0; +pthread_mutex_t mutex; + +void *incr_shared_res(void *iter_num) { + int max_iterations = *(int *)iter_num; + for (__uint64_t i = 0; i < max_iterations; i++) { + pthread_mutex_lock(&mutex); + shared_num += 1; + //printf("shared_num current value: %d\n", shared_num); + pthread_mutex_unlock(&mutex); + } + // pthread_mutex_unlock(&mutex); +} + +int main(int argc, char *argv[]) { + pthread_mutex_init(&mutex, NULL); + + mutex_test_args args = read_args(argc, argv); + + pthread_t *threads = calloc(args.thread_num, sizeof(pthread_t)); + for (unsigned i = 0; i < args.thread_num; i++) { + pthread_create(&threads[i], NULL, incr_shared_res, &args.iter_num); + } + + for (unsigned i = 0; i < args.thread_num; i++) { + pthread_join(threads[i], NULL); + } + printf("shared_num value after threads work is: %d\n", shared_num); + free(threads); + return 0; +}