blob: 4d13611b5e0a41803a4bc592af23fd946fac70eb [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumf1644a51992-04-05 14:25:41 +00002Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
Guido van Rossumf70e43a1991-02-19 12:39:46 +00003Netherlands.
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"
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 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 DO_TIMES
66#include <sys/times.h>
67#include <sys/param.h>
68#include <errno.h>
69#endif
70
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000071/* Time methods */
72
73static object *
74time_time(self, args)
75 object *self;
76 object *args;
77{
Guido van Rossum6590d4a1991-04-04 10:49:03 +000078 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079 if (!getnoarg(args))
80 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +000081 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +000082#ifdef macintosh
83/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
84/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000085#define TIMEDIFF ((time_t) \
86 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
87 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +000088#endif
Guido van Rossum6590d4a1991-04-04 10:49:03 +000089 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000090}
91
92static jmp_buf sleep_intr;
93
Guido van Rossum2762f251992-03-27 17:22:13 +000094/* ARGSUSED */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095static void
96sleep_catcher(sig)
Guido van Rossum2762f251992-03-27 17:22:13 +000097 int sig; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000098{
99 longjmp(sleep_intr, 1);
100}
101
102static object *
103time_sleep(self, args)
104 object *self;
105 object *args;
106{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000107 long secs;
Guido van Rossum2762f251992-03-27 17:22:13 +0000108 SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000109 if (!getargs(args, "l", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000111 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000113 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 signal(SIGINT, sigsave);
115 err_set(KeyboardInterrupt);
116 return NULL;
117 }
118 sigsave = signal(SIGINT, SIG_IGN);
119 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
120 signal(SIGINT, sleep_catcher);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000121#ifdef BSD_TIME
122 longsleep(secs);
123#else
124 sleep((int)secs);
125#endif
126 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127 signal(SIGINT, sigsave);
128 INCREF(None);
129 return None;
130}
131
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000132#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000134#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135
136#ifdef AMOEBA
137#define DO_MILLI
138extern long sys_milli();
139#define millitimer sys_milli
140#endif /* AMOEBA */
141
Guido van Rossum426035c1991-02-19 12:27:35 +0000142#ifdef BSD_TIME
143#define DO_MILLI
144#endif /* BSD_TIME */
145
Guido van Rossum80c9d881991-04-16 08:47:51 +0000146#ifdef TURBO_C
147#define DO_MILLI
148#endif
149
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150#ifdef DO_MILLI
151
152static object *
153time_millisleep(self, args)
154 object *self;
155 object *args;
156{
157 long msecs;
158 SIGTYPE (*sigsave)();
159 if (!getlongarg(args, &msecs))
160 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000161 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000163 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 signal(SIGINT, sigsave);
165 err_set(KeyboardInterrupt);
166 return NULL;
167 }
168 sigsave = signal(SIGINT, SIG_IGN);
169 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
170 signal(SIGINT, sleep_catcher);
171 millisleep(msecs);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000172 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 signal(SIGINT, sigsave);
174 INCREF(None);
175 return None;
176}
177
178static object *
179time_millitimer(self, args)
180 object *self;
181 object *args;
182{
183 long msecs;
184 extern long millitimer();
185 if (!getnoarg(args))
186 return NULL;
187 msecs = millitimer();
188 return newintobject(msecs);
189}
190
191#endif /* DO_MILLI */
192
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000193#ifdef DO_TIMES
194
195static object *
196time_times(self, args)
197 object *self;
198 object *args;
199{
200 struct tms t;
201 clock_t c;
202 object *tuple;
Guido van Rossum2762f251992-03-27 17:22:13 +0000203 if (!getnoarg(args))
204 return NULL;
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000205 errno = 0;
206 c = times(&t);
207 if (c == (clock_t) -1) {
208 err_errno(IOError);
209 return NULL;
210 }
211 tuple = newtupleobject(4);
212 if (tuple == NULL)
213 return NULL;
214 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
215 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
216 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
217 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
218 if (err_occurred()) {
219 DECREF(tuple);
220 return NULL;
221 }
222 return tuple;
223}
224
225#endif
226
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227
228static struct methodlist time_methods[] = {
229#ifdef DO_MILLI
230 {"millisleep", time_millisleep},
231 {"millitimer", time_millitimer},
232#endif /* DO_MILLI */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000233#ifdef DO_TIMES
234 {"times", time_times},
235#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 {"sleep", time_sleep},
237 {"time", time_time},
238 {NULL, NULL} /* sentinel */
239};
240
241
242void
243inittime()
244{
245 initmodule("time", time_methods);
246}
247
248
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000249#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
251#define MacTicks (* (long *)0x16A)
252
Guido van Rossum80c9d881991-04-16 08:47:51 +0000253#ifdef THINK_C_3_0
Guido van Rossumff4949e1992-08-05 19:58:53 +0000254sleep(secs)
255 int secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000256{
257 register long deadline;
258
Guido van Rossumff4949e1992-08-05 19:58:53 +0000259 deadline = MacTicks + mecs * 60;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260 while (MacTicks < deadline) {
261 if (intrcheck())
262 sleep_catcher(SIGINT);
263 }
264}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000265#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000266
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267millisleep(msecs)
268 long msecs;
269{
270 register long deadline;
271
272 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
273 while (MacTicks < deadline) {
274 if (intrcheck())
275 sleep_catcher(SIGINT);
276 }
277}
278
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000279long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000280millitimer()
281{
282 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
283}
284
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000285#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000286
287
288#ifdef BSD_TIME
289
Guido van Rossumed233a51992-06-23 09:07:03 +0000290#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000291
Guido van Rossum56627461991-04-03 19:15:32 +0000292long
Guido van Rossum426035c1991-02-19 12:27:35 +0000293millitimer()
294{
295 struct timeval t;
296 struct timezone tz;
297 if (gettimeofday(&t, &tz) != 0)
298 return -1;
299 return t.tv_sec*1000 + t.tv_usec/1000;
Guido van Rossum426035c1991-02-19 12:27:35 +0000300}
301
Guido van Rossum426035c1991-02-19 12:27:35 +0000302millisleep(msecs)
303 long msecs;
304{
305 struct timeval t;
306 t.tv_sec = msecs/1000;
307 t.tv_usec = (msecs%1000)*1000;
308 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
309}
310
Guido van Rossumff4949e1992-08-05 19:58:53 +0000311longsleep(secs)
312 long secs;
313{
314 struct timeval t;
315 t.tv_sec = secs;
316 t.tv_usec = 0;
317 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
318}
319
Guido van Rossum426035c1991-02-19 12:27:35 +0000320#endif /* BSD_TIME */
321
Guido van Rossum80c9d881991-04-16 08:47:51 +0000322
323#ifdef TURBO_C /* Maybe also for MS-DOS? */
324
325#ifndef CLOCKS_PER_SEC
326#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
327#endif
328
329static
330millisleep(msecs)
331 long msecs;
332{
333 delay(msecs);
334}
335
336static long
337millitimer()
338{
339 clock_t ticks;
340
341 ticks = clock(); /* ticks since program start */
342 return ticks * CLOCKS_PER_SEC;
343}
344
345#endif /* TURBO_C */