timemodule.c revision 80c9d88cbfb50dcf65e57da7283ee2d73b8d3698
1/*********************************************************** 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 25/* Time module */ 26 27#include "allobjects.h" 28 29#include "modsupport.h" 30 31#include "sigtype.h" 32 33#include <signal.h> 34#include <setjmp.h> 35 36/* 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*/ 53 54#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 */ 60 61/* Time methods */ 62 63static object * 64time_time(self, args) 65 object *self; 66 object *args; 67{ 68 time_t secs; 69 if (!getnoarg(args)) 70 return NULL; 71 time(&secs); 72#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); 81} 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 125#ifdef BSD_TIME 126#define DO_MILLI 127#endif /* BSD_TIME */ 128 129#ifdef TURBO_C 130#define DO_MILLI 131#endif 132 133#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 196#ifdef THINK_C_3_0 197sleep(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} 208#endif 209 210millisleep(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 222long 223millitimer() 224{ 225 return MacTicks * 50 / 3; /* MacTicks * 1000 / 60 */ 226} 227 228#endif /* THINK_C */ 229 230 231#ifdef BSD_TIME 232 233long 234millitimer() 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 244millisleep(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 255 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 */ 279