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
38
int
pthread_mutex_init
(
pthread_mutex_t
*
m
,
const
pthread_mutexattr_t
*
attr
) {
39
(
void
)
attr
;
40
*
m
= 0;
41
return
0;
42
}
43
int
pthread_mutex_destroy
(
pthread_mutex_t
*
m
) { (
void
)
m
;
return
0; }
44
int
pthread_mutex_lock
(
pthread_mutex_t
*
m
) { (
void
)
m
;
return
0; }
45
int
pthread_mutex_trylock
(
pthread_mutex_t
*
m
) { (
void
)
m
;
return
0; }
46
int
pthread_mutex_unlock
(
pthread_mutex_t
*
m
) { (
void
)
m
;
return
0; }
47
48
int
pthread_rwlock_init
(
pthread_rwlock_t
*
rw
,
const
pthread_rwlockattr_t
*
attr
) {
49
(
void
)
attr
;
50
*
rw
= 0;
51
return
0;
52
}
53
int
pthread_rwlock_destroy
(
pthread_rwlock_t
*
rw
) { (
void
)
rw
;
return
0; }
54
int
pthread_rwlock_rdlock
(
pthread_rwlock_t
*
rw
) { (
void
)
rw
;
return
0; }
55
int
pthread_rwlock_wrlock
(
pthread_rwlock_t
*
rw
) { (
void
)
rw
;
return
0; }
56
int
pthread_rwlock_unlock
(
pthread_rwlock_t
*
rw
) { (
void
)
rw
;
return
0; }
57
58
int
pthread_cond_init
(
pthread_cond_t
*
c
,
const
pthread_condattr_t
*
attr
) {
59
(
void
)
attr
;
60
*
c
= 0;
61
return
0;
62
}
63
int
pthread_cond_destroy
(
pthread_cond_t
*
c
) { (
void
)
c
;
return
0; }
64
int
pthread_cond_signal
(
pthread_cond_t
*
c
) { (
void
)
c
;
return
0; }
65
int
pthread_cond_broadcast
(
pthread_cond_t
*
c
) { (
void
)
c
;
return
0; }
66
int
pthread_cond_wait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
) {
67
(
void
)
c
;
68
(
void
)
m
;
69
return
0;
/* never block: no other thread could signal */
70
}
71
int
pthread_cond_timedwait
(
pthread_cond_t
*
c
,
pthread_mutex_t
*
m
,
const
struct
timespec
*
abstime
) {
72
(
void
)
c
;
73
(
void
)
m
;
74
(
void
)
abstime
;
75
return
ETIMEDOUT
;
76
}
77
int
pthread_condattr_init
(
pthread_condattr_t
*
a
) { (
void
)
a
;
return
0; }
78
int
pthread_condattr_destroy
(
pthread_condattr_t
*
a
) { (
void
)
a
;
return
0; }
79
int
pthread_condattr_setclock
(
pthread_condattr_t
*
a
,
clockid_t
id
) {
80
(
void
)
a
;
81
(
void
)
id
;
82
return
0;
83
}
84
85
int
pthread_attr_init
(
pthread_attr_t
*
a
) {
86
memset
(
a
, 0,
sizeof
(*
a
));
87
return
0;
88
}
89
int
pthread_attr_destroy
(
pthread_attr_t
*
a
) { (
void
)
a
;
return
0; }
90
int
pthread_attr_setdetachstate
(
pthread_attr_t
*
a
,
int
state) {
91
(
void
)
a
;
92
(
void
)state;
93
return
0;
94
}
95
int
pthread_attr_setstacksize
(
pthread_attr_t
*
a
,
size_t
size) {
96
(
void
)
a
;
97
(
void
)size;
98
return
0;
99
}
100
101
int
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
}
108
int
pthread_join
(
pthread_t
t
,
void
**
ret
) {
109
(
void
)
t
;
110
(
void
)
ret
;
111
return
ESRCH
;
112
}
113
int
pthread_detach
(
pthread_t
t
) {
114
(
void
)
t
;
115
return
ESRCH
;
116
}
117
pthread_t
pthread_self
(
void
) {
return
(
pthread_t
)1; }
118
int
pthread_equal
(
pthread_t
a
,
pthread_t
b) {
return
a
== b; }
119
120
int
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
129
static
void
*
g_key_values
[
CWIST_BAREMETAL_KEYS
];
130
static
unsigned
g_key_count
;
131
132
int
pthread_key_create
(
pthread_key_t
*key,
void
(*destructor)(
void
*)) {
133
(
void
)destructor;
/* the only thread never exits */
134
if
(
g_key_count
>=
CWIST_BAREMETAL_KEYS
)
return
EAGAIN
;
135
*key = (
pthread_key_t
)
g_key_count
++;
136
return
0;
137
}
138
void
*
pthread_getspecific
(
pthread_key_t
key) {
139
return
(
unsigned
)key <
g_key_count
?
g_key_values
[key] :
NULL
;
140
}
141
int
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
147
int
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
154
static
inline
uint32_t
atomic_irq_save
(
void
) {
155
uint32_t
primask
;
156
__asm
volatile
(
"mrs %0, primask\n\tcpsid i"
:
"=r"
(
primask
)::
"memory"
);
157
return
primask
;
158
}
159
static
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. */
165
uint64_t
__atomic_load_8
(
const
volatile
void
*mem,
int
order
) {
166
(
void
)
order
;
167
uint32_t
s =
atomic_irq_save
();
168
uint64_t
v
= *(
const
volatile
uint64_t
*)mem;
169
atomic_irq_restore
(s);
170
return
v
;
171
}
172
void
__atomic_store_8
(
volatile
void
*mem,
uint64_t
val
,
int
order
) {
173
(
void
)
order
;
174
uint32_t
s =
atomic_irq_save
();
175
*(
volatile
uint64_t
*)mem =
val
;
176
atomic_irq_restore
(s);
177
}
178
uint64_t
__atomic_exchange_8
(
volatile
void
*mem,
uint64_t
val
,
int
order
) {
179
(
void
)
order
;
180
uint32_t
s =
atomic_irq_save
();
181
uint64_t
old
= *(
volatile
uint64_t
*)mem;
182
*(
volatile
uint64_t
*)mem =
val
;
183
atomic_irq_restore
(s);
184
return
old
;
185
}
186
bool
__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
;
191
uint32_t
s =
atomic_irq_save
();
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
;
198
atomic_irq_restore
(s);
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
}
211
CWIST_BAREMETAL_FETCH_OP
(
add
, +)
212
CWIST_BAREMETAL_FETCH_OP
(sub, -)
213
CWIST_BAREMETAL_FETCH_OP
(
and
, &)
214
CWIST_BAREMETAL_FETCH_OP
(
or
, |)
215
CWIST_BAREMETAL_FETCH_OP
(
xor
, ^)
216
#undef CWIST_BAREMETAL_FETCH_OP
217
218
#endif
/* ARMv7-M / ARMv8-M mainline */
219
220
#endif
/* CWIST_BAREMETAL */
cap
size_t cap
Definition
otel.c:56
platform.h
Target capability macros shared by all CWIST sources.
port.h
Hooks a bare-metal firmware supplies to CWIST (issue #447).
src
sys
port
baremetal.c
Generated by
1.9.8