Atomic-mips.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-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_MIPS_H_
00019 #define _OASYS_ATOMIC_MIPS_H_
00020 
00021 namespace oasys {
00022 
00028 struct atomic_t {
00029     atomic_t(u_int32_t v = 0) : value(v) {}
00030 
00031     volatile u_int32_t value;
00032 };
00033 
00041 static inline u_int32_t
00042 atomic_add_ret(volatile atomic_t *v, u_int32_t i)
00043 {
00044         u_int32_t ret;
00045         u_int32_t temp;
00046 
00047         __asm__ __volatile__(
00048                 "       .set    mips3                                   \n"
00049                 "1:     ll      %1, %2              # atomic_add_return \n"
00050                 "       addu    %0, %1, %3                              \n"
00051                 "       sc      %0, %2                                  \n"
00052                 "       beqzl   %0, 1b                                  \n"
00053                 "       addu    %0, %1, %3                              \n"
00054                 "       sync                                            \n"
00055                 "       .set    mips0                                   \n"
00056                 : "=&r" (ret), "=&r" (temp), "=m" (v->value)
00057                 : "Ir" (i), "m" (v->value)
00058                 : "memory");
00059 
00060         return ret;
00061 }
00062 
00069 static inline u_int32_t
00070 atomic_sub_ret(volatile atomic_t * v, u_int32_t i)
00071 {
00072         u_int32_t ret;
00073         u_int32_t temp;
00074 
00075         __asm__ __volatile__(
00076                 "       .set    mips3                                   \n"
00077                 "1:     ll      %1, %2          # atomic_sub_return     \n"
00078                 "       subu    %0, %1, %3                              \n"
00079                 "       sc      %0, %2                                  \n"
00080                 "       beqzl   %0, 1b                                  \n"
00081                 "       subu    %0, %1, %3                              \n"
00082                 "       sync                                            \n"
00083                 "       .set    mips0                                   \n"
00084                 : "=&r" (ret), "=&r" (temp), "=m" (v->value)
00085                 : "Ir" (i), "m" (v->value)
00086                 : "memory");
00087 
00088          return ret;
00089 }
00090 
00091 
00094 
00095 static inline void
00096 atomic_add(volatile atomic_t* v, u_int32_t i)
00097 {
00098     atomic_add_ret(v, i);
00099 }
00100 
00101 static inline void
00102 atomic_sub(volatile atomic_t* v, u_int32_t i)
00103 {
00104     atomic_sub_ret(v, i);
00105 }
00106 
00107 static inline void
00108 atomic_incr(volatile atomic_t* v)
00109 {
00110     atomic_add(v, 1);
00111 }
00112 
00113 static inline void
00114 atomic_decr(volatile atomic_t* v)
00115 {
00116     atomic_sub(v, 1);
00117 }
00118 
00119 static inline u_int32_t
00120 atomic_incr_ret(volatile atomic_t* v)
00121 {
00122     return atomic_add_ret(v, 1);
00123 }
00124 
00125 static inline u_int32_t
00126 atomic_decr_ret(volatile atomic_t* v)
00127 {
00128     return atomic_sub_ret(v, 1);
00129 }
00130 
00131 static inline bool
00132 atomic_decr_test(volatile atomic_t* v)
00133 {
00134     return (atomic_sub_ret(v, 1) == 0);
00135 }
00136 
00137 
00138 
00150 static inline u_int32_t
00151 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00152 {
00153         u_int32_t ret;
00154 
00155         __asm__ __volatile__(
00156                 "       .set    push                                    \n"
00157                 "       .set    noat                                    \n"
00158                 "       .set    mips3                                   \n"
00159                 "1:     ll      %0, %2                  # __cmpxchg_u32 \n"
00160                 "       bne     %0, %z3, 2f                             \n"
00161                 "       .set    mips0                                   \n"
00162                 "       move    $1, %z4                                 \n"
00163                 "       .set    mips3                                   \n"
00164                 "       sc      $1, %1                                  \n"
00165                 "       beqzl   $1, 1b                                  \n"
00166 #ifdef CONFIG_SMP
00167                 "       sync                                            \n"
00168 #endif
00169                 "2:                                                     \n"
00170                 "       .set    pop                                     \n"
00171                 : "=&r" (ret), "=R" (*v)
00172                 : "R" (*v), "Jr" (o), "Jr" (n)
00173                 : "memory");
00174 
00175                 return ret;
00176 }
00177 
00178 }
00179 
00180 // namespace oasy
00181 
00182 #endif /* _OASYS_ATOMIC_MIPS_H_ */

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