00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 INLINE UpdateSeq::
00022 UpdateSeq() {
00023 _seq = (unsigned int)SC_initial;
00024 }
00025
00026
00027
00028
00029
00030
00031 INLINE UpdateSeq UpdateSeq::
00032 initial() {
00033 return UpdateSeq();
00034 }
00035
00036
00037
00038
00039
00040
00041 INLINE UpdateSeq UpdateSeq::
00042 old() {
00043 UpdateSeq result;
00044 result._seq = (unsigned int)SC_old;
00045 return result;
00046 }
00047
00048
00049
00050
00051
00052
00053 INLINE UpdateSeq UpdateSeq::
00054 fresh() {
00055 UpdateSeq result;
00056 result._seq = (unsigned int)SC_fresh;
00057 return result;
00058 }
00059
00060
00061
00062
00063
00064
00065 INLINE UpdateSeq::
00066 UpdateSeq(const UpdateSeq ©) {
00067 _seq = AtomicAdjust::get(copy._seq);
00068 }
00069
00070
00071
00072
00073
00074
00075 INLINE UpdateSeq &UpdateSeq::
00076 operator = (const UpdateSeq ©) {
00077 AtomicAdjust::set(_seq, AtomicAdjust::get(copy._seq));
00078 return *this;
00079 }
00080
00081
00082
00083
00084
00085
00086 INLINE void UpdateSeq::
00087 clear() {
00088 AtomicAdjust::set(_seq, (AtomicAdjust::Integer)SC_initial);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097 INLINE bool UpdateSeq::
00098 is_initial() const {
00099 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_initial;
00100 }
00101
00102
00103
00104
00105
00106
00107 INLINE bool UpdateSeq::
00108 is_old() const {
00109 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_old;
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 INLINE bool UpdateSeq::
00119 is_fresh() const {
00120 return AtomicAdjust::get(_seq) == (AtomicAdjust::Integer)SC_fresh;
00121 }
00122
00123
00124
00125
00126
00127
00128
00129 INLINE bool UpdateSeq::
00130 is_special() const {
00131
00132 return ((AtomicAdjust::get(_seq) + 1) <= 2);
00133 }
00134
00135
00136
00137
00138
00139
00140 INLINE bool UpdateSeq::
00141 operator == (const UpdateSeq &other) const {
00142 return AtomicAdjust::get(_seq) == AtomicAdjust::get(other._seq);
00143 }
00144
00145
00146
00147
00148
00149
00150 INLINE bool UpdateSeq::
00151 operator != (const UpdateSeq &other) const {
00152 return AtomicAdjust::get(_seq) != AtomicAdjust::get(other._seq);
00153 }
00154
00155
00156
00157
00158
00159
00160 INLINE bool UpdateSeq::
00161 operator < (const UpdateSeq &other) const {
00162 return priv_lt(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq));
00163 }
00164
00165
00166
00167
00168
00169
00170 INLINE bool UpdateSeq::
00171 operator <= (const UpdateSeq &other) const {
00172 return priv_le(AtomicAdjust::get(_seq), AtomicAdjust::get(other._seq));
00173 }
00174
00175
00176
00177
00178
00179
00180 INLINE bool UpdateSeq::
00181 operator > (const UpdateSeq &other) const {
00182 return (other < (*this));
00183 }
00184
00185
00186
00187
00188
00189
00190 INLINE bool UpdateSeq::
00191 operator >= (const UpdateSeq &other) const {
00192 return (other <= (*this));
00193 }
00194
00195
00196
00197
00198
00199
00200 INLINE UpdateSeq UpdateSeq::
00201 operator ++ () {
00202 AtomicAdjust::Integer old_seq = AtomicAdjust::get(_seq);
00203 AtomicAdjust::Integer new_seq = old_seq + 1;
00204 if (priv_is_special(new_seq)) {
00205
00206
00207 new_seq = (AtomicAdjust::Integer)SC_old + 1;
00208 }
00209
00210 #ifdef HAVE_THREADS
00211 AtomicAdjust::Integer result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq);
00212 while (result != old_seq) {
00213
00214 old_seq = AtomicAdjust::get(_seq);
00215 new_seq = old_seq + 1;
00216 if (priv_is_special(new_seq)) {
00217
00218
00219 new_seq = (AtomicAdjust::Integer)SC_old + 1;
00220 }
00221 result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq);
00222 }
00223 #else
00224 _seq = new_seq;
00225 #endif // HAVE_THREADS
00226
00227 return *this;
00228 }
00229
00230
00231
00232
00233
00234
00235 INLINE UpdateSeq UpdateSeq::
00236 operator ++ (int) {
00237 AtomicAdjust::Integer old_seq = AtomicAdjust::get(_seq);
00238 AtomicAdjust::Integer new_seq = old_seq + 1;
00239 if (priv_is_special(new_seq)) {
00240
00241
00242 new_seq = (AtomicAdjust::Integer)SC_old + 1;
00243 }
00244
00245 #ifdef HAVE_THREADS
00246 AtomicAdjust::Integer result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq);
00247 while (result != old_seq) {
00248
00249 old_seq = AtomicAdjust::get(_seq);
00250 new_seq = old_seq + 1;
00251 if (priv_is_special(new_seq)) {
00252
00253
00254 new_seq = (AtomicAdjust::Integer)SC_old + 1;
00255 }
00256 result = AtomicAdjust::compare_and_exchange(_seq, old_seq, new_seq);
00257 }
00258 #else
00259 _seq = new_seq;
00260 #endif // HAVE_THREADS
00261
00262 UpdateSeq temp;
00263 temp._seq = old_seq;
00264 return temp;
00265 }
00266
00267
00268
00269
00270
00271
00272 INLINE void UpdateSeq::
00273 output(ostream &out) const {
00274 AtomicAdjust::Integer seq = AtomicAdjust::get(_seq);
00275 switch (seq) {
00276 case SC_initial:
00277 out << "initial";
00278 break;
00279
00280 case SC_old:
00281 out << "old";
00282 break;
00283
00284 case SC_fresh:
00285 out << "fresh";
00286 break;
00287
00288 default:
00289 out << (unsigned int)seq;
00290 }
00291 }
00292
00293
00294
00295
00296
00297
00298 INLINE bool UpdateSeq::
00299 priv_is_special(AtomicAdjust::Integer seq) {
00300
00301 return (((unsigned int)seq + 1) <= 2);
00302 }
00303
00304
00305
00306
00307
00308
00309 INLINE bool UpdateSeq::
00310 priv_lt(AtomicAdjust::Integer a, AtomicAdjust::Integer b) {
00311
00312
00313
00314
00315
00316 return
00317 (priv_is_special(a) || priv_is_special(b)) ? ((unsigned int)a < (unsigned int)b) :
00318 ((signed int)(a - b) < 0);
00319 }
00320
00321
00322
00323
00324
00325
00326 INLINE bool UpdateSeq::
00327 priv_le(AtomicAdjust::Integer a, AtomicAdjust::Integer b) {
00328 return (a == b) || priv_lt(a, b);
00329 }
00330
00331 INLINE ostream &operator << (ostream &out, const UpdateSeq &value) {
00332 value.output(out);
00333 return out;
00334 }