blob: 0b8faf2edbe6939b177278858db9da380cb8603f [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 Rossum1d2a9ad1991-06-24 22:23:45 +000072#ifdef applec /* MPW */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000073/* Difference in origin between Mac and Unix clocks: */
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +000074/* For THINK C 3.0 add a correction like 5*3600;
75 it converts to UCT from local assuming EST */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000076#define TIMEDIFF ((time_t) \
77 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
78 secs -= TIMEDIFF;
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +000079/* XXX It's almost better to directly fetch the Mac clock... */
80#endif /* applec */
Guido van Rossum6590d4a1991-04-04 10:49:03 +000081 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082}
83
84static jmp_buf sleep_intr;
85
86static void
87sleep_catcher(sig)
88 int sig;
89{
90 longjmp(sleep_intr, 1);
91}
92
93static object *
94time_sleep(self, args)
95 object *self;
96 object *args;
97{
98 int secs;
99 SIGTYPE (*sigsave)();
100 if (!getintarg(args, &secs))
101 return NULL;
102 if (setjmp(sleep_intr)) {
103 signal(SIGINT, sigsave);
104 err_set(KeyboardInterrupt);
105 return NULL;
106 }
107 sigsave = signal(SIGINT, SIG_IGN);
108 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
109 signal(SIGINT, sleep_catcher);
110 sleep(secs);
111 signal(SIGINT, sigsave);
112 INCREF(None);
113 return None;
114}
115
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000116#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117#define DO_MILLI
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000118#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119
120#ifdef AMOEBA
121#define DO_MILLI
122extern long sys_milli();
123#define millitimer sys_milli
124#endif /* AMOEBA */
125
Guido van Rossum426035c1991-02-19 12:27:35 +0000126#ifdef BSD_TIME
127#define DO_MILLI
128#endif /* BSD_TIME */
129
Guido van Rossum80c9d881991-04-16 08:47:51 +0000130#ifdef TURBO_C
131#define DO_MILLI
132#endif
133
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000134#ifdef DO_MILLI
135
136static object *
137time_millisleep(self, args)
138 object *self;
139 object *args;
140{
141 long msecs;
142 SIGTYPE (*sigsave)();
143 if (!getlongarg(args, &msecs))
144 return NULL;
145 if (setjmp(sleep_intr)) {
146 signal(SIGINT, sigsave);
147 err_set(KeyboardInterrupt);
148 return NULL;
149 }
150 sigsave = signal(SIGINT, SIG_IGN);
151 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
152 signal(SIGINT, sleep_catcher);
153 millisleep(msecs);
154 signal(SIGINT, sigsave);
155 INCREF(None);
156 return None;
157}
158
159static object *
160time_millitimer(self, args)
161 object *self;
162 object *args;
163{
164 long msecs;
165 extern long millitimer();
166 if (!getnoarg(args))
167 return NULL;
168 msecs = millitimer();
169 return newintobject(msecs);
170}
171
172#endif /* DO_MILLI */
173
174
175static struct methodlist time_methods[] = {
176#ifdef DO_MILLI
177 {"millisleep", time_millisleep},
178 {"millitimer", time_millitimer},
179#endif /* DO_MILLI */
180 {"sleep", time_sleep},
181 {"time", time_time},
182 {NULL, NULL} /* sentinel */
183};
184
185
186void
187inittime()
188{
189 initmodule("time", time_methods);
190}
191
192
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000193#ifdef macintosh
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194
195#define MacTicks (* (long *)0x16A)
196
Guido van Rossum80c9d881991-04-16 08:47:51 +0000197#ifdef THINK_C_3_0
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198sleep(msecs)
199 int msecs;
200{
201 register long deadline;
202
203 deadline = MacTicks + msecs * 60;
204 while (MacTicks < deadline) {
205 if (intrcheck())
206 sleep_catcher(SIGINT);
207 }
208}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000209#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211millisleep(msecs)
212 long msecs;
213{
214 register long deadline;
215
216 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
217 while (MacTicks < deadline) {
218 if (intrcheck())
219 sleep_catcher(SIGINT);
220 }
221}
222
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000223long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000224millitimer()
225{
226 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
227}
228
Guido van Rossum1d2a9ad1991-06-24 22:23:45 +0000229#endif /* macintosh */
Guido van Rossum426035c1991-02-19 12:27:35 +0000230
231
232#ifdef BSD_TIME
233
Guido van Rossum6a1f54c1991-05-05 20:15:54 +0000234#ifdef _IBMR2
235/* AIX defines fd_set in a separate file. Sigh... */
236#include <sys/select.h>
237#endif
238
Guido van Rossum56627461991-04-03 19:15:32 +0000239long
Guido van Rossum426035c1991-02-19 12:27:35 +0000240millitimer()
241{
242 struct timeval t;
243 struct timezone tz;
244 if (gettimeofday(&t, &tz) != 0)
245 return -1;
246 return t.tv_sec*1000 + t.tv_usec/1000;
247
248}
249
Guido van Rossum426035c1991-02-19 12:27:35 +0000250millisleep(msecs)
251 long msecs;
252{
253 struct timeval t;
254 t.tv_sec = msecs/1000;
255 t.tv_usec = (msecs%1000)*1000;
256 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
257}
258
259#endif /* BSD_TIME */
260
Guido van Rossum80c9d881991-04-16 08:47:51 +0000261
262#ifdef TURBO_C /* Maybe also for MS-DOS? */
263
264#ifndef CLOCKS_PER_SEC
265#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
266#endif
267
268static
269millisleep(msecs)
270 long msecs;
271{
272 delay(msecs);
273}
274
275static long
276millitimer()
277{
278 clock_t ticks;
279
280 ticks = clock(); /* ticks since program start */
281 return ticks * CLOCKS_PER_SEC;
282}
283
284#endif /* TURBO_C */