cwist
Modern C web framework with libttak runtime
Loading...
Searching...
No Matches
baremetal.c
Go to the documentation of this file.
1
22#include <cwist/sys/platform.h>
23
24#if defined(CWIST_BAREMETAL)
25
26#include <cwist/sys/port.h>
27
28#include <errno.h>
29#include <pthread.h>
30#include <sched.h>
31#include <stdbool.h>
32#include <stdint.h>
33#include <string.h>
34#include <time.h>
35
36/* --- pthread: one thread, nothing contends --------------------------------- */
37
39 (void)attr;
40 *m = 0;
41 return 0;
42}
43int pthread_mutex_destroy(pthread_mutex_t *m) { (void)m; return 0; }
44int pthread_mutex_lock(pthread_mutex_t *m) { (void)m; return 0; }
45int pthread_mutex_trylock(pthread_mutex_t *m) { (void)m; return 0; }
46int pthread_mutex_unlock(pthread_mutex_t *m) { (void)m; return 0; }
47
49 (void)attr;
50 *rw = 0;
51 return 0;
52}
57
59 (void)attr;
60 *c = 0;
61 return 0;
62}
63int pthread_cond_destroy(pthread_cond_t *c) { (void)c; return 0; }
64int pthread_cond_signal(pthread_cond_t *c) { (void)c; return 0; }
65int pthread_cond_broadcast(pthread_cond_t *c) { (void)c; return 0; }
67 (void)c;
68 (void)m;
69 return 0; /* never block: no other thread could signal */
70}
72 (void)c;
73 (void)m;
75 return ETIMEDOUT;
76}
80 (void)a;
81 (void)id;
82 return 0;
83}
84
86 memset(a, 0, sizeof(*a));
87 return 0;
88}
89int pthread_attr_destroy(pthread_attr_t *a) { (void)a; return 0; }
91 (void)a;
92 (void)state;
93 return 0;
94}
96 (void)a;
97 (void)size;
98 return 0;
99}
100
101int pthread_create(pthread_t *t, const pthread_attr_t *attr, void *(*fn)(void *), void *arg) {
102 (void)t;
103 (void)attr;
104 (void)fn;
105 (void)arg;
106 return EAGAIN; /* no threads: callers fall back to inline/no worker */
107}
108int pthread_join(pthread_t t, void **ret) {
109 (void)t;
110 (void)ret;
111 return ESRCH;
112}
114 (void)t;
115 return ESRCH;
116}
117pthread_t pthread_self(void) { return (pthread_t)1; }
118int pthread_equal(pthread_t a, pthread_t b) { return a == b; }
119
120int pthread_once(pthread_once_t *once, void (*init)(void)) {
121 if (!once->init_executed) {
122 once->init_executed = 1;
123 init();
124 }
125 return 0;
126}
127
128#define CWIST_BAREMETAL_KEYS 32
130static unsigned g_key_count;
131
132int pthread_key_create(pthread_key_t *key, void (*destructor)(void *)) {
133 (void)destructor; /* the only thread never exits */
135 *key = (pthread_key_t)g_key_count++;
136 return 0;
137}
139 return (unsigned)key < g_key_count ? g_key_values[key] : NULL;
140}
141int pthread_setspecific(pthread_key_t key, const void *value) {
142 if ((unsigned)key >= g_key_count) return EINVAL;
143 g_key_values[key] = (void *)value;
144 return 0;
145}
146
147int sched_yield(void) { return 0; }
148
149/* --- 64-bit atomics (Cortex-M: mask interrupts around the access) ------------ */
150
151#if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || \
152 defined(__ARM_ARCH_8_1M_MAIN__)
153
154static inline uint32_t atomic_irq_save(void) {
156 __asm volatile("mrs %0, primask\n\tcpsid i" : "=r"(primask)::"memory");
157 return primask;
158}
159static inline void atomic_irq_restore(uint32_t primask) {
160 __asm volatile("msr primask, %0" ::"r"(primask) : "memory");
161}
162
163/* GCC's libcall ABI for 8-byte atomics; the memory-order argument is moot
164 * with interrupts masked on a single core. */
165uint64_t __atomic_load_8(const volatile void *mem, int order) {
166 (void)order;
168 uint64_t v = *(const volatile uint64_t *)mem;
170 return v;
171}
172void __atomic_store_8(volatile void *mem, uint64_t val, int order) {
173 (void)order;
175 *(volatile uint64_t *)mem = val;
177}
178uint64_t __atomic_exchange_8(volatile void *mem, uint64_t val, int order) {
179 (void)order;
181 uint64_t old = *(volatile uint64_t *)mem;
182 *(volatile uint64_t *)mem = val;
184 return old;
185}
186bool __atomic_compare_exchange_8(volatile void *mem, void *expected, uint64_t desired, bool weak,
187 int success, int failure) {
188 (void)weak;
189 (void)success;
190 (void)failure;
192 uint64_t cur = *(volatile uint64_t *)mem;
193 bool ok = cur == *(uint64_t *)expected;
194 if (ok)
195 *(volatile uint64_t *)mem = desired;
196 else
197 *(uint64_t *)expected = cur;
199 return ok;
200}
201
202#define CWIST_BAREMETAL_FETCH_OP(name, op) \
203 uint64_t __atomic_fetch_##name##_8(volatile void *mem, uint64_t val, int order) { \
204 (void)order; \
205 uint32_t s = atomic_irq_save(); \
206 uint64_t old = *(volatile uint64_t *)mem; \
207 *(volatile uint64_t *)mem = old op val; \
208 atomic_irq_restore(s); \
209 return old; \
210 }
216#undef CWIST_BAREMETAL_FETCH_OP
217
218#endif /* ARMv7-M / ARMv8-M mainline */
219
220#endif /* CWIST_BAREMETAL */
size_t cap
Definition otel.c:56
Target capability macros shared by all CWIST sources.
Hooks a bare-metal firmware supplies to CWIST (issue #447).