1 /**
2 * @file atomic_qnx.h
3 *
4 * @brief Atomic operations abstraction
5 *
6 *
7 * @ver 02.00.00.46_alpha1
8 *
9 * ============================================================================
10 *
11 * Copyright (c) 2008-2009, Texas Instruments Incorporated
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 *
20 * * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * * Neither the name of Texas Instruments Incorporated nor the names of
25 * its contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
30 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
32 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
35 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
36 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
37 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
38 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 * Contact information for paper mail:
40 * Texas Instruments
41 * Post Office Box 655303
42 * Dallas, Texas 75265
43 * Contact information:
44 * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
45 * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
46 * ============================================================================
47 *
48 */
51 #ifndef ATOMIC_QNX_H
52 #define ATOMIC_QNX_H
54 /* Standard libc headers */
55 #include <stdio.h>
56 #include <pthread.h>
59 /* =============================================================================
60 * Typedef
61 * =============================================================================
62 */
63 /*! @brief Typedef for atomic variable */
64 typedef UInt32 Atomic;
67 /* =============================================================================
68 * Global
69 * =============================================================================
70 */
71 /* Lock used by atomic operations to create psuedo atomicity */
72 static pthread_mutex_t Atomic_lock = PTHREAD_MUTEX_INITIALIZER;
75 /* =============================================================================
76 * APIs & Macros
77 * =============================================================================
78 */
79 /*!
80 * @brief Function to read an variable atomically
81 *
82 * @param var Pointer to atomic variable
83 */
84 static inline UInt32 Atomic_read (Atomic * var)
85 {
86 UInt32 ret;
88 pthread_mutex_lock (&Atomic_lock);
89 ret = *var;
90 pthread_mutex_unlock (&Atomic_lock);
92 /*! @retval value Current value of the atomic variable */
93 return ret;
94 }
97 /*!
98 * @brief Function to set an variable atomically
99 *
100 * @param var Pointer to atomic variable
101 * @param val Value to be set
102 */
103 static inline void Atomic_set (Atomic * var, UInt32 val)
104 {
105 pthread_mutex_lock (&Atomic_lock);
106 *var = val;
107 pthread_mutex_unlock (&Atomic_lock);
108 }
111 /*!
112 * @brief Function to increment an variable atomically
113 *
114 * @param var Pointer to atomic variable
115 * @param val Value to be set
116 */
117 static inline UInt32 Atomic_inc_return (Atomic * var)
118 {
119 UInt32 ret;
121 pthread_mutex_lock (&Atomic_lock);
122 *var = *var + 1u;
123 ret = *var;
124 pthread_mutex_unlock (&Atomic_lock);
126 /*! @retval value Current value of the atomic variable */
127 return ret;
128 }
131 /*!
132 * @brief Function to decrement an variable atomically
133 *
134 * @param var Pointer to atomic variable
135 * @param val Value to be set
136 */
137 static inline UInt32 Atomic_dec_return (Atomic * var)
138 {
139 UInt32 ret;
141 pthread_mutex_lock (&Atomic_lock);
142 *var = *var - 1u;
143 ret = *var;
144 pthread_mutex_unlock (&Atomic_lock);
146 /*! @retval value Current value of the atomic variable */
147 return ret;
148 }
151 /*!
152 * @brief Function to compare a mask and set if not equal
153 *
154 * @params v Pointer to atomic variable
155 * @params mask Mask to compare with
156 * @params val Value to be set if mask does not match.
157 */
158 static inline void Atomic_cmpmask_and_set(Atomic * var, UInt32 mask, UInt32 val)
159 {
160 UInt32 ret;
162 pthread_mutex_lock (&Atomic_lock);
163 ret = *var;
164 if ((ret & mask) != mask) {
165 *var = val;
166 }
167 pthread_mutex_unlock (&Atomic_lock);
168 }
170 /*!
171 * @brief Function to compare a mask and then check current value less than
172 * provided value.
173 *
174 * @params v Pointer to atomic variable
175 * @params mask Mask to compare with
176 * @params val Value to be set if mask does not match.
177 */
178 static inline Bool Atomic_cmpmask_and_lt(Atomic * var, UInt32 mask, UInt32 val)
179 {
180 Bool ret = TRUE;
181 UInt32 cur = 0;
183 pthread_mutex_lock (&Atomic_lock);
184 cur = *var;
185 if ((cur & mask) == mask) {
186 if (cur >= val) {
187 ret = FALSE;
188 }
189 }
190 pthread_mutex_unlock (&Atomic_lock);
192 /*! @retval TRUE if mask matches and current value is less than given
193 * value */
194 /*! @retval FALSE either mask doesnot matches or current value is not less
195 * than given value */
196 return ret;
197 }
199 /*!
200 * @brief Function to compare a mask and then check current value greater than
201 * provided value.
202 *
203 * @params v Pointer to atomic variable
204 * @params mask Mask to compare with
205 * @params val Value to be set if mask does not match.
206 */
207 static inline Bool Atomic_cmpmask_and_gt(Atomic * var, UInt32 mask, UInt32 val)
208 {
209 Bool ret = TRUE;
210 UInt32 cur = 0;
212 pthread_mutex_lock (&Atomic_lock);
213 cur = *var;
214 if ((cur & mask) == mask) {
215 if (cur < val) {
216 ret = FALSE;
217 }
218 }
219 pthread_mutex_unlock (&Atomic_lock);
221 /*! @retval TRUE if mask matches and current value is less than given
222 * value */
223 /*! @retval FALSE either mask doesnot matches or current value is not
224 * greater than given value */
225 return ret;
226 }
228 #endif /* if !defined(ATOMIC_QNX_H) */