ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/time.C
Revision: 1.1
Committed: Sun Aug 13 17:16:01 2006 UTC (17 years, 9 months ago) by elmex
Content type: text/plain
Branch: MAIN
Log Message:
Made server compile with C++.
Removed cfanim plugin and crossedit.
C++ here we come.

File Contents

# User Rev Content
1 elmex 1.1 /*
2     * static char *rcsid_time_c =
3     * "$Id$";
4     */
5    
6     /*
7     CrossFire, A Multiplayer game for X-windows
8    
9     Copyright (C) 2002 Mark Wedel & Crossfire Development Team
10     Copyright (C) 1992 Frank Tore Johansen
11    
12     This program is free software; you can redistribute it and/or modify
13     it under the terms of the GNU General Public License as published by
14     the Free Software Foundation; either version 2 of the License, or
15     (at your option) any later version.
16    
17     This program is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20     GNU General Public License for more details.
21    
22     You should have received a copy of the GNU General Public License
23     along with this program; if not, write to the Free Software
24     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25    
26     The authors can be reached via e-mail at crossfire-devel@real-time.com
27     */
28    
29     #include <global.h>
30     #include <funcpoint.h>
31     #include <tod.h>
32    
33     #ifndef WIN32 /* ---win32 exclude header */
34     #include <stdio.h>
35     #include <sys/types.h>
36     #include <sys/time.h>
37     #endif /* win32 */
38    
39     /*
40     * Gloabal variables:
41     */
42     long max_time = MAX_TIME;
43     struct timeval last_time;
44    
45     #define PBUFLEN 100
46     long process_utime_save[PBUFLEN];
47     long psaveind;
48     long process_max_utime = 0;
49     long process_min_utime = 999999999;
50     long process_tot_mtime;
51     long pticks;
52     long process_utime_long_count;
53    
54     const char *season_name[] =
55     {
56     "The Season of New Year",
57     "The Season of Growth",
58     "The Season of Harvest",
59     "The Season of Decay",
60     "The Season of the Blizzard",
61     "\n"
62     };
63    
64     const char *weekdays[DAYS_PER_WEEK] = {
65     "the Day of the Moon",
66     "the Day of the Bull",
67     "the Day of the Deception",
68     "the Day of Thunder",
69     "the Day of Freedom",
70     "the Day of the Great Gods",
71     "the Day of the Sun"
72     };
73    
74     const char *month_name[MONTHS_PER_YEAR] = {
75     "Month of Winter", /* 0 */
76     "Month of the Ice Dragon",
77     "Month of the Frost Giant",
78     "Month of Valriel",
79     "Month of Lythander",
80     "Month of the Harvest",
81     "Month of Gaea",
82     "Month of Futility",
83     "Month of the Dragon",
84     "Month of the Sun",
85     "Month of the Great Infernus",
86     "Month of Ruggilli",
87     "Month of the Dark Shades",
88     "Month of the Devourers",
89     "Month of Sorig",
90     "Month of the Ancient Darkness",
91     "Month of Gorokh"
92     };
93    
94     /*
95     * Initialise all variables used in the timing routines.
96     */
97    
98     void
99     reset_sleep(void)
100     {
101     int i;
102     for(i = 0; i < PBUFLEN; i++)
103     process_utime_save[i] = 0;
104     psaveind = 0;
105     process_max_utime = 0;
106     process_min_utime = 999999999;
107     process_tot_mtime = 0;
108     pticks = 0;
109    
110     (void) GETTIMEOFDAY(&last_time);
111     }
112    
113     void
114     log_time(long process_utime)
115     {
116     pticks++;
117     if (++psaveind >= PBUFLEN)
118     psaveind = 0;
119     process_utime_save[psaveind] = process_utime;
120     if (process_utime > process_max_utime)
121     process_max_utime = process_utime;
122     if (process_utime < process_min_utime)
123     process_min_utime = process_utime;
124     process_tot_mtime += process_utime/1000;
125     }
126    
127     /*
128     * enough_elapsed_time will return true if the time passed since
129     * last tick is more than max-time.
130     */
131    
132     int
133     enough_elapsed_time(void)
134     {
135     static struct timeval new_time;
136     long elapsed_utime;
137    
138     (void) GETTIMEOFDAY(&new_time);
139    
140     elapsed_utime = (new_time.tv_sec - last_time.tv_sec) * 1000000 +
141     new_time.tv_usec - last_time.tv_usec;
142     if (elapsed_utime > max_time) {
143     log_time(elapsed_utime);
144     last_time.tv_sec = new_time.tv_sec;
145     last_time.tv_usec = new_time.tv_usec;
146     return 1;
147     }
148     return 0;
149     }
150    
151     /*
152     * sleep_delta checks how much time has elapsed since last tick.
153     * If it is less than max_time, the remaining time is slept with select().
154     */
155    
156     void
157     sleep_delta(void)
158     {
159     static struct timeval new_time;
160     long sleep_sec, sleep_usec;
161    
162     (void) GETTIMEOFDAY(&new_time);
163    
164     sleep_sec = last_time.tv_sec - new_time.tv_sec;
165     sleep_usec = max_time - (new_time.tv_usec - last_time.tv_usec);
166    
167     /* This is very ugly, but probably the fastest for our use: */
168     while (sleep_usec < 0) {
169     sleep_usec += 1000000;
170     sleep_sec -= 1;
171     }
172     while (sleep_usec > 1000000) {
173     sleep_usec -= 1000000;
174     sleep_sec +=1;
175     }
176    
177     log_time((new_time.tv_sec - last_time.tv_sec)*1000000
178     + new_time.tv_usec - last_time.tv_usec);
179    
180     if (sleep_sec >= 0 && sleep_usec > 0) {
181     static struct timeval sleep_time;
182     sleep_time.tv_sec = sleep_sec;
183     sleep_time.tv_usec = sleep_usec;
184    
185     #ifndef WIN32 /* 'select' doesn't work on Windows, 'Sleep' is used instead */
186     select(0, NULL, NULL, NULL, &sleep_time);
187     #else
188     if (sleep_time.tv_sec) Sleep(sleep_time.tv_sec*1000);
189     Sleep((int)(sleep_time.tv_usec/1000.));
190     #endif
191     }
192     else
193     process_utime_long_count++;
194     /*
195     * Set last_time to when we're expected to wake up:
196     */
197     last_time.tv_usec += max_time;
198     while (last_time.tv_usec > 1000000) {
199     last_time.tv_usec -= 1000000;
200     last_time.tv_sec++;
201     }
202     /*
203     * Don't do too much catching up:
204     * (Things can still get jerky on a slow/loaded computer)
205     */
206     if (last_time.tv_sec * 1000000 + last_time.tv_usec <
207     new_time.tv_sec * 1000000 + new_time.tv_usec)
208     {
209     last_time.tv_sec = new_time.tv_sec;
210     last_time.tv_usec = new_time.tv_usec;
211     }
212     }
213    
214     void
215     set_max_time(long t) {
216     max_time = t;
217     }
218    
219     extern unsigned long todtick;
220    
221     void
222     get_tod(timeofday_t *tod)
223     {
224     tod->year = todtick/HOURS_PER_YEAR;
225     tod->month = (todtick/HOURS_PER_MONTH)%MONTHS_PER_YEAR;
226     tod->day = (todtick%HOURS_PER_MONTH)/DAYS_PER_MONTH;
227     tod->dayofweek = tod->day%DAYS_PER_WEEK;
228     tod->hour = todtick%HOURS_PER_DAY;
229     tod->minute = (pticks%PTICKS_PER_CLOCK)/(PTICKS_PER_CLOCK/58);
230     if (tod->minute > 58)
231     tod->minute = 58; /* it's imprecise at best anyhow */
232     tod->weekofmonth = tod->day/WEEKS_PER_MONTH;
233     if (tod->month < 3)
234     tod->season = 0;
235     else if (tod->month < 6)
236     tod->season = 1;
237     else if (tod->month < 9)
238     tod->season = 2;
239     else if (tod->month < 12)
240     tod->season = 3;
241     else
242     tod->season = 4;
243     }
244    
245     void
246     print_tod(object *op)
247     {
248     timeofday_t tod;
249     const char *suf;
250     int day;
251    
252     get_tod(&tod);
253     sprintf(errmsg, "It is %d minute%s past %d o'clock %s, on %s",
254     tod.minute+1, ((tod.minute+1 < 2) ? "" : "s"),
255     ((tod.hour % 14 == 0) ? 14 : ((tod.hour)%14)),
256     ((tod.hour >= 14) ? "pm" : "am"),
257     weekdays[tod.dayofweek]);
258     new_draw_info(NDI_UNIQUE, 0,op,errmsg);
259    
260     day = tod.day + 1;
261     if (day == 1 || ((day % 10) == 1 && day > 20))
262     suf = "st";
263     else if (day == 2 || ((day % 10) == 2 && day > 20))
264     suf = "nd";
265     else if (day == 3 || ((day % 10) == 3 && day > 20))
266     suf = "rd";
267     else
268     suf = "th";
269     sprintf(errmsg, "The %d%s Day of the %s, Year %d", day, suf,
270     month_name[tod.month], tod.year+1);
271     new_draw_info(NDI_UNIQUE, 0,op,errmsg);
272    
273     sprintf(errmsg, "Time of Year: %s", season_name[tod.season]);
274     new_draw_info(NDI_UNIQUE, 0,op,errmsg);
275     }
276    
277     void
278     time_info(object *op)
279     {
280     int tot = 0, maxt = 0, mint = 99999999, long_count = 0, i;
281    
282     print_tod(op);
283     if (!QUERY_FLAG(op,FLAG_WIZ))
284     return;
285    
286     new_draw_info (NDI_UNIQUE, 0,op,"Total time:");
287     sprintf(errmsg,"ticks=%ld time=%ld.%2ld",
288     pticks, process_tot_mtime/1000, process_tot_mtime%1000);
289     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
290     sprintf(errmsg,"avg time=%ldms max time=%ldms min time=%ldms",
291     process_tot_mtime/pticks, process_max_utime/1000,
292     process_min_utime/1000);
293     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
294     sprintf(errmsg,"ticks longer than max time (%ldms) = %ld (%ld%%)",
295     max_time/1000,
296     process_utime_long_count, 100*process_utime_long_count/pticks);
297     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
298    
299     sprintf(errmsg,"Time last %ld ticks:", pticks > PBUFLEN ? PBUFLEN : pticks);
300     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
301    
302     for (i = 0; i < (pticks > PBUFLEN ? PBUFLEN : pticks); i++) {
303     tot += process_utime_save[i];
304     if (process_utime_save[i] > maxt) maxt = process_utime_save[i];
305     if (process_utime_save[i] < mint) mint = process_utime_save[i];
306     if (process_utime_save[i] > max_time) long_count++;
307     }
308    
309     sprintf(errmsg,"avg time=%ldms max time=%dms min time=%dms",
310     tot/(pticks > PBUFLEN ? PBUFLEN : pticks)/1000, maxt/1000,
311     mint/1000);
312     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
313     sprintf(errmsg,"ticks longer than max time (%ldms) = %d (%ld%%)",
314     max_time/1000, long_count,
315     100*long_count/(pticks > PBUFLEN ? PBUFLEN : pticks));
316     new_draw_info (NDI_UNIQUE, 0,op,errmsg);
317     }
318    
319     long
320     seconds(void)
321     {
322     struct timeval now;
323    
324     (void) GETTIMEOFDAY(&now);
325     return now.tv_sec;
326     }