Replace getUSecOfDay with monotonic timer (#5865)
[packages/base.git] / include / HsBase.h
1 /* -----------------------------------------------------------------------------
2 *
3 * (c) The University of Glasgow 2001-2004
4 *
5 * Definitions for package `base' which are visible in Haskell land.
6 *
7 * ---------------------------------------------------------------------------*/
8
9 #ifndef __HSBASE_H__
10 #define __HSBASE_H__
11
12 #ifdef __NHC__
13 # include "Nhc98BaseConfig.h"
14 #else
15 #include "HsBaseConfig.h"
16 #endif
17
18 /* ultra-evil... */
19 #undef PACKAGE_BUGREPORT
20 #undef PACKAGE_NAME
21 #undef PACKAGE_STRING
22 #undef PACKAGE_TARNAME
23 #undef PACKAGE_VERSION
24
25 /* Needed to get the macro version of errno on some OSs (eg. Solaris).
26 We must do this, because these libs are only compiled once, but
27 must work in both single-threaded and multi-threaded programs. */
28 #define _REENTRANT 1
29
30 #include "HsFFI.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <math.h>
35
36 #if HAVE_SYS_TYPES_H
37 #include <sys/types.h>
38 #endif
39 #if HAVE_UNISTD_H
40 #include <unistd.h>
41 #endif
42 #if HAVE_SYS_STAT_H
43 #include <sys/stat.h>
44 #endif
45 #if HAVE_FCNTL_H
46 # include <fcntl.h>
47 #endif
48 #if HAVE_TERMIOS_H
49 #include <termios.h>
50 #endif
51 #if HAVE_SIGNAL_H
52 #include <signal.h>
53 /* Ultra-ugly: OpenBSD uses broken macros for sigemptyset and sigfillset (missing casts) */
54 #if __OpenBSD__
55 #undef sigemptyset
56 #undef sigfillset
57 #endif
58 #endif
59 #if HAVE_ERRNO_H
60 #include <errno.h>
61 #endif
62 #if HAVE_STRING_H
63 #include <string.h>
64 #endif
65 #if HAVE_UTIME_H
66 #include <utime.h>
67 #endif
68 #if HAVE_SYS_UTSNAME_H
69 #include <sys/utsname.h>
70 #endif
71 #if HAVE_GETTIMEOFDAY
72 # if HAVE_SYS_TIME_H
73 # include <sys/time.h>
74 # endif
75 #elif HAVE_GETCLOCK
76 # if HAVE_SYS_TIMERS_H
77 # define POSIX_4D9 1
78 # include <sys/timers.h>
79 # endif
80 #endif
81 #if HAVE_TIME_H
82 #include <time.h>
83 #endif
84 #if HAVE_SYS_TIMEB_H
85 #include <sys/timeb.h>
86 #endif
87 #if HAVE_WINDOWS_H
88 #include <windows.h>
89 #endif
90 #if HAVE_SYS_TIMES_H
91 #include <sys/times.h>
92 #endif
93 #if HAVE_WINSOCK_H && defined(__MINGW32__)
94 #include <winsock.h>
95 #endif
96 #if HAVE_LIMITS_H
97 #include <limits.h>
98 #endif
99 #if HAVE_WCTYPE_H
100 #include <wctype.h>
101 #endif
102 #if HAVE_INTTYPES_H
103 # include <inttypes.h>
104 #elif HAVE_STDINT_H
105 # include <stdint.h>
106 #endif
107 #if HAVE_CLOCK_GETTIME
108 # ifdef _POSIX_MONOTONIC_CLOCK
109 # define CLOCK_ID CLOCK_MONOTONIC
110 # else
111 # define CLOCK_ID CLOCK_REALTIME
112 # endif
113 #elif defined(darwin_HOST_OS)
114 # include <mach/mach.h>
115 # include <mach/mach_time.h>
116 #endif
117
118 #if !defined(__MINGW32__) && !defined(irix_HOST_OS)
119 # if HAVE_SYS_RESOURCE_H
120 # include <sys/resource.h>
121 # endif
122 #endif
123
124 #if !HAVE_GETRUSAGE && HAVE_SYS_SYSCALL_H
125 # include <sys/syscall.h>
126 # if defined(SYS_GETRUSAGE) /* hpux_HOST_OS */
127 # define getrusage(a, b) syscall(SYS_GETRUSAGE, a, b)
128 # define HAVE_GETRUSAGE 1
129 # endif
130 #endif
131
132 /* For System */
133 #if HAVE_SYS_WAIT_H
134 #include <sys/wait.h>
135 #endif
136 #if HAVE_VFORK_H
137 #include <vfork.h>
138 #endif
139 #include "WCsubst.h"
140
141 #if defined(__MINGW32__)
142 /* in Win32Utils.c */
143 extern void maperrno (void);
144 extern HsWord64 getMonotonicUSec(void);
145 #endif
146
147 #if defined(__MINGW32__)
148 #include <io.h>
149 #include <fcntl.h>
150 #include <shlobj.h>
151 #include <share.h>
152 #endif
153
154 #if HAVE_SYS_SELECT_H
155 #include <sys/select.h>
156 #endif
157
158 /* in inputReady.c */
159 extern int fdReady(int fd, int write, int msecs, int isSock);
160
161 /* -----------------------------------------------------------------------------
162 INLINE functions.
163
164 These functions are given as inlines here for when compiling via C,
165 but we also generate static versions into the cbits library for
166 when compiling to native code.
167 -------------------------------------------------------------------------- */
168
169 #ifndef INLINE
170 # if defined(_MSC_VER)
171 # define INLINE extern __inline
172 # else
173 # define INLINE static inline
174 # endif
175 #endif
176
177 INLINE int __hscore_get_errno(void) { return errno; }
178 INLINE void __hscore_set_errno(int e) { errno = e; }
179
180 INLINE HsInt
181 __hscore_bufsiz(void)
182 {
183 return BUFSIZ;
184 }
185
186 INLINE int
187 __hscore_o_binary(void)
188 {
189 #if defined(_MSC_VER)
190 return O_BINARY;
191 #else
192 return CONST_O_BINARY;
193 #endif
194 }
195
196 INLINE int
197 __hscore_o_rdonly(void)
198 {
199 #ifdef O_RDONLY
200 return O_RDONLY;
201 #else
202 return 0;
203 #endif
204 }
205
206 INLINE int
207 __hscore_o_wronly( void )
208 {
209 #ifdef O_WRONLY
210 return O_WRONLY;
211 #else
212 return 0;
213 #endif
214 }
215
216 INLINE int
217 __hscore_o_rdwr( void )
218 {
219 #ifdef O_RDWR
220 return O_RDWR;
221 #else
222 return 0;
223 #endif
224 }
225
226 INLINE int
227 __hscore_o_append( void )
228 {
229 #ifdef O_APPEND
230 return O_APPEND;
231 #else
232 return 0;
233 #endif
234 }
235
236 INLINE int
237 __hscore_o_creat( void )
238 {
239 #ifdef O_CREAT
240 return O_CREAT;
241 #else
242 return 0;
243 #endif
244 }
245
246 INLINE int
247 __hscore_o_excl( void )
248 {
249 #ifdef O_EXCL
250 return O_EXCL;
251 #else
252 return 0;
253 #endif
254 }
255
256 INLINE int
257 __hscore_o_trunc( void )
258 {
259 #ifdef O_TRUNC
260 return O_TRUNC;
261 #else
262 return 0;
263 #endif
264 }
265
266 INLINE int
267 __hscore_o_noctty( void )
268 {
269 #ifdef O_NOCTTY
270 return O_NOCTTY;
271 #else
272 return 0;
273 #endif
274 }
275
276 INLINE int
277 __hscore_o_nonblock( void )
278 {
279 #ifdef O_NONBLOCK
280 return O_NONBLOCK;
281 #else
282 return 0;
283 #endif
284 }
285
286 INLINE int
287 __hscore_ftruncate( int fd, off_t where )
288 {
289 #if defined(HAVE_FTRUNCATE)
290 return ftruncate(fd,where);
291 #elif defined(HAVE__CHSIZE)
292 return _chsize(fd,where);
293 #else
294 // ToDo: we should use _chsize_s() on Windows which allows a 64-bit
295 // offset, but it doesn't seem to be available from mingw at this time
296 // --SDM (01/2008)
297 #error at least ftruncate or _chsize functions are required to build
298 #endif
299 }
300
301 INLINE int
302 __hscore_setmode( int fd, HsBool toBin )
303 {
304 #if defined(_MSC_VER) || defined(__MINGW32__) || defined(_WIN32)
305 return setmode(fd,(toBin == HS_BOOL_TRUE) ? _O_BINARY : _O_TEXT);
306 #else
307 return 0;
308 #endif
309 }
310
311 #if __GLASGOW_HASKELL__
312
313 #endif /* __GLASGOW_HASKELL__ */
314
315 #if defined(__MINGW32__)
316 // We want the versions of stat/fstat/lseek that use 64-bit offsets,
317 // and you have to ask for those explicitly. Unfortunately there
318 // doesn't seem to be a 64-bit version of truncate/ftruncate, so while
319 // hFileSize and hSeek will work with large files, hSetFileSize will not.
320 typedef struct _stati64 struct_stat;
321 typedef off64_t stsize_t;
322 #else
323 typedef struct stat struct_stat;
324 typedef off_t stsize_t;
325 #endif
326
327 INLINE HsInt
328 __hscore_sizeof_stat( void )
329 {
330 return sizeof(struct_stat);
331 }
332
333 INLINE time_t __hscore_st_mtime ( struct_stat* st ) { return st->st_mtime; }
334 INLINE stsize_t __hscore_st_size ( struct_stat* st ) { return st->st_size; }
335 #if !defined(_MSC_VER)
336 INLINE mode_t __hscore_st_mode ( struct_stat* st ) { return st->st_mode; }
337 INLINE dev_t __hscore_st_dev ( struct_stat* st ) { return st->st_dev; }
338 INLINE ino_t __hscore_st_ino ( struct_stat* st ) { return st->st_ino; }
339 #endif
340
341 #if defined(__MINGW32__)
342 INLINE int __hscore_stat(wchar_t *file, struct_stat *buf) {
343 return _wstati64(file,buf);
344 }
345
346 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
347 return _fstati64(fd,buf);
348 }
349 INLINE int __hscore_lstat(wchar_t *fname, struct_stat *buf )
350 {
351 return _wstati64(fname,buf);
352 }
353 #else
354 INLINE int __hscore_stat(char *file, struct_stat *buf) {
355 return stat(file,buf);
356 }
357
358 INLINE int __hscore_fstat(int fd, struct_stat *buf) {
359 return fstat(fd,buf);
360 }
361
362 INLINE int __hscore_lstat( const char *fname, struct stat *buf )
363 {
364 #if HAVE_LSTAT
365 return lstat(fname, buf);
366 #else
367 return stat(fname, buf);
368 #endif
369 }
370 #endif
371
372 #if HAVE_TERMIOS_H
373 INLINE tcflag_t __hscore_lflag( struct termios* ts ) { return ts->c_lflag; }
374
375 INLINE void
376 __hscore_poke_lflag( struct termios* ts, tcflag_t t ) { ts->c_lflag = t; }
377
378 INLINE unsigned char*
379 __hscore_ptr_c_cc( struct termios* ts )
380 { return (unsigned char*) &ts->c_cc; }
381
382 INLINE HsInt
383 __hscore_sizeof_termios( void )
384 {
385 #ifndef __MINGW32__
386 return sizeof(struct termios);
387 #else
388 return 0;
389 #endif
390 }
391 #endif
392
393 #if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(_WIN32)
394 INLINE HsInt
395 __hscore_sizeof_sigset_t( void )
396 {
397 return sizeof(sigset_t);
398 }
399 #endif
400
401 INLINE int
402 __hscore_echo( void )
403 {
404 #ifdef ECHO
405 return ECHO;
406 #else
407 return 0;
408 #endif
409
410 }
411
412 INLINE int
413 __hscore_tcsanow( void )
414 {
415 #ifdef TCSANOW
416 return TCSANOW;
417 #else
418 return 0;
419 #endif
420
421 }
422
423 INLINE int
424 __hscore_icanon( void )
425 {
426 #ifdef ICANON
427 return ICANON;
428 #else
429 return 0;
430 #endif
431 }
432
433 INLINE int __hscore_vmin( void )
434 {
435 #ifdef VMIN
436 return VMIN;
437 #else
438 return 0;
439 #endif
440 }
441
442 INLINE int __hscore_vtime( void )
443 {
444 #ifdef VTIME
445 return VTIME;
446 #else
447 return 0;
448 #endif
449 }
450
451 INLINE int __hscore_sigttou( void )
452 {
453 #ifdef SIGTTOU
454 return SIGTTOU;
455 #else
456 return 0;
457 #endif
458 }
459
460 INLINE int __hscore_sig_block( void )
461 {
462 #ifdef SIG_BLOCK
463 return SIG_BLOCK;
464 #else
465 return 0;
466 #endif
467 }
468
469 INLINE int __hscore_sig_setmask( void )
470 {
471 #ifdef SIG_SETMASK
472 return SIG_SETMASK;
473 #else
474 return 0;
475 #endif
476 }
477
478 #ifndef __MINGW32__
479 INLINE size_t __hscore_sizeof_siginfo_t (void)
480 {
481 return sizeof(siginfo_t);
482 }
483 #endif
484
485 INLINE int
486 __hscore_f_getfl( void )
487 {
488 #ifdef F_GETFL
489 return F_GETFL;
490 #else
491 return 0;
492 #endif
493 }
494
495 INLINE int
496 __hscore_f_setfl( void )
497 {
498 #ifdef F_SETFL
499 return F_SETFL;
500 #else
501 return 0;
502 #endif
503 }
504
505 INLINE int
506 __hscore_f_setfd( void )
507 {
508 #ifdef F_SETFD
509 return F_SETFD;
510 #else
511 return 0;
512 #endif
513 }
514
515 INLINE long
516 __hscore_fd_cloexec( void )
517 {
518 #ifdef FD_CLOEXEC
519 return FD_CLOEXEC;
520 #else
521 return 0;
522 #endif
523 }
524
525 // defined in rts/RtsStartup.c.
526 extern void* __hscore_get_saved_termios(int fd);
527 extern void __hscore_set_saved_termios(int fd, void* ts);
528
529 #ifdef __MINGW32__
530 INLINE int __hscore_open(wchar_t *file, int how, mode_t mode) {
531 if ((how & O_WRONLY) || (how & O_RDWR) || (how & O_APPEND))
532 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYRW,mode);
533 // _O_NOINHERIT: see #2650
534 else
535 return _wsopen(file,how | _O_NOINHERIT,_SH_DENYWR,mode);
536 // _O_NOINHERIT: see #2650
537 }
538 #else
539 INLINE int __hscore_open(char *file, int how, mode_t mode) {
540 return open(file,how,mode);
541 }
542 #endif
543
544 #if darwin_HOST_OS
545 // You should not access _environ directly on Darwin in a bundle/shared library.
546 // See #2458 and http://developer.apple.com/library/mac/#documentation/Darwin/Reference/ManPages/man7/environ.7.html
547 #include <crt_externs.h>
548 INLINE char **__hscore_environ(void) { return *(_NSGetEnviron()); }
549 #else
550 /* ToDo: write a feature test that doesn't assume 'environ' to
551 * be in scope at link-time. */
552 extern char** environ;
553 INLINE char **__hscore_environ(void) { return environ; }
554 #endif
555
556 /* lossless conversions between pointers and integral types */
557 INLINE void * __hscore_from_uintptr(uintptr_t n) { return (void *)n; }
558 INLINE void * __hscore_from_intptr (intptr_t n) { return (void *)n; }
559 INLINE uintptr_t __hscore_to_uintptr (void *p) { return (uintptr_t)p; }
560 INLINE intptr_t __hscore_to_intptr (void *p) { return (intptr_t)p; }
561
562 void errorBelch2(const char*s, char *t);
563 void debugBelch2(const char*s, char *t);
564
565 #endif /* __HSBASE_H__ */
566