/* * %CopyrightBegin% * * Copyright Ericsson AB 1997-2011. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * %CopyrightEnd% * * This file handles differences between different Unix systems. * This should be the only place with conditional compilation * depending on the type of OS. */ #ifndef _ERL_OSE_SYS_H #define _ERL_OSE_SYS_H #include "ose.h" #undef NIL #include "ramlog.h" #include "erts.sig" #include "fcntl.h" #include "math.h" #include "stdio.h" #include "stdlib.h" #include "string.h" #include "sys/param.h" #include "sys/time.h" #include "time.h" #include "dirent.h" #include "ethread.h" /* FIXME: configuration options */ #define ERTS_SCHED_MIN_SPIN 1 #define ERTS_SCHED_ONLY_POLL_SCHED_1 1 #define ERTS_SCHED_FAIR 1 #define NO_SYSCONF 1 #define OPEN_MAX FOPEN_MAX #define MAP_ANON MAP_ANONYMOUS #ifndef HAVE_MMAP # define HAVE_MMAP 0 #endif #if HAVE_MMAP # include "sys/mman.h" #endif /* * Min number of async threads */ #define ERTS_MIN_NO_OF_ASYNC_THREADS 1 /* * Our own type of "FD's" */ #define ERTS_SYS_FD_TYPE struct erts_sys_fd_type* #define NO_FSTAT_ON_SYS_FD_TYPE 1 /* They are signals, not files */ #include "sys/stat.h" /* FIXME mremap is not defined in OSE - POSIX issue */ extern void *mremap (void *__addr, size_t __old_len, size_t __new_len, int __flags, ...); /* FIXME: mremap constants */ #define MREMAP_MAYMOVE 1 #define MREMAP_FIXED 2 typedef void *GETENV_STATE; /* ** For the erl_timer_sup module. */ #define HAVE_GETHRTIME typedef long long SysHrTime; extern SysHrTime sys_gethrtime(void); void sys_init_hrtime(void); typedef time_t erts_time_t; typedef struct timeval SysTimeval; #define sys_gettimeofday(Arg) ((void) gettimeofday((Arg), NULL)) typedef struct { clock_t tms_utime; clock_t tms_stime; clock_t tms_cutime; clock_t tms_cstime; } SysTimes; extern int erts_ticks_per_sec; #define SYS_CLK_TCK (erts_ticks_per_sec) extern clock_t sys_times(SysTimes *buffer); /* No use in having other resolutions than 1 Ms. */ #define SYS_CLOCK_RESOLUTION 1 #define erts_isfinite finite #ifdef NO_FPE_SIGNALS #define erts_get_current_fp_exception() NULL #ifdef ERTS_SMP #define erts_thread_init_fp_exception() do{}while(0) #endif # define __ERTS_FP_CHECK_INIT(fpexnp) do {} while (0) # define __ERTS_FP_ERROR(fpexnp, f, Action) if (!finite(f)) { Action; } else {} # define __ERTS_FP_ERROR_THOROUGH(fpexnp, f, Action) __ERTS_FP_ERROR(fpexnp, f, Action) # define __ERTS_SAVE_FP_EXCEPTION(fpexnp) # define __ERTS_RESTORE_FP_EXCEPTION(fpexnp) #define erts_sys_block_fpe() 0 #define erts_sys_unblock_fpe(x) do{}while(0) #else /* !NO_FPE_SIGNALS */ extern volatile unsigned long *erts_get_current_fp_exception(void); #ifdef ERTS_SMP extern void erts_thread_init_fp_exception(void); #endif # if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) # define erts_fwait(fpexnp,f) \ __asm__ __volatile__("fwait" : "=m"(*(fpexnp)) : "m"(f)) # elif (defined(__powerpc__) || defined(__ppc__)) && defined(__GNUC__) # define erts_fwait(fpexnp,f) \ __asm__ __volatile__("" : "=m"(*(fpexnp)) : "fm"(f)) # elif defined(__sparc__) && defined(__linux__) && defined(__GNUC__) # define erts_fwait(fpexnp,f) \ __asm__ __volatile__("" : "=m"(*(fpexnp)) : "em"(f)) # else # define erts_fwait(fpexnp,f) \ __asm__ __volatile__("" : "=m"(*(fpexnp)) : "g"(f)) # endif # if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) extern void erts_restore_fpu(void); # else # define erts_restore_fpu() /*empty*/ # endif # if (!defined(__GNUC__) || \ (__GNUC__ < 2) || \ (__GNUC__ == 2 && __GNUC_MINOR < 96)) && \ !defined(__builtin_expect) # define __builtin_expect(x, expected_value) (x) # endif static __inline__ int erts_check_fpe(volatile unsigned long *fp_exception, double f) { erts_fwait(fp_exception, f); if (__builtin_expect(*fp_exception == 0, 1)) return 0; *fp_exception = 0; erts_restore_fpu(); return 1; } # undef erts_fwait # undef erts_restore_fpu extern void erts_fp_check_init_error(volatile unsigned long *fp_exception); static __inline__ void __ERTS_FP_CHECK_INIT(volatile unsigned long *fp_exception) { if (__builtin_expect(*fp_exception == 0, 1)) return; erts_fp_check_init_error(fp_exception); } # define __ERTS_FP_ERROR(fpexnp, f, Action) do { if (erts_check_fpe((fpexnp),(f))) { Action; } } while (0) # define __ERTS_SAVE_FP_EXCEPTION(fpexnp) unsigned long old_erl_fp_exception = *(fpexnp) # define __ERTS_RESTORE_FP_EXCEPTION(fpexnp) \ do { *(fpexnp) = old_erl_fp_exception; } while (0) /* This is for library calls where we don't trust the external code to always throw floating-point exceptions on errors. */ static __inline__ int erts_check_fpe_thorough(volatile unsigned long *fp_exception, double f) { return erts_check_fpe(fp_exception, f) || !finite(f); } # define __ERTS_FP_ERROR_THOROUGH(fpexnp, f, Action) \ do { if (erts_check_fpe_thorough((fpexnp),(f))) { Action; } } while (0) int erts_sys_block_fpe(void); void erts_sys_unblock_fpe(int); #endif /* !NO_FPE_SIGNALS */ #define ERTS_FP_CHECK_INIT(p) __ERTS_FP_CHECK_INIT(&(p)->fp_exception) #define ERTS_FP_ERROR(p, f, A) __ERTS_FP_ERROR(&(p)->fp_exception, f, A) #define ERTS_FP_ERROR_THOROUGH(p, f, A) __ERTS_FP_ERROR_THOROUGH(&(p)->fp_exception, f, A) /* FIXME: force HAVE_GETPAGESIZE and stub getpagesize */ #ifndef HAVE_GETPAGESIZE #define HAVE_GETPAGESIZE 1 #endif extern int getpagesize(void); #ifndef HZ #define HZ 60 #endif /* OSE5 doesn't provide limits.h so a number of macros should be * added manually */ #ifndef CHAR_BIT #define CHAR_BIT 8 #endif /* Minimum and maximum values a `signed int' can hold. */ #ifndef INT_MAX #define INT_MAX 2147483647 #endif #ifndef INT_MIN #define INT_MIN (-INT_MAX - 1) #endif #ifndef UINT_MAX # define UINT_MAX 4294967295U #endif /* static void erts_ose_sys_send(union SIGNAL **signal,PROCESS dst, char* file,int line) { SIGSELECT **ziggy = (SIGSELECT**)signal; printf("%s:%d 0x%x Send signal 0x%x(0x%x) to 0x%x\r\n", file,line,current_process(),ziggy[0][0],*ziggy,dst); send(signal,dst); } #define send(signal,dst) erts_ose_sys_send(signal,dst,__FILE__,__LINE__) static void erts_ose_sys_send_w_sender(union SIGNAL **signal, PROCESS sender,PROCESS dst, char* file,int line) { SIGSELECT **ziggy = (SIGSELECT**)signal; printf("%s:%d 0x%x Send signal 0x%x(0x%x) to 0x%x as 0x%x\r\n", file,line,current_process(),ziggy[0][0],*ziggy,dst,sender); send_w_sender(signal,sender,dst); } #define send_w_sender(signal,sender,dst) \ erts_ose_sys_send_w_sender(signal,sender,dst,__FILE__,__LINE__) static union SIGNAL *erts_ose_sys_receive(SIGSELECT *sigsel, char *file, int line) { SIGSELECT *sig; int i; printf("%s:%d 0x%x receive({%d,",file,line,current_process(),sigsel[0]); for (i = 1; i < sigsel[0]; i++) printf("0x%x, ",sigsel[i]); if (sigsel[0] != 0) printf("0x%x",sigsel[i]); printf("})\n"); sig = (SIGSELECT*)receive(sigsel); printf("%s:%d 0x%x got 0x%x from 0x%x\n",file,line,current_process(), *sig,sender((union SIGNAL**)(&sig))); return (union SIGNAL*)sig; } #define receive(SIGSEL) erts_ose_sys_receive(SIGSEL,__FILE__,__LINE__) static union SIGNAL *erts_ose_sys_receive_w_tmo(OSTIME tmo,SIGSELECT *sigsel, char *file,int line) { SIGSELECT *sig; int i; if (tmo == 0) { sig = (SIGSELECT*)receive_w_tmo(tmo,sigsel); if (sig != NULL) { printf("%s:%d 0x%x receive_w_tmo(0,{%d,",file,line,current_process(), sigsel[0]); for (i = 1; i < sigsel[0]; i++) printf("0x%x, ",sigsel[i]); if (sigsel[0] != 0) printf("0x%x",sigsel[i]); printf("})\n"); printf("%s:%d 0x%x got 0x%x from 0x%x\n",file,line,current_process(), *sig,sender((union SIGNAL**)(&sig))); } } else { printf("%s:%d 0x%x receive_w_tmo(%u,{%d,",file,line,current_process(),tmo, sigsel[0]); for (i = 1; i < sigsel[0]; i++) printf("0x%x, ",sigsel[i]); if (sigsel[0] != 0) printf("0x%x",sigsel[i]); printf("})\n"); sig = (SIGSELECT*)receive_w_tmo(tmo,sigsel); printf("%s:%d 0x%x got ",file,line,current_process()); if (sig == NULL) printf("TIMEOUT\n"); else printf("0x%x from 0x%x\n",*sig,sender((union SIGNAL**)(&sig))); } return (union SIGNAL*)sig; } #define receive_w_tmo(tmo,sigsel) erts_ose_sys_receive_w_tmo(tmo,sigsel, \ __FILE__,__LINE__) static union SIGNAL *erts_ose_sys_receive_fsem(OSTIME tmo,SIGSELECT *sigsel, OSFSEMVAL fsem, char *file,int line) { SIGSELECT *sig; int i; if (tmo == 0) { sig = (SIGSELECT*)receive_fsem(tmo,sigsel,fsem); if (sig != NULL && sig != OS_RCV_FSEM) { printf("%s:%d 0x%x receive_fsem(0,{%d,",file,line,current_process(), sigsel[0]); for (i = 1; i < sigsel[0]; i++) printf("0x%x, ",sigsel[i]); if (sigsel[0] != 0) printf("0x%x",sigsel[i]); printf("},%d)\n",fsem); printf("%s:%d 0x%x got 0x%x from 0x%x\n",file,line,current_process(), *sig,sender((union SIGNAL**)(&sig))); } } else { printf("%s:%d 0x%x receive_fsem(%u,{%d,",file,line,current_process(),tmo, sigsel[0]); for (i = 1; i < sigsel[0]; i++) printf("0x%x, ",sigsel[i]); if (sigsel[0] != 0) printf("0x%x",sigsel[i]); printf("},%d)\n",fsem); sig = (SIGSELECT*)receive_fsem(tmo,sigsel,fsem); printf("%s:%d 0x%x got ",file,line,current_process()); if (sig == NULL) printf("TIMEOUT\n"); else if (sig == OS_RCV_FSEM) printf("FSEM\n"); else printf("0x%x from 0x%x\n",*sig,sender((union SIGNAL**)(&sig))); } return (union SIGNAL*)sig; } #define receive_fsem(tmo,sigsel,fsem) \ erts_ose_sys_receive_fsem(tmo,sigsel,fsem,__FILE__,__LINE__) */ #endif /* _ERL_OSE_SYS_H */