Skip to content

Commit abe4f9c

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 7b65e20 commit abe4f9c

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
@@ -126,8 +126,22 @@ if (AVM_DISABLE_SMP)
126126
else()
127127
include(CheckIncludeFile)
128128
CHECK_INCLUDE_FILE(stdatomic.h STDATOMIC_INCLUDE)
129-
if(NOT STDATOMIC_INCLUDE)
130-
message(FATAL_ERROR "stdatomic.h cannot be found, you need to disable SMP on this platform")
129+
if(HAVE_PLATFORM_SMP_H)
130+
target_compile_definitions(libAtomVM PUBLIC HAVE_PLATFORM_SMP_H)
131+
endif()
132+
include(CheckCSourceCompiles)
133+
check_c_source_compiles("
134+
#include <stdatomic.h>
135+
int main() {
136+
_Static_assert(ATOMIC_POINTER_LOCK_FREE == 2, \"Expected ATOMIC_POINTER_LOCK_FREE to be equal to 2\");
137+
}
138+
" ATOMIC_POINTER_LOCK_FREE_IS_TWO)
139+
if (NOT ATOMIC_POINTER_LOCK_FREE_IS_TWO AND NOT HAVE_PLATFORM_SMP_H)
140+
if (NOT STDATOMIC_INCLUDE)
141+
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")
142+
else()
143+
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")
144+
endif()
131145
endif()
132146
endif()
133147

src/libAtomVM/context.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ void context_update_flags(Context *ctx, int mask, int value) CLANG_THREAD_SANITI
177177
enum ContextFlags desired;
178178
do {
179179
desired = (expected & mask) | value;
180-
} while (!atomic_compare_exchange_weak(&ctx->flags, &expected, desired));
180+
} while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&ctx->flags, &expected, desired));
181181
#else
182182
ctx->flags = (ctx->flags & mask) | value;
183183
#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"
@@ -68,7 +69,10 @@
6869
ctx->x[1] = (b); \
6970
return term_invalid_term();
7071

72+
#ifndef MAX
7173
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
74+
#endif
75+
7276
#define NOT_FOUND (0xFF)
7377

7478
#ifdef ENABLE_ADVANCED_TRACE
@@ -2525,7 +2529,7 @@ static term nif_erlang_system_flag(Context *ctx, int argc, term argv[])
25252529
argv[1] = BADARG_ATOM;
25262530
return term_invalid_term();
25272531
}
2528-
while (!atomic_compare_exchange_weak(&ctx->global->online_schedulers, &old_value, new_value)) {};
2532+
while (!ATOMIC_COMPARE_EXCHANGE_WEAK(&ctx->global->online_schedulers, &old_value, new_value)) {};
25292533
return term_from_int32(old_value);
25302534
}
25312535
#else

src/libAtomVM/opcodesswitch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,7 +902,9 @@ typedef union
902902
}
903903

904904

905+
#ifndef MIN
905906
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
907+
#endif
906908

907909
#ifdef IMPL_EXECUTE_LOOP
908910
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)