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
00034 #include <global.h>
00035 #include <tod.h>
00036
00037 #ifndef WIN32
00038 #include <stdio.h>
00039 #include <sys/types.h>
00040 #include <sys/time.h>
00041 #endif
00042
00046 uint32 max_time = MAX_TIME;
00047 struct timeval last_time;
00048
00050 #define PBUFLEN 100
00051 static uint32 process_utime_save[PBUFLEN];
00052 static uint32 psaveind;
00053 static uint32 process_max_utime = 0;
00054 static uint32 process_min_utime = 999999999;
00055 static uint32 process_tot_mtime;
00056 uint32 pticks;
00057 static uint32 process_utime_long_count;
00060 static const char *const season_name[SEASONS_PER_YEAR+1] = {
00061 "The Season of New Year",
00062 "The Season of Growth",
00063 "The Season of Harvest",
00064 "The Season of Decay",
00065 "The Season of the Blizzard",
00066 "\n"
00067 };
00068
00070 static const char *const weekdays[DAYS_PER_WEEK] = {
00071 "the Day of the Moon",
00072 "the Day of the Bull",
00073 "the Day of the Deception",
00074 "the Day of Thunder",
00075 "the Day of Freedom",
00076 "the Day of the Great Gods",
00077 "the Day of the Sun"
00078 };
00079
00081 static const char *const month_name[MONTHS_PER_YEAR] = {
00082 "Month of Winter",
00083 "Month of the Ice Dragon",
00084 "Month of the Frost Giant",
00085 "Month of Valriel",
00086 "Month of Lythander",
00087 "Month of the Harvest",
00088 "Month of Gaea",
00089 "Month of Futility",
00090 "Month of the Dragon",
00091 "Month of the Sun",
00092 "Month of the Great Infernus",
00093 "Month of Ruggilli",
00094 "Month of the Dark Shades",
00095 "Month of the Devourers",
00096 "Month of Sorig",
00097 "Month of the Ancient Darkness",
00098 "Month of Gorokh"
00099 };
00100
00101 static const char *const periodsofday[PERIODS_PER_DAY] = {
00102 "Night",
00103 "Dawn",
00104 "Morning",
00105 "Noon",
00106 "Evening",
00107 "Dusk"
00108 };
00109
00113 const char *get_periodofday(const int index) {
00114 return ((index >= 0) && (index < PERIODS_PER_DAY)) ? periodsofday[index] : NULL;
00115 }
00116
00120 const char *get_month_name(const int index) {
00121 return ((index >= 0) && (index < MONTHS_PER_YEAR)) ? month_name[index] : NULL;
00122 }
00123
00127 const char *get_weekday(const int index) {
00128 return ((index >= 0) && (index < DAYS_PER_WEEK)) ? weekdays[index] : NULL;
00129 }
00130
00134 const char *get_season_name(const int index) {
00135 return ((index >= 0) && (index < (SEASONS_PER_YEAR+1))) ? season_name[index] : NULL;
00136 }
00137
00141 void reset_sleep(void) {
00142 int i;
00143
00144 for (i = 0; i < PBUFLEN; i++)
00145 process_utime_save[i] = 0;
00146 psaveind = 0;
00147 process_max_utime = 0;
00148 process_min_utime = 999999999;
00149 process_tot_mtime = 0;
00150 pticks = 0;
00151
00152 (void)GETTIMEOFDAY(&last_time);
00153 }
00154
00158 static void log_time(uint32 process_utime) {
00159 pticks++;
00160 if (++psaveind >= PBUFLEN)
00161 psaveind = 0;
00162 process_utime_save[psaveind] = process_utime;
00163 if (process_utime > process_max_utime)
00164 process_max_utime = process_utime;
00165 if (process_utime < process_min_utime)
00166 process_min_utime = process_utime;
00167 process_tot_mtime += process_utime/1000;
00168 }
00169
00175 int enough_elapsed_time(void) {
00176 static struct timeval new_time;
00177 uint32 elapsed_utime;
00178
00179 (void)GETTIMEOFDAY(&new_time);
00180
00181 elapsed_utime = (new_time.tv_sec-last_time.tv_sec)*1000000+new_time.tv_usec-last_time.tv_usec;
00182 if (elapsed_utime > max_time) {
00183 log_time(elapsed_utime);
00184 last_time.tv_sec = new_time.tv_sec;
00185 last_time.tv_usec = new_time.tv_usec;
00186 return 1;
00187 }
00188 return 0;
00189 }
00190
00195 void sleep_delta(void) {
00196 static struct timeval new_time;
00197 long sleep_sec, sleep_usec;
00198
00199 (void)GETTIMEOFDAY(&new_time);
00200
00201 sleep_sec = last_time.tv_sec-new_time.tv_sec;
00202 sleep_usec = max_time-(new_time.tv_usec-last_time.tv_usec);
00203
00204
00205 while (sleep_usec < 0) {
00206 sleep_usec += 1000000;
00207 sleep_sec -= 1;
00208 }
00209 while (sleep_usec > 1000000) {
00210 sleep_usec -= 1000000;
00211 sleep_sec += 1;
00212 }
00213
00214 log_time((new_time.tv_sec-last_time.tv_sec)*1000000+new_time.tv_usec-last_time.tv_usec);
00215
00216 if (sleep_sec >= 0 && sleep_usec > 0) {
00217 static struct timeval sleep_time;
00218
00219 sleep_time.tv_sec = sleep_sec;
00220 sleep_time.tv_usec = sleep_usec;
00221
00222 #ifndef WIN32
00223 select(0, NULL, NULL, NULL, &sleep_time);
00224 #else
00225 if (sleep_time.tv_sec)
00226 Sleep(sleep_time.tv_sec*1000);
00227 Sleep((int)(sleep_time.tv_usec/1000.));
00228 #endif
00229 } else
00230 process_utime_long_count++;
00231
00232
00233
00234 last_time.tv_usec += max_time;
00235 while (last_time.tv_usec > 1000000) {
00236 last_time.tv_usec -= 1000000;
00237 last_time.tv_sec++;
00238 }
00239
00240
00241
00242
00243 if (last_time.tv_sec*1000000+last_time.tv_usec <
00244 new_time.tv_sec*1000000+new_time.tv_usec) {
00245 last_time.tv_sec = new_time.tv_sec;
00246 last_time.tv_usec = new_time.tv_usec;
00247 }
00248 }
00249
00256 void set_max_time(long t) {
00257 max_time = t;
00258 }
00259
00260 extern unsigned long todtick;
00261
00268 void get_tod(timeofday_t *tod) {
00269 tod->year = todtick/HOURS_PER_YEAR;
00270 tod->month = (todtick/HOURS_PER_MONTH)%MONTHS_PER_YEAR;
00271 tod->day = (todtick%HOURS_PER_MONTH)/DAYS_PER_MONTH;
00272 tod->dayofweek = tod->day%DAYS_PER_WEEK;
00273 tod->hour = todtick%HOURS_PER_DAY;
00274 tod->minute = (pticks%PTICKS_PER_CLOCK)/(PTICKS_PER_CLOCK/58);
00275 if (tod->minute > 58)
00276 tod->minute = 58;
00277 tod->weekofmonth = tod->day/WEEKS_PER_MONTH;
00278 if (tod->month < 3)
00279 tod->season = 0;
00280 else if (tod->month < 6)
00281 tod->season = 1;
00282 else if (tod->month < 9)
00283 tod->season = 2;
00284 else if (tod->month < 12)
00285 tod->season = 3;
00286 else
00287 tod->season = 4;
00288
00289 if (tod->hour < 5)
00290 tod->periodofday = 0;
00291 else if (tod->hour < 8)
00292 tod->periodofday = 1;
00293 else if (tod->hour < 13)
00294 tod->periodofday = 2;
00295 else if (tod->hour < 15)
00296 tod->periodofday = 3;
00297 else if (tod->hour < 20)
00298 tod->periodofday = 4;
00299 else if (tod->hour < 23)
00300 tod->periodofday = 5;
00301 else
00302 tod->periodofday = 0;
00303 }
00304
00311 static void print_tod(object *op) {
00312 timeofday_t tod;
00313 const char *suf;
00314 int day;
00315
00316 get_tod(&tod);
00317
00318 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
00319 "It is %d minute%s past %d o'clock %s, on %s",
00320 "It is %d minute%s past %d o'clock %s, on %s",
00321 tod.minute+1, ((tod.minute+1 < 2) ? "" : "s"),
00322 ((tod.hour%14 == 0) ? 14 : ((tod.hour)%14)),
00323 ((tod.hour >= 14) ? "pm" : "am"),
00324 weekdays[tod.dayofweek]);
00325
00326 day = tod.day+1;
00327 if (day == 1 || ((day%10) == 1 && day > 20))
00328 suf = "st";
00329 else if (day == 2 || ((day%10) == 2 && day > 20))
00330 suf = "nd";
00331 else if (day == 3 || ((day%10) == 3 && day > 20))
00332 suf = "rd";
00333 else
00334 suf = "th";
00335
00336 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
00337 "The %d%s Day of the %s, Year %d",
00338 "The %d%s Day of the %s, Year %d",
00339 day, suf, month_name[tod.month], tod.year+1);
00340
00341 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_INFO,
00342 "Time of Year: %s",
00343 "Time of Year: %s",
00344 season_name[tod.season]);
00345 }
00346
00353 void time_info(object *op) {
00354 int tot = 0, long_count = 0;
00355 uint32 maxt = 0, mint = 99999999, i;
00356
00357 print_tod(op);
00358
00359 if (!QUERY_FLAG(op, FLAG_WIZ))
00360 return;
00361
00362 draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00363 "Total time:", NULL);
00364
00365 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00366 "ticks=%d time=%d.%2d",
00367 "ticks=%d time=%d.%2d",
00368 pticks, process_tot_mtime/1000, process_tot_mtime%1000);
00369
00370 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00371 "avg time=%dms max time=%dms min time=%dms",
00372 "avg time=%dms max time=%dms min time=%dms",
00373 process_tot_mtime/pticks, process_max_utime/1000,
00374 process_min_utime/1000);
00375
00376 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00377 "ticks longer than max time (%dms) = %d (%d%%)",
00378 "ticks longer than max time (%dms) = %d (%d%%)",
00379 max_time/1000,
00380 process_utime_long_count, 100*process_utime_long_count/pticks);
00381
00382
00383 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00384 "Time last %d ticks:",
00385 "Time last %d ticks:",
00386 MIN(pticks, PBUFLEN));
00387
00388 for (i = 0; i < MIN(pticks, PBUFLEN); i++) {
00389 tot += process_utime_save[i];
00390 if (process_utime_save[i] > maxt)
00391 maxt = process_utime_save[i];
00392 if (process_utime_save[i] < mint)
00393 mint = process_utime_save[i];
00394 if (process_utime_save[i] > max_time)
00395 long_count++;
00396 }
00397
00398 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00399 "avg time=%dms max time=%dms min time=%dms",
00400 "avg time=%dms max time=%dms min time=%dms",
00401 tot/MIN(pticks, PBUFLEN)/1000, maxt/1000,
00402 mint/1000);
00403
00404 draw_ext_info_format(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_DEBUG,
00405 "ticks longer than max time (%dms) = %d (%d%%)",
00406 "ticks longer than max time (%dms) = %d (%d%%)",
00407 max_time/1000, long_count,
00408 100*long_count/MIN(pticks, PBUFLEN));
00409 }
00410
00417 long seconds(void) {
00418 struct timeval now;
00419
00420 (void)GETTIMEOFDAY(&now);
00421 return now.tv_sec;
00422 }