|
GNU Radio 3.3.0 C++ API
|
00001 /* -------------------------------------------------------------- */ 00002 /* (C)Copyright 2001,2007, */ 00003 /* International Business Machines Corporation, */ 00004 /* Sony Computer Entertainment, Incorporated, */ 00005 /* Toshiba Corporation, */ 00006 /* */ 00007 /* All Rights Reserved. */ 00008 /* */ 00009 /* Redistribution and use in source and binary forms, with or */ 00010 /* without modification, are permitted provided that the */ 00011 /* following conditions are met: */ 00012 /* */ 00013 /* - Redistributions of source code must retain the above copyright*/ 00014 /* notice, this list of conditions and the following disclaimer. */ 00015 /* */ 00016 /* - Redistributions in binary form must reproduce the above */ 00017 /* copyright notice, this list of conditions and the following */ 00018 /* disclaimer in the documentation and/or other materials */ 00019 /* provided with the distribution. */ 00020 /* */ 00021 /* - Neither the name of IBM Corporation nor the names of its */ 00022 /* contributors may be used to endorse or promote products */ 00023 /* derived from this software without specific prior written */ 00024 /* permission. */ 00025 /* */ 00026 /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND */ 00027 /* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, */ 00028 /* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ 00029 /* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ 00030 /* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR */ 00031 /* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ 00032 /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT */ 00033 /* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; */ 00034 /* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) */ 00035 /* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN */ 00036 /* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR */ 00037 /* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ 00038 /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 00039 /* -------------------------------------------------------------- */ 00040 /* PROLOG END TAG zYx */ 00041 #ifndef _SPU_MUTEX_H_ 00042 #define _SPU_MUTEX_H_ 1 00043 00044 #include "sync_utils.h" 00045 #include "sync_irq.h" 00046 #include <spu_mfcio.h> 00047 00048 typedef eaddr_t mutex_ea_t; 00049 00050 #define DECL_MUTEX_VARS() \ 00051 char _tmp[256]; \ 00052 char *tmp = (char *) ALIGN(_tmp, 128); \ 00053 volatile s32 *buf = (volatile s32 *) &tmp[0]; \ 00054 u32 size = 128, tagid = 0; \ 00055 u32 offset; \ 00056 addr64 ea64 00057 00058 /* RAW_TEST_AND_SET 00059 * Macro implementing the test and set primitive. 00060 * 00061 * RAW_TEST_AND_SET(==, 1) used by spin_try_lock() 00062 * RAW_TEST_AND_SET(>=, 1) used by read_try_lock() 00063 * RAW_TEST_AND_SET(==, -1) used by write_try_lock() 00064 */ 00065 #define RAW_TEST_AND_SET(_RELOP_, _val) \ 00066 ea64.ull = ALIGN128_EA(ea); \ 00067 offset = OFFSET128_EA_U32(ea); \ 00068 do { \ 00069 MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); \ 00070 spu_readch(MFC_RdAtomicStat); \ 00071 SET_HIT; \ 00072 if (likely(buf[offset] _RELOP_ 0)) { \ 00073 buf[offset] += _val; \ 00074 MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ 00075 status = spu_readch(MFC_RdAtomicStat); \ 00076 ret_val = 1; \ 00077 } else { \ 00078 MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ 00079 spu_readch(MFC_RdAtomicStat); \ 00080 status = ret_val = 0; \ 00081 break; \ 00082 } \ 00083 } while (status != 0) 00084 00085 /* RAW_SPINLOCK 00086 * Macro implementing the spinlock primitive. 00087 * 00088 * RAW_SPINLOCK(==, 1) used by spin_lock() 00089 * RAW_SPINLOCK(>=, 1) used by read_lock() 00090 * RAW_SPINLOCK(==, -1) used by write_lock() 00091 */ 00092 00093 00094 #define RAW_SPINLOCK(_RELOP_, _val) \ 00095 ea64.ull = ALIGN128_EA(ea); \ 00096 offset = OFFSET128_EA_U32(ea); \ 00097 do { \ 00098 MFC_DMA(buf, ea64, size, tagid, MFC_GETLLAR_CMD); \ 00099 spu_readch(MFC_RdAtomicStat); \ 00100 SET_HIT; \ 00101 status = 1; \ 00102 if (likely(buf[offset] _RELOP_ 0)) { \ 00103 buf[offset] += _val; \ 00104 MFC_DMA(buf, ea64, size, tagid, MFC_PUTLLC_CMD); \ 00105 status = spu_readch(MFC_RdAtomicStat); \ 00106 } \ 00107 } while (status != 0); 00108 00109 00110 static inline void _lock_init(eaddr_t ea) 00111 { 00112 DECL_MUTEX_VARS(); 00113 u32 oldtmask, tagmask; 00114 00115 tagid = mfc_tag_reserve(); 00116 00117 tagmask = 1 << (tagid & 31); 00118 00119 /* __lock_init 00120 * Internal routine to initialize a spinlock or 00121 * reader/writer lock. 00122 */ 00123 ea64.ull = ALIGN128_EA(ea); 00124 offset = OFFSET128_EA_U32(ea); 00125 MFC_DMA(buf, ea64, size, tagid & 31, MFC_GET_CMD); 00126 oldtmask = spu_readch(MFC_RdTagMask); 00127 spu_writech(MFC_WrTagMask, tagmask); 00128 spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); 00129 spu_readch(MFC_RdTagStat); 00130 00131 buf[offset] = 0; 00132 MFC_DMA(buf, ea64, size, tagid & 31, MFC_PUT_CMD); 00133 spu_writech(MFC_WrTagMask, tagmask); 00134 spu_writech(MFC_WrTagUpdate, MFC_TAG_UPDATE_ANY); 00135 spu_readch(MFC_RdTagStat); 00136 spu_writech(MFC_WrTagMask, oldtmask); 00137 mfc_tag_release(tagid); 00138 } 00139 00140 static inline void _spin_lock(eaddr_t ea) 00141 { 00142 DECL_MUTEX_VARS(); 00143 s32 status; 00144 00145 /* _spin_lock 00146 * Internal routine to acquire spinlock. 00147 */ 00148 /* non trace - no hit/miss indicator */ 00149 #define SET_HIT 00150 RAW_SPINLOCK(==, 1); 00151 } 00152 00153 #ifdef LIBSYNC_TRACE 00154 static inline s32 _spin_lock_trace(eaddr_t ea) 00155 { 00156 DECL_MUTEX_VARS(); 00157 s32 status = 0; 00158 /* trace - need hit/miss indicator */ 00159 #undef SET_HIT 00160 #define SET_HIT if (status == 0) hit = buf[offset] 00161 s32 hit; 00162 00163 hit = 0; 00164 /* _spin_lock_trace for trace 00165 * Internal routine to acquire spinlock. 00166 */ 00167 RAW_SPINLOCK(==, 1); 00168 00169 return hit; 00170 00171 #undef SET_HIT 00172 #define SET_HIT 00173 } 00174 00175 #endif /* LIBSYNC_TRACE */ 00176 00177 00178 #endif /* SPU_MUTEX_H */