blob: 738887d5c1fd4d26bb24acec3cced0519b5a5c83 [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 Rossum6590d4a1991-04-04 10:49:03 +000072#ifdef THINK_C
73#ifndef THINK_C_3_0
74/* Difference in origin between Mac and Unix clocks: */
75#define TIMEDIFF ((time_t) \
76 (((1970-1904)*365L + (1970-1904)/4) * 24 * 3600))
77 secs -= TIMEDIFF;
78#endif
79#endif
80 return newintobject((long)secs);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000081}
82
83static jmp_buf sleep_intr;
84
85static void
86sleep_catcher(sig)
87 int sig;
88{
89 longjmp(sleep_intr, 1);
90}
91
92static object *
93time_sleep(self, args)
94 object *self;
95 object *args;
96{
97 int secs;
98 SIGTYPE (*sigsave)();
99 if (!getintarg(args, &secs))
100 return NULL;
101 if (setjmp(sleep_intr)) {
102 signal(SIGINT, sigsave);
103 err_set(KeyboardInterrupt);
104 return NULL;
105 }
106 sigsave = signal(SIGINT, SIG_IGN);
107 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
108 signal(SIGINT, sleep_catcher);
109 sleep(secs);
110 signal(SIGINT, sigsave);
111 INCREF(None);
112 return None;
113}
114
115#ifdef THINK_C
116#define DO_MILLI
117#endif /* THINK_C */
118
119#ifdef AMOEBA
120#define DO_MILLI
121extern long sys_milli();
122#define millitimer sys_milli
123#endif /* AMOEBA */
124
Guido van Rossum426035c1991-02-19 12:27:35 +0000125#ifdef BSD_TIME
126#define DO_MILLI
127#endif /* BSD_TIME */
128
Guido van Rossum80c9d881991-04-16 08:47:51 +0000129#ifdef TURBO_C
130#define DO_MILLI
131#endif
132
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000133#ifdef DO_MILLI
134
135static object *
136time_millisleep(self, args)
137 object *self;
138 object *args;
139{
140 long msecs;
141 SIGTYPE (*sigsave)();
142 if (!getlongarg(args, &msecs))
143 return NULL;
144 if (setjmp(sleep_intr)) {
145 signal(SIGINT, sigsave);
146 err_set(KeyboardInterrupt);
147 return NULL;
148 }
149 sigsave = signal(SIGINT, SIG_IGN);
150 if (sigsave != (SIGTYPE (*)()) SIG_IGN)
151 signal(SIGINT, sleep_catcher);
152 millisleep(msecs);
153 signal(SIGINT, sigsave);
154 INCREF(None);
155 return None;
156}
157
158static object *
159time_millitimer(self, args)
160 object *self;
161 object *args;
162{
163 long msecs;
164 extern long millitimer();
165 if (!getnoarg(args))
166 return NULL;
167 msecs = millitimer();
168 return newintobject(msecs);
169}
170
171#endif /* DO_MILLI */
172
173
174static struct methodlist time_methods[] = {
175#ifdef DO_MILLI
176 {"millisleep", time_millisleep},
177 {"millitimer", time_millitimer},
178#endif /* DO_MILLI */
179 {"sleep", time_sleep},
180 {"time", time_time},
181 {NULL, NULL} /* sentinel */
182};
183
184
185void
186inittime()
187{
188 initmodule("time", time_methods);
189}
190
191
192#ifdef THINK_C
193
194#define MacTicks (* (long *)0x16A)
195
Guido van Rossum80c9d881991-04-16 08:47:51 +0000196#ifdef THINK_C_3_0
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197sleep(msecs)
198 int msecs;
199{
200 register long deadline;
201
202 deadline = MacTicks + msecs * 60;
203 while (MacTicks < deadline) {
204 if (intrcheck())
205 sleep_catcher(SIGINT);
206 }
207}
Guido van Rossum80c9d881991-04-16 08:47:51 +0000208#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210millisleep(msecs)
211 long msecs;
212{
213 register long deadline;
214
215 deadline = MacTicks + msecs * 3 / 50; /* msecs * 60 / 1000 */
216 while (MacTicks < deadline) {
217 if (intrcheck())
218 sleep_catcher(SIGINT);
219 }
220}
221
Guido van Rossum6590d4a1991-04-04 10:49:03 +0000222long
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000223millitimer()
224{
225 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */
226}
227
228#endif /* THINK_C */
Guido van Rossum426035c1991-02-19 12:27:35 +0000229
230
231#ifdef BSD_TIME
232
Guido van Rossum56627461991-04-03 19:15:32 +0000233long
Guido van Rossum426035c1991-02-19 12:27:35 +0000234millitimer()
235{
236 struct timeval t;
237 struct timezone tz;
238 if (gettimeofday(&t, &tz) != 0)
239 return -1;
240 return t.tv_sec*1000 + t.tv_usec/1000;
241
242}
243
Guido van Rossum426035c1991-02-19 12:27:35 +0000244millisleep(msecs)
245 long msecs;
246{
247 struct timeval t;
248 t.tv_sec = msecs/1000;
249 t.tv_usec = (msecs%1000)*1000;
250 (void) select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t);
251}
252
253#endif /* BSD_TIME */
254
Guido van Rossum80c9d881991-04-16 08:47:51 +0000255
256#ifdef TURBO_C /* Maybe also for MS-DOS? */
257
258#ifndef CLOCKS_PER_SEC
259#define CLOCKS_PER_SEC 55 /* 54.945 msec per tick (18.2 HZ clock) */
260#endif
261
262static
263millisleep(msecs)
264 long msecs;
265{
266 delay(msecs);
267}
268
269static long
270millitimer()
271{
272 clock_t ticks;
273
274 ticks = clock(); /* ticks since program start */
275 return ticks * CLOCKS_PER_SEC;
276}
277
278#endif /* TURBO_C */