blob: b8b22e34c2e911424112554f3a3730175d2fa825 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum775f4da1993-01-09 17:18:52 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
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"
Guido van Rossum3f5da241990-12-20 15:06:42 +000028#include "modsupport.h"
Guido van Rossumff4949e1992-08-05 19:58:53 +000029#include "ceval.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000030
31#include "sigtype.h"
32
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033#include <signal.h>
34#include <setjmp.h>
35
Guido van Rossuma2b7f401993-01-04 09:09:59 +000036#ifdef BSD_TIME
37#define HAVE_GETTIMEOFDAY
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000038#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
Guido van Rossuma2b7f401993-01-04 09:09:59 +000039#endif
40
Guido van Rossum6d946f91992-08-14 13:49:30 +000041#ifdef macintosh
42#define NO_UNISTD
43#endif
44
Guido van Rossum2762f251992-03-27 17:22:13 +000045#ifndef NO_UNISTD
46#include <unistd.h>
47#endif
48
Guido van Rossum80c9d881991-04-16 08:47:51 +000049/* What happens here is not trivial.
50 The BSD_TIME code needs <sys/time.h> (for struct timeval).
51 The rest of the code needs only time_t, except some MS-DOS
52 code which needs clock_t as well.
53 Standard C says that time_t is defined in <time.h>, and
54 does not have <sys/types.h>; THINK C agrees (MS-DOS too?).
55 What's worse, in pure 4.3 BSD, older SunOS versions, and
56 probably everything derived from BSD, you can't #include
57 both <time.h> and <sys/time.h> in the same file, since
58 <sys/time.h> includes <time.h> without any protection,
59 and <time.h> contains a typedef, which can't be parsed twice!
60 So on traditional UNIX systems we include <sys/types.h>
61 and <sys/time.h> and hope this implies <time.h> and time_t,
62 while on other systems, including conforming Standard C
63 systems (where 'unix' can't be defined), we rely on <time.h>.
64 Still one problem: BSD_TIME won't work with strict Standard C...
65*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossum80c9d881991-04-16 08:47:51 +000067#ifdef unix
68#include <sys/types.h>
69#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
70#else /* !unix */
71#include <time.h>
72#endif /* !unix */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073
Guido van Rossum0b0db8e1993-01-21 16:07:51 +000074/* XXX This is bogus -- times() is defined in posixmodule.c */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +000075#ifdef DO_TIMES
76#include <sys/times.h>
77#include <sys/param.h>
78#include <errno.h>
79#endif
80
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081/* Time methods */
82
83static object *
84time_time(self, args)
85 object *self;
86 object *args;
87{
Guido van Rossuma2b7f401993-01-04 09:09:59 +000088#ifdef HAVE_GETTIMEOFDAY
89 struct timeval t;
90 struct timezone tz;
91 if (!getnoarg(args))
92 return NULL;
93 if (gettimeofday(&t, &tz) != 0) {
94 err_errno(IOError);
95 return NULL;
96 }
97 return newfloatobject(t.tv_sec*1.0 + t.tv_usec*0.000001);
98#else /* !HAVE_GETTIMEOFDAY */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000099 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 if (!getnoarg(args))
101 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000102 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +0000103#ifdef macintosh
104/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
105/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000106#define TIMEDIFF ((time_t) \
107 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
108 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +0000109#endif
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000110 return newfloatobject((double)secs);
111#endif /* !HAVE_GETTIMEOFDAY */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112}
113
114static jmp_buf sleep_intr;
115
Guido van Rossum2762f251992-03-27 17:22:13 +0000116/* ARGSUSED */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117static void
118sleep_catcher(sig)
Guido van Rossum2762f251992-03-27 17:22:13 +0000119 int sig; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120{
121 longjmp(sleep_intr, 1);
122}
123
124static object *
125time_sleep(self, args)
126 object *self;
127 object *args;
128{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000129 double secs;
Guido van Rossum2762f251992-03-27 17:22:13 +0000130 SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
Guido van Rossum775f4da1993-01-09 17:18:52 +0000131 if (!getargs(args, "d", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000133 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000135 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000136 signal(SIGINT, sigsave);
137 err_set(KeyboardInterrupt);
138 return NULL;
139 }
140 sigsave = signal(SIGINT, SIG_IGN);
141 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
142 signal(SIGINT, sleep_catcher);
Guido van Rossum775f4da1993-01-09 17:18:52 +0000143 floatsleep(secs);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000144 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145 signal(SIGINT, sigsave);
146 INCREF(None);
147 return None;
148}
149
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000150#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000152#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153
154#ifdef AMOEBA
155#define DO_MILLI
156extern long sys_milli();
157#define millitimer sys_milli
158#endif /* AMOEBA */
159
Guido van Rossum426035c1991-02-19 12:27:35 +0000160#ifdef BSD_TIME
161#define DO_MILLI
162#endif /* BSD_TIME */
163
Guido van Rossum80c9d881991-04-16 08:47:51 +0000164#ifdef TURBO_C
165#define DO_MILLI
166#endif
167
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168#ifdef DO_MILLI
169
170static object *
171time_millisleep(self, args)
172 object *self;
173 object *args;
174{
175 long msecs;
176 SIGTYPE (*sigsave)();
177 if (!getlongarg(args, &msecs))
178 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000181 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000182 signal(SIGINT, sigsave);
183 err_set(KeyboardInterrupt);
184 return NULL;
185 }
186 sigsave = signal(SIGINT, SIG_IGN);
187 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
188 signal(SIGINT, sleep_catcher);
Guido van Rossum775f4da1993-01-09 17:18:52 +0000189 floatsleep(msecs / 1000.0);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000190 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 signal(SIGINT, sigsave);
192 INCREF(None);
193 return None;
194}
195
196static object *
197time_millitimer(self, args)
198 object *self;
199 object *args;
200{
201 long msecs;
202 extern long millitimer();
203 if (!getnoarg(args))
204 return NULL;
205 msecs = millitimer();
206 return newintobject(msecs);
207}
208
209#endif /* DO_MILLI */
210
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000211#ifdef DO_TIMES
212
213static object *
214time_times(self, args)
215 object *self;
216 object *args;
217{
218 struct tms t;
219 clock_t c;
Guido van Rossum2762f251992-03-27 17:22:13 +0000220 if (!getnoarg(args))
221 return NULL;
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000222 errno = 0;
223 c = times(&t);
224 if (c == (clock_t) -1) {
225 err_errno(IOError);
226 return NULL;
227 }
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000228 return mkvalue("dddd",
229 (double)t.tms_utime / HZ,
230 (double)t.tms_stime / HZ,
231 (double)t.tms_cutime / HZ,
232 (double)t.tms_cstime / HZ);
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000233}
234
235#endif
236
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237
238static struct methodlist time_methods[] = {
239#ifdef DO_MILLI
240 {"millisleep", time_millisleep},
241 {"millitimer", time_millitimer},
242#endif /* DO_MILLI */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000243#ifdef DO_TIMES
244 {"times", time_times},
245#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000246 {"sleep", time_sleep},
247 {"time", time_time},
248 {NULL, NULL} /* sentinel */
249};
250
251
252void
253inittime()
254{
255 initmodule("time", time_methods);
256}
257
258
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000259#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260
261#define MacTicks (* (long *)0x16A)
262
Guido van Rossum80c9d881991-04-16 08:47:51 +0000263#ifdef THINK_C_3_0
Guido van Rossumff4949e1992-08-05 19:58:53 +0000264sleep(secs)
265 int secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266{
267 register long deadline;
268
Guido van Rossumff4949e1992-08-05 19:58:53 +0000269 deadline = MacTicks + mecs * 60;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 while (MacTicks < deadline) {
271 if (intrcheck())
272 sleep_catcher(SIGINT);
273 }
274}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000275#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276
Guido van Rossum775f4da1993-01-09 17:18:52 +0000277floatsleep(secs)
278 double secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279{
280 register long deadline;
281
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000282 deadline = MacTicks + (long)(secs * 60.0);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283 while (MacTicks < deadline) {
284 if (intrcheck())
285 sleep_catcher(SIGINT);
286 }
287}
288
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000289long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290millitimer()
291{
292 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
293}
294
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000295#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000296
297
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000298#ifdef unix
Guido van Rossum426035c1991-02-19 12:27:35 +0000299
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000300#ifdef BSD_TIME
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000301
Guido van Rossum56627461991-04-03 19:15:32 +0000302long
Guido van Rossum426035c1991-02-19 12:27:35 +0000303millitimer()
304{
305 struct timeval t;
306 struct timezone tz;
307 if (gettimeofday(&t, &tz) != 0)
308 return -1;
309 return t.tv_sec*1000 + t.tv_usec/1000;
Guido van Rossum426035c1991-02-19 12:27:35 +0000310}
311
Guido van Rossum775f4da1993-01-09 17:18:52 +0000312floatsleep(secs)
313 double secs;
Guido van Rossum426035c1991-02-19 12:27:35 +0000314{
315 struct timeval t;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000316 double frac;
317 extern double fmod PROTO((double, double));
318 extern double floor PROTO((double));
319 frac = fmod(secs, 1.0);
320 secs = floor(secs);
321 t.tv_sec = (long)secs;
322 t.tv_usec = (long)(frac*1000000.0);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000323 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
324}
325
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000326#else /* !BSD_TIME */
327
328floatsleep(secs)
329 double secs;
330{
331 sleep((int)secs);
332}
333
334#endif /* !BSD_TIME */
335
336#endif /* unix */
Guido van Rossum426035c1991-02-19 12:27:35 +0000337
Guido van Rossum80c9d881991-04-16 08:47:51 +0000338
339#ifdef TURBO_C /* Maybe also for MS-DOS? */
340
341#ifndef CLOCKS_PER_SEC
342#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
343#endif
344
Guido van Rossum775f4da1993-01-09 17:18:52 +0000345floatsleep(secs)
346 double secs;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000347{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000348 delay(long(secs/1000.0));
Guido van Rossum80c9d881991-04-16 08:47:51 +0000349}
350
Guido van Rossum0b0db8e1993-01-21 16:07:51 +0000351long
Guido van Rossum80c9d881991-04-16 08:47:51 +0000352millitimer()
353{
354 clock_t ticks;
355
356 ticks = clock(); /* ticks since program start */
Guido van Rossum775f4da1993-01-09 17:18:52 +0000357 return ticks * CLOCKS_PER_SEC;/* XXX shouldn't this be different? */
Guido van Rossum80c9d881991-04-16 08:47:51 +0000358}
359
360#endif /* TURBO_C */