Atomic-ppc.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2005-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_PPC_H_
00019 #define _OASYS_ATOMIC_PPC_H_
00020 
00021 #include "../debug/DebugUtils.h"
00022 
00023 namespace oasys {
00024 
00030 struct atomic_t {
00031     atomic_t(u_int32_t v = 0) : value(v) {}
00032 
00033     volatile u_int32_t value;
00034 };
00035 
00043 static inline u_int32_t
00044 atomic_add_ret(volatile atomic_t* v, u_int32_t i)
00045 {
00046     register u_int32_t ret;
00047 
00048     __asm__ __volatile__(
00049         "1:     lwarx %0, 0, %2\n"       /* load old value */
00050         "       add %0, %3, %0\n"        /* calculate new value */
00051         "       stwcx. %0, 0, %2\n"      /* attempt to store */
00052         "       bne- 1b\n"               /* spin if failed */
00053         : "=&r" (ret), "=m" (v->value)
00054         : "r" (v), "r" (i), "m" (v->value)
00055         : "cc", "memory");
00056 
00057     return ret;
00058 }
00059 
00066 static inline u_int32_t
00067 atomic_sub_ret(volatile atomic_t* v, u_int32_t i)
00068 {
00069     register u_int32_t ret;
00070 
00071     __asm__ __volatile__(
00072         "1:     lwarx %0, 0, %2\n"       /* load old value */
00073         "       subfc %0, %3, %0\n"      /* calculate new value */
00074         "       stwcx. %0, 0, %2\n"      /* attempt to store */
00075         "       bne- 1b\n"               /* spin if failed */
00076         : "=&r" (ret), "=m" (v->value)
00077         : "r" (v), "r" (i), "m" (v->value)
00078         : "cc", "memory");
00079 
00080     return ret;
00081 }
00082 
00085 
00086 static inline void
00087 atomic_add(volatile atomic_t* v, u_int32_t i)
00088 {
00089     atomic_add_ret(v, i);
00090 }
00091 
00092 static inline void
00093 atomic_sub(volatile atomic_t* v, u_int32_t i)
00094 {
00095     atomic_sub_ret(v, i);
00096 }
00097 
00098 static inline void
00099 atomic_incr(volatile atomic_t* v)
00100 {
00101     atomic_add(v, 1);
00102 }
00103 
00104 static inline void
00105 atomic_decr(volatile atomic_t* v)
00106 {
00107     atomic_sub(v, 1);
00108 }
00109 
00110 static inline u_int32_t
00111 atomic_incr_ret(volatile atomic_t* v)
00112 {
00113     return atomic_add_ret(v, 1);
00114 }
00115 
00116 static inline u_int32_t
00117 atomic_decr_ret(volatile atomic_t* v)
00118 {
00119     return atomic_sub_ret(v, 1);
00120 }
00121 
00122 static inline bool
00123 atomic_decr_test(volatile atomic_t* v)
00124 {
00125     return (atomic_sub_ret(v, 1) == 0);
00126 }
00127 
00129 
00140 static inline u_int32_t
00141 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00142 {
00143     register u_int32_t ret;
00144 
00145     __asm __volatile (
00146         "1:     lwarx %0, 0, %2\n"       /* load old value */
00147         "       cmplw %3, %0\n"          /* compare */
00148         "       bne 2f\n"                /* exit if not equal */
00149         "       stwcx. %4, 0, %2\n"      /* attempt to store */
00150         "       bne- 1b\n"               /* spin if failed */
00151         "       b 3f\n"                  /* we've succeeded */
00152         "       2:\n"
00153         "       stwcx. %0, 0, %2\n"      /* clear reservation (74xx) */
00154         "       3:\n"
00155         : "=&r" (ret), "=m" (v->value)
00156         : "r" (v), "r" (o), "r" (n), "m" (v->value)
00157         : "cc", "memory");
00158 
00159     return (ret);
00160 }
00161 
00162 } // namespace oasys
00163 
00164 #endif /* _OASYS_ATOMIC_PPC_H_ */

Generated on Thu Jun 7 16:56:48 2007 for DTN Reference Implementation by  doxygen 1.5.1