1 /*
2  * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*
8  * @file	spinlock.h
9  * @brief	Spinlock primitives for libmetal.
10  */
11 
12 #ifndef __METAL_SPINLOCK__H__
13 #define __METAL_SPINLOCK__H__
14 
15 #include <metal/atomic.h>
16 #include <metal/cpu.h>
17 
18 #ifdef __cplusplus
19 extern "C" {
20 #endif
21 
22 /** \defgroup spinlock Spinlock Interfaces
23  *  @{
24  */
25 
26 struct metal_spinlock {
27 	atomic_flag v;
28 };
29 
30 /** Static metal spinlock initialization. */
31 #define METAL_SPINLOCK_INIT		{ATOMIC_FLAG_INIT}
32 
33 /**
34  * @brief	Initialize a libmetal spinlock.
35  * @param[in]	slock	Spinlock to initialize.
36  */
metal_spinlock_init(struct metal_spinlock * slock)37 static inline void metal_spinlock_init(struct metal_spinlock *slock)
38 {
39 	atomic_flag_clear(&slock->v);
40 }
41 
42 /**
43  * @brief	Acquire a spinlock.
44  * @param[in]	slock   Spinlock to acquire.
45  * @see metal_spinlock_release
46  */
metal_spinlock_acquire(struct metal_spinlock * slock)47 static inline void metal_spinlock_acquire(struct metal_spinlock *slock)
48 {
49 	while (atomic_flag_test_and_set(&slock->v)) {
50 		metal_cpu_yield();
51 	}
52 }
53 
54 /**
55  * @brief	Release a previously acquired spinlock.
56  * @param[in]	slock	Spinlock to release.
57  * @see metal_spinlock_acquire
58  */
metal_spinlock_release(struct metal_spinlock * slock)59 static inline void metal_spinlock_release(struct metal_spinlock *slock)
60 {
61 	atomic_flag_clear(&slock->v);
62 }
63 
64 /** @} */
65 
66 #ifdef __cplusplus
67 }
68 #endif
69 
70 #endif /* __METAL_SPINLOCK__H__ */
71