Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support of OCaml 5.0 (cleaned version) #124

Closed
wants to merge 42 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
abfa48b
Add -Wl,--start-group & -Wl,--end-group
dinosaure Jan 9, 2023
32633a8
Delete the usage of `sed -i` (and replace it by `sed && mv`)
dinosaure Jan 9, 2023
d2e4a0b
Specify the architecture into the OCaml's `./configure` script
dinosaure Jan 9, 2023
0f97e4d
Add $$PTHREAD_LIB into our pattern to modify nativecclibs
dinosaure Jan 9, 2023
6a0fc20
Add runtime/primitives as a dependency for the coldstart rule
dinosaure Jan 9, 2023
453e289
ocamlrun{,d,i} are located into the runtime directory
dinosaure Jan 9, 2023
10f2f9b
Delete fake libcamlrun{,d,i}.a from the Makefile
dinosaure Jan 9, 2023
7975a11
/runtime/Makefile was deleted (OCaml 5.0) and everything is into /Mak…
dinosaure Jan 11, 2023
5480611
Replace ocamlyacc by $$(ocamlyacc_PROGRAM)
dinosaure Jan 9, 2023
b45acbd
Replace the number of domains into our OCaml runtime
dinosaure Jan 9, 2023
a87ca82
Disable debug runtime
dinosaure Jan 9, 2023
a817e26
Delete unecessary tweak Makefile rule about objinfo_helper
dinosaure Jan 11, 2023
0c86e1a
Add a missing / into our nolibc's test-include/%.c rule
dinosaure Jan 9, 2023
9f94617
Add the -p option when we use mkdir (nolibc's Makefile)
dinosaure Jan 9, 2023
b89d736
Set NATIVE_COMPILER to true into the OCaml's Makefile.config
dinosaure Jan 9, 2023
230213d
Add test-include/sys/ as a dependency for test-headers (nolibc's Make…
dinosaure Jan 9, 2023
d912fb0
Define EBUSY
dinosaure Jan 9, 2023
a0b57c0
Define O_RDWR
dinosaure Jan 9, 2023
81b73f9
Define SIG_BLOCK/SIG_SETMASK
dinosaure Jan 9, 2023
7d021b8
Define S_{IR,IW}USR
dinosaure Jan 11, 2023
d96e157
Stub pthread
dinosaure Jan 9, 2023
5dab641
Stub sigfillset
dinosaure Jan 9, 2023
8188ff9
Stub fputs, fopen and fclose and implement puts and putchar
dinosaure Jan 13, 2023
57cea73
Stub strerror_r
dinosaure Jan 11, 2023
2e94e8c
Stub ftruncate
dinosaure Jan 11, 2023
d2704ed
Stub usleep
dinosaure Jan 11, 2023
f694bb4
Export stdrup & strcpy
dinosaure Jan 11, 2023
f1a4264
Export qsort and mktemp
dinosaure Jan 9, 2023
221d3c7
Export fstat
dinosaure Jan 11, 2023
e43f6e5
Export islanum and tolower
dinosaure Jan 9, 2023
c1cf5d1
Add longjmp & setjmp
dinosaure Jan 9, 2023
d4bfcfa
Add the sched.h interface (and the CPU_ZERO value)
dinosaure Jan 9, 2023
924cbf5
Add the stdatomic.h
dinosaure Jan 11, 2023
50f066a
Add sysconf.c (to let OCaml to know the _SC_PAGE{,_}SIZE)
dinosaure Jan 13, 2023
f9d621e
Add the mmap() function
dinosaure Jan 13, 2023
f3f662e
Initialise the Thread Local Store
dinosaure Jan 11, 2023
93f3506
Upgrade ocaml-solo5 with OCaml 5.0
dinosaure Jan 11, 2023
9c45880
Upgrade GitHub workflow and Cirrus CI with OCaml 5.0
dinosaure Jan 11, 2023
256805f
Fix the example & the test program
dinosaure Jan 19, 2023
d5ef317
Use __c11 atomic macros when they are available (and fix the LLVM sup…
dinosaure Jan 19, 2023
88b0c71
Update to the new Solo5 API.
palainp Feb 7, 2023
d7f336b
minor change to trigger CI
hannesm May 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ freebsd_task:
OPAMYES: 1
env:
matrix:
- OCAML_VERSION: 4.12.1
- OCAML_VERSION: 4.13.0
- OCAML_VERSION: 4.13.1
- OCAML_VERSION: 5.0.0
pkg_install_script: pkg install -y ocaml-opam gmp gmake pkgconf bash
opam_ocaml_cache:
folder: $HOME/.opam
Expand Down
13 changes: 1 addition & 12 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
strategy:
matrix:
operating-system: [ubuntu-latest]
ocaml-version: [4.13.1]
ocaml-version: [5.0.0]
mode:
- name: hvt
exec: false
Expand All @@ -17,17 +17,6 @@ jobs:
exec: false
- name: xen
exec: false
include:
- operating-system: ubuntu-latest
ocaml-version: 4.13.0
mode:
name: spt
exec: true
- operating-system: ubuntu-latest
ocaml-version: 4.12.1
mode:
name: spt
exec: true
runs-on: ${{ matrix.operating-system }}
steps:
- uses: actions/checkout@v2
Expand Down
56 changes: 36 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LOCAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(TOP)/nolibc/include -include _solo5/override
# CFLAGS used by the OCaml compiler to build C stubs
GLOBAL_CFLAGS=$(MAKECONF_CFLAGS) -I$(MAKECONF_PREFIX)/solo5-sysroot/include/nolibc/ -include _solo5/overrides.h
# LIBS used by the OCaml compiler to link executables
GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS)
GLOBAL_LIBS=-L$(MAKECONF_PREFIX)/solo5-sysroot/lib/nolibc/ -Wl,--start-group -lnolibc -lopenlibm $(MAKECONF_EXTRA_LIBS) -Wl,--end-group

# NOLIBC
NOLIBC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/src -I$(TOP)/openlibm/include
Expand Down Expand Up @@ -45,28 +45,43 @@ ocaml/Makefile:
# configure link test
# - We override OCAML_OS_TYPE since configure just hardcodes it to "Unix".
OC_CFLAGS=$(LOCAL_CFLAGS) -I$(TOP)/openlibm/include -I$(TOP)/openlibm/src -nostdlib
OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS)
OC_LIBS=-L$(TOP)/nolibc -lnolibc -L$(TOP)/openlibm -Wl,--start-group -lopenlibm -nostdlib $(MAKECONF_EXTRA_LIBS) -Wl,--end-group
ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a
# configure: Do not build dynlink
sed -i -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure
sed -e 's/otherlibraries="dynlink"/otherlibraries=""/g' ocaml/configure > ocaml/configure.sed && \
mv ocaml/configure.sed ocaml/configure
# configure: Allow precise input of flags and libs
sed -i -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure
sed -i -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure
sed -i -e 's/nativecclibs="$$cclibs $$DLLIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure
# runtime/Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system
sed -i -e 's/^all: $$(BYTECODE_STATIC_LIBRARIES) $$(BYTECODE_SHARED_LIBRARIES)/all: primitives ld.conf/' ocaml/runtime/Makefile
sed -i -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/runtime/Makefile
sed -i -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/runtime/Makefile
sed -i -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/runtime/Makefile
echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/runtime/Makefile
echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/runtime/Makefile
echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/runtime/Makefile
touch ocaml/runtime/libcamlrun.a ocaml/runtime/libcamlrund.a ocaml/runtime/libcamlruni.a
sed -e 's/oc_cflags="/oc_cflags="$$OC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \
mv ocaml/configure.sed ocaml/configure
sed -e 's/ocamlc_cflags="/ocamlc_cflags="$$OCAMLC_CFLAGS /g' ocaml/configure > ocaml/configure.sed && \
mv ocaml/configure.sed ocaml/configure
sed -e 's/nativecclibs="$$cclibs $$DLLIBS $$PTHREAD_LIBS"/nativecclibs="$$GLOBAL_LIBS"/g' ocaml/configure > ocaml/configure.sed && \
mv ocaml/configure.sed ocaml/configure
sed -e 's/^arch=none$$/arch=$(MAKECONF_OCAML_BUILD_ARCH)/' ocaml/configure > ocaml/configure.sed && \
mv ocaml/configure.sed ocaml/configure
chmod +x ocaml/configure
# Makefile: Runtime rules: don't build libcamlrun.a and import ocamlrun from the system
sed -e 's/^ocamlrun$$(EXE):.*/dummy:/g' ocaml/Makefile > ocaml/Makefile.sed && \
mv ocaml/Makefile.sed ocaml/Makefile
sed -e 's/^ocamlruni$$(EXE):.*/dummyi:/g' ocaml/Makefile > ocaml/Makefile.sed && \
mv ocaml/Makefile.sed ocaml/Makefile
sed -e 's/^ocamlrund$$(EXE):.*/dummyd:/g' ocaml/Makefile > ocaml/Makefile.sed && \
mv ocaml/Makefile.sed ocaml/Makefile
sed -e 's,^coldstart: $(COLDSTART_DEPS)$$,coldstart: runtime/primitives $$(COLDSTART_DEPS),' ocaml/Makefile > ocaml/Makefile.sed && \
mv ocaml/Makefile.sed ocaml/Makefile
echo -e "ocamlrun:\n\tcp $(shell which ocamlrun) .\n" >> ocaml/Makefile
echo -e "ocamlrund:\n\tcp $(shell which ocamlrund) .\n" >> ocaml/Makefile
echo -e "ocamlruni:\n\tcp $(shell which ocamlruni) .\n" >> ocaml/Makefile
echo -e "runtime/ocamlrun\$$(EXE):\n\tcp $(shell which ocamlrun) runtime/\n" >> ocaml/Makefile
echo -e "runtime/ocamlrund\$$(EXE):\n\tcp $(shell which ocamlrund) runtime/\n" >> ocaml/Makefile
echo -e "runtime/ocamlruni\$$(EXE):\n\tcp $(shell which ocamlruni) runtime/\n" >> ocaml/Makefile
# yacc/Makefile: import ocamlyacc from the system
sed -i -e 's/^ocamlyacc$$(EXE):.*/dummy:/g' ocaml/yacc/Makefile
echo -e "ocamlyacc:\n\tcp $(shell which ocamlyacc) .\n" >> ocaml/yacc/Makefile
# tools/Makefile: stub out objinfo_helper
echo -e "objinfo_helper:\n\ttouch objinfo_helper\n" >> ocaml/tools/Makefile
sed -e 's,^$$(ocamlyacc_PROGRAM)$$(EXE):.*,dummy_yacc:,g' ocaml/Makefile > ocaml/Makefile.sed && \
mv ocaml/Makefile.sed ocaml/Makefile
echo -e "\$$(ocamlyacc_PROGRAM)\$$(EXE):\n\tcp $(shell which ocamlyacc) yacc/\n" >> ocaml/Makefile
# patch ocaml 5.0.0 runtime for single domain/thread solo5
sed -e 's/#define Max_domains 128/#define Max_domains 1/' ocaml/runtime/caml/domain.h > ocaml/runtime/caml/domain.h.sed && \
mv ocaml/runtime/caml/domain.h.sed ocaml/runtime/caml/domain.h
# av_cv_libm_cos=no is passed to configure to prevent -lm being used (which
# would use the host system libm instead of the freestanding openlibm, see
# https://github.com/mirage/ocaml-solo5/issues/101
Expand All @@ -89,10 +104,11 @@ ocaml/Makefile.config: ocaml/Makefile openlibm/libopenlibm.a nolibc/libnolibc.a
-disable-systhreads\
-disable-unix-lib\
-disable-instrumented-runtime\
-disable-debug-runtime\
-disable-ocamltest\
-disable-ocamldoc\
$(MAKECONF_OCAML_CONFIGURE_OPTIONS)
echo "ARCH=$(MAKECONF_OCAML_BUILD_ARCH)" >> ocaml/Makefile.config
echo 'NATIVE_COMPILER=true' >> ocaml/Makefile.config
echo 'SAK_CC=cc' >> ocaml/Makefile.config
echo 'SAK_CFLAGS=' >> ocaml/Makefile.config
echo 'SAK_LINK=cc $(SAK_CFLAGS) $$(OUTPUTEXE)$$(1) $$(2)' >> ocaml/Makefile.config
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ Run: `solo5-hvt _build/default.solo5/main.exe`

## Supported compiler versions

Tested against OCaml 4.12.1 through 4.13.0. Other versions may require
changing `configure.sh`.
Tested against OCaml 5.0. Other versions may require changing `configure.sh`.

## Porting to a different (uni)kernel base layer

Expand Down
1 change: 1 addition & 0 deletions example/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ void _nolibc_init(uintptr_t heap_start, size_t heap_size); // defined in nolibc/
int solo5_app_main(const struct solo5_start_info *si) {
_nolibc_init(si->heap_start, si->heap_size);
caml_startup(unused_argv);
return 0;
}
18 changes: 10 additions & 8 deletions nolibc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ OBJS=assert.o \
dtoa.o \
memchr.o memcmp.o memcpy.o memmove.o memset.o \
strcmp.o strlen.o strtol.o strchr.o strchrnul.o strncpy.o stpncpy.o \
strstr.o strncmp.o \
strstr.o strncmp.o puts.o \
stubs.o \
vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o
vfprintf.o vsnprintf.o snprintf.o fprintf.o printf.o \
sysconf.o \
mmap.o

dtoa.o: CFLAGS+=-fno-strict-aliasing

Expand All @@ -42,15 +44,15 @@ TEST_H_OBJS=$(patsubst %.h,test-%.o,$(HEADERS))

# For each HEADER we want to test, generate a C source file including only
# that HEADER. As above, HEADER may include subdirectories.
test-include/%.c: include/%.h | test-include/sys
test-include/%.c: include/%.h | test-include/sys/
echo "#include \"../$<\"" >$@

.PRECIOUS: test-include/%.c

test-include:
mkdir $@
test-include/:
mkdir -p $@

test-include/sys: test-include
mkdir $@
test-include/sys/: test-include/
mkdir -p $@

test-headers: $(TEST_H_OBJS)
test-headers: test-include/sys/ $(TEST_H_OBJS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
test-headers: test-include/sys/ $(TEST_H_OBJS)
test-headers: $(TEST_H_OBJS) | test-include/sys/

The dependency on test-include/sys/ is order only.

8 changes: 1 addition & 7 deletions nolibc/assert.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>

/*
* These functions deliberately do not call printf() or malloc() in order to
* abort as quickly as possible without triggering further errors.
*/

static void puts(const char *s)
{
(void)write(2, s, strlen(s));
}

void _assert_fail(const char *file, const char *line, const char *e)
{
puts(file);
Expand Down
2 changes: 2 additions & 0 deletions nolibc/include/ctype.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ int isdigit(int);
int isprint(int);
int isspace(int);
int isupper(int);
int isalnum(int);
int tolower(int);

#endif
4 changes: 4 additions & 0 deletions nolibc/include/errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,9 @@ extern int errno;
#define EINVAL 6
#define ENOMEM 7
#define EMFILE 8
#define EBUSY 9
/* TODO(dinosaure): we probably should follow the Cosmopolitan
* project about these constants and use values where we have
* an {unix,bsd} consensus. */

#endif
4 changes: 4 additions & 0 deletions nolibc/include/fcntl.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,9 @@ int open(const char *, int, ...);
#define O_CREAT (1<<3)
#define O_TRUNC (1<<4)
#define O_EXCL (1<<5)
#define O_RDWR (1<<6)
/* TODO(dinosaure): same as errno values, we should take a
* look on the Cosmopolitan project and set values when
* we can find an {unix,bsd} consensus. */

#endif
57 changes: 57 additions & 0 deletions nolibc/include/pthread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#ifndef _PTHREAD_H
#define _PTHREAD_H

#include <stddef.h>
#include <signal.h>

typedef unsigned long int pthread_t;
typedef int cpu_set_t;

int pthread_getaffinity_np(pthread_t, size_t, cpu_set_t *);

pthread_t pthread_self(void);

typedef int pthread_attr_t;

int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *);
int pthread_join(pthread_t, void **);
int pthread_attr_init(pthread_attr_t *);
void pthread_cleanup_push(void (*)(void *), void *);
void pthread_cleanup_pop(int);

typedef int pthread_mutex_t;
typedef int pthread_cond_t;

int pthread_mutex_lock(pthread_mutex_t *);
int pthread_mutex_trylock(pthread_mutex_t *);
int pthread_mutex_unlock(pthread_mutex_t *);

#define PTHREAD_MUTEX_INITIALIZER 0
#define PTHREAD_COND_INITIALIZER 0

int pthread_sigmask(int, const sigset_t *, sigset_t *);
int pthread_detach(pthread_t);
int pthread_equal(pthread_t, pthread_t);

typedef int pthread_mutexattr_t;

int pthread_mutexattr_init(pthread_mutexattr_t *);
int pthread_mutexattr_settype(pthread_mutexattr_t *, int);

#define PTHREAD_MUTEX_ERRORCHECK 0

int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
int pthread_mutexattr_destroy(pthread_mutexattr_t *);
int pthread_mutex_destroy(pthread_mutex_t *);

typedef int pthread_condattr_t;

int pthread_condattr_init(pthread_condattr_t *);
int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);

int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
int pthread_cond_broadcast(pthread_cond_t *);
int pthread_cond_signal(pthread_cond_t *);
int pthread_cond_destroy(pthread_cond_t *);

#endif
8 changes: 8 additions & 0 deletions nolibc/include/sched.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef _SCHED_H
#define _SCHED_H

typedef int cpu_set_t;

#define CPU_ZERO (x) 0

#endif
4 changes: 4 additions & 0 deletions nolibc/include/setjmp.h
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
#include <signal.h>

void longjmp(int, int) __attribute__ ((__noreturn__));

#define setjmp(buf) 0
16 changes: 13 additions & 3 deletions nolibc/include/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,24 @@
typedef int jmp_buf;
int setjmp(jmp_buf);
void (*signal(int sig, void (*func)(int)))(int);
#define SIG_DFL NULL
#define SIG_IGN NULL
#define SIG_ERR NULL
#define SIG_DFL 0
#define SIG_IGN 0
#define SIG_ERR 0
#define SIG_BLOCK 0
#define SIG_SETMASK 0
/*
* The following definitions are not required by the OCaml runtime, but are
* needed to build the freestanding version of GMP used by Mirage.
* For OCaml 5.0.0, it's not totally true. SIG_{BLOCK,SETMASK,IGN,DFL) are
* needed by the OCaml runtime.
Comment on lines 13 to +16
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* The following definitions are not required by the OCaml runtime, but are
* needed to build the freestanding version of GMP used by Mirage.
* For OCaml 5.0.0, it's not totally true. SIG_{BLOCK,SETMASK,IGN,DFL) are
* needed by the OCaml runtime.
* The following definitions are required to build the freestanding version of GMP used by Mirage.
OCaml 5.0.0 also required the SIG_{BLOCK,SETMASK,IGN,DFL) definition.

We rephrased part of the comment that was outdated by OCaml 5.0.0 support.

*
* NOTE: Solo5 does not implement signals, but we should not trigger
* a situation where these values are really used.
*/
#define SIGFPE 1
int raise(int);

typedef int sigset_t;
int sigfillset(sigset_t *);

#endif
69 changes: 69 additions & 0 deletions nolibc/include/stdatomic.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#ifndef _STDATOMIC_H
#define _STDATOMIC_H

// Compatibility with non-clang compilers
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif

#define atomic_load_explicit(x, mode) ( *x )
#define atomic_load(x) ( *x )

extern int memory_order_release;
extern int memory_order_acquire;
extern int memory_order_relaxed;
extern int memory_order_seq_cst;

#if __has_builtin(__c11_atomic_fetch_add)
#define atomic_fetch_add(X, Y) __c11_atomic_fetch_add(X, Y, __ATOMIC_SEQ_CST)
#else
#define atomic_fetch_add(X, Y) ({ __auto_type tmp = *X; *X = tmp + Y; tmp; })
#endif

#define atomic_fetch_add_explicit(X, Y, MOD) atomic_fetch_add(X, Y)

#define atomic_thread_fence(MO) do {} while (0)

typedef unsigned long long atomic_uint_fast64_t;

#if __has_builtin(__c11_atomic_compare_exchange_strong)
#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \
__c11_atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED, \
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#else
#define atomic_compare_exchange_strong(OBJ, EXPECTED, DESIRED) \
({ int ret = 0; \
if (*OBJ == *EXPECTED) { \
*OBJ = DESIRED; \
ret = 1; \
} \
ret; \
})
#endif

#if __has_builtin(__c11_atomic_exchange)
#define atomic_exchange(OBJ, DESIRED) \
__c11_atomic_exchange(OBJ, DESIRED, __ATOMIC_SEQ_CST)
#else
#define atomic_exchange(OBJ, DESIRED) \
({ __auto_type tmp = *OBJ; \
*OBJ = DESIRED; \
tmp; \
})
#endif

#define atomic_store(OBJ, DESIRED) do { *OBJ = DESIRED; } while(0)
#define atomic_store_explicit(OBJ, DESIRED, ORDER) atomic_store(OBJ, DESIRED)

#if __has_builtin(__c11_atomic_fetch_or)
#define atomic_fetch_or(OBJ, ARG) \
__c11_atomic_fetch_or(OBJ, ARG, __ATOMIC_SEQ_CST)
#else
#define atomic_fetch_or(OBJ, ARG) \
({ __auto_type tmp = *OBJ; \
*OBJ = *OBJ | ARG; \
tmp; \
})
#endif

#endif
Loading