RTEMS  5.0.0
smplockseq.h
Go to the documentation of this file.
1 
9 /*
10  * Copyright (c) 2016 embedded brains GmbH
11  *
12  * The license and distribution terms for this file may be
13  * found in the file LICENSE in this distribution or at
14  * http://www.rtems.org/license/LICENSE.
15  */
16 
17 #ifndef _RTEMS_SCORE_SMPLOCKSEQ_H
18 #define _RTEMS_SCORE_SMPLOCKSEQ_H
19 
20 #include <rtems/score/cpuopts.h>
21 
22 #if defined(RTEMS_SMP)
23 
24 #include <rtems/score/assert.h>
25 #include <rtems/score/atomic.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif /* __cplusplus */
30 
50 typedef struct {
56  Atomic_Uint sequence;
57 } SMP_sequence_lock_Control;
58 
62 #define SMP_SEQUENCE_LOCK_INITIALIZER { ATOMIC_INITIALIZER_UINT( 0 ) }
63 
71 static inline void _SMP_sequence_lock_Initialize( SMP_sequence_lock_Control *lock )
72 {
73  _Atomic_Init_uint( &lock->sequence, 0 );
74 }
75 
83 static inline void _SMP_sequence_lock_Destroy( SMP_sequence_lock_Control *lock )
84 {
85  (void) lock;
86 }
87 
99 static inline unsigned int _SMP_sequence_lock_Write_begin(
100  SMP_sequence_lock_Control *lock
101 )
102 {
103  unsigned int seq;
104 
105  seq = _Atomic_Load_uint( &lock->sequence, ATOMIC_ORDER_RELAXED );
106  _Assert( seq % 2 == 0 );
107 
108  _Atomic_Store_uint( &lock->sequence, seq + 1, ATOMIC_ORDER_RELAXED );
109 
110  /* There is no atomic store with acquire/release semantics */
111  _Atomic_Fence( ATOMIC_ORDER_ACQ_REL );
112 
113  return seq;
114 }
115 
122 static inline void _SMP_sequence_lock_Write_end(
123  SMP_sequence_lock_Control *lock,
124  unsigned int seq
125 )
126 {
127  _Atomic_Store_uint( &lock->sequence, seq + 2, ATOMIC_ORDER_RELEASE );
128 }
129 
139 static inline unsigned int _SMP_sequence_lock_Read_begin(
140  const SMP_sequence_lock_Control *lock
141 )
142 {
143  return _Atomic_Load_uint( &lock->sequence, ATOMIC_ORDER_ACQUIRE );
144 }
145 
157 static inline bool _SMP_sequence_lock_Read_retry(
158  SMP_sequence_lock_Control *lock,
159  unsigned int seq
160 )
161 {
162  unsigned int seq2;
163 
164  seq2 = _Atomic_Fetch_add_uint( &lock->sequence, 0, ATOMIC_ORDER_RELEASE );
165  return seq != seq2 || seq % 2 != 0;
166 }
167 
170 #ifdef __cplusplus
171 }
172 #endif /* __cplusplus */
173 
174 #endif /* RTEMS_SMP */
175 
176 #endif /* _RTEMS_SCORE_SMPLOCKSEQ_H */
Atomic Operations API.