summaryrefslogtreecommitdiff
path: root/lib/libc/internal/include
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/internal/include')
-rw-r--r--lib/libc/internal/include/__stdio.h2
-rw-r--r--lib/libc/internal/include/__thread.h44
-rw-r--r--lib/libc/internal/include/atomic.h32
-rw-r--r--lib/libc/internal/include/libc.h18
-rw-r--r--lib/libc/internal/include/libc/fsbase.h7
-rw-r--r--lib/libc/internal/include/libc/futex.h7
-rw-r--r--lib/libc/internal/include/libc/tcb.h9
-rw-r--r--lib/libc/internal/include/libc/thread.h6
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