atomic_templates.h

00001 /* -*- mode:C++; c-basic-offset:4 -*-
00002      Shore-MT -- Multi-threaded port of the SHORE storage manager
00003    
00004                        Copyright (c) 2007-2009
00005       Data Intensive Applications and Systems Labaratory (DIAS)
00006                Ecole Polytechnique Federale de Lausanne
00007    
00008                          All Rights Reserved.
00009    
00010    Permission to use, copy, modify and distribute this software and
00011    its documentation is hereby granted, provided that both the
00012    copyright notice and this permission notice appear in all copies of
00013    the software, derivative works or modified versions, and any
00014    portions thereof, and that both notices appear in supporting
00015    documentation.
00016    
00017    This code is distributed in the hope that it will be useful, but
00018    WITHOUT ANY WARRANTY; without even the implied warranty of
00019    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS
00020    DISCLAIM ANY LIABILITY OF ANY KIND FOR ANY DAMAGES WHATSOEVER
00021    RESULTING FROM THE USE OF THIS SOFTWARE.
00022 */
00023 
00024 // -*- mode:c++; c-basic-offset:4 -*-
00025 /*<std-header orig-src='shore'>
00026 
00027  $Id: atomic_templates.h,v 1.4 2010/06/15 17:24:24 nhall Exp $
00028 
00029 SHORE -- Scalable Heterogeneous Object REpository
00030 
00031 Copyright (c) 1994-99 Computer Sciences Department, University of
00032                       Wisconsin -- Madison
00033 All Rights Reserved.
00034 
00035 Permission to use, copy, modify and distribute this software and its
00036 documentation is hereby granted, provided that both the copyright
00037 notice and this permission notice appear in all copies of the
00038 software, derivative works or modified versions, and any portions
00039 thereof, and that both notices appear in supporting documentation.
00040 
00041 THE AUTHORS AND THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY
00042 OF WISCONSIN - MADISON ALLOW FREE USE OF THIS SOFTWARE IN ITS
00043 "AS IS" CONDITION, AND THEY DISCLAIM ANY LIABILITY OF ANY KIND
00044 FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
00045 
00046 This software was developed with support by the Advanced Research
00047 Project Agency, ARPA order number 018 (formerly 8230), monitored by
00048 the U.S. Army Research Laboratory under contract DAAB07-91-C-Q518.
00049 Further funding for this work was provided by DARPA through
00050 Rome Research Laboratory Contract No. F30602-97-2-0247.
00051 
00052 */
00053 
00054 /*
00055 * The vast majority of the atomic add instructions are for
00056 * incrementing or decrementing by one. For those, we use
00057 * atomic_inc and atomic_dec.
00058 *
00059 * For the few others, we need to be careful about the
00060 * delta argument lest we lose bits in it by silent conversion
00061 * from a 64-bit int to a 32-bit int.
00062 * For that reason, we've made templates for each delta type
00063 * and what with their unwieldy names, we might be forced to
00064 * be careful about which we use.
00065 *
00066 */
00067 
00068 #ifndef ATOMIC_TEMPLATES_H
00069 #define ATOMIC_TEMPLATES_H
00070 
00071 #include "atomic_ops.h"
00072 
00073 /* The volatile in the template might appear to be
00074  * redundant, but it allows us to use T that isn't itself volatile
00075  *
00076  * Don't be surprised if you have to expand this list of 
00077  * specializations.
00078  */
00079 
00080 template<class T>
00081 void atomic_inc(T volatile &val);
00082 template<class T>
00083 void atomic_dec(T volatile &val);
00084 
00085 template<>
00086 inline void atomic_inc(int volatile &val)
00087 { atomic_add_int( (unsigned int volatile *)&val, 1); }
00088 
00089 template<>
00090 inline void atomic_inc(unsigned int volatile &val)
00091 { atomic_add_int(&val, 1); }
00092 
00093 template<>
00094 inline void atomic_inc(unsigned long volatile &val)
00095 { atomic_add_long(&val, 1); }
00096 
00097 template<>
00098 inline void atomic_inc(unsigned long long volatile &val)
00099 { atomic_add_64((volatile uint64_t *)&val, 1); }
00100 
00101 template<>
00102 inline void atomic_dec(int volatile &val)
00103 { atomic_add_int( (unsigned int volatile *)&val, -1); }
00104 
00105 
00106 template<>
00107 inline void atomic_dec(unsigned int volatile &val)
00108 { atomic_add_int(&val, -1); }
00109 
00110 template<>
00111 inline void atomic_dec(unsigned long volatile &val)
00112 { atomic_add_long(&val, -1); }
00113 
00114 template<>
00115 inline void atomic_dec(unsigned long long volatile &val)
00116 { atomic_add_64((volatile uint64_t *)&val, -1); }
00117 
00118 
00119 template<class T>
00120 T atomic_inc_nv(T volatile &val);
00121 template<class T>
00122 T atomic_dec_nv(T volatile &val);
00123 
00124 template<>
00125 inline int atomic_inc_nv(int volatile &val)
00126 { return atomic_add_int_nv((unsigned int volatile*)&val, 1); }
00127 template<>
00128 inline unsigned int atomic_inc_nv(unsigned int volatile &val)
00129 { return atomic_add_int_nv(&val, 1); }
00130 template<>
00131 inline unsigned long atomic_inc_nv(unsigned long volatile &val)
00132 { return atomic_add_long_nv(&val, 1); }
00133 #ifndef ARCH_LP64
00134 inline unsigned long long atomic_inc_nv(unsigned long long volatile &val)
00135 { return atomic_add_64_nv(&val, 1); }
00136 #endif
00137 
00138 template<>
00139 inline int atomic_dec_nv(int volatile &val)
00140 { return atomic_add_int_nv((unsigned int volatile*)&val, -1); }
00141 template<>
00142 inline unsigned int atomic_dec_nv(unsigned int volatile &val)
00143 { return atomic_add_int_nv(&val, -1); }
00144 template<>
00145 inline unsigned long atomic_dec_nv(unsigned long volatile &val)
00146 { return atomic_add_long_nv(&val, -1); }
00147 #ifndef ARCH_LP64
00148 inline unsigned long long atomic_dec_nv(unsigned long long volatile &val)
00149 { return atomic_add_64_nv(&val, -1); }
00150 #endif
00151 
00152 
00153 /* The following templates take an int delta */
00154 
00155 template<class T>
00156 void atomic_add_int_delta(T volatile &val, int delta);
00157 
00158 template<>
00159 inline void atomic_add_int_delta(unsigned int volatile &val, int delta) 
00160 { atomic_add_int(&val, delta); }
00161 
00162 template<>
00163 inline void atomic_add_int_delta(int volatile &val, int delta) 
00164 { atomic_add_int((unsigned int volatile*)&val, delta); }
00165 
00166 template<>
00167 inline void atomic_add_int_delta(unsigned long volatile &val, int delta) 
00168 { atomic_add_long(&val, delta); }
00169 
00170 template<>
00171 inline void atomic_add_int_delta(long volatile &val, int delta) 
00172 { atomic_add_long((unsigned long volatile*)&val, delta); }
00173 
00174 #ifndef ARCH_LP64
00175 // Needed when building for 32 bits:
00176 template<>
00177 inline void atomic_add_int_delta(unsigned long long volatile &val, int delta) 
00178 { 
00179     int64_t  deltalg=delta;
00180     atomic_add_64(&val, deltalg); 
00181 }
00182 
00183 template<>
00184 inline void atomic_add_int_delta(long long volatile &val, int delta) 
00185 { 
00186     int64_t  deltalg=delta;
00187     atomic_add_64((unsigned long long volatile *)&val, deltalg); 
00188 }
00189 #endif
00190 
00191 /* atomic_add_nv variants */
00192 
00193 template<class T>
00194 T atomic_add_nv_int_delta(T volatile &val, int delta);
00195 
00196 template<>
00197 inline unsigned int atomic_add_nv_int_delta(unsigned int volatile &val, int delta) 
00198 { return atomic_add_int_nv(&val, delta); }
00199 
00200 template<>
00201 inline int atomic_add_nv_int_delta(int volatile &val, int delta) 
00202 { return atomic_add_int_nv((unsigned int*) &val, delta); }
00203 
00204 template<>
00205 inline unsigned long atomic_add_nv_int_delta(unsigned long volatile &val, int delta) 
00206 { return atomic_add_long_nv(&val, delta); }
00207 
00208 template<>
00209 inline long atomic_add_nv_int_delta(long volatile &val, int delta) 
00210 { return atomic_add_long_nv((unsigned long*) &val, delta); }
00211 
00212 #ifndef ARCH_LP64
00213 
00214 template<>
00215 inline unsigned long long atomic_add_nv_int_delta(unsigned long long volatile &val, int delta) 
00216 { return atomic_add_64_nv(&val, delta); }
00217 
00218 template<>
00219 inline long long atomic_add_nv_int_delta(long long volatile &val, int delta) 
00220 { return atomic_add_64_nv((unsigned long long *)&val, delta); }
00221 
00222 #endif
00223 
00224 /* The following templates take a long delta */
00225 
00226 template<class T>
00227 void atomic_add_long_delta(T volatile &val, long delta);
00228 
00229 template<>
00230 inline void atomic_add_long_delta(unsigned int volatile &val, long delta) 
00231 { atomic_add_int(&val, delta); }
00232 
00233 template<>
00234 inline void atomic_add_long_delta(int volatile &val, long delta) 
00235 { atomic_add_int((unsigned int volatile*)&val, delta); }
00236 
00237 template<>
00238 inline void atomic_add_long_delta(unsigned long volatile &val, long delta) 
00239 { atomic_add_long(&val, delta); }
00240 
00241 template<>
00242 inline void atomic_add_long_delta(long volatile &val, long delta) 
00243 { atomic_add_long((unsigned long volatile*)&val, delta); }
00244 
00245 #ifndef ARCH_LP64
00246 // Needed when building for 32 bits:
00247 template<>
00248 inline void atomic_add_long_delta(unsigned long long volatile &val, long delta) 
00249 { 
00250     int64_t  deltalg=delta;
00251     atomic_add_64(&val, deltalg); 
00252 }
00253 
00254 template<>
00255 inline void atomic_add_long_delta(long long volatile &val, long delta) 
00256 { 
00257     int64_t  deltalg=delta;
00258     atomic_add_64((unsigned long long volatile *)&val, deltalg); 
00259 }
00260 #endif
00261 
00262 /* atomic_add_nv variants */
00263 
00264 template<class T>
00265 T atomic_add_nv_long_delta(T volatile &val, long delta);
00266 
00267 template<>
00268 inline unsigned int atomic_add_nv_long_delta(unsigned int volatile &val, long delta) 
00269 { return atomic_add_int_nv(&val, delta); }
00270 
00271 template<>
00272 inline int atomic_add_nv_long_delta(int volatile &val, long delta) 
00273 { return atomic_add_int_nv((unsigned int*) &val, delta); }
00274 
00275 template<>
00276 inline unsigned long atomic_add_nv_long_delta(unsigned long volatile &val, long delta) 
00277 { return atomic_add_long_nv(&val, delta); }
00278 
00279 template<>
00280 inline long atomic_add_nv_long_delta(long volatile &val, long delta) 
00281 { return atomic_add_long_nv((unsigned long*) &val, delta); }
00282 
00283 #ifndef ARCH_LP64
00284 
00285 template<>
00286 inline unsigned long long atomic_add_nv_long_delta(unsigned long long volatile &val, long delta) 
00287 { return atomic_add_64_nv(&val, delta); }
00288 
00289 template<>
00290 inline long long atomic_add_nv_long_delta(long long volatile &val, long delta) 
00291 { return atomic_add_64_nv((unsigned long long *)&val, delta); }
00292 
00293 #endif
00294 #endif

Generated on Wed Jul 7 17:22:32 2010 for Shore Storage Manager by  doxygen 1.4.7