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