Atomic-ppc.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2005 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 
00039 #ifndef _OASYS_ATOMIC_PPC_H_
00040 #define _OASYS_ATOMIC_PPC_H_
00041 
00042 #include "../debug/DebugUtils.h"
00043 
00044 namespace oasys {
00045 
00051 struct atomic_t {
00052     atomic_t(u_int32_t v = 0) : value(v) {}
00053 
00054     volatile u_int32_t value;
00055 };
00056 
00064 static inline u_int32_t
00065 atomic_add_ret(volatile atomic_t* v, u_int32_t i)
00066 {
00067     register u_int32_t ret;
00068 
00069     __asm__ __volatile__(
00070         "1:     lwarx %0, 0, %2\n"       /* load old value */
00071         "       add %0, %3, %0\n"        /* calculate new value */
00072         "       stwcx. %0, 0, %2\n"      /* attempt to store */
00073         "       bne- 1b\n"               /* spin if failed */
00074         : "=&r" (ret), "=m" (v->value)
00075         : "r" (v), "r" (i), "m" (v->value)
00076         : "cc", "memory");
00077 
00078     return ret;
00079 }
00080 
00087 static inline u_int32_t
00088 atomic_sub_ret(volatile atomic_t* v, u_int32_t i)
00089 {
00090     register u_int32_t ret;
00091 
00092     __asm__ __volatile__(
00093         "1:     lwarx %0, 0, %2\n"       /* load old value */
00094         "       subfc %0, %3, %0\n"      /* calculate new value */
00095         "       stwcx. %0, 0, %2\n"      /* attempt to store */
00096         "       bne- 1b\n"               /* spin if failed */
00097         : "=&r" (ret), "=m" (v->value)
00098         : "r" (v), "r" (i), "m" (v->value)
00099         : "cc", "memory");
00100 
00101     return ret;
00102 }
00103 
00106 
00107 static inline void
00108 atomic_add(volatile atomic_t* v, u_int32_t i)
00109 {
00110     atomic_add_ret(v, i);
00111 }
00112 
00113 static inline void
00114 atomic_sub(volatile atomic_t* v, u_int32_t i)
00115 {
00116     atomic_sub_ret(v, i);
00117 }
00118 
00119 static inline void
00120 atomic_incr(volatile atomic_t* v)
00121 {
00122     atomic_add(v, 1);
00123 }
00124 
00125 static inline void
00126 atomic_decr(volatile atomic_t* v)
00127 {
00128     atomic_sub(v, 1);
00129 }
00130 
00131 static inline u_int32_t
00132 atomic_incr_ret(volatile atomic_t* v)
00133 {
00134     return atomic_add_ret(v, 1);
00135 }
00136 
00137 static inline u_int32_t
00138 atomic_decr_ret(volatile atomic_t* v)
00139 {
00140     return atomic_sub_ret(v, 1);
00141 }
00142 
00143 static inline bool
00144 atomic_decr_test(volatile atomic_t* v)
00145 {
00146     return (atomic_sub_ret(v, 1) == 0);
00147 }
00148 
00150 
00161 static inline u_int32_t
00162 atomic_cmpxchg32(volatile atomic_t* v, u_int32_t o, u_int32_t n)
00163 {
00164     register u_int32_t ret;
00165 
00166     __asm __volatile (
00167         "1:     lwarx %0, 0, %2\n"       /* load old value */
00168         "       cmplw %3, %0\n"          /* compare */
00169         "       bne 2f\n"                /* exit if not equal */
00170         "       stwcx. %4, 0, %2\n"      /* attempt to store */
00171         "       bne- 1b\n"               /* spin if failed */
00172         "       b 3f\n"                  /* we've succeeded */
00173         "       2:\n"
00174         "       stwcx. %0, 0, %2\n"      /* clear reservation (74xx) */
00175         "       3:\n"
00176         : "=&r" (ret), "=m" (v->value)
00177         : "r" (v), "r" (o), "r" (n), "m" (v->value)
00178         : "cc", "memory");
00179 
00180     return (ret);
00181 }
00182 
00183 } // namespace oasys
00184 
00185 #endif /* _OASYS_ATOMIC_PPC_H_ */

Generated on Fri Dec 22 14:47:57 2006 for DTN Reference Implementation by  doxygen 1.5.1