qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

synchronization_util.h (2531B)


      1 // Copyright 2022 Stefan Kerkmann
      2 // SPDX-License-Identifier: GPL-2.0-or-later
      3 
      4 #pragma once
      5 
      6 #if defined(PLATFORM_SUPPORTS_SYNCHRONIZATION)
      7 #    if defined(SPLIT_KEYBOARD)
      8 void split_shared_memory_lock(void);
      9 void split_shared_memory_unlock(void);
     10 #    endif
     11 #else
     12 #    if defined(SPLIT_KEYBOARD)
     13 inline void split_shared_memory_lock(void) {};
     14 inline void split_shared_memory_unlock(void) {};
     15 #    endif
     16 #endif
     17 
     18 /* GCCs cleanup attribute expects a function with one parameter, which is a
     19  * pointer to a type compatible with the variable. As we don't want to expose
     20  * the platforms internal mutex type this workaround with auto generated adapter
     21  * function is defined */
     22 #define QMK_DECLARE_AUTOUNLOCK_HELPERS(prefix)                              \
     23     inline unsigned prefix##_autounlock_lock_helper(void) {                 \
     24         prefix##_lock();                                                    \
     25         return 0;                                                           \
     26     }                                                                       \
     27                                                                             \
     28     inline void prefix##_autounlock_unlock_helper(unsigned* unused_guard) { \
     29         prefix##_unlock();                                                  \
     30     }
     31 
     32 /* Generate an out-of-line implementation in case the inline functions defined
     33  * by the above macro don't actually get inlined. */
     34 #define QMK_IMPLEMENT_AUTOUNLOCK_HELPERS(prefix)                  \
     35     extern inline unsigned prefix##_autounlock_lock_helper(void); \
     36     extern inline void     prefix##_autounlock_unlock_helper(unsigned* unused_guard);
     37 
     38 /* Convinience macro the automatically generate the correct RAII-style
     39  * lock_autounlock function macro */
     40 #define QMK_DECLARE_AUTOUNLOCK_CALL(prefix) unsigned prefix##_guard __attribute__((unused, cleanup(prefix##_autounlock_unlock_helper))) = prefix##_autounlock_lock_helper
     41 
     42 #if defined(SPLIT_KEYBOARD)
     43 QMK_DECLARE_AUTOUNLOCK_HELPERS(split_shared_memory)
     44 
     45 /**
     46  * @brief Acquire exclusive access to the split keyboard shared memory, by
     47  * calling the platforms `split_shared_memory_lock()` function. The lock is
     48  * automatically released by calling the platforms `split_shared_memory_unlock()`
     49  * function. This happens when the block where
     50  * `split_shared_memory_lock_autounlock()` is called in goes out of scope i.e.
     51  * when the enclosing function returns.
     52  */
     53 #    define split_shared_memory_lock_autounlock QMK_DECLARE_AUTOUNLOCK_CALL(split_shared_memory)
     54 #endif