blob: 69a0c888238c976e44ac681fde53f9f93201ec94 [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 Rossum6d946f91992-08-14 13:49:30 +000036#ifdef macintosh
37#define NO_UNISTD
38#endif
39
Guido van Rossum2762f251992-03-27 17:22:13 +000040#ifndef NO_UNISTD
41#include <unistd.h>
42#endif
43
Guido van Rossum80c9d881991-04-16 08:47:51 +000044/* What happens here is not trivial.
45 The BSD_TIME code needs <sys/time.h> (for struct timeval).
46 The rest of the code needs only time_t, except some MS-DOS
47 code which needs clock_t as well.
48 Standard C says that time_t is defined in <time.h>, and
49 does not have <sys/types.h>; THINK C agrees (MS-DOS too?).
50 What's worse, in pure 4.3 BSD, older SunOS versions, and
51 probably everything derived from BSD, you can't #include
52 both <time.h> and <sys/time.h> in the same file, since
53 <sys/time.h> includes <time.h> without any protection,
54 and <time.h> contains a typedef, which can't be parsed twice!
55 So on traditional UNIX systems we include <sys/types.h>
56 and <sys/time.h> and hope this implies <time.h> and time_t,
57 while on other systems, including conforming Standard C
58 systems (where 'unix' can't be defined), we rely on <time.h>.
59 Still one problem: BSD_TIME won't work with strict Standard C...
60*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000061
Guido van Rossum80c9d881991-04-16 08:47:51 +000062#ifdef unix
63#include <sys/types.h>
64#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
65#else /* !unix */
66#include <time.h>
67#endif /* !unix */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000068
Guido van Rossum27aaa6d1992-03-12 17:33:14 +000069#ifdef DO_TIMES
70#include <sys/times.h>
71#include <sys/param.h>
72#include <errno.h>
73#endif
74
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075/* Time methods */
76
77static object *
78time_time(self, args)
79 object *self;
80 object *args;
81{
Guido van Rossum6590d4a1991-04-04 10:49:03 +000082 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 if (!getnoarg(args))
84 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +000085 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +000086#ifdef macintosh
87/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
88/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000089#define TIMEDIFF ((time_t) \
90 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
91 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +000092#endif
Guido van Rossum6590d4a1991-04-04 10:49:03 +000093 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094}
95
96static jmp_buf sleep_intr;
97
Guido van Rossum2762f251992-03-27 17:22:13 +000098/* ARGSUSED */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099static void
100sleep_catcher(sig)
Guido van Rossum2762f251992-03-27 17:22:13 +0000101 int sig; /* Not used but required by interface */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000102{
103 longjmp(sleep_intr, 1);
104}
105
106static object *
107time_sleep(self, args)
108 object *self;
109 object *args;
110{
Guido van Rossumff4949e1992-08-05 19:58:53 +0000111 long secs;
Guido van Rossum2762f251992-03-27 17:22:13 +0000112 SIGTYPE (*sigsave)() = 0; /* Initialized to shut lint up */
Guido van Rossumff4949e1992-08-05 19:58:53 +0000113 if (!getargs(args, "l", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000114 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000115 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000117 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000118 signal(SIGINT, sigsave);
119 err_set(KeyboardInterrupt);
120 return NULL;
121 }
122 sigsave = signal(SIGINT, SIG_IGN);
123 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
124 signal(SIGINT, sleep_catcher);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000125#ifdef BSD_TIME
126 longsleep(secs);
127#else
128 sleep((int)secs);
129#endif
130 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131 signal(SIGINT, sigsave);
132 INCREF(None);
133 return None;
134}
135
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000136#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000137#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000138#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000139
140#ifdef AMOEBA
141#define DO_MILLI
142extern long sys_milli();
143#define millitimer sys_milli
144#endif /* AMOEBA */
145
Guido van Rossum426035c1991-02-19 12:27:35 +0000146#ifdef BSD_TIME
147#define DO_MILLI
148#endif /* BSD_TIME */
149
Guido van Rossum80c9d881991-04-16 08:47:51 +0000150#ifdef TURBO_C
151#define DO_MILLI
152#endif
153
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000154#ifdef DO_MILLI
155
156static object *
157time_millisleep(self, args)
158 object *self;
159 object *args;
160{
161 long msecs;
162 SIGTYPE (*sigsave)();
163 if (!getlongarg(args, &msecs))
164 return NULL;
Guido van Rossumff4949e1992-08-05 19:58:53 +0000165 BGN_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 if (setjmp(sleep_intr)) {
Guido van Rossumff4949e1992-08-05 19:58:53 +0000167 RET_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 signal(SIGINT, sigsave);
169 err_set(KeyboardInterrupt);
170 return NULL;
171 }
172 sigsave = signal(SIGINT, SIG_IGN);
173 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
174 signal(SIGINT, sleep_catcher);
175 millisleep(msecs);
Guido van Rossumff4949e1992-08-05 19:58:53 +0000176 END_SAVE
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177 signal(SIGINT, sigsave);
178 INCREF(None);
179 return None;
180}
181
182static object *
183time_millitimer(self, args)
184 object *self;
185 object *args;
186{
187 long msecs;
188 extern long millitimer();
189 if (!getnoarg(args))
190 return NULL;
191 msecs = millitimer();
192 return newintobject(msecs);
193}
194
195#endif /* DO_MILLI */
196
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000197#ifdef DO_TIMES
198
199static object *
200time_times(self, args)
201 object *self;
202 object *args;
203{
204 struct tms t;
205 clock_t c;
206 object *tuple;
Guido van Rossum2762f251992-03-27 17:22:13 +0000207 if (!getnoarg(args))
208 return NULL;
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000209 errno = 0;
210 c = times(&t);
211 if (c == (clock_t) -1) {
212 err_errno(IOError);
213 return NULL;
214 }
215 tuple = newtupleobject(4);
216 if (tuple == NULL)
217 return NULL;
218 settupleitem(tuple, 0, newfloatobject((double)t.tms_utime / HZ));
219 settupleitem(tuple, 1, newfloatobject((double)t.tms_stime / HZ));
220 settupleitem(tuple, 2, newfloatobject((double)t.tms_cutime / HZ));
221 settupleitem(tuple, 3, newfloatobject((double)t.tms_cstime / HZ));
222 if (err_occurred()) {
223 DECREF(tuple);
224 return NULL;
225 }
226 return tuple;
227}
228
229#endif
230
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231
232static struct methodlist time_methods[] = {
233#ifdef DO_MILLI
234 {"millisleep", time_millisleep},
235 {"millitimer", time_millitimer},
236#endif /* DO_MILLI */
Guido van Rossum27aaa6d1992-03-12 17:33:14 +0000237#ifdef DO_TIMES
238 {"times", time_times},
239#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 {"sleep", time_sleep},
241 {"time", time_time},
242 {NULL, NULL} /* sentinel */
243};
244
245
246void
247inittime()
248{
249 initmodule("time", time_methods);
250}
251
252
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000253#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254
255#define MacTicks (* (long *)0x16A)
256
Guido van Rossum80c9d881991-04-16 08:47:51 +0000257#ifdef THINK_C_3_0
Guido van Rossumff4949e1992-08-05 19:58:53 +0000258sleep(secs)
259 int secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260{
261 register long deadline;
262
Guido van Rossumff4949e1992-08-05 19:58:53 +0000263 deadline = MacTicks + mecs * 60;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000264 while (MacTicks < deadline) {
265 if (intrcheck())
266 sleep_catcher(SIGINT);
267 }
268}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000269#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000271millisleep(msecs)
272 long msecs;
273{
274 register long deadline;
275
276 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
277 while (MacTicks < deadline) {
278 if (intrcheck())
279 sleep_catcher(SIGINT);
280 }
281}
282
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000283long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284millitimer()
285{
286 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
287}
288
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000289#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000290
291
292#ifdef BSD_TIME
293
Guido van Rossumed233a51992-06-23 09:07:03 +0000294#include "myselect.h" /* Implies <sys/types.h>, <sys/time.h>, <sys/param.h> */
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000295
Guido van Rossum56627461991-04-03 19:15:32 +0000296long
Guido van Rossum426035c1991-02-19 12:27:35 +0000297millitimer()
298{
299 struct timeval t;
300 struct timezone tz;
301 if (gettimeofday(&t, &tz) != 0)
302 return -1;
303 return t.tv_sec*1000 + t.tv_usec/1000;
Guido van Rossum426035c1991-02-19 12:27:35 +0000304}
305
Guido van Rossum426035c1991-02-19 12:27:35 +0000306millisleep(msecs)
307 long msecs;
308{
309 struct timeval t;
310 t.tv_sec = msecs/1000;
311 t.tv_usec = (msecs%1000)*1000;
312 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
313}
314
Guido van Rossumff4949e1992-08-05 19:58:53 +0000315longsleep(secs)
316 long secs;
317{
318 struct timeval t;
319 t.tv_sec = secs;
320 t.tv_usec = 0;
321 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
322}
323
Guido van Rossum426035c1991-02-19 12:27:35 +0000324#endif /* BSD_TIME */
325
Guido van Rossum80c9d881991-04-16 08:47:51 +0000326
327#ifdef TURBO_C /* Maybe also for MS-DOS? */
328
329#ifndef CLOCKS_PER_SEC
330#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
331#endif
332
333static
334millisleep(msecs)
335 long msecs;
336{
337 delay(msecs);
338}
339
340static long
341millitimer()
342{
343 clock_t ticks;
344
345 ticks = clock(); /* ticks since program start */
346 return ticks * CLOCKS_PER_SEC;
347}
348
349#endif /* TURBO_C */