blob: f886691b7ff2214e4d2171ee0cf00114f5d25dc5 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Time module */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
28
29#include "modsupport.h"
30
31#include "sigtype.h"
32
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033#include <signal.h>
34#include <setjmp.h>
35
Guido van Rossum2762f251992-03-27 17:22:13 +000036#ifndef NO_UNISTD
37#include <unistd.h>
38#endif
39
Guido van Rossum80c9d881991-04-16 08:47:51 +000040/* What happens here is not trivial.
41 The BSD_TIME code needs <sys/time.h> (for struct timeval).
42 The rest of the code needs only time_t, except some MS-DOS
43 code which needs clock_t as well.
44 Standard C says that time_t is defined in <time.h>, and
45 does not have <sys/types.h>; THINK C agrees (MS-DOS too?).
46 What's worse, in pure 4.3 BSD, older SunOS versions, and
47 probably everything derived from BSD, you can't #include
48 both <time.h> and <sys/time.h> in the same file, since
49 <sys/time.h> includes <time.h> without any protection,
50 and <time.h> contains a typedef, which can't be parsed twice!
51 So on traditional UNIX systems we include <sys/types.h>
52 and <sys/time.h> and hope this implies <time.h> and time_t,
53 while on other systems, including conforming Standard C
54 systems (where 'unix' can't be defined), we rely on <time.h>.
55 Still one problem: BSD_TIME won't work with strict Standard C...
56*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057
Guido van Rossum80c9d881991-04-16 08:47:51 +000058#ifdef unix
59#include <sys/types.h>
60#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
61#else /* !unix */
62#include <time.h>
63#endif /* !unix */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000064
Guido van Rossum27aaa6d1992-03-12 17:33:14 +000065#ifdef sgi
66#define DO_TIMES
67#endif
68
69#ifdef sun
70#define DO_TIMES
71#endif
72
73#ifdef DO_TIMES
74#include <sys/times.h>
75#include <sys/param.h>
76#include <errno.h>
77#endif
78
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079/* Time methods */
80
81static object *
82time_time(self, args)
83 object *self;
84 object *args;
85{
Guido van Rossum6590d4a1991-04-04 10:49:03 +000086 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087 if (!getnoarg(args))
88 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +000089 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +000090#ifdef macintosh
91/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
92/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000093#define TIMEDIFF ((time_t) \
94 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
95 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +000096#endif
Guido van Rossum6590d4a1991-04-04 10:49:03 +000097 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098}
99
100static jmp_buf sleep_intr;
101
Guido van Rossum2762f251992-03-27 17:22:13 +0000102/* ARGSUSED */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103static void
104sleep_catcher(sig)
Guido van Rossum2762f251992-03-27 17:22:13 +0000105 int sig; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106{
107 longjmp(sleep_intr, 1);
108}
109
110static object *
111time_sleep(self, args)
112 object *self;
113 object *args;
114{
115 int secs;
Guido van Rossum2762f251992-03-27 17:22:13 +0000116 SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117 if (!getintarg(args, &secs))
118 return NULL;
119 if (setjmp(sleep_intr)) {
120 signal(SIGINT, sigsave);
121 err_set(KeyboardInterrupt);
122 return NULL;
123 }
124 sigsave = signal(SIGINT, SIG_IGN);
125 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
126 signal(SIGINT, sleep_catcher);
127 sleep(secs);
128 signal(SIGINT, sigsave);
129 INCREF(None);
130 return None;
131}
132
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000133#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000135#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136
137#ifdef AMOEBA
138#define DO_MILLI
139extern long sys_milli();
140#define millitimer sys_milli
141#endif /* AMOEBA */
142
Guido van Rossum426035c1991-02-19 12:27:35 +0000143#ifdef BSD_TIME
144#define DO_MILLI
145#endif /* BSD_TIME */
146
Guido van Rossum80c9d881991-04-16 08:47:51 +0000147#ifdef TURBO_C
148#define DO_MILLI
149#endif
150
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151#ifdef DO_MILLI
152
153static object *
154time_millisleep(self, args)
155 object *self;
156 object *args;
157{
158 long msecs;
159 SIGTYPE (*sigsave)();
160 if (!getlongarg(args, &msecs))
161 return NULL;
162 if (setjmp(sleep_intr)) {
163 signal(SIGINT, sigsave);
164 err_set(KeyboardInterrupt);
165 return NULL;
166 }
167 sigsave = signal(SIGINT, SIG_IGN);
168 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
169 signal(SIGINT, sleep_catcher);
170 millisleep(msecs);
171 signal(SIGINT, sigsave);
172 INCREF(None);
173 return None;
174}
175
176static object *
177time_millitimer(self, args)
178 object *self;
179 object *args;
180{
181 long msecs;
182 extern long millitimer();
183 if (!getnoarg(args))
184 return NULL;
185 msecs = millitimer();
186 return newintobject(msecs);
187}
188
189#endif /* DO_MILLI */
190
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000191#ifdef DO_TIMES
192
193static object *
194time_times(self, args)
195 object *self;
196 object *args;
197{
198 struct tms t;
199 clock_t c;
200 object *tuple;
Guido van Rossum2762f251992-03-27 17:22:13 +0000201 if (!getnoarg(args))
202 return NULL;
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000203 errno = 0;
204 c = times(&t);
205 if (c == (clock_t) -1) {
206 err_errno(IOError);
207 return NULL;
208 }
209 tuple = newtupleobject(4);
210 if (tuple == NULL)
211 return NULL;
212 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
213 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
214 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
215 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
216 if (err_occurred()) {
217 DECREF(tuple);
218 return NULL;
219 }
220 return tuple;
221}
222
223#endif
224
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225
226static struct methodlist time_methods[] = {
227#ifdef DO_MILLI
228 {"millisleep", time_millisleep},
229 {"millitimer", time_millitimer},
230#endif /* DO_MILLI */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000231#ifdef DO_TIMES
232 {"times", time_times},
233#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234 {"sleep", time_sleep},
235 {"time", time_time},
236 {NULL, NULL} /* sentinel */
237};
238
239
240void
241inittime()
242{
243 initmodule("time", time_methods);
244}
245
246
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000247#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
249#define MacTicks (* (long *)0x16A)
250
Guido van Rossum80c9d881991-04-16 08:47:51 +0000251#ifdef THINK_C_3_0
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252sleep(msecs)
253 int msecs;
254{
255 register long deadline;
256
257 deadline = MacTicks + msecs * 60;
258 while (MacTicks < deadline) {
259 if (intrcheck())
260 sleep_catcher(SIGINT);
261 }
262}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000263#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000265millisleep(msecs)
266 long msecs;
267{
268 register long deadline;
269
270 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
271 while (MacTicks < deadline) {
272 if (intrcheck())
273 sleep_catcher(SIGINT);
274 }
275}
276
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000277long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278millitimer()
279{
280 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
281}
282
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000283#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000284
285
286#ifdef BSD_TIME
287
Guido van Rossum0bb1a511991-11-27 14:55:18 +0000288#ifdef _AIX /* I *think* this works */
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000289/* AIX defines fd_set in a separate file. Sigh... */
290#include <sys/select.h>
291#endif
292
Guido van Rossum56627461991-04-03 19:15:32 +0000293long
Guido van Rossum426035c1991-02-19 12:27:35 +0000294millitimer()
295{
296 struct timeval t;
297 struct timezone tz;
298 if (gettimeofday(&t, &tz) != 0)
299 return -1;
300 return t.tv_sec*1000 + t.tv_usec/1000;
301
302}
303
Guido van Rossum426035c1991-02-19 12:27:35 +0000304millisleep(msecs)
305 long msecs;
306{
307 struct timeval t;
308 t.tv_sec = msecs/1000;
309 t.tv_usec = (msecs%1000)*1000;
310 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
311}
312
313#endif /* BSD_TIME */
314
Guido van Rossum80c9d881991-04-16 08:47:51 +0000315
316#ifdef TURBO_C /* Maybe also for MS-DOS? */
317
318#ifndef CLOCKS_PER_SEC
319#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
320#endif
321
322static
323millisleep(msecs)
324 long msecs;
325{
326 delay(msecs);
327}
328
329static long
330millitimer()
331{
332 clock_t ticks;
333
334 ticks = clock(); /* ticks since program start */
335 return ticks * CLOCKS_PER_SEC;
336}
337
338#endif /* TURBO_C */