diff --git a/p99/p99_constraint.h b/p99/p99_constraint.h
index 08dc113fa506a7beaa9b4bc2a4887d957d2b87ca..e4dab007f9984ef5463e10219a4ac6b45db75ab2 100644
--- a/p99/p99_constraint.h
+++ b/p99/p99_constraint.h
@@ -351,7 +351,7 @@ P99_WEAK(p99_constraint_handler)
 void p99_constraint_handler(const char * restrict p00_msg,
                             void * restrict p00_ptr,
                             errno_t p00_err) {
-  constraint_handler_t p00_func = atomic_load(&p00_constraint_handler);
+  constraint_handler_t p00_func = atomic_load_explicit(&p00_constraint_handler, memory_order_acquire);
   if (p00_func) p00_func(p00_msg, p00_ptr, p00_err);
 }
 
@@ -377,7 +377,7 @@ void abort_handler_s(const char * restrict p00_msg,
 p99_inline
 constraint_handler_t set_constraint_handler_s(constraint_handler_t p00_hand) {
   if (!p00_hand) p00_hand = P99_CONSTRAINT_HANDLER;
-  return atomic_exchange(&p00_constraint_handler, p00_hand);
+  return atomic_exchange_explicit(&p00_constraint_handler, p00_hand, memory_order_acq_rel);
 }
 
 # endif
@@ -387,6 +387,9 @@ errno_t p00_constraint_call(errno_t p00_cond, char const* p00_file, char const*
   if (p00_cond) {
     if (p00_file) P00_JMP_BUF_FILE = p00_file;
     if (p00_context) P00_JMP_BUF_CONTEXT = p00_context;
+    /* Ensure that all dependent data for this error has been */   \
+    /* synchronized. */                                            \
+    atomic_thread_fence(memory_order_seq_cst);                     \
     p99_constraint_handler(p00_info, 0, p00_cond);
   }
   return p00_cond;
diff --git a/p99/p99_fifo.h b/p99/p99_fifo.h
index 240a75ae3797b8c8664a5723ec04395b2cc5cc09..5630c458e691e9d92d207d19bd003d51fa2b3943 100644
--- a/p99/p99_fifo.h
+++ b/p99/p99_fifo.h
@@ -55,27 +55,27 @@ do {                                                                       \
   register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]);                       \
   register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]);                       \
   p00_el->p99_lifo = 0;                                                    \
-  P99_MACRO_VAR(p00_head, atomic_load(p00_h));                             \
+  P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
   for (;;) {                                                               \
     if (p00_head) {                                                        \
       /* spin lock the whole fifo */                                       \
-      if (atomic_compare_exchange_weak(p00_h, &p00_head, 0)) {             \
+      if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_relaxed)) { \
         /* make p00_el the last element */                                 \
-        atomic_exchange(p00_t, p00_el)->p99_lifo = p00_el;                 \
+        atomic_exchange_explicit(p00_t, p00_el, memory_order_acq_rel)->p99_lifo = p00_el; \
         /* unlock the fifo */                                              \
-        atomic_store(p00_h, p00_head);                                     \
+        atomic_store_explicit(p00_h, p00_head, memory_order_release);      \
         break;                                                             \
       }                                                                    \
     } else {                                                               \
-      P99_MACRO_VAR(p00_tail, atomic_load(p00_t));                         \
+      P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_relaxed)); \
       if (!p00_tail                                                        \
-          && atomic_compare_exchange_weak(p00_t, &p00_tail, p00_el)) {     \
+          && atomic_compare_exchange_weak_explicit(p00_t, &p00_tail, p00_el, memory_order_acq_rel, memory_order_relaxed)) { \
         /* the fifo was empty, our element is inserted, update the head */ \
-        atomic_store(p00_h, p00_el);                                       \
+        atomic_store_explicit(p00_h, p00_el, memory_order_release);        \
         break;                                                             \
       }                                                                    \
       /* we were in the middle of an update of another thread */           \
-      p00_head = atomic_load(p00_h);                                       \
+      p00_head = atomic_load_explicit(p00_h, memory_order_consume);        \
     }                                                                      \
   }                                                                        \
 } while (false)
@@ -129,26 +129,26 @@ p99_extension                                                            \
   register const P99_MACRO_VAR(p00_l, (L));                              \
   register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]);                     \
   register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]);                     \
-  P99_MACRO_VAR(p00_head, atomic_load(p00_h));                           \
+  P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
   for (;;) {                                                             \
     if (p00_head) {                                                      \
       /* spin lock the whole fifo */                                     \
-      if (atomic_compare_exchange_weak(p00_h, &p00_head, 0)) {           \
+      if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
         if (p00_head->p99_lifo)                                          \
           /* there is still another element to come in the fifo, make it \
              the head */                                                 \
-          atomic_store(p00_h, p00_head->p99_lifo);                       \
+          atomic_store_explicit(p00_h, p00_head->p99_lifo, memory_order_release); \
         else                                                             \
           /* this was the last element in the fifo, set the tail to 0,   \
              too */                                                      \
-          atomic_store(p00_t, 0);                                        \
+          atomic_store_explicit(p00_t, 0, memory_order_release);         \
         p00_head->p99_lifo = 0;                                          \
         break;                                                           \
       }                                                                  \
     } else {                                                             \
-      register P99_MACRO_VAR(p00_tail, atomic_load(p00_t));              \
+      register P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
       if (!p00_tail) break;                                              \
-      p00_head = atomic_load(p00_h);                                     \
+      p00_head = atomic_load_explicit(p00_h, memory_order_relaxed);      \
     }                                                                    \
   }                                                                      \
   /* make sure that the result can not be used as an lvalue */           \
@@ -174,18 +174,18 @@ p99_extension                                                      \
   register const P99_MACRO_VAR(p00_l, (L));                        \
   register const P99_MACRO_VAR(p00_h, &(*p00_l)[0]);               \
   register const P99_MACRO_VAR(p00_t, &(*p00_l)[1]);               \
-  P99_MACRO_VAR(p00_head, atomic_load(p00_h));                     \
+  P99_MACRO_VAR(p00_head, atomic_load_explicit(p00_h, memory_order_relaxed)); \
   for (;;) {                                                       \
     if (p00_head) {                                                \
       /* spin lock the whole fifo */                               \
-      if (atomic_compare_exchange_weak(p00_h, &p00_head, 0)) {     \
-        atomic_store(p00_t, 0);                                    \
+      if (atomic_compare_exchange_weak_explicit(p00_h, &p00_head, 0, memory_order_acq_rel, memory_order_consume)) { \
+        atomic_store_explicit(p00_t, 0, memory_order_release);     \
         break;                                                     \
       }                                                            \
     } else {                                                       \
-      register const P99_MACRO_VAR(p00_tail, atomic_load(p00_t));  \
+      register const P99_MACRO_VAR(p00_tail, atomic_load_explicit(p00_t, memory_order_consume)); \
       if (!p00_tail) break;                                        \
-      p00_head = atomic_load(p00_h);                               \
+      p00_head = atomic_load_explicit(p00_h, memory_order_relaxed);\
     }                                                              \
   }                                                                \
   /* make sure that the result can not be used as an lvalue */     \
diff --git a/p99/p99_threads.h b/p99/p99_threads.h
index fba3bd82ab7fed3d464c097cc1e5a3471edc2326..d6727ae3d9c2be15478df2d4f8b9f59500759c35 100644
--- a/p99/p99_threads.h
+++ b/p99/p99_threads.h
@@ -317,13 +317,18 @@ p00_thrd ** p00_foreign_tab;
 
 P99_WEAK(p00_foreign_cleanup)
 void p00_foreign_cleanup(void) {
-  size_t p00_foreign = atomic_load(&p00_foreign_nb);
+  size_t p00_foreign = atomic_load_explicit(&p00_foreign_nb, memory_order_consume);
   p00_thrd ** p00_thrd = p00_foreign_tab;
   p00_foreign_tab = 0;
-  for (size_t p00_i = 0; p00_i < p00_foreign; ++p00_i) {
-    if (!pthread_equal(p00_thrd[p00_i]->p00_id, pthread_self()))
-      fputs("found foreign thread\n", stderr);
-    free(p00_thrd[p00_i]);
+  if (p00_foreign) {
+    /* Ensure that all data is synchronized with all threads, not only
+       with the last one that changed p00_foreign_nb. */
+    atomic_thread_fence(memory_order_seq_cst);
+    for (size_t p00_i = 0; p00_i < p00_foreign; ++p00_i) {
+      if (!pthread_equal(p00_thrd[p00_i]->p00_id, pthread_self()))
+        fputs("found foreign thread\n", stderr);
+      free(p00_thrd[p00_i]);
+    }
   }
   free(p00_thrd);
 }
@@ -337,7 +342,7 @@ p99_inline
 thrd_t thrd_current(void) {
   p00_thrd * p00_loc = P00_THRD_LOCAL;
   if (P99_UNLIKELY(!p00_loc)) {
-    size_t p00_nb = atomic_fetch_add(&p00_foreign_nb, 1);
+    size_t p00_nb = atomic_fetch_add_explicit(&p00_foreign_nb, 1, memory_order_acq_rel);
     if (!p00_nb) atexit(p00_foreign_cleanup);
     if ((p00_nb^(p00_nb-1)) == (p00_nb+(p00_nb-1))) {
       p00_foreign_tab = realloc(p00_foreign_tab, sizeof(p00_thrd*[2*(p00_nb+1)]));
diff --git a/p99/p99_tp.h b/p99/p99_tp.h
index c0bfdb89c8ab1f434603af72a03f09cc9f0053ce..79971a30de9f9facf02f3fb6c208bbc1fc9d4334 100644
--- a/p99/p99_tp.h
+++ b/p99/p99_tp.h
@@ -119,7 +119,7 @@ uintptr_t p00_tp_tick_get(void) {
   if (P99_UNLIKELY(!(*p00_ret & p00_mask))) {
     uintptr_t p00_tack = 0;
     while (!p00_tack) {
-      p00_tack = atomic_fetch_add(&p00_tp_tack, 1u);
+      p00_tack = atomic_fetch_add_explicit(&p00_tp_tack, 1u, memory_order_acq_rel);
       p00_tack &= p00_mask;
     }
     *p00_ret = (p00_tack << p00_bits);
@@ -184,7 +184,7 @@ struct p99_tp_state {
 p99_inline
 bool p00_tp_cmpxchg(_Atomic(p00_tp_glue) volatile*const p00_p, p00_tp_glue volatile*const p00_prev, p00_tp_glue p00_new) {
   P99_MARK("wide cmpxchg start");
-  bool ret = atomic_compare_exchange_weak(p00_p, p00_prev, p00_new);
+  bool ret = atomic_compare_exchange_weak_explicit(p00_p, p00_prev, p00_new, memory_order_acq_rel, memory_order_consume);
   P99_MARK("wide cmpxchg end");
   return ret;
 }
@@ -193,7 +193,7 @@ p99_inline
 p00_tp_glue p00_tp_get(register p99_tp volatile*const p00_tp) {
   register p00_tp_glue p00_ret
   = P99_LIKELY(p00_tp)
-    ? atomic_load(&p00_tp->p00_val)
+    ? atomic_load_explicit(&p00_tp->p00_val, memory_order_consume)
     : (p00_tp_glue)P00_TP_GLUE_INITIALIZER((void*)0, p00_tp_tick_get());
   if (p00_tp && P99_UNLIKELY(!p00_tp_i2i(p00_ret))) {
     /* Only store it in addressable memory if we can't avoid it. */
@@ -214,7 +214,7 @@ p99_inline
 p00_tp_glue p99_tp_xchg(p99_tp volatile* p00_tp, void* p00_val) {
   p00_tp_glue p00_ret
   = P99_LIKELY(p00_tp)
-    ? atomic_load(&p00_tp->p00_val)
+    ? atomic_load_explicit(&p00_tp->p00_val, memory_order_consume)
     : (p00_tp_glue)P00_TP_GLUE_INITIALIZER((void*)0, p00_tp_tick_get());
   if (P99_LIKELY(p00_tp)) {
     register p00_tp_glue p00_rep = P00_TP_GLUE_INITIALIZER(p00_val, p00_tp_tick_get());
@@ -429,7 +429,7 @@ p99_extension ({                                                 \
     /* ensure that the pointer is converted to the */            \
     /* base type, and that the return can't be used as lvalue */ \
     register __typeof__(p00_ref) const p00_r = p00_ref;          \
-    if (p00_r) atomic_fetch_add(&p00_r->p99_cnt, 1);             \
+    if (p00_r) atomic_fetch_add_explicit(&p00_r->p99_cnt, 1, memory_order_acq_rel); \
     p00_r;                                                       \
 })
 
@@ -439,7 +439,7 @@ p99_extension ({                                                   \
     /* ensure that pointer that is returned is converted to the */ \
     /* base type, and that the return can't be used as lvalue */   \
     register P99_TP_TYPE(p00_tp)* const p00_r = (REF);             \
-    if (p00_r) atomic_fetch_add(&p00_r->p99_cnt, 1);               \
+    if (p00_r) atomic_fetch_add_explicit(&p00_r->p99_cnt, 1, memory_order_acq_rel); \
     p00_r;                                                         \
 })
 
@@ -451,7 +451,7 @@ p99_extension ({                                                 \
     /* ensure that the pointer is converted to the */            \
     /* base type, and that the return can't be used as lvalue */ \
     register __typeof__(*p00_ref)*const p00_r = p00_ref;         \
-    if (p00_r && (atomic_fetch_sub(&p00_r->p99_cnt, 1) == 1))    \
+    if (p00_r && (atomic_fetch_sub_explicit(&p00_r->p99_cnt, 1, memory_order_acq_rel) == 1)) \
       p00_d(p00_r);                                              \
     p00_r;                                                       \
 })