blob: 89d889c7c43bf0dc519b705eea55751f4f5ff7ae [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
38#endif
39
Guido van Rossum6d946f91992-08-14 13:49:30 +000040#ifdef macintosh
41#define NO_UNISTD
42#endif
43
Guido van Rossum2762f251992-03-27 17:22:13 +000044#ifndef NO_UNISTD
45#include <unistd.h>
46#endif
47
Guido van Rossum80c9d881991-04-16 08:47:51 +000048/* What happens here is not trivial.
49 The BSD_TIME code needs <sys/time.h> (for struct timeval).
50 The rest of the code needs only time_t, except some MS-DOS
51 code which needs clock_t as well.
52 Standard C says that time_t is defined in <time.h>, and
53 does not have <sys/types.h>; THINK C agrees (MS-DOS too?).
54 What's worse, in pure 4.3 BSD, older SunOS versions, and
55 probably everything derived from BSD, you can't #include
56 both <time.h> and <sys/time.h> in the same file, since
57 <sys/time.h> includes <time.h> without any protection,
58 and <time.h> contains a typedef, which can't be parsed twice!
59 So on traditional UNIX systems we include <sys/types.h>
60 and <sys/time.h> and hope this implies <time.h> and time_t,
61 while on other systems, including conforming Standard C
62 systems (where 'unix' can't be defined), we rely on <time.h>.
63 Still one problem: BSD_TIME won't work with strict Standard C...
64*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065
Guido van Rossum80c9d881991-04-16 08:47:51 +000066#ifdef unix
67#include <sys/types.h>
68#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
69#else /* !unix */
70#include <time.h>
71#endif /* !unix */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000072
Guido van Rossum27aaa6d1992-03-12 17:33:14 +000073#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 Rossuma2b7f401993-01-04 09:09:59 +000086#ifdef HAVE_GETTIMEOFDAY
87 struct timeval t;
88 struct timezone tz;
89 if (!getnoarg(args))
90 return NULL;
91 if (gettimeofday(&t, &tz) != 0) {
92 err_errno(IOError);
93 return NULL;
94 }
95 return newfloatobject(t.tv_sec*1.0 + t.tv_usec*0.000001);
96#else /* !HAVE_GETTIMEOFDAY */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000097 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098 if (!getnoarg(args))
99 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000100 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +0000101#ifdef macintosh
102/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
103/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000104#define TIMEDIFF ((time_t) \
105 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
106 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +0000107#endif
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000108 return newfloatobject((double)secs);
109#endif /* !HAVE_GETTIMEOFDAY */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110}
111
112static jmp_buf sleep_intr;
113
Guido van Rossum2762f251992-03-27 17:22:13 +0000114/* ARGSUSED */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115static void
116sleep_catcher(sig)
Guido van Rossum2762f251992-03-27 17:22:13 +0000117 int sig; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118{
119 longjmp(sleep_intr, 1);
120}
121
122static object *
123time_sleep(self, args)
124 object *self;
125 object *args;
126{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000127 double secs;
Guido van Rossum2762f251992-03-27 17:22:13 +0000128 SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
Guido van Rossum775f4da1993-01-09 17:18:52 +0000129 if (!getargs(args, "d", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000130 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000131 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000133 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134 signal(SIGINT, sigsave);
135 err_set(KeyboardInterrupt);
136 return NULL;
137 }
138 sigsave = signal(SIGINT, SIG_IGN);
139 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
140 signal(SIGINT, sleep_catcher);
Guido van Rossum775f4da1993-01-09 17:18:52 +0000141 floatsleep(secs);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000142 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143 signal(SIGINT, sigsave);
144 INCREF(None);
145 return None;
146}
147
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000148#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000150#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151
152#ifdef AMOEBA
153#define DO_MILLI
154extern long sys_milli();
155#define millitimer sys_milli
156#endif /* AMOEBA */
157
Guido van Rossum426035c1991-02-19 12:27:35 +0000158#ifdef BSD_TIME
159#define DO_MILLI
160#endif /* BSD_TIME */
161
Guido van Rossum80c9d881991-04-16 08:47:51 +0000162#ifdef TURBO_C
163#define DO_MILLI
164#endif
165
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166#ifdef DO_MILLI
167
168static object *
169time_millisleep(self, args)
170 object *self;
171 object *args;
172{
173 long msecs;
174 SIGTYPE (*sigsave)();
175 if (!getlongarg(args, &msecs))
176 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000177 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000179 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180 signal(SIGINT, sigsave);
181 err_set(KeyboardInterrupt);
182 return NULL;
183 }
184 sigsave = signal(SIGINT, SIG_IGN);
185 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
186 signal(SIGINT, sleep_catcher);
Guido van Rossum775f4da1993-01-09 17:18:52 +0000187 floatsleep(msecs / 1000.0);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000188 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189 signal(SIGINT, sigsave);
190 INCREF(None);
191 return None;
192}
193
194static object *
195time_millitimer(self, args)
196 object *self;
197 object *args;
198{
199 long msecs;
200 extern long millitimer();
201 if (!getnoarg(args))
202 return NULL;
203 msecs = millitimer();
204 return newintobject(msecs);
205}
206
207#endif /* DO_MILLI */
208
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000209#ifdef DO_TIMES
210
211static object *
212time_times(self, args)
213 object *self;
214 object *args;
215{
216 struct tms t;
217 clock_t c;
218 object *tuple;
Guido van Rossum2762f251992-03-27 17:22:13 +0000219 if (!getnoarg(args))
220 return NULL;
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000221 errno = 0;
222 c = times(&t);
223 if (c == (clock_t) -1) {
224 err_errno(IOError);
225 return NULL;
226 }
227 tuple = newtupleobject(4);
228 if (tuple == NULL)
229 return NULL;
230 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
231 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
232 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
233 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
234 if (err_occurred()) {
235 DECREF(tuple);
236 return NULL;
237 }
238 return tuple;
239}
240
241#endif
242
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243
244static struct methodlist time_methods[] = {
245#ifdef DO_MILLI
246 {"millisleep", time_millisleep},
247 {"millitimer", time_millitimer},
248#endif /* DO_MILLI */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000249#ifdef DO_TIMES
250 {"times", time_times},
251#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000252 {"sleep", time_sleep},
253 {"time", time_time},
254 {NULL, NULL} /* sentinel */
255};
256
257
258void
259inittime()
260{
261 initmodule("time", time_methods);
262}
263
264
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000265#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266
267#define MacTicks (* (long *)0x16A)
268
Guido van Rossum80c9d881991-04-16 08:47:51 +0000269#ifdef THINK_C_3_0
Guido van Rossumff4949e1992-08-05 19:58:53 +0000270sleep(secs)
271 int secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000272{
273 register long deadline;
274
Guido van Rossumff4949e1992-08-05 19:58:53 +0000275 deadline = MacTicks + mecs * 60;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276 while (MacTicks < deadline) {
277 if (intrcheck())
278 sleep_catcher(SIGINT);
279 }
280}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000281#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000282
Guido van Rossum775f4da1993-01-09 17:18:52 +0000283floatsleep(secs)
284 double secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000285{
286 register long deadline;
287
Guido van Rossum775f4da1993-01-09 17:18:52 +0000288 deadline = MacTicks + long(secs * 60.0);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289 while (MacTicks < deadline) {
290 if (intrcheck())
291 sleep_catcher(SIGINT);
292 }
293}
294
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000295long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296millitimer()
297{
298 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
299}
300
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000301#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000302
303
304#ifdef BSD_TIME
305
Guido van Rossumed233a51992-06-23 09:07:03 +0000306#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000307
Guido van Rossum56627461991-04-03 19:15:32 +0000308long
Guido van Rossum426035c1991-02-19 12:27:35 +0000309millitimer()
310{
311 struct timeval t;
312 struct timezone tz;
313 if (gettimeofday(&t, &tz) != 0)
314 return -1;
315 return t.tv_sec*1000 + t.tv_usec/1000;
Guido van Rossum426035c1991-02-19 12:27:35 +0000316}
317
Guido van Rossum775f4da1993-01-09 17:18:52 +0000318floatsleep(secs)
319 double secs;
Guido van Rossum426035c1991-02-19 12:27:35 +0000320{
321 struct timeval t;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000322 double frac;
323 extern double fmod PROTO((double, double));
324 extern double floor PROTO((double));
325 frac = fmod(secs, 1.0);
326 secs = floor(secs);
327 t.tv_sec = (long)secs;
328 t.tv_usec = (long)(frac*1000000.0);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000329 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
330}
331
Guido van Rossum426035c1991-02-19 12:27:35 +0000332#endif /* BSD_TIME */
333
Guido van Rossum80c9d881991-04-16 08:47:51 +0000334
335#ifdef TURBO_C /* Maybe also for MS-DOS? */
336
337#ifndef CLOCKS_PER_SEC
338#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
339#endif
340
341static
Guido van Rossum775f4da1993-01-09 17:18:52 +0000342floatsleep(secs)
343 double secs;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000344{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000345 delay(long(secs/1000.0));
Guido van Rossum80c9d881991-04-16 08:47:51 +0000346}
347
348static long
349millitimer()
350{
351 clock_t ticks;
352
353 ticks = clock(); /* ticks since program start */
Guido van Rossum775f4da1993-01-09 17:18:52 +0000354 return ticks * CLOCKS_PER_SEC;/* XXX shouldn't this be different? */
Guido van Rossum80c9d881991-04-16 08:47:51 +0000355}
356
357#endif /* TURBO_C */