usermode/library/mtm/src/mode/common/barrier.h

00001 /*
00002     Copyright (C) 2011 Computer Sciences Department, 
00003     University of Wisconsin -- Madison
00004 
00005     ----------------------------------------------------------------------
00006 
00007     This file is part of Mnemosyne: Lightweight Persistent Memory, 
00008     originally developed at the University of Wisconsin -- Madison.
00009 
00010     Mnemosyne was originally developed primarily by Haris Volos
00011     with contributions from Andres Jaan Tack.
00012 
00013     ----------------------------------------------------------------------
00014 
00015     Mnemosyne is free software; you can redistribute it and/or
00016     modify it under the terms of the GNU General Public License
00017     as published by the Free Software Foundation, version 2
00018     of the License.
00019  
00020     Mnemosyne is distributed in the hope that it will be useful,
00021     but WITHOUT ANY WARRANTY; without even the implied warranty of
00022     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00023     GNU General Public License for more details.
00024 
00025     You should have received a copy of the GNU General Public License
00026     along with this program; if not, write to the Free Software
00027     Foundation, Inc., 51 Franklin Street, Fifth Floor, 
00028     Boston, MA  02110-1301, USA.
00029 
00030 ### END HEADER ###
00031 */
00032 
00033 #ifndef _BARRIER_H
00034 #define _BARRIER_H
00035 
00036 #define DECLARE_READ_BARRIER(NAME, T, LOCK)                                    \
00037 _ITM_TYPE_##T _ITM_CALL_CONVENTION                                             \
00038 mtm_##NAME##_##LOCK##T(mtm_tx_t *tx,                                           \
00039                        const _ITM_TYPE_##T *ptr);
00040 
00041 #define DECLARE_WRITE_BARRIER(NAME, T, LOCK)                                   \
00042 void _ITM_CALL_CONVENTION mtm_##NAME##_##LOCK##T(mtm_tx_t *tx,                 \
00043                                                 _ITM_TYPE_##T *addr,           \
00044                                                 _ITM_TYPE_##T value);
00045 
00046 
00047 #define DECLARE_READ_BARRIERS(name, type, encoding)                            \
00048   DECLARE_READ_BARRIER(name, encoding, R)                                      \
00049   DECLARE_READ_BARRIER(name, encoding, RaR)                                    \
00050   DECLARE_READ_BARRIER(name, encoding, RaW)                                    \
00051   DECLARE_READ_BARRIER(name, encoding, RfW)                                    \
00052 
00053 
00054 #define DECLARE_WRITE_BARRIERS(name, type, encoding)                           \
00055   DECLARE_WRITE_BARRIER(name, encoding, W)                                     \
00056   DECLARE_WRITE_BARRIER(name, encoding, WaR)                                   \
00057   DECLARE_WRITE_BARRIER(name, encoding, WaW)
00058 
00059 typedef union convert_u {
00060   mtm_word_t w;
00061   uint8_t b[sizeof(mtm_word_t)];
00062 } convert_t;
00063 
00064 #if 0
00065 # define DEFINE_LOAD_BYTES(NAME)                                               \
00066    DEFINE_IDENTITY_LOAD_BYTES(NAME)
00067 
00068 # define DEFINE_STORE_BYTES(NAME)                                              \
00069    DEFINE_IDENTITY_STORE_BYTES(NAME)
00070 #else
00071 # define DEFINE_LOAD_BYTES(NAME)                                               \
00072    DEFINE_TM_LOAD_BYTES(NAME)
00073 
00074 # define DEFINE_STORE_BYTES(NAME)                                              \
00075    DEFINE_TM_STORE_BYTES(NAME)
00076 
00077 #endif
00078 
00079 
00080 #define DEFINE_IDENTITY_LOAD_BYTES(NAME)                                       \
00081 void mtm_##NAME##_load_bytes(mtm_tx_t *tx,                                     \
00082                              volatile uint8_t *addr,                           \
00083                              uint8_t *buf,                                     \
00084                              size_t size)                                      \
00085 {                                                                              \
00086   convert_t    val;                                                            \
00087   unsigned int i;                                                              \
00088   mtm_word_t   *a;                                                             \
00089                                                                                \
00090   if (size == 0) {                                                             \
00091     return;                                                                    \
00092   }                                                                            \
00093   for (i=0; i < size; i++) {                                                   \
00094     buf[i] = addr[i];                                                          \
00095   }                                                                            \
00096 }
00097 
00098 #define DEFINE_TM_LOAD_BYTES(NAME)                                             \
00099 void mtm_##NAME##_load_bytes(mtm_tx_t *tx,                                     \
00100                              volatile uint8_t *addr,                           \
00101                              uint8_t *buf,                                     \
00102                              size_t size)                                      \
00103 {                                                                              \
00104   convert_t    val;                                                            \
00105   unsigned int i;                                                              \
00106   mtm_word_t   *a;                                                             \
00107                                                                                \
00108   if (size == 0) {                                                             \
00109     return;                                                                    \
00110   }                                                                                \
00111   i = (uintptr_t)addr & (sizeof(mtm_word_t) - 1);                              \
00112   if (i != 0) {                                                                \
00113     /* First bytes */                                                          \
00114     a = (mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)(sizeof(mtm_word_t) - 1));\
00115     val.w = mtm_##NAME##_load(tx, a++);                                        \
00116     for (; i < sizeof(mtm_word_t) && size > 0; i++, size--) {                  \
00117       *buf++ = val.b[i];                                                       \
00118     }                                                                          \
00119   } else {                                                                     \
00120     a = (mtm_word_t *)addr;                                                    \
00121   }                                                                                \
00122   /* Full words */                                                             \
00123   while (size >= sizeof(mtm_word_t)) {                                         \
00124     *((mtm_word_t *)buf) = mtm_##NAME##_load(tx, a++);                         \
00125     buf += sizeof(mtm_word_t);                                                 \
00126     size -= sizeof(mtm_word_t);                                                \
00127   }                                                                            \
00128   if (size > 0) {                                                              \
00129     /* Last bytes */                                                           \
00130     val.w = mtm_##NAME##_load(tx, a);                                          \
00131     i = 0;                                                                     \
00132     for (i = 0; size > 0; i++, size--) {                                       \
00133       *buf++ = val.b[i];                                                       \
00134     }                                                                          \
00135   }                                                                            \
00136 }
00137 
00138 
00139 #define DEFINE_IDENTITY_STORE_BYTES(NAME)                                      \
00140 void mtm_##NAME##_store_bytes(mtm_tx_t *tx,                                    \
00141                               volatile uint8_t *addr,                          \
00142                               uint8_t *buf,                                    \
00143                               size_t size)                                     \
00144 {                                                                              \
00145   convert_t    val;                                                            \
00146   convert_t    mask;                                                           \
00147   unsigned int i;                                                              \
00148   mtm_word_t   *a;                                                             \
00149                                                                                \
00150   if (size == 0) {                                                             \
00151     return;                                                                    \
00152   }                                                                            \
00153   for (i=0; i < size; i++) {                                                   \
00154     addr[i] = buf[i];                                                          \
00155   }                                                                            \
00156 }
00157 
00158 
00159 #define DEFINE_TM_STORE_BYTES(NAME)                                            \
00160 void mtm_##NAME##_store_bytes(mtm_tx_t *tx,                                    \
00161                               volatile uint8_t *addr,                          \
00162                               uint8_t *buf,                                    \
00163                               size_t size)                                     \
00164 {                                                                              \
00165   convert_t    val;                                                            \
00166   convert_t    mask;                                                           \
00167   unsigned int i;                                                              \
00168   mtm_word_t   *a;                                                             \
00169                                                                                \
00170   if (size == 0) {                                                             \
00171     return;                                                                    \
00172   }                                                                            \
00173   i = (uintptr_t)addr & (sizeof(mtm_word_t) - 1);                              \
00174   if (i != 0) {                                                                \
00175     /* First bytes */                                                          \
00176     a = (mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)(sizeof(mtm_word_t) - 1));\
00177     val.w = mask.w = 0;                                                        \
00178     for (; i < sizeof(mtm_word_t) && size > 0; i++, size--) {                  \
00179       mask.b[i] = 0xFF;                                                        \
00180       val.b[i] = *buf++;                                                       \
00181     }                                                                          \
00182     mtm_##NAME##_store2(tx, a++, val.w, mask.w);                               \
00183   } else {                                                                     \
00184     a = (mtm_word_t *)addr;                                                    \
00185   }                                                                                \
00186   /* Full words */                                                             \
00187   while (size >= sizeof(mtm_word_t)) {                                         \
00188     mtm_##NAME##_store(tx, a++, *((mtm_word_t *)buf));                         \
00189     buf += sizeof(mtm_word_t);                                                 \
00190     size -= sizeof(mtm_word_t);                                                \
00191   }                                                                            \
00192   if (size > 0) {                                                              \
00193     /* Last bytes */                                                           \
00194     val.w = mask.w = 0;                                                        \
00195     for (i = 0; size > 0; i++, size--) {                                       \
00196       mask.b[i] = 0xFF;                                                        \
00197       val.b[i] = *buf++;                                                       \
00198     }                                                                          \
00199     mtm_##NAME##_store2(tx, a, val.w, mask.w);                                 \
00200   }                                                                            \
00201 }
00202 
00203 #define READ_BARRIER(NAME, T, LOCK)                                            \
00204 _ITM_TYPE_##T _ITM_CALL_CONVENTION                                             \
00205 mtm_##NAME##_##LOCK##T(mtm_tx_t *tx,                                           \
00206                        const _ITM_TYPE_##T *addr)                              \
00207 {                                                                              \
00208   _ITM_TYPE_##T val;                                                           \
00209   mtm_##NAME##_load_bytes(tx,                                                  \
00210                           (volatile uint8_t *)addr,                            \
00211                           (uint8_t *)&val,                                     \
00212                           sizeof(_ITM_TYPE_##T));                              \
00213   return val;                                                                  \
00214 }
00215 
00216 
00217 #define WRITE_BARRIER(NAME, T, LOCK)                                           \
00218 void _ITM_CALL_CONVENTION mtm_##NAME##_##LOCK##T(mtm_tx_t *tx,                 \
00219                                                  _ITM_TYPE_##T *addr,          \
00220                                                  _ITM_TYPE_##T value)          \
00221 {                                                                              \
00222   mtm_##NAME##_store_bytes(tx,                                                 \
00223                            (volatile uint8_t *)addr,                           \
00224                            (uint8_t *)&value,                                  \
00225                            sizeof(_ITM_TYPE_##T));                             \
00226 }
00227 
00228 
00229 #define DEFINE_READ_BARRIERS(name, type, encoding)      \
00230   READ_BARRIER(name, encoding, R)                       \
00231   READ_BARRIER(name, encoding, RaR)                         \
00232   READ_BARRIER(name, encoding, RaW)                         \
00233   READ_BARRIER(name, encoding, RfW)                             \
00234 
00235 
00236 #define DEFINE_WRITE_BARRIERS(name, type, encoding)     \
00237   WRITE_BARRIER(name, encoding, W)                      \
00238   WRITE_BARRIER(name, encoding, WaR)                    \
00239   WRITE_BARRIER(name, encoding, WaW)
00240 
00241 
00242 /*
00243  * The following is an effort of implementing special wrappers for the case
00244  * when the address is word aligned.
00245  */
00246 #if 0
00247 
00248 typedef union convert_U32_u convert_CE_t;
00249 typedef union convert_U16_u convert_E_t;
00250 typedef union convert_U16_u convert_M128_t;
00251 typedef union convert_U16_u convert_CD_t;
00252 typedef union convert_U8_u  convert_U8_t;
00253 typedef union convert_U8_u  convert_D_t;
00254 typedef union convert_U8_u  convert_M64_t;
00255 typedef union convert_U8_u  convert_CF_t;
00256 typedef union convert_U4_u  convert_U4_t;
00257 typedef union convert_U4_u  convert_F_t;
00258 typedef union convert_U2_u  convert_U2_t;
00259 typedef union convert_U1_u  convert_U1_t;
00260 
00261 union convert_U32_u {
00262         _ITM_TYPE_U8   U8[2];
00263         _ITM_TYPE_U4   U4[4];
00264         _ITM_TYPE_U2   U2[8];
00265         _ITM_TYPE_U1   U1[16];
00266         _ITM_TYPE_CE   CE;
00267 };
00268 
00269 union convert_U16_u {
00270         _ITM_TYPE_U8   U8[2];
00271         _ITM_TYPE_U4   U4[4];
00272         _ITM_TYPE_U2   U2[8];
00273         _ITM_TYPE_U1   U1[16];
00274         _ITM_TYPE_E    E;
00275         _ITM_TYPE_M128 M128;
00276         _ITM_TYPE_CD   CD;
00277 };
00278 
00279 union convert_U8_u {
00280         _ITM_TYPE_U8   U8;
00281         _ITM_TYPE_U4   U4[2];
00282         _ITM_TYPE_U2   U2[4];
00283         _ITM_TYPE_U1   U1[8];
00284         _ITM_TYPE_D    D;
00285         _ITM_TYPE_M64  M64;
00286         _ITM_TYPE_CF   CF;
00287 };
00288 
00289 union convert_U4_u {
00290         _ITM_TYPE_U4   U4;
00291         _ITM_TYPE_U2   U2[2];
00292         _ITM_TYPE_U1   U1[4];
00293         _ITM_TYPE_F    F;
00294 };
00295 
00296 union convert_U2_u {
00297         _ITM_TYPE_U2   U2;
00298         _ITM_TYPE_U1   U1[2];
00299 };
00300 
00301 union convert_U1_u {
00302         _ITM_TYPE_U1   U1;
00303 };
00304 
00305 
00306 #define WRITE_BARRIER(NAME, T, LOCK)                                           \
00307 void _ITM_CALL_CONVENTION mtm_##NAME##LOCK##T(mtm_tx_t *tx,                    \
00308                                               volatile _ITM_TYPE_##T *addr,    \
00309                                               _ITM_TYPE_##T value)             \
00310 {                                                                              \
00311   if (((uintptr_t)addr & (sizeof(_ITM_TYPE_##T))-1) != 0) {                    \
00312     stm_store_bytes(tx, \
00313                     (volatile uint8_t *)addr, \
00314                     (uint8_t *)&value, \
00315                     sizeof(_ITM_TYPE_##T)); \
00316   } else if (sizeof(mtm_word_t) == 4) { \
00317     if (sizeof(_ITM_TYPE_##T) >= 4) {    \
00318           int i;                                         \
00319       convert_##T##_t val;                                                \
00320           val.#T = value;                                                          \
00321           for (i=0; i<sizeof(_ITM_TYPE_##T)/4; i++) {                             \
00322         stm_store(tx, (volatile mtm_word_t *)addr+i, (mtm_word_t)val.U4[i]);\
00323           }                                                                  \
00324         } else {                                                               \
00325       convert_U4_t val, mask;                                                      \
00326       val.#T[((uintptr_t)addr & 0x03) >> (sizeof(_ITM_TYPE_##T)-1)] = value;       \
00327       mask.U4 = 0;                                                               \
00328       mask.#T[((uintptr_t)addr & 0x03) >> (sizeof(_ITM_TYPE_##T)-1)] = ~(_ITM_TYPE_##T)0;     \
00329       stm_store2(tx,                                                           \
00330                  (volatile mtm_word_t *)((uintptr_t)addr & ~(uintptr_t)0x03),  \
00331                  (mtm_word_t)val.U4, (mtm_word_t)mask.U4);                     \
00332         }                                                                          \
00333   } else {               \
00334   }                          \
00335 }
00336 #endif
00337 
00338 
00339 
00340 #endif

Generated on Sat Apr 23 11:43:36 2011 for Mnemosyne by  doxygen 1.4.7