00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _MACE_TIME_H
00034 #define _MACE_TIME_H
00035
00036 #include <inttypes.h>
00037 #include <pthread.h>
00038 #include "RandomUtil.h"
00039 #include "TimeUtil.h"
00040 #include "Printable.h"
00041 #include "Serializable.h"
00042 #include "hash_string.h"
00043 #include "Traits.h"
00044
00050 class Sim;
00051
00052 namespace mace {
00053 typedef uint64_t MonotoneTime;
00054
00055 class MonotoneTimeImpl {
00056 public:
00057 static MonotoneTimeImpl* mt;
00058
00059 virtual MonotoneTime getTime() {
00060 return TimeUtil::timeu();
00061 }
00062
00063 virtual ~MonotoneTimeImpl() {
00064 }
00065 };
00066
00067 class MonotoneTimeInit {
00068 public:
00069 static MonotoneTimeInit init;
00070 MonotoneTimeInit() {
00071 if (MonotoneTimeImpl::mt == NULL) {
00072 MonotoneTimeImpl::mt = new MonotoneTimeImpl();
00073 }
00074 }
00075 };
00076
00078 inline MonotoneTime getmtime() {
00079 return MonotoneTimeImpl::mt->getTime();
00080 }
00081
00083
00094 class MaceTime : public PrintPrintable, public Serializable {
00095 friend class ::Sim;
00096 friend class mace::KeyTraits<MaceTime>;
00097
00098 public:
00100 MaceTime() : realtime(0), tainted(true) {
00101 }
00102
00104 MaceTime(uint64_t offset) : realtime(offset), tainted(true) {
00105 }
00106
00108 MaceTime(const MaceTime& other) : realtime(other.realtime), tainted(other.tainted) {
00109 }
00110
00112 MaceTime& operator=(const MaceTime& other) {
00113 realtime = other.realtime;
00114 tainted = other.tainted;
00115 return *this;
00116 }
00117
00119 MaceTime& operator=(uint64_t offset) {
00120 realtime = offset;
00121 tainted = true;
00122 return *this;
00123 }
00124
00126 MaceTime operator+(const MaceTime& other) const {
00127 return plus(other);
00128 }
00129
00131 MaceTime operator-(const MaceTime& other) const {
00132 return minus(other);
00133 }
00134
00136 bool operator==(const MaceTime& other) const {
00137 return realtime == other.realtime;
00138 }
00139
00141 bool operator==(const uint64_t& other) const {
00142 return realtime == other;
00143 }
00144
00146 bool operator!=(const MaceTime& other) const {
00147 return realtime != other.realtime;
00148 }
00149
00151 bool operator!=(const uint64_t& other) const {
00152 return realtime != other;
00153 }
00154
00155
00156
00157
00158
00160
00165 bool lessThan(const MaceTime& other, uint trueWeight = 1, uint falseWeight = 1) const {
00166 if (simulated && (tainted || other.tainted)) {
00167 return RandomUtil::randInt(2, falseWeight, trueWeight);
00168 }
00169 else {
00170 return realtime < other.realtime;
00171 }
00172 }
00173
00175
00180 bool greaterThan(const MaceTime& other,
00181 uint trueWeight = 1, uint falseWeight = 1) const {
00182 return !lessThanOrEqual(other, falseWeight, trueWeight);
00183 }
00184
00186
00191 bool lessThanOrEqual(const MaceTime& other,
00192 uint trueWeight = 1, uint falseWeight = 1) const {
00193 if (simulated && (tainted || other.tainted)) {
00194 return RandomUtil::randInt(2, falseWeight, trueWeight);
00195 }
00196 else {
00197 return realtime <= other.realtime;
00198 }
00199 }
00200
00202
00207 bool greaterThanOrEqual(const MaceTime& other,
00208 uint trueWeight = 1, uint falseWeight = 1) const {
00209 return !lessThan(other, falseWeight, trueWeight);
00210 }
00211
00213
00218 bool equals(const MaceTime& other, uint trueWeight = 1, uint falseWeight = 1) const {
00219 if (simulated && (tainted || other.tainted)) {
00220 return RandomUtil::randInt(2, falseWeight, trueWeight);
00221 }
00222 else {
00223 return realtime == other.realtime;
00224 }
00225 }
00226
00228
00233 bool notEquals(const MaceTime& other,
00234 uint trueWeight = 1, uint falseWeight = 1) const {
00235 return !equals(other, falseWeight, trueWeight);
00236 }
00237
00239 MaceTime plus(const MaceTime& other) const {
00240 MaceTime t(*this);
00241 t.realtime += other.realtime;
00242 t.tainted |= other.tainted;
00243 return t;
00244 }
00245
00247 MaceTime minus(const MaceTime& other) const {
00248 MaceTime t(*this);
00249 t.realtime -= other.realtime;
00250 t.tainted |= other.tainted;
00251 return t;
00252 }
00253
00255 MaceTime scaleBy(uint amount) const {
00256 MaceTime t(*this);
00257 t.realtime *= amount;
00258
00259 return t;
00260 }
00261
00263 MaceTime scaleBy(double amount) const {
00264 MaceTime t(*this);
00265 t.realtime = (uint64_t)((double)t.realtime * amount);
00266
00267 return t;
00268 }
00269
00270 void serialize(std::string& s) const {
00271 mace::serialize(s, &realtime);
00272 }
00273
00274 int deserialize(istream& in) throw(SerializationException) {
00275 int off = 0;
00276 off += mace::deserialize(in, &realtime);
00277 tainted = true;
00278 return off;
00279 }
00280
00281 void print(std::ostream& out) const {
00282 out << realtime;
00283 }
00284
00285 void printState(std::ostream& out) const {
00286 if(simulated && tainted) {
00287 out << "NON-DET";
00288 } else {
00289 out << realtime;
00290 }
00291 }
00292
00293 size_t hashOf() const {
00294 static const hash_bytes<uint64_t> h = hash_bytes<uint64_t>();
00295 return h(realtime);
00296 }
00297
00298 uint64_t time() const {
00299 return realtime;
00300 }
00301
00303 bool isZero() const {
00304 return realtime == 0;
00305 }
00306
00308 static const MaceTime& min(const MaceTime& l, const MaceTime& r) {
00309 if (l.realtime < r.realtime) {
00310 return l;
00311 }
00312 return r;
00313 }
00314
00316 static MaceTime currentTime() {
00317 MaceTime t(TimeUtil::timeu());
00318 t.tainted = true;
00319 return t;
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330 private:
00331 uint64_t realtime;
00332 bool tainted;
00333 static bool simulated;
00334
00335 };
00336
00338 class MaceTimeComparitor {
00339 public:
00340 bool operator()(const MaceTime& l, const MaceTime& r) const {
00341 return l.time() < r.time();
00342 }
00343 };
00344
00346 class MaceTimeEquality {
00347 public:
00348 bool operator()(const MaceTime& l, const MaceTime& r) const {
00349 return l.time() == r.time();
00350 }
00351 };
00352
00354 class MaceTimeHash {
00355 public:
00356 size_t operator()(const MaceTime& x) const {
00357 return x.hashOf();
00358 }
00359 };
00360
00361 template<>
00362 class KeyTraits<MaceTime> : public KeyTraits<unsigned long long> {
00363 public:
00364 static void append(std::string& str, const MaceTime& key) {
00365 char buf[30];
00366
00367 sprintf(buf, "%" PRIu64, key.time());
00368 str += buf;
00369 }
00370 static bool isDeterministic() {
00371 return !MaceTime::simulated;
00372 }
00373 static MaceTime extract(std::istream& in)
00374 throw(SerializationException) {
00375 std::string token = SerializationUtil::get(in, '<');
00376 return strtoull(token.c_str(), NULL, 10);
00377 }
00378 };
00379
00381 class LogicalClock {
00382 public:
00383 typedef uint32_t lclock_t;
00384
00385 private:
00386 lclock_t clock;
00387 static LogicalClock* inst;
00388
00389 LogicalClock() : clock(0) {}
00390
00391 public:
00392 lclock_t getClock() { return clock; }
00393 void updatePending(lclock_t val) {
00394 ThreadSpecific::setPendingClock(val);
00395 }
00396 void tick() {
00397 clock = std::max(clock, ThreadSpecific::getPendingClock()) + 1;
00398 }
00399
00400 static LogicalClock& instance() {
00401 if (inst == NULL) {
00402 inst = new LogicalClock();
00403 }
00404 return *inst;
00405 }
00406
00407 private:
00409
00412 class ThreadSpecific {
00413
00414
00415 public:
00416 ThreadSpecific();
00417 ~ThreadSpecific();
00418 static ThreadSpecific* init();
00419 static lclock_t getPendingClock();
00420 static void setPendingClock(lclock_t val);
00421
00422 private:
00423 static void initKey();
00424
00425 private:
00426 static pthread_key_t pkey;
00427 static pthread_once_t keyOnce;
00428 lclock_t pending;
00429 };
00430 };
00431
00432 };
00433
00434 namespace __gnu_cxx {
00436 template<> struct hash<mace::MaceTime> {
00437 size_t operator()(const mace::MaceTime& x) const {
00438 return x.hashOf();
00439 }
00440 };
00441 }
00442
00443 #endif // _MACE_TIME_H