Atomic-arm.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 
00018 #ifndef _OASYS_ATOMIC_ARM_H_
00019 #define _OASYS_ATOMIC_ARM_H_
00020 
00021 #include "../compat/inttypes.h"
00022 
00023 namespace oasys {
00024 
00032 struct atomic_t {
00033     atomic_t(u_int32_t v = 0)
00034         : value(v), lock(0) {}
00035 
00036     volatile u_int32_t value;
00037     volatile u_int32_t lock;
00038 };
00039 
00043 static inline void
00044 atomic_lock(volatile atomic_t* v)
00045 {
00046     u_int32_t tmp;
00047     
00048     __asm__ __volatile__("@ atomic_lock\n"
00049         "1:     mov     %0, #1\n"       /* move 1 into r0 */
00050         "       swp     %0, %0, [%1]\n" /* swap into lock location */
00051         "       teq     %0, #0\n"       /* test if we got it  */
00052         "       bne     1b"             /* jump if not */
00053         : "=&r" (tmp)
00054         : "r" (&v->lock)
00055         : "cc", "memory");
00056 }
00057 
00061 static inline bool
00062 atomic_try_lock(volatile atomic_t* v)
00063 {
00064     u_int32_t tmp;
00065     
00066     __asm__ __volatile__("@ atomic_lock\n"
00067         "1:     mov     %0, #1\n"       /* move 1 into r0 */
00068         "       swp     %0, %0, [%1]\n" /* swap into lock location */
00069         : "=&r" (tmp)
00070         : "r" (&v->lock)
00071         : "cc", "memory");
00072 
00073     return (tmp == 0);
00074 }
00075 
00076 static inline void
00077 atomic_unlock(volatile atomic_t* v)
00078 {
00079     v->lock = 0;
00080 }
00081 
00089 static inline u_int32_t
00090 atomic_add_ret(volatile atomic_t* v, u_int32_t i)
00091 {
00092     u_int32_t ret;
00093     
00094     atomic_lock(v);
00095     v->value += i;
00096     ret = v->value;
00097     atomic_unlock(v);
00098     
00099     return ret;
00100 }
00101 
00108 static inline u_int32_t
00109 atomic_sub_ret(volatile atomic_t* v, u_int32_t i)
00110 {
00111     u_int32_t ret;
00112     
00113     atomic_lock(v);
00114     v->value -= i;
00115     ret = v->value;
00116     atomic_unlock(v);
00117     
00118     return ret;
00119 }
00120 
00123 
00124 static inline void
00125 atomic_add(volatile atomic_t* v, u_int32_t i)
00126 {
00127     atomic_add_ret(v, i);
00128 }
00129 
00130 static inline void
00131 atomic_sub(volatile atomic_t* v, u_int32_t i)
00132 {
00133     atomic_sub_ret(v, i);
00134 }
00135 
00136 static inline void
00137 atomic_incr(volatile atomic_t* v)
00138 {
00139     atomic_add(v, 1);
00140 }
00141 
00142 static inline void
00143 atomic_decr(volatile atomic_t* v)
00144 {
00145     atomic_sub(v, 1);
00146 }
00147 
00148 static inline u_int32_t
00149 atomic_incr_ret(volatile atomic_t* v)
00150 {
00151     return atomic_add_ret(v, 1);
00152 }
00153 
00154 static inline u_int32_t
00155 atomic_decr_ret(volatile atomic_t* v)
00156 {
00157     return atomic_sub_ret(v, 1);
00158 }
00159 
00160 static inline bool
00161 atomic_decr_test(volatile atomic_t* v)
00162 {
00163     return (atomic_sub_ret(v, 1) == 0);
00164 }
00165 
00167 
00178 static inline u_int32_t
00179 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00180 {
00181     u_int32_t ret;
00182     
00183     atomic_lock(v);
00184     ret = v->value;
00185     if (v->value == o) {
00186         v->value = n;
00187     }
00188     atomic_unlock(v);
00189     
00190     return ret;
00191 }
00192 
00193 } // namespace oasys
00194 
00195 #endif /* _OASYS_ATOMIC_ARM_H_ */

Generated on Thu Jun 7 12:54:25 2007 for DTN Reference Implementation by  doxygen 1.5.1