Skip to content

Commit 8938362

Browse files
committed
Prepare SMP code to support Pico
Allow smp platforms to define their own spinlock structures Allow smp platforms to not provide stdatomic.h Allow platforms to define MIN and MAX macros Signed-off-by: Paul Guyot <[email protected]>
1 parent e2e83b6 commit 8938362

File tree

11 files changed

+43
-57
lines changed

11 files changed

+43
-57
lines changed

src/libAtomVM/CMakeLists.txt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,22 @@ if (AVM_DISABLE_SMP)
130130
else()
131131
include(CheckIncludeFile)
132132
CHECK_INCLUDE_FILE(stdatomic.h STDATOMIC_INCLUDE)
133-
if(NOT STDATOMIC_INCLUDE)
134-
message(FATAL_ERROR "stdatomic.h cannot be found, you need to disable SMP on this platform")
133+
if(HAVE_PLATFORM_SMP_H)
134+
target_compile_definitions(libAtomVM PUBLIC HAVE_PLATFORM_SMP_H)
135+
endif()
136+
include(CheckCSourceCompiles)
137+
check_c_source_compiles("
138+
#include <stdatomic.h>
139+
int main() {
140+
_Static_assert(ATOMIC_POINTER_LOCK_FREE == 2, \"Expected ATOMIC_POINTER_LOCK_FREE to be equal to 2\");
141+
}
142+
" ATOMIC_POINTER_LOCK_FREE_IS_TWO)
143+
if (NOT ATOMIC_POINTER_LOCK_FREE_IS_TWO AND NOT HAVE_PLATFORM_SMP_H)
144+
if (NOT STDATOMIC_INCLUDE)
145+
message(FATAL_ERROR "stdatomic.h cannot be found, you need to disable SMP on this platform or provide platform_smp.h and define HAVE_PLATFORM_SMP_H")
146+
else()
147+
message(FATAL_ERROR "Platform doesn't support atomic pointers, you need to disable SMP or provide platform_smp.h and define HAVE_PLATFORM_SMP_H")
148+
endif()
135149
endif()
136150
endif()
137151

src/libAtomVM/context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ void context_update_flags(Context *ctx, int mask, int value) CLANG_THREAD_SANITI
181181
enum ContextFlags desired;
182182
do {
183183
desired = (expected & mask) | value;
184-
} while (!atomic_compare_exchange_weak(&ctx->flags, &expected, desired));
184+
} while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&ctx->flags, &expected, desired));
185185
#else
186186
ctx->flags = (ctx->flags & mask) | value;
187187
#endif

src/libAtomVM/context.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,10 @@ extern "C" {
3535
#include "globalcontext.h"
3636
#include "linkedlist.h"
3737
#include "mailbox.h"
38+
#include "smp.h"
3839
#include "term.h"
3940
#include "timer_list.h"
4041

41-
#if !defined(AVM_NO_SMP) && !defined(__cplusplus)
42-
#include <stdatomic.h>
43-
#define ATOMIC _Atomic
44-
#else
45-
#define ATOMIC
46-
#endif
47-
4842
struct Module;
4943

5044
#ifndef TYPEDEF_MODULE

src/libAtomVM/globalcontext.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@ extern "C" {
3434

3535
#include <stdint.h>
3636

37-
#if !defined(AVM_NO_SMP) && !defined(__cplusplus)
38-
#include <stdatomic.h>
39-
#define ATOMIC _Atomic
40-
#else
41-
#define ATOMIC
42-
#endif
43-
4437
#include "atom.h"
4538
#include "linkedlist.h"
4639
#include "smp.h"
@@ -102,7 +95,7 @@ struct GlobalContext
10295
#endif
10396

10497
#if !defined(AVM_NO_SMP) && ATOMIC_LLONG_LOCK_FREE == 2
105-
atomic_ullong ref_ticks;
98+
unsigned long long ATOMIC ref_ticks;
10699
#else
107100
unsigned long long ref_ticks;
108101
#ifndef AVM_NO_SMP

src/libAtomVM/mailbox.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ static void mailbox_post_message(Context *c, MailboxMessage *m)
142142
MailboxMessage *current_first = NULL;
143143
do {
144144
m->next = current_first;
145-
} while (!atomic_compare_exchange_weak(&c->mailbox.outer_first, &current_first, m));
145+
} while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&c->mailbox.outer_first, &current_first, m));
146146
#else
147147
m->next = c->mailbox.outer_first;
148148
c->mailbox.outer_first = m;
@@ -242,7 +242,7 @@ MailboxMessage *mailbox_process_outer_list(Mailbox *mbox)
242242
// Empty outer list using CAS
243243
MailboxMessage *current = mbox->outer_first;
244244
#ifndef AVM_NO_SMP
245-
while (!atomic_compare_exchange_weak(&mbox->outer_first, &current, NULL)) {
245+
while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&mbox->outer_first, &current, NULL)) {
246246
};
247247
#else
248248
mbox->outer_first = NULL;

src/libAtomVM/mailbox.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,10 @@
3333
extern "C" {
3434
#endif
3535

36-
#if !defined(AVM_NO_SMP) && !defined(__cplusplus)
37-
#include <stdatomic.h>
38-
#define ATOMIC _Atomic
39-
#else
40-
#define ATOMIC
41-
#endif
42-
4336
#include <stdbool.h>
4437

4538
#include "list.h"
39+
#include "smp.h"
4640
#include "term_typedef.h"
4741

4842
struct Context;

src/libAtomVM/nifs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "platform_nifs.h"
3636
#include "port.h"
3737
#include "scheduler.h"
38+
#include "smp.h"
3839
#include "sys.h"
3940
#include "term.h"
4041
#include "utils.h"
@@ -70,7 +71,10 @@
7071
ctx->x[1] = (b); \
7172
return term_invalid_term();
7273

74+
#ifndef MAX
7375
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
76+
#endif
77+
7478
#define NOT_FOUND (0xFF)
7579

7680
#ifdef ENABLE_ADVANCED_TRACE
@@ -2543,7 +2547,7 @@ static term nif_erlang_system_flag(Context *ctx, int argc, term argv[])
25432547
argv[1] = BADARG_ATOM;
25442548
return term_invalid_term();
25452549
}
2546-
while (!atomic_compare_exchange_weak(&ctx->global->online_schedulers, &old_value, new_value)) {};
2550+
while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&ctx->global->online_schedulers, &old_value, new_value)) {};
25472551
return term_from_int32(old_value);
25482552
}
25492553
#else

src/libAtomVM/opcodesswitch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,9 @@ typedef union
944944
}
945945

946946

947+
#ifndef MIN
947948
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
949+
#endif
948950

949951
#ifdef IMPL_EXECUTE_LOOP
950952
struct Int24

src/libAtomVM/refc_binary.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,11 @@
2525
extern "C" {
2626
#endif
2727

28-
#include "list.h"
2928
#include <stdbool.h>
3029
#include <stdlib.h>
3130

32-
#if !defined(AVM_NO_SMP) && !defined(__cplusplus)
33-
#include <stdatomic.h>
34-
#define ATOMIC _Atomic
35-
#else
36-
#define ATOMIC
37-
#endif
31+
#include "list.h"
32+
#include "smp.h"
3833

3934
struct RefcBinary
4035
{

src/libAtomVM/smp.h

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -42,22 +42,18 @@ extern "C" {
4242
#define CLANG_THREAD_SANITIZE_SAFE
4343
#endif
4444

45-
#ifndef AVM_NO_SMP
46-
45+
#if defined(AVM_NO_SMP)
46+
#define ATOMIC
47+
#else
4748
#include <stdbool.h>
48-
4949
#ifndef __cplusplus
50+
#ifdef HAVE_PLATFORM_SMP_H
51+
#include "platform_smp.h"
52+
#else
5053
#include <stdatomic.h>
54+
#define ATOMIC_COMPARE_EXCHANGE_WEAK atomic_compare_exchange_weak
5155
#define ATOMIC _Atomic
52-
53-
#if ATOMIC_POINTER_LOCK_FREE != 2
54-
#error Current SMP implementation requires lock-free atomic pointers which this platform does not support, please disable SMP
5556
#endif
56-
57-
#if ATOMIC_LONG_LOCK_FREE != 2
58-
#error Current SMP implementation requires lock-free atomic long (32 bits) words which this platform does not support, please disable SMP
59-
#endif
60-
6157
#else
6258
#define ATOMIC
6359
#endif
@@ -87,10 +83,12 @@ typedef struct RWLock RWLock;
8783
typedef struct GlobalContext GlobalContext;
8884
#endif
8985

86+
#if !defined(SMP_PLATFORM_SPINLOCK)
9087
struct SpinLock
9188
{
9289
int ATOMIC lock;
9390
};
91+
#endif
9492

9593
/**
9694
* @brief Create a new mutex.
@@ -180,7 +178,7 @@ void smp_rwlock_wrlock(RWLock *lock);
180178
*/
181179
void smp_rwlock_unlock(RWLock *lock);
182180

183-
#ifndef __cplusplus
181+
#if !defined(__cplusplus) && !defined(SMP_PLATFORM_SPINLOCK)
184182

185183
/**
186184
* @brief Initialize a spinlock based on atomics.
@@ -200,7 +198,7 @@ static inline void smp_spinlock_lock(SpinLock *lock)
200198
int current;
201199
do {
202200
current = 0;
203-
} while (!atomic_compare_exchange_weak(&lock->lock, &current, 1));
201+
} while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&lock->lock, &current, 1));
204202
}
205203

206204
/**

0 commit comments

Comments
 (0)