diff options
Diffstat (limited to 'lib/libc/internal/include')
| -rw-r--r-- | lib/libc/internal/include/__stdio.h | 2 | ||||
| -rw-r--r-- | lib/libc/internal/include/__thread.h | 44 | ||||
| -rw-r--r-- | lib/libc/internal/include/atomic.h | 32 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc.h | 18 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc/fsbase.h | 7 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc/futex.h | 7 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc/tcb.h | 9 | ||||
| -rw-r--r-- | lib/libc/internal/include/libc/thread.h | 6 |
8 files changed, 101 insertions, 24 deletions
diff --git a/lib/libc/internal/include/__stdio.h b/lib/libc/internal/include/__stdio.h index 487a0382..7846b139 100644 --- a/lib/libc/internal/include/__stdio.h +++ b/lib/libc/internal/include/__stdio.h @@ -31,8 +31,6 @@ struct __FILE { struct __FILE *next; }; -#define __FILE(__stream) ((struct __FILE *)(__stream)) - void __libc_fadd(struct __FILE *f); #endif diff --git a/lib/libc/internal/include/__thread.h b/lib/libc/internal/include/__thread.h index 7639707a..3c68f8dd 100644 --- a/lib/libc/internal/include/__thread.h +++ b/lib/libc/internal/include/__thread.h @@ -1,8 +1,50 @@ #ifndef __LIBC_THREAD_H #define __LIBC_THREAD_H +#include <stdatomic.h> +#include <stddef.h> +#include <stdint.h> + +#define THREAD_STACK_SIZE (1024 * 1024) +#define THREAD_GUARD_SIZE 8192 + +enum __thread_state { THREAD_STATE_EXITED, THREAD_STATE_JOINABLE, THREAD_STATE_DETACHED }; + +struct tls { + void *data; + size_t length; + size_t size; + size_t align; +}; + struct __thread_self { - int tid; + struct __thread_self *self; + + /* Backing mapping for this thread (used by thrd_join/thrd_detach to munmap safely) */ + void *map_base; + size_t map_size; + +#ifdef __aarch64__ + uintptr_t *dtv; + uintptr_t canary; +#endif + + long tid; + int res; + int errno_v; + volatile int state; + +#ifdef __x86_64__ + uintptr_t canary; + uintptr_t *dtv; +#endif }; +void __libc_tls_copy(void *); + +#if defined(__x86_64__) +long __clone(long (*fn)(void *), void *arg, unsigned long flags, void *child_stack, long *ptid, void *newtls, + long *ctid); +#endif + #endif diff --git a/lib/libc/internal/include/atomic.h b/lib/libc/internal/include/atomic.h index e0593021..d40c1eae 100644 --- a/lib/libc/internal/include/atomic.h +++ b/lib/libc/internal/include/atomic.h @@ -1,22 +1,32 @@ #ifndef __LIBC_ATOMIC_H #define __LIBC_ATOMIC_H +#include <libc/futex.h> +#include <sched.h> #include <stdatomic.h> +#include <unistd.h> #define LIBC_LOCK(__lock) __libc_lock(&((__lock))) -#define LIBC_UNLOCK(__lock) atomic_flag_clear(&((__lock))) +#define LIBC_UNLOCK(__lock) __libc_unlock(&((__lock))) -static __inline void __libc_lock(volatile atomic_flag *lock) +__attribute__((__always_inline__)) __inline void __libc_unlock(volatile atomic_flag *lock) { - while (atomic_flag_test_and_set_explicit(lock, memory_order_acquire)) { - unsigned int spins = 1; - do { - for (unsigned int i = 0; i < spins; i++) - __asm__ volatile("pause"); - if (spins < 64) - spins *= 2; - } while (atomic_flag_test_and_set_explicit( - lock, memory_order_relaxed)); + atomic_flag_clear_explicit(lock, memory_order_release); + __futex_wake((volatile int *)lock, 1); +} + +__attribute__((__always_inline__)) __inline void __libc_lock(volatile atomic_flag *lock) +{ + if (atomic_flag_test_and_set_explicit(lock, memory_order_acquire) == 0) + return; + + while (1) { + __futex_wait((volatile int *)lock, 1); + + if (atomic_flag_test_and_set_explicit(lock, memory_order_acquire) == 0) + return; + + sched_yield(); } } diff --git a/lib/libc/internal/include/libc.h b/lib/libc/internal/include/libc.h index f06fa6d8..75a06dd2 100644 --- a/lib/libc/internal/include/libc.h +++ b/lib/libc/internal/include/libc.h @@ -1,26 +1,20 @@ #ifndef __LIBC_LIBC_H #define __LIBC_LIBC_H +#include <__stdio.h> #include <stdatomic.h> #include <stddef.h> #include <sys/cdefs.h> #define weak_reference(old, new) extern __typeof(old)((new)) __attribute__((__weak__, __alias__(#old))) -struct tls { - struct tls *next; - void *data; - size_t size; - size_t align; - size_t length; - size_t offset; -}; - struct libc { - size_t auxv[32]; + size_t *auxv; + struct { void *base; size_t size; + size_t align; } tls; enum { @@ -32,6 +26,10 @@ struct libc { volatile atomic_flag malloc; volatile atomic_flag environ; } lock; + + struct __FILE stdin; + struct __FILE stdout; + struct __FILE stderr; }; extern struct libc __libc; diff --git a/lib/libc/internal/include/libc/fsbase.h b/lib/libc/internal/include/libc/fsbase.h new file mode 100644 index 00000000..61f4abce --- /dev/null +++ b/lib/libc/internal/include/libc/fsbase.h @@ -0,0 +1,7 @@ +#ifndef __LIBC_FSBASE_H +#define __LIBC_FSBASE_H + +void *rdfsbase(void); +void wrfsbase(unsigned long); + +#endif diff --git a/lib/libc/internal/include/libc/futex.h b/lib/libc/internal/include/libc/futex.h new file mode 100644 index 00000000..a00cf0e7 --- /dev/null +++ b/lib/libc/internal/include/libc/futex.h @@ -0,0 +1,7 @@ +#ifndef __LIBC_FUTEX_H +#define __LIBC_FUTEX_H + +int __futex_wait(volatile int *, int); +int __futex_wake(volatile int *, int); + +#endif diff --git a/lib/libc/internal/include/libc/tcb.h b/lib/libc/internal/include/libc/tcb.h new file mode 100644 index 00000000..1defd41c --- /dev/null +++ b/lib/libc/internal/include/libc/tcb.h @@ -0,0 +1,9 @@ +#ifndef __LIBC_TCB_H +#define __LIBC_TCB_H + +#include <stdint.h> + +void *__libc_tcb_get(void); +void __libc_tcb_set(uint64_t); + +#endif diff --git a/lib/libc/internal/include/libc/thread.h b/lib/libc/internal/include/libc/thread.h new file mode 100644 index 00000000..6422a0e2 --- /dev/null +++ b/lib/libc/internal/include/libc/thread.h @@ -0,0 +1,6 @@ +#ifndef __LIBC_THREAD_H +#define __LIBC_THREAD_H + +void *__libc_thread_self(void); + +#endif |
