blob: 848e3220af39955327a1efd4da812f53372a4965 [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 Rossum80c9d881991-04-16 08:47:51 +000036/* What happens here is not trivial.
37 The BSD_TIME code needs <sys/time.h> (for struct timeval).
38 The rest of the code needs only time_t, except some MS-DOS
39 code which needs clock_t as well.
40 Standard C says that time_t is defined in <time.h>, and
41 does not have <sys/types.h>; THINK C agrees (MS-DOS too?).
42 What's worse, in pure 4.3 BSD, older SunOS versions, and
43 probably everything derived from BSD, you can't #include
44 both <time.h> and <sys/time.h> in the same file, since
45 <sys/time.h> includes <time.h> without any protection,
46 and <time.h> contains a typedef, which can't be parsed twice!
47 So on traditional UNIX systems we include <sys/types.h>
48 and <sys/time.h> and hope this implies <time.h> and time_t,
49 while on other systems, including conforming Standard C
50 systems (where 'unix' can't be defined), we rely on <time.h>.
51 Still one problem: BSD_TIME won't work with strict Standard C...
52*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000053
Guido van Rossum80c9d881991-04-16 08:47:51 +000054#ifdef unix
55#include <sys/types.h>
56#include <sys/time.h> /* Implies <time.h> everywhere, as far as I know */
57#else /* !unix */
58#include <time.h>
59#endif /* !unix */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000060
61/* Time methods */
62
63static object *
64time_time(self, args)
65 object *self;
66 object *args;
67{
Guido van Rossum6590d4a1991-04-04 10:49:03 +000068 time_t secs;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000069 if (!getnoarg(args))
70 return NULL;
Guido van Rossum80c9d881991-04-16 08:47:51 +000071 time(&secs);
Guido van Rossum00c567c1991-07-27 23:09:30 +000072#ifdef macintosh
73/* The Mac epoch is 1904, while UNIX uses 1970; Python prefers 1970 */
74/* Moreover, the Mac returns local time. This we cannot fix... */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000075#define TIMEDIFF ((time_t) \
76 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
77 secs -= TIMEDIFF;
Guido van Rossum00c567c1991-07-27 23:09:30 +000078#endif
Guido van Rossum6590d4a1991-04-04 10:49:03 +000079 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080}
81
82static jmp_buf sleep_intr;
83
84static void
85sleep_catcher(sig)
86 int sig;
87{
88 longjmp(sleep_intr, 1);
89}
90
91static object *
92time_sleep(self, args)
93 object *self;
94 object *args;
95{
96 int secs;
97 SIGTYPE (*sigsave)();
98 if (!getintarg(args, &secs))
99 return NULL;
100 if (setjmp(sleep_intr)) {
101 signal(SIGINT, sigsave);
102 err_set(KeyboardInterrupt);
103 return NULL;
104 }
105 sigsave = signal(SIGINT, SIG_IGN);
106 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
107 signal(SIGINT, sleep_catcher);
108 sleep(secs);
109 signal(SIGINT, sigsave);
110 INCREF(None);
111 return None;
112}
113
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000114#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000116#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117
118#ifdef AMOEBA
119#define DO_MILLI
120extern long sys_milli();
121#define millitimer sys_milli
122#endif /* AMOEBA */
123
Guido van Rossum426035c1991-02-19 12:27:35 +0000124#ifdef BSD_TIME
125#define DO_MILLI
126#endif /* BSD_TIME */
127
Guido van Rossum80c9d881991-04-16 08:47:51 +0000128#ifdef TURBO_C
129#define DO_MILLI
130#endif
131
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000132#ifdef DO_MILLI
133
134static object *
135time_millisleep(self, args)
136 object *self;
137 object *args;
138{
139 long msecs;
140 SIGTYPE (*sigsave)();
141 if (!getlongarg(args, &msecs))
142 return NULL;
143 if (setjmp(sleep_intr)) {
144 signal(SIGINT, sigsave);
145 err_set(KeyboardInterrupt);
146 return NULL;
147 }
148 sigsave = signal(SIGINT, SIG_IGN);
149 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
150 signal(SIGINT, sleep_catcher);
151 millisleep(msecs);
152 signal(SIGINT, sigsave);
153 INCREF(None);
154 return None;
155}
156
157static object *
158time_millitimer(self, args)
159 object *self;
160 object *args;
161{
162 long msecs;
163 extern long millitimer();
164 if (!getnoarg(args))
165 return NULL;
166 msecs = millitimer();
167 return newintobject(msecs);
168}
169
170#endif /* DO_MILLI */
171
172
173static struct methodlist time_methods[] = {
174#ifdef DO_MILLI
175 {"millisleep", time_millisleep},
176 {"millitimer", time_millitimer},
177#endif /* DO_MILLI */
178 {"sleep", time_sleep},
179 {"time", time_time},
180 {NULL, NULL} /* sentinel */
181};
182
183
184void
185inittime()
186{
187 initmodule("time", time_methods);
188}
189
190
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000191#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192
193#define MacTicks (* (long *)0x16A)
194
Guido van Rossum80c9d881991-04-16 08:47:51 +0000195#ifdef THINK_C_3_0
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196sleep(msecs)
197 int msecs;
198{
199 register long deadline;
200
201 deadline = MacTicks + msecs * 60;
202 while (MacTicks < deadline) {
203 if (intrcheck())
204 sleep_catcher(SIGINT);
205 }
206}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000207#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209millisleep(msecs)
210 long msecs;
211{
212 register long deadline;
213
214 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
215 while (MacTicks < deadline) {
216 if (intrcheck())
217 sleep_catcher(SIGINT);
218 }
219}
220
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000221long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222millitimer()
223{
224 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
225}
226
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000227#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000228
229
230#ifdef BSD_TIME
231
Guido van Rossum0bb1a511991-11-27 14:55:18 +0000232#ifdef _AIX /* I *think* this works */
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000233/* AIX defines fd_set in a separate file. Sigh... */
234#include <sys/select.h>
235#endif
236
Guido van Rossum56627461991-04-03 19:15:32 +0000237long
Guido van Rossum426035c1991-02-19 12:27:35 +0000238millitimer()
239{
240 struct timeval t;
241 struct timezone tz;
242 if (gettimeofday(&t, &tz) != 0)
243 return -1;
244 return t.tv_sec*1000 + t.tv_usec/1000;
245
246}
247
Guido van Rossum426035c1991-02-19 12:27:35 +0000248millisleep(msecs)
249 long msecs;
250{
251 struct timeval t;
252 t.tv_sec = msecs/1000;
253 t.tv_usec = (msecs%1000)*1000;
254 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
255}
256
257#endif /* BSD_TIME */
258
Guido van Rossum80c9d881991-04-16 08:47:51 +0000259
260#ifdef TURBO_C /* Maybe also for MS-DOS? */
261
262#ifndef CLOCKS_PER_SEC
263#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
264#endif
265
266static
267millisleep(msecs)
268 long msecs;
269{
270 delay(msecs);
271}
272
273static long
274millitimer()
275{
276 clock_t ticks;
277
278 ticks = clock(); /* ticks since program start */
279 return ticks * CLOCKS_PER_SEC;
280}
281
282#endif /* TURBO_C */