1 /* 2 * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 /* 8 * @file generic/mutex.h 9 * @brief Generic mutex primitives for libmetal. 10 */ 11 12 #ifndef __METAL_MUTEX__H__ 13 #error "Include metal/mutex.h instead of metal/generic/mutex.h" 14 #endif 15 16 #ifndef __METAL_GENERIC_MUTEX__H__ 17 #define __METAL_GENERIC_MUTEX__H__ 18 19 #include <metal/atomic.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 typedef struct { 26 atomic_int v; 27 } metal_mutex_t; 28 29 #define METAL_MUTEX_UNLOCKED 0 30 #define METAL_MUTEX_LOCKED 1 31 32 /* 33 * METAL_MUTEX_INIT - used for initializing an mutex element in a static struct 34 * or global 35 */ 36 #define METAL_MUTEX_INIT(m) { ATOMIC_VAR_INIT(METAL_MUTEX_UNLOCKED) } 37 /* 38 * METAL_MUTEX_DEFINE - used for defining and initializing a global or 39 * static singleton mutex 40 */ 41 #define METAL_MUTEX_DEFINE(m) metal_mutex_t m = METAL_MUTEX_INIT(m) 42 __metal_mutex_init(metal_mutex_t * mutex)43static inline void __metal_mutex_init(metal_mutex_t *mutex) 44 { 45 atomic_store(&mutex->v, METAL_MUTEX_UNLOCKED); 46 } 47 __metal_mutex_deinit(metal_mutex_t * mutex)48static inline void __metal_mutex_deinit(metal_mutex_t *mutex) 49 { 50 (void)mutex; 51 } 52 __metal_mutex_try_acquire(metal_mutex_t * mutex)53static inline int __metal_mutex_try_acquire(metal_mutex_t *mutex) 54 { 55 int unlocked = METAL_MUTEX_UNLOCKED; 56 57 if (atomic_compare_exchange_strong(&mutex->v, &unlocked, 58 METAL_MUTEX_LOCKED)) { 59 return 1; /* acquired */ 60 } else { 61 return 0; /* not acquired */ 62 } 63 } 64 __metal_mutex_acquire(metal_mutex_t * mutex)65static inline void __metal_mutex_acquire(metal_mutex_t *mutex) 66 { 67 int unlocked = METAL_MUTEX_UNLOCKED; 68 69 while (!atomic_compare_exchange_weak(&mutex->v, &unlocked, 70 METAL_MUTEX_LOCKED)) { 71 ; 72 } 73 } 74 __metal_mutex_release(metal_mutex_t * mutex)75static inline void __metal_mutex_release(metal_mutex_t *mutex) 76 { 77 atomic_store(&mutex->v, METAL_MUTEX_UNLOCKED); 78 } 79 __metal_mutex_is_acquired(metal_mutex_t * mutex)80static inline int __metal_mutex_is_acquired(metal_mutex_t *mutex) 81 { 82 return atomic_load(&mutex->v); 83 } 84 85 #ifdef __cplusplus 86 } 87 #endif 88 89 #endif /* __METAL_GENERIC_MUTEX__H__ */ 90