Swapping arrays for an interrupt, quickly

This might be okay on AVR, since __sync_synchronize() is only a compile-time fence (in the absence of caches, out-of-order execution, multiple cores, etc.).
However, on non-AVR targets, you should use the standard library atomics and fences, e.g. std::atomic_signal_fence - cppreference.com.
This is because C++ has a well-defined memory model, and rigorously defines the behavior and synchronization and memory order guarantees for all atomic operations and fences.

A full memory fence like __sync_synchronize() is serious overkill: for interrupt handlers, you should only need compile-time barriers. (*)
Even for multithreaded applications, you only need atomic exchange/load-acquire and store-release operations to implement a mutex, not full barriers. See e.g. Correctly Implementing a Spinlock in C++ | Erik Rigtorp

In the context of interrupts, a mutex is essentially useless, because the ISR cannot possibly acquire it without deadlocking.


(*) Since both the access of the volatile variable mutexFlag and the call to (no)interrupts() (access of a volatile register) have observable side effects, you don't need any additional ordering constraints in this case.
However, volatile does not guarantee any memory order, so it cannot be used for multithreaded applications.