00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #ifndef _VIRTUAL_TIME_H_
00036 #define _VIRTUAL_TIME_H_
00037
00038
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include <comparable.h>
00042
00043 #define VT_PORT 3486
00044
00045
00046 enum VT_msg_sign { POSITIVE, NEGATIVE };
00047 enum VT_msg_q { IN, OUT };
00048
00049 #define MICRO 1000000
00050
00051 #ifndef MAX_ULONG
00052 #define MAX_ULONG 2147483647L
00053 #endif
00054
00055
00056 class VT_message;
00057
00058 class VT_timestamp {
00059 unsigned long _sec;
00060 unsigned long _usec;
00061
00062 static const unsigned int _strlen = (sizeof(unsigned long) * 2) + 1;
00063 static char *_format;
00064
00065 char _string[_strlen + 1];
00066
00067 static VT_timestamp _local_virtual_time;
00068 static VT_timestamp _global_virtual_time;
00069
00070 friend class VT_message;
00071
00072 public:
00073 VT_timestamp() {
00074 _sec = _local_virtual_time._sec;
00075 _usec = _local_virtual_time._usec;
00076 sprintf(_string, _format, _sec, _usec);
00077 };
00078 VT_timestamp(unsigned long s, unsigned long u) {
00079 _sec = s;
00080 _usec = u;
00081 sprintf(_string, _format, _sec, _usec);
00082 };
00083 VT_timestamp(char *string) {
00084 strncpy(_string, string, _strlen);
00085 sscanf(_string, _format, &_sec, &_usec);
00086 };
00087
00088 char *to_string() { return _string; };
00089 unsigned long get_sec() { return _sec; };
00090 unsigned long get_usec() { return _usec; };
00091
00092 inline void operator++ (int) {
00093 _usec++;
00094 if (_usec >= MICRO) {
00095 _usec = 0;
00096 _sec++;
00097 if (_sec >= MAX_ULONG)
00098 _sec = 0;
00099 }
00100 }
00101
00102 inline void operator++ () {
00103 _usec++;
00104 if (_usec >= MICRO) {
00105 _usec = 0;
00106 _sec++;
00107 if (_sec >= MAX_ULONG)
00108 _sec = 0;
00109 }
00110 }
00111
00112 inline VT_timestamp& operator+ (int usec) {
00113 _usec += usec;
00114 if (_usec >= MICRO) {
00115 _usec = _usec - MICRO;
00116 _sec++;
00117 }
00118 return *this;
00119 }
00120
00121 inline VT_timestamp& operator+ (VT_timestamp other) {
00122 _usec += other.get_usec();
00123 _sec += other.get_sec();
00124 if (_usec >= MICRO) {
00125 _usec = _usec - MICRO;
00126 _sec++;
00127 }
00128 return *this;
00129 }
00130
00131 inline bool operator== (VT_timestamp other) {
00132 if (_sec == other.get_sec() && _usec == other.get_usec())
00133 return true;
00134 return false;
00135 };
00136
00137 inline bool operator< (VT_timestamp other) {
00138 if (_sec < other.get_sec())
00139 return true;
00140 if (_sec == other.get_sec() && _usec < other.get_usec())
00141 return true;
00142 return false;
00143 };
00144
00145 inline bool operator> (VT_timestamp other) {
00146 if (_sec > other.get_sec())
00147 return true;
00148 if (_sec == other.get_sec() && _usec > other.get_usec())
00149 return true;
00150 return false;
00151 };
00152
00153 inline bool operator<= (VT_timestamp other) {
00154 if (_sec <= other.get_sec())
00155 return true;
00156 if (_sec == other.get_sec() && _usec <= other.get_usec())
00157 return true;
00158 return false;
00159 };
00160
00161 inline bool operator>= (VT_timestamp other) {
00162 if (_sec >= other.get_sec())
00163 return true;
00164 if (_sec == other.get_sec() && _usec >= other.get_usec())
00165 return true;
00166 return false;
00167 };
00168
00169 static void init(VT_timestamp t) {
00170 _local_virtual_time = t;
00171 };
00172 static void tick(void) {
00173 _local_virtual_time++;
00174 if (_local_virtual_time >= VT_timestamp::max())
00175 _local_virtual_time = VT_timestamp(0L, 0L);
00176 };
00177
00178 static VT_timestamp local_vt() {
00179 return _local_virtual_time;
00180 };
00181 static VT_timestamp global_vt() {
00182 return _global_virtual_time;
00183 };
00184 static VT_timestamp max() {
00185 return VT_timestamp(MAX_ULONG, MAX_ULONG);
00186 };
00187 static int string_len() { return _strlen; };
00188 static void min_time(VT_timestamp t[], int n, VT_timestamp &min) {
00189 int i;
00190 min = VT_timestamp::max();
00191 for (i = 0; i < n; i++) {
00192 if (t[i] < min)
00193 min = t[i];
00194 }
00195 };
00196 };
00197
00198 inline VT_timestamp global_virtual_time()
00199 {
00200 return VT_timestamp::global_vt();
00201 }
00202
00203 inline VT_timestamp local_virtual_time()
00204 {
00205 return VT_timestamp::local_vt();
00206 }
00207
00208
00209 class VT_message : public Comparable<VT_timestamp> {
00210
00211
00212 static const unsigned int _strlen = (sizeof(int) * 5) +
00213 (VT_timestamp::_strlen * 2) + 16;
00214
00215 const char *key_fromat_string() { return VT_timestamp::_format; };
00216
00217 char _string[_strlen + 1];
00218
00219 VT_timestamp _svt;
00220 VT_timestamp _rvt;
00221
00222 public:
00223 VT_msg_q msg_queue;
00224 VT_msg_sign msg_sign;
00225 unsigned int sender;
00226 unsigned int rcvr;
00227 char *content;
00228
00229 VT_message(unsigned int, char*);
00230 VT_message(char*);
00231 ~VT_message() { };
00232
00233 VT_timestamp svt() {
00234 if (msg_queue == OUT) return key;
00235 return _svt;
00236 };
00237 void set_svt(VT_timestamp t) {
00238 if (msg_queue == OUT) key = t;
00239 else _svt = t;
00240 };
00241
00242 VT_timestamp rvt() {
00243 if (msg_queue == IN) return key;
00244 return _rvt;
00245 };
00246 void set_rvt(VT_timestamp t) {
00247 if (msg_queue == IN) key = t;
00248 else _rvt = t;
00249 };
00250
00251 Comparable<VT_timestamp> compare() {
00252 if (msg_queue == IN) return Comparable<VT_timestamp>(_rvt);
00253 return Comparable<VT_timestamp>(_svt);
00254 };
00255
00256 char *to_string() {
00257 sprintf(_string, "%s::%u::%s::%u::%d::%s",
00258 _svt.to_string(), sender, _rvt.to_string(), rcvr,
00259 msg_sign, content);
00260 return _string;
00261 };
00262
00263 static int string_len() { return _strlen; };
00264 };
00265
00266
00267 int checkpoint(unsigned long node_id);
00268 int chkpt_all(void);
00269 int restore(unsigned long node_id);
00270
00271 #endif // _VIRTUAL_TIME_H_