diff options
Diffstat (limited to 'erts/emulator')
31 files changed, 13 insertions, 7487 deletions
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index a919f0e3ac..c5080d5b5d 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -23,10 +23,6 @@ include ../vsn.mk include $(ERL_TOP)/make/$(TARGET)/otp.mk -include $(TARGET)/gen_git_version.mk -ifeq ($(findstring ose,$(TARGET)),ose) -include $(ERL_TOP)/make/$(TARGET)/ose_lm.mk -endif - ENABLE_ALLOC_TYPE_VARS = @ENABLE_ALLOC_TYPE_VARS@ HIPE_ENABLED=@HIPE_ENABLED@ DTRACE_ENABLED=@DTRACE_ENABLED@ @@ -245,9 +241,7 @@ HCC = @HCC@ LD = @LD@ DEXPORT = @DEXPORT@ RANLIB = @RANLIB@ -ifneq ($(findstring ose,$(TARGET)),ose) STRIP = strip -endif PERL = @PERL@ RM = @RM@ MKDIR = @MKDIR@ @@ -684,14 +678,6 @@ $(OBJDIR)/%.o: $(TTF_DIR)/%.c $(OBJDIR)/%.o: sys/$(ERLANG_OSTYPE)/%.c $(V_CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ -ifeq ($(findstring ose,$(TARGET)),ose) -$(OBJDIR)/ose_confd.o: $(OSE_CONFD) - $(V_CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ - -$(OBJDIR)/crt0_lm.o: $(CRT0_LM) - $(V_CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ -endif - $(OBJDIR)/%.o: sys/common/%.c $(V_CC) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@ @@ -810,29 +796,6 @@ OS_OBJS = \ $(OBJDIR)/dosmap.o else -ifeq ($(findstring ose,$(TARGET)),ose) -OS_OBJS = \ - $(OBJDIR)/sys.o \ - $(OBJDIR)/driver_tab.o \ - $(OBJDIR)/ose_efile.o \ - $(OBJDIR)/gzio.o \ - $(OBJDIR)/elib_memmove.o - -OS_OBJS += $(OBJDIR)/ose_confd.o \ - $(OBJDIR)/crt0_lm.o - -OS_OBJS += $(OBJDIR)/sys_float.o \ - $(OBJDIR)/sys_time.o - -DRV_OBJS = \ - $(OBJDIR)/efile_drv.o \ - $(OBJDIR)/ose_signal_drv.o \ - $(OBJDIR)/inet_drv.o \ - $(OBJDIR)/zlib_drv.o \ - $(OBJDIR)/ram_file_drv.o \ - $(OBJDIR)/ttsl_drv.o - -else OS_OBJS = \ $(OBJDIR)/sys.o \ $(OBJDIR)/driver_tab.o \ @@ -849,7 +812,6 @@ DRV_OBJS = \ $(OBJDIR)/ram_file_drv.o \ $(OBJDIR)/ttsl_drv.o endif -endif ifneq ($(STATIC_NIFS),no) STATIC_NIF_LIBS = $(STATIC_NIFS) @@ -1022,19 +984,12 @@ $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(STATIC_DRIVER_LIBS) $(LIBS) else -ifeq ($(findstring ose,$(TARGET)),ose) -$(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(LCF) - $(call build-ose-load-module, $@, $(INIT_OBJS) $(OBJS), $(STATIC_NIF_LIBS) \ - $(STATIC_DRIVER_LIBS) $(LIBS), $(BEAM_LMCONF)) - -else $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(ld_verbose)$(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \ $(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) \ $(STATIC_NIF_LIBS) $(STATIC_DRIVER_LIBS) $(LIBS) endif -endif # ---------------------------------------------------------------------- # Dependencies diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index f9a2f3e33e..6328b3d18f 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -437,13 +437,6 @@ atom orelse atom os_pid atom os_type atom os_version -atom ose_bg_proc -atom ose_int_proc -atom ose_phantom -atom ose_pri_proc -atom ose_process_prio -atom ose_process_type -atom ose_ti_proc atom out atom out_exited atom out_exiting diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types index 1d5dec4807..4804fb407d 100644 --- a/erts/emulator/beam/erl_alloc.types +++ b/erts/emulator/beam/erl_alloc.types @@ -394,21 +394,6 @@ type SYS_WRITE_BUF BINARY SYSTEM sys_write_buf +endif -+if ose - -type SYS_READ_BUF TEMPORARY SYSTEM sys_read_buf -type FD_TAB LONG_LIVED SYSTEM fd_tab -type FD_ENTRY_BUF STANDARD SYSTEM fd_entry_buf -type FD_SIG_LIST SHORT_LIVED SYSTEM fd_sig_list -type DRV_EV STANDARD SYSTEM driver_event -type CS_PROG_PATH LONG_LIVED SYSTEM cs_prog_path -type ENVIRONMENT TEMPORARY SYSTEM environment -type PUTENV_STR SYSTEM SYSTEM putenv_string -type PRT_REP_EXIT STANDARD SYSTEM port_report_exit - -+endif - - +if win32 type DRV_DATA_BUF SYSTEM SYSTEM drv_data_buf diff --git a/erts/emulator/beam/erl_async.c b/erts/emulator/beam/erl_async.c index f071898046..be0bc0cfec 100644 --- a/erts/emulator/beam/erl_async.c +++ b/erts/emulator/beam/erl_async.c @@ -167,7 +167,6 @@ async_ready_q(Uint sched_id) #endif - void erts_init_async(void) { diff --git a/erts/emulator/beam/erl_driver.h b/erts/emulator/beam/erl_driver.h index ef2d41e7a2..e71b87803b 100644 --- a/erts/emulator/beam/erl_driver.h +++ b/erts/emulator/beam/erl_driver.h @@ -690,16 +690,6 @@ EXTERN char *driver_dl_error(void); EXTERN int erl_drv_putenv(char *key, char *value); EXTERN int erl_drv_getenv(char *key, char *value, size_t *value_size); -#ifdef __OSE__ -typedef ErlDrvUInt ErlDrvOseEventId; -EXTERN union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent ev); -EXTERN ErlDrvEvent erl_drv_ose_event_alloc(SIGSELECT sig, ErlDrvOseEventId handle, - ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig), void *extra); -EXTERN void erl_drv_ose_event_free(ErlDrvEvent ev); -EXTERN void erl_drv_ose_event_fetch(ErlDrvEvent ev, SIGSELECT *sig, - ErlDrvOseEventId *handle, void **extra); -#endif - #endif /* !ERL_DRIVER_TYPES_ONLY */ #ifdef WIN32_DYNAMIC_ERL_DRIVER diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 5c38db1cbc..2c09834d19 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -1734,7 +1734,7 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp) reds = ERTS_PORT_REDS_INPUT; ASSERT((state & ERTS_PORT_SFLGS_DEAD) == 0); DTRACE_DRIVER(driver_ready_input, pp); - /* NOTE some windows/ose drivers use ->ready_input + /* NOTE some windows drivers use ->ready_input for input and output */ (*pp->drv_ptr->ready_input)((ErlDrvData) pp->drv_data, ptp->u.alive.td.io.event); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 11485c57df..0b4274f920 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -58,11 +58,7 @@ #define ERTS_PROC_MIN_CONTEXT_SWITCH_REDS_COST (CONTEXT_REDS/10) -#ifndef ERTS_SCHED_MIN_SPIN #define ERTS_SCHED_SPIN_UNTIL_YIELD 100 -#else -#define ERTS_SCHED_SPIN_UNTIL_YIELD 1 -#endif #define ERTS_SCHED_SYS_SLEEP_SPINCOUNT_VERY_LONG 40 #define ERTS_SCHED_AUX_WORK_SLEEP_SPINCOUNT_FACT_VERY_LONG 1000 @@ -152,12 +148,7 @@ extern BeamInstr beam_apply[]; extern BeamInstr beam_exit[]; extern BeamInstr beam_continue_exit[]; -#ifdef __OSE__ -/* Eager check I/O not supported on OSE yet. */ -int erts_eager_check_io = 0; -#else int erts_eager_check_io = 1; -#endif int erts_sched_compact_load; int erts_sched_balance_util = 0; Uint erts_no_schedulers; @@ -2521,19 +2512,10 @@ try_set_sys_scheduling(void) #endif static ERTS_INLINE int -prepare_for_sys_schedule(ErtsSchedulerData *esdp, int non_blocking) +prepare_for_sys_schedule(int non_blocking) { if (non_blocking && erts_eager_check_io) { #ifdef ERTS_SMP -#ifdef ERTS_SCHED_ONLY_POLL_SCHED_1 - if (esdp->no != 1) { - /* If we are not scheduler 1 and ERTS_SCHED_ONLY_POLL_SCHED_1 is used - then we make sure to wake scheduler 1 */ - ErtsRunQueue *rq = ERTS_RUNQ_IX(0); - wake_scheduler(rq); - return 0; - } -#endif return try_set_sys_scheduling(); #else return 1; @@ -2543,16 +2525,6 @@ prepare_for_sys_schedule(ErtsSchedulerData *esdp, int non_blocking) #ifdef ERTS_SMP while (!erts_port_task_have_outstanding_io_tasks() && try_set_sys_scheduling()) { -#ifdef ERTS_SCHED_ONLY_POLL_SCHED_1 - if (esdp->no != 1) { - /* If we are not scheduler 1 and ERTS_SCHED_ONLY_POLL_SCHED_1 is used - then we make sure to wake scheduler 1 */ - ErtsRunQueue *rq = ERTS_RUNQ_IX(0); - clear_sys_scheduling(); - wake_scheduler(rq); - return 0; - } -#endif if (!erts_port_task_have_outstanding_io_tasks()) return 1; clear_sys_scheduling(); @@ -2876,8 +2848,6 @@ aux_thread(void *unused) erts_thr_progress_active(NULL, thr_prgr_active = 0); erts_thr_progress_prepare_wait(NULL); - ERTS_SCHED_FAIR_YIELD(); - flgs = sched_spin_wait(ssi, 0); if (flgs & ERTS_SSI_FLG_SLEEPING) { @@ -2945,7 +2915,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * be waiting in erl_sys_schedule() */ - if (ERTS_SCHEDULER_IS_DIRTY(esdp) || !prepare_for_sys_schedule(esdp, 0)) { + if (ERTS_SCHEDULER_IS_DIRTY(esdp) || !prepare_for_sys_schedule(0)) { sched_waiting(esdp->no, rq); @@ -3010,8 +2980,6 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) erts_thr_progress_prepare_wait(esdp); } - ERTS_SCHED_FAIR_YIELD(); - flgs = sched_spin_wait(ssi, spincount); if (flgs & ERTS_SSI_FLG_SLEEPING) { ASSERT(flgs & ERTS_SSI_FLG_WAITING); @@ -3082,13 +3050,8 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) #ifdef ERTS_DIRTY_SCHEDULERS ASSERT(!ERTS_SCHEDULER_IS_DIRTY(esdp)); #endif - -#ifdef ERTS_SCHED_ONLY_POLL_SCHED_1 - ASSERT(esdp->no == 1); -#endif sched_waiting_sys(esdp->no, rq); - erts_smp_runq_unlock(rq); ASSERT(working); @@ -3158,7 +3121,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * Got to check that we still got I/O tasks; otherwise * we have to continue checking for I/O... */ - if (!prepare_for_sys_schedule(esdp, 0)) { + if (!prepare_for_sys_schedule(0)) { spincount *= ERTS_SCHED_TSE_SLEEP_SPINCOUNT_FACT; goto tse_wait; } @@ -3180,7 +3143,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq) * Got to check that we still got I/O tasks; otherwise * we have to wait in erl_sys_schedule() after all... */ - if (!prepare_for_sys_schedule(esdp, 0)) { + if (!prepare_for_sys_schedule(0)) { /* * Not allowed to wait in erl_sys_schedule; * do tse wait instead... @@ -5301,17 +5264,11 @@ erts_early_init_scheduling(int no_schedulers) wakeup_other.threshold = ERTS_SCHED_WAKEUP_OTHER_THRESHOLD_MEDIUM; wakeup_other.type = ERTS_SCHED_WAKEUP_OTHER_TYPE_DEFAULT; #endif -#ifndef ERTS_SCHED_MIN_SPIN sched_busy_wait.sys_schedule = ERTS_SCHED_SYS_SLEEP_SPINCOUNT_MEDIUM; sched_busy_wait.tse = (ERTS_SCHED_SYS_SLEEP_SPINCOUNT_MEDIUM * ERTS_SCHED_TSE_SLEEP_SPINCOUNT_FACT); sched_busy_wait.aux_work = (ERTS_SCHED_SYS_SLEEP_SPINCOUNT_MEDIUM * ERTS_SCHED_AUX_WORK_SLEEP_SPINCOUNT_FACT_MEDIUM); -#else - sched_busy_wait.sys_schedule = ERTS_SCHED_SYS_SLEEP_SPINCOUNT_NONE; - sched_busy_wait.tse = ERTS_SCHED_SYS_SLEEP_SPINCOUNT_NONE; - sched_busy_wait.aux_work = ERTS_SCHED_SYS_SLEEP_SPINCOUNT_NONE; -#endif } int @@ -8184,18 +8141,12 @@ erts_start_schedulers(void) erts_snprintf(opts.name, 16, "%lu_scheduler", actual + 1); -#ifdef __OSE__ - /* This should be done in the bind strategy */ - opts.coreNo = (actual+1) % ose_num_cpus(); -#endif - res = ethr_thr_create(&esdp->tid, sched_thread_func, (void*)esdp, &opts); if (res != 0) { break; } } - erts_no_schedulers = actual; #ifdef ERTS_DIRTY_SCHEDULERS @@ -8224,10 +8175,6 @@ erts_start_schedulers(void) erts_snprintf(opts.name, 16, "aux"); -#ifdef __OSE__ - opts.coreNo = 0; -#endif /* __OSE__ */ - res = ethr_thr_create(&aux_tid, aux_thread, NULL, &opts); if (res != 0) erl_exit(1, "Failed to create aux thread\n"); @@ -8247,7 +8194,6 @@ erts_start_schedulers(void) actual, actual == 1 ? " was" : "s were"); erts_send_error_to_logger_nogl(dsbufp); } - } #endif /* ERTS_SMP */ @@ -9388,12 +9334,10 @@ Process *schedule(Process *p, int calls) int leader_update = ERTS_SCHEDULER_IS_DIRTY(esdp) ? 0 : erts_thr_progress_update(esdp); aux_work = erts_atomic32_read_acqb(&esdp->ssi->aux_work); - if (aux_work | leader_update | ERTS_SCHED_FAIR) { + if (aux_work | leader_update) { erts_smp_runq_unlock(rq); if (leader_update) erts_thr_progress_leader_update(esdp); - else if (ERTS_SCHED_FAIR) - ERTS_SCHED_FAIR_YIELD(); if (aux_work) handle_aux_work(&esdp->aux_work_data, aux_work, 0); erts_smp_runq_lock(rq); @@ -9469,7 +9413,7 @@ Process *schedule(Process *p, int calls) } else if (!ERTS_SCHEDULER_IS_DIRTY(esdp) && (fcalls > input_reductions && - prepare_for_sys_schedule(esdp, !0))) { + prepare_for_sys_schedule(!0))) { ErtsMonotonicTime current_time; /* * Schedule system-level activities. diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index ffbf3e2bff..65422b8c15 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -685,13 +685,6 @@ extern ErtsAlignedSchedulerData *erts_aligned_dirty_io_scheduler_data; extern ErtsSchedulerData *erts_scheduler_data; #endif -#ifdef ERTS_SCHED_FAIR -#define ERTS_SCHED_FAIR_YIELD() ETHR_YIELD() -#else -#define ERTS_SCHED_FAIR 0 -#define ERTS_SCHED_FAIR_YIELD() -#endif - #if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK) int erts_smp_lc_runq_is_locked(ErtsRunQueue *); #endif diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index 7baa3b1a54..e9dd96efc4 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -3273,8 +3273,6 @@ sys_msg_dispatcher_func(void *unused) if (erts_thr_progress_update(NULL)) erts_thr_progress_leader_update(NULL); - ERTS_SCHED_FAIR_YIELD(); - #ifdef DEBUG_PRINTOUTS print_msg_type(smqp); #endif @@ -3429,9 +3427,6 @@ static void init_sys_msg_dispatcher(void) { erts_smp_thr_opts_t thr_opts = ERTS_SMP_THR_OPTS_DEFAULT_INITER; -#ifdef __OSE__ - thr_opts.coreNo = 0; -#endif thr_opts.detached = 1; thr_opts.name = "sys_msg_dispatcher"; init_smq_element_alloc(); @@ -3439,7 +3434,6 @@ init_sys_msg_dispatcher(void) sys_message_queue_end = NULL; erts_smp_cnd_init(&smq_cnd); erts_smp_mtx_init(&smq_mtx, "sys_msg_q"); - erts_smp_thr_create(&sys_msg_dispatcher_tid, sys_msg_dispatcher_func, NULL, diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c index 915d0f4328..fdd26fcc4b 100644 --- a/erts/emulator/beam/io.c +++ b/erts/emulator/beam/io.c @@ -52,9 +52,7 @@ #include "erl_hl_timer.h" extern ErlDrvEntry fd_driver_entry; -#ifndef __OSE__ extern ErlDrvEntry vanilla_driver_entry; -#endif extern ErlDrvEntry spawn_driver_entry; extern ErlDrvEntry *driver_tab[]; /* table of static drivers, only used during initialization */ @@ -2794,9 +2792,7 @@ void erts_init_io(int port_tab_size, erts_smp_rwmtx_rwlock(&erts_driver_list_lock); init_driver(&fd_driver, &fd_driver_entry, NULL); -#ifndef __OSE__ init_driver(&vanilla_driver, &vanilla_driver_entry, NULL); -#endif init_driver(&spawn_driver, &spawn_driver_entry, NULL); erts_init_static_drivers(); for (dp = driver_tab; *dp != NULL; dp++) diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 14eeb0ee8f..34011147d9 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -74,9 +74,7 @@ #if defined (__WIN32__) # include "erl_win_sys.h" -#elif defined (__OSE__) -# include "erl_ose_sys.h" -#else +#else # include "erl_unix_sys.h" #ifndef UNIX # define UNIX 1 diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c index 0317a95e8b..2cb4662fc3 100644 --- a/erts/emulator/drivers/common/efile_drv.c +++ b/erts/emulator/drivers/common/efile_drv.c @@ -101,15 +101,9 @@ # include "config.h" #endif -#ifndef __OSE__ #include <ctype.h> #include <sys/types.h> #include <stdlib.h> -#else -#include "ctype.h" -#include "sys/types.h" -#include "stdlib.h" -#endif /* Need (NON)BLOCKING macros for sendfile */ #ifndef WANT_NONBLOCKING diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c index 549de6503c..31b4b22081 100644 --- a/erts/emulator/drivers/common/inet_drv.c +++ b/erts/emulator/drivers/common/inet_drv.c @@ -94,10 +94,6 @@ typedef unsigned long long llu_t; #define INT16_MAX (32767) #endif -#ifdef __OSE__ -#include "inet.h" -#endif - #ifdef __WIN32__ #define STRNCASECMP strncasecmp @@ -298,139 +294,7 @@ static unsigned long one_value = 1; #define TCP_SHUT_RD SD_RECEIVE #define TCP_SHUT_RDWR SD_BOTH -#elif defined (__OSE__) - -/* - * Some notes about how inet (currently only tcp) works on OSE. - * The driver uses OSE signals to communicate with the one_inet - * process. Because of the difference in how signals and file descriptors - * work the whole select/deselect mechanic is very different. - * In ose when a sock_select is done a function is called. That function - * notes the changes that the driver want to do, but does not act on it. - * later when the function returns the new desired state is compared - * to the previous state and the apprioriate actions are taken. The action - * is usually to either request more data from the stack or stop requesting - * data. - * - * One thing to note is that the driver never does select/deselect. It always - * listens for the signals. Flow of data is regulated by sending or not sending - * signals to the ose inet process. - * - * The interesting functions to look at are: - * * inet_driver_select : called when sock_select is called - * * tcp_inet_ose_dispatch_signal : checks state changes and sends new signals - * * tcp_inet_drv_output_ose : ready output callback, reads signals and calls - * dispatch_signal - * * tcp_inet_drv_input_ose : ready input callback. - */ - -#include "efs.h" -#include "sys/socket.h" -#include "sys/uio.h" -#include "sfk/sys/sfk_uio.h" -#include "netinet/in.h" -#include "netinet/tcp.h" -#include "netdb.h" -#include "ose_spi/socket.sig" - - -static ssize_t writev_fallback(int fd, const struct iovec *iov, int iovcnt, int max_sz); - -#define INVALID_SOCKET -1 -#define INVALID_EVENT -1 -#define SOCKET_ERROR -1 - -#define SOCKET int -#define HANDLE int -#define FD_READ ERL_DRV_READ -#define FD_WRITE ERL_DRV_WRITE -#define FD_CLOSE 0 -#define FD_CONNECT (1<<4) -#define FD_ACCEPT (1<<5) -#define SOCK_FD_ERROR (1<<6) - -#define sock_connect(s, addr, len) connect((s), (addr), (len)) -#define sock_listen(s, b) listen((s), (b)) -#define sock_bind(s, addr, len) bind((s), (addr), (len)) -#define sock_getopt(s,t,n,v,l) getsockopt((s),(t),(n),(v),(l)) -#define sock_setopt(s,t,n,v,l) setsockopt((s),(t),(n),(v),(l)) -#define sock_name(s, addr, len) getsockname((s), (addr), (len)) -#define sock_peer(s, addr, len) getpeername((s), (addr), (len)) -#define sock_ntohs(x) ntohs((x)) -#define sock_ntohl(x) ntohl((x)) -#define sock_htons(x) htons((x)) -#define sock_htonl(x) htonl((x)) - -#define sock_accept(s, addr, len) accept((s), (addr), (len)) -#define sock_send(s,buf,len,flag) inet_send((s),(buf),(len),(flag)) -#define sock_sendto(s,buf,blen,flag,addr,alen) \ - sendto((s),(buf),(blen),(flag),(addr),(alen)) -#define sock_sendv(s, vec, size, np, flag) \ - (*(np) = writev_fallback((s), (struct iovec*)(vec), (size), (*(np)))) -#define sock_sendmsg(s,msghdr,flag) sendmsg((s),(msghdr),(flag)) - -#define sock_open(af, type, proto) socket((af), (type), (proto)) -#define sock_close(s) close((s)) -#define sock_dup(s) dup((s)) -#define sock_shutdown(s, how) shutdown((s), (how)) - -#define sock_hostname(buf, len) gethostname((buf), (len)) -#define sock_getservbyname(name,proto) getservbyname((name), (proto)) -#define sock_getservbyport(port,proto) getservbyport((port), (proto)) - -#define sock_recv(s,buf,len,flag) recv((s),(buf),(len),(flag)) -#define sock_recvfrom(s,buf,blen,flag,addr,alen) \ - recvfrom((s),(buf),(blen),(flag),(addr),(alen)) -#define sock_recvmsg(s,msghdr,flag) recvmsg((s),(msghdr),(flag)) - -#define sock_errno() errno -#define sock_create_event(d) ((d)->s) /* return file descriptor */ -#define sock_close_event(e) /* do nothing */ - -#ifndef WANT_NONBLOCKING -#define WANT_NONBLOCKING -#endif -#include "sys.h" - -typedef unsigned long u_long; -#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0) -#define IN_CLASSA_NET 0xff000000 -#define IN_CLASSA_NSHIFT 24 -#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) -#define IN_CLASSA_MAX 128 - -#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000) -#define IN_CLASSB_NET 0xffff0000 -#define IN_CLASSB_NSHIFT 16 -#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) -#define IN_CLASSB_MAX 65536 - -#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000) -#define IN_CLASSC_NET 0xffffff00 -#define IN_CLASSC_NSHIFT 8 -#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) - -#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000) -#define IN_MULTICAST(a) IN_CLASSD(a) - -#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000) -#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000) - -#define sock_select(d, flags, onoff) do { \ - ASSERT(!(d)->is_ignored); \ - (d)->event_mask = (onoff) ? \ - ((d)->event_mask | (flags)) : \ - ((d)->event_mask & ~(flags)); \ - DEBUGF(("(%s / %d) sock_select(%ld): flags=%02X, onoff=%d, event_mask=%02lX, s=%d\r\n", \ - __FILE__, __LINE__, (long) (d)->port, (flags), (onoff), (unsigned long) (d)->event_mask, (d)->s)); \ - inet_driver_select((d), (flags), (onoff)); \ - } while(0) - -#define TCP_SHUT_WR SHUT_WR -#define TCP_SHUT_RD SHUT_RD -#define TCP_SHUT_RDWR SHUT_RDWR - -#else /* !__OSE__ && !__WIN32__ */ +#else /* !__WIN32__ */ #include <sys/time.h> #ifdef NETDB_H_NEEDS_IN_H @@ -704,7 +568,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n) #define TCP_SHUT_RD SHUT_RD #define TCP_SHUT_RDWR SHUT_RDWR -#endif /* !__WIN32__ && !__OSE__ */ +#endif /* !__WIN32__ */ #ifdef HAVE_SOCKLEN_T # define SOCKLEN_T socklen_t @@ -1166,13 +1030,6 @@ typedef struct { char *netns; /* Socket network namespace name as full file path */ #endif -#ifdef __OSE__ - int select_state; /* state to keep track of whether we - should trigger another read/write - request at end of ready_input/output */ - ErlDrvEvent events[6]; -#endif - } inet_descriptor; @@ -1188,10 +1045,8 @@ static void tcp_inet_stop(ErlDrvData); static void tcp_inet_command(ErlDrvData, char*, ErlDrvSizeT); static void tcp_inet_commandv(ErlDrvData, ErlIOVec*); static void tcp_inet_flush(ErlDrvData drv_data); -#ifndef __OSE__ static void tcp_inet_drv_input(ErlDrvData, ErlDrvEvent); static void tcp_inet_drv_output(ErlDrvData data, ErlDrvEvent event); -#endif static ErlDrvData tcp_inet_start(ErlDrvPort, char* command); static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData, unsigned int, char*, ErlDrvSizeT, char**, ErlDrvSizeT); @@ -1204,71 +1059,6 @@ static void tcp_inet_event(ErlDrvData, ErlDrvEvent); static void find_dynamic_functions(void); #endif -#ifdef __OSE__ -/* The structure of the signal used for requesting asynchronous - * notification from the stack. Under normal circumstances the network stack - * shouldn't overwrite the value set in the fd field by the sender - * of the request */ -struct OseAsyncSig { - struct FmEvent event; - int fd; -}; - -union SIGNAL { - SIGSELECT signo; - struct OseAsyncSig async; -}; - -static ErlDrvSSizeT tcp_inet_ctl_ose(ErlDrvData e, unsigned int cmd, - char* buf, ErlDrvSizeT len, - char** rbuf, ErlDrvSizeT rsize); -static void tcp_inet_commandv_ose(ErlDrvData e, ErlIOVec* ev); -static void tcp_inet_drv_output_ose(ErlDrvData data, ErlDrvEvent event); -static void tcp_inet_drv_input_ose(ErlDrvData data, ErlDrvEvent event); -static ErlDrvOseEventId inet_resolve_signal(union SIGNAL *sig); - -#ifdef INET_DRV_DEBUG - -static char *read_req = "SO_EVENT_READ_REQUEST"; -static char *read_rep = "SO_EVENT_READ_REPLY"; -static char *write_req = "SO_EVENT_WRITE_REQUEST"; -static char *write_rep = "SO_EVENT_WRITE_REPLY"; -static char *eof_req = "SO_EVENT_EOF_REQUEST"; -static char *eof_rep = "SO_EVENT_EOF_REPLY"; -static char *accept_req = "SO_EVENT_ACCEPT_REQUEST"; -static char *accept_rep = "SO_EVENT_ACCEPT_REPLY"; -static char *connect_req = "SO_EVENT_CONNECT_REQUEST"; -static char *connect_rep = "SO_EVENT_CONNECT_REPLY"; -static char *error_req = "SO_EVENT_ERROR_REQUEST"; -static char *error_rep = "SO_EVENT_ERROR_REPLY"; -static char signo_tmp[32]; - -static char *signo_to_string(SIGSELECT signo) { - switch (signo) { - case SO_EVENT_READ_REQUEST: { return read_req; } - case SO_EVENT_READ_REPLY: { return read_rep; } - case SO_EVENT_WRITE_REQUEST: { return write_req; } - case SO_EVENT_WRITE_REPLY: { return write_rep; } - case SO_EVENT_EOF_REQUEST: { return eof_req; } - case SO_EVENT_EOF_REPLY: { return eof_rep; } - case SO_EVENT_ACCEPT_REQUEST: { return accept_req; } - case SO_EVENT_ACCEPT_REPLY: { return accept_rep; } - case SO_EVENT_CONNECT_REQUEST: { return connect_req; } - case SO_EVENT_CONNECT_REPLY: { return connect_rep; } - case SO_EVENT_ERROR_REQUEST: { return error_req; } - case SO_EVENT_ERROR_REPLY: { return error_rep; } - } - - snprintf(signo_tmp,32,"0x%x",signo); - - return signo_tmp; -} - -#endif - -#endif /* __OSE__ */ - - static struct erl_drv_entry tcp_inet_driver_entry = { tcp_inet_init, /* inet_init will add this driver !! */ @@ -1278,9 +1068,6 @@ static struct erl_drv_entry tcp_inet_driver_entry = #ifdef __WIN32__ tcp_inet_event, NULL, -#elif defined(__OSE__) - tcp_inet_drv_input_ose, /*ready_input*/ - tcp_inet_drv_output_ose, /*ready_output*/ #else tcp_inet_drv_input, tcp_inet_drv_output, @@ -1288,17 +1075,9 @@ static struct erl_drv_entry tcp_inet_driver_entry = "tcp_inet", NULL, NULL, -#ifdef __OSE__ - tcp_inet_ctl_ose, -#else tcp_inet_ctl, -#endif tcp_inet_timeout, -#ifdef __OSE__ - tcp_inet_commandv_ose, -#else tcp_inet_commandv, -#endif NULL, tcp_inet_flush, NULL, @@ -1450,14 +1229,6 @@ static int packet_inet_output(udp_descriptor* udesc, HANDLE event); /* convert descriptor pointer to inet_descriptor pointer */ #define INETP(d) (&(d)->inet) -#ifdef __OSE__ -static void inet_driver_select(inet_descriptor* desc, - int flags, int onoff); -static void tcp_inet_ose_dispatch_signals(tcp_descriptor *desc, - int prev_select_state, - union SIGNAL *sig); -#endif - static int async_ref = 0; /* async reference id generator */ #define NEW_ASYNC_ID() ((async_ref++) & 0xffff) @@ -4353,16 +4124,6 @@ static void desc_close(inet_descriptor* desc) desc->forced_events = 0; desc->send_would_block = 0; #endif -#ifdef __OSE__ - if (desc->events[0]) { - driver_select(desc->port,desc->events[0],FD_READ|FD_WRITE|ERL_DRV_USE,0); - driver_select(desc->port,desc->events[1],FD_READ|FD_WRITE|ERL_DRV_USE,0); - driver_select(desc->port,desc->events[2],FD_READ|FD_WRITE|ERL_DRV_USE,0); - driver_select(desc->port,desc->events[3],FD_READ|FD_WRITE|ERL_DRV_USE,0); - driver_select(desc->port,desc->events[4],FD_READ|FD_WRITE|ERL_DRV_USE,0); - driver_select(desc->port,desc->events[5],FD_READ|FD_WRITE|ERL_DRV_USE,0); - } -#else /* * We should close the fd here, but the other driver might still * be selecting on it. @@ -4372,7 +4133,6 @@ static void desc_close(inet_descriptor* desc) ERL_DRV_USE, 0); else inet_stop_select((ErlDrvEvent)(long)desc->event,NULL); -#endif desc->event = INVALID_EVENT; /* closed by stop_select callback */ desc->s = INVALID_SOCKET; desc->event_mask = 0; @@ -4414,65 +4174,6 @@ static int erl_inet_close(inet_descriptor* desc) return 0; } -#ifdef __OSE__ -static void inet_select_init(inet_descriptor* desc) -{ - desc->events[0] = - erl_drv_ose_event_alloc(SO_EVENT_READ_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[0], - ERL_DRV_READ|ERL_DRV_USE, 1); - - desc->events[1] = - erl_drv_ose_event_alloc(SO_EVENT_EOF_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[1], - ERL_DRV_READ|ERL_DRV_USE, 1); - - desc->events[2] = - erl_drv_ose_event_alloc(SO_EVENT_ACCEPT_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[2], - ERL_DRV_READ|ERL_DRV_USE, 1); - - /* trigger tcp_inet_input */ - desc->events[3] = - erl_drv_ose_event_alloc(SO_EVENT_WRITE_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[3], - ERL_DRV_WRITE|ERL_DRV_USE, 1); - - desc->events[4] = - erl_drv_ose_event_alloc(SO_EVENT_CONNECT_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[4], - ERL_DRV_WRITE|ERL_DRV_USE, 1); - - desc->events[5] = - erl_drv_ose_event_alloc(SO_EVENT_ERROR_REPLY, - desc->s, - inet_resolve_signal, - NULL); - driver_select(desc->port, desc->events[5], - ERL_DRV_WRITE|ERL_DRV_USE, 1); - - /* Issue a select on error event before any other select to be sure we are - prepared to receive error notifications from the stack, even in the - situations when select isn't issued */ - sock_select(desc, SOCK_FD_ERROR, 1); -} -#endif - static ErlDrvSSizeT inet_ctl_open(inet_descriptor* desc, int domain, int type, char** rbuf, ErlDrvSizeT rsize) { @@ -4555,9 +4256,6 @@ static ErlDrvSSizeT inet_ctl_open(inet_descriptor* desc, int domain, int type, #ifdef __WIN32__ driver_select(desc->port, desc->event, ERL_DRV_READ, 1); #endif -#ifdef __OSE__ - inet_select_init(desc); -#endif desc->state = INET_STATE_OPEN; desc->stype = type; @@ -4581,13 +4279,7 @@ static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type, if (name.sa.sa_family != domain) return ctl_error(EINVAL, rbuf, rsize); } -#ifdef __OSE__ - /* for fdopen duplicating the sd will allow to uniquely identify - the signal from OSE with erlang port */ - desc->s = sock_dup(s); -#else desc->s = s; -#endif if ((desc->event = sock_create_event(desc)) == INVALID_EVENT) return ctl_error(sock_errno(), rbuf, rsize); @@ -4605,12 +4297,6 @@ static ErlDrvSSizeT inet_ctl_fdopen(inet_descriptor* desc, int domain, int type, sz = sizeof(name); if (!IS_SOCKET_ERROR(sock_peer(s, (struct sockaddr*) &name, &sz))) { desc->state = INET_STATE_CONNECTED; -#ifdef __OSE__ - /* since we are dealing with different descriptors (i.e. inet and - socket) the select part should be initialized with the right - values */ - inet_select_init(desc); -#endif } } @@ -8404,15 +8090,6 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol) #ifdef HAVE_SETNS desc->netns = NULL; #endif -#ifdef __OSE__ - desc->select_state = 0; - desc->events[0] = NULL; - desc->events[1] = NULL; - desc->events[2] = NULL; - desc->events[3] = NULL; - desc->events[4] = NULL; - desc->events[5] = NULL; -#endif return (ErlDrvData)desc; } @@ -9139,10 +8816,6 @@ static tcp_descriptor* tcp_inet_copy(tcp_descriptor* desc,SOCKET s, copy_desc->inet.port = port; copy_desc->inet.dport = driver_mk_port(port); -#ifdef __OSE__ - inet_select_init(©_desc->inet); -#endif - *err = 0; return copy_desc; } @@ -9204,23 +8877,6 @@ static void tcp_inet_stop(ErlDrvData e) inet_stop(INETP(desc)); } -#ifdef __OSE__ - -static ErlDrvSSizeT tcp_inet_ctl_ose(ErlDrvData e, unsigned int cmd, - char* buf, ErlDrvSizeT len, - char** rbuf, ErlDrvSizeT rsize) { - - tcp_descriptor* desc = (tcp_descriptor*)e; - int prev_select_state = INETP(desc)->select_state; - - ErlDrvSSizeT res = tcp_inet_ctl(e,cmd,buf,len,rbuf,rsize); - - tcp_inet_ose_dispatch_signals((tcp_descriptor*)e,prev_select_state,NULL); - - return res; -} -#endif - /* TCP requests from Erlang */ static ErlDrvSSizeT tcp_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, ErlDrvSizeT len, @@ -9662,17 +9318,6 @@ static void tcp_inet_command(ErlDrvData e, char *buf, ErlDrvSizeT len) DEBUGF(("tcp_inet_command(%ld) }\r\n", (long)desc->inet.port)); } -#ifdef __OSE__ - -static void tcp_inet_commandv_ose(ErlDrvData e, ErlIOVec* ev) { - int prev_select_state = INETP((tcp_descriptor*)e)->select_state; - tcp_inet_commandv(e, ev); - tcp_inet_ose_dispatch_signals((tcp_descriptor*)e,prev_select_state,NULL); -} - -#endif - - static void tcp_inet_commandv(ErlDrvData e, ErlIOVec* ev) { tcp_descriptor* desc = (tcp_descriptor*)e; @@ -9745,22 +9390,6 @@ static void inet_stop_select(ErlDrvEvent event, void* _) { #ifdef __WIN32__ WSACloseEvent((HANDLE)event); -#elif defined(__OSE__) - ErlDrvOseEventId id; - union SIGNAL *sig; - erl_drv_ose_event_fetch(event, NULL, &id,NULL); - DEBUGF(("inet_stop_select(?#?) {s=%d\n",id)); - sock_close((int)id); - /* On socket close all the signals waiting to be processed as part of the - select should be deallocated */ - while((sig = erl_drv_ose_get_signal(event))) { - DEBUGF(("inet_stop_select(?#?): Freeing signal %s\n", - signo_to_string(sig->signo))); - free_buf(&sig); - } - erl_drv_ose_event_free(event); - DEBUGF(("inet_stop_select(?#?) }\n")); - #else sock_close((SOCKET)(long)event); #endif @@ -10309,146 +9938,7 @@ static void tcp_inet_event(ErlDrvData e, ErlDrvEvent event) return; } -#elif defined(__OSE__) /* !__WIN32__ */ -/* The specific resolve signal function. It will return the socket descriptor - for which the select was issued */ -static ErlDrvOseEventId inet_resolve_signal(union SIGNAL *sig) { - DEBUGF(("%s(?#?): s=%d got signal %s, status = %d, extra = %d, sender = 0x%x\n", - __FUNCTION__,sig->async.fd,signo_to_string(sig->signo), - sig->async.event.status, - sig->async.event.extra,sender(&sig))); - if (sig->signo == SO_EVENT_READ_REPLY || - sig->signo == SO_EVENT_ACCEPT_REPLY || - sig->signo == SO_EVENT_EOF_REPLY || - sig->signo == SO_EVENT_WRITE_REPLY || - sig->signo == SO_EVENT_ERROR_REPLY || - sig->signo == SO_EVENT_CONNECT_REPLY ) { - return sig->async.fd; - } - - return -1; -} - -static void inet_driver_select(inet_descriptor* desc, - int flags, int onoff) { - ASSERT(!desc->is_ignored); - - if(onoff) { - desc->select_state |= flags; - } else { - desc->select_state &= ~flags; - } -} - -static ssize_t writev_fallback(int fd, const struct iovec *iov, int iovcnt, int max_sz) -{ - size_t data_len = 0; - size_t sent = 0; - ssize_t n; - int i; - - for(i = 0; i < iovcnt; i++) - { - data_len = iov[i].iov_len; -tryagain: - n = sock_send(fd, iov[i].iov_base, data_len, 0); - if (IS_SOCKET_ERROR(n)) { - /* If buffer length is greater than the amount stack is able to - * send out then try to send at least max_sz (this comes with - * SO_EVENT_WRITE_REPLY signal*/ - if ((errno == EMSGSIZE) && (max_sz > 0) && (data_len > max_sz)) { - data_len = max_sz; - goto tryagain; - } - break; - } - sent += n; - } - return sent; -} - -#define OSE_EVENT_REQ(TCP_DESC,EVENT) do { \ - union SIGNAL *sig = alloc(sizeof(struct OseAsyncSig), EVENT); \ - sig->async.fd = INETP(TCP_DESC)->s; \ - ose_request_event(INETP(TCP_DESC)->s, &sig, 1); \ - DEBUGF(("%s(%ld): s=%d sent %s\r\n",__FUNCTION__, \ - INETP(TCP_DESC)->port,INETP(TCP_DESC)->s,signo_to_string(EVENT))); \ - } while(0) - -static void tcp_inet_ose_dispatch_signals(tcp_descriptor *desc, - int prev_select_state, - union SIGNAL *sig) { - if (sig) { - DEBUGF(("tcp_inet_ose_dispatch_signals(%ld) {s=%d resend\r\n", - (long)INETP(desc)->port,INETP(desc)->s)); - /* We are reacting to a signal, which means that if - the select_state for that signal is still activated - we should send a new signal */ - switch (sig->signo) { - case SO_EVENT_READ_REPLY: { - if (INETP(desc)->select_state & FD_READ) - OSE_EVENT_REQ(desc,SO_EVENT_READ_REQUEST); - break; - } - case SO_EVENT_WRITE_REPLY: { - if (INETP(desc)->select_state & FD_WRITE) - OSE_EVENT_REQ(desc,SO_EVENT_WRITE_REQUEST); - break; - } - case SO_EVENT_CONNECT_REPLY: { - if (INETP(desc)->select_state & FD_CONNECT) - OSE_EVENT_REQ(desc,SO_EVENT_CONNECT_REQUEST); - break; - } - case SO_EVENT_ACCEPT_REPLY: { - if (INETP(desc)->select_state & FD_ACCEPT) - OSE_EVENT_REQ(desc,SO_EVENT_ACCEPT_REQUEST); - break; - } - case SO_EVENT_ERROR_REPLY: { - if (INETP(desc)->select_state & SOCK_FD_ERROR) - OSE_EVENT_REQ(desc,SO_EVENT_ERROR_REQUEST); - break; - } - - } - DEBUGF(("tcp_inet_ose_dispatch_signals(%ld) }\r\n", - (long)INETP(desc)->port)); - } - - if (INETP(desc)->select_state != prev_select_state) { - /* If the select state has changed we have to issue signals for - the state parts that have changed. */ - int xor_select_state = INETP(desc)->select_state ^ prev_select_state; - DEBUGF(("tcp_inet_ose_dispatch_signals(%ld) {s=%d select change\r\n", - (long)INETP(desc)->port,INETP(desc)->s)); - if ((xor_select_state & FD_READ) && - (INETP(desc)->select_state & FD_READ)) { - OSE_EVENT_REQ(desc,SO_EVENT_READ_REQUEST); - } - if ((xor_select_state & FD_WRITE) && - (INETP(desc)->select_state & FD_WRITE)) { - OSE_EVENT_REQ(desc,SO_EVENT_WRITE_REQUEST); - } - if ((xor_select_state & FD_CONNECT) && - (INETP(desc)->select_state & FD_CONNECT)) { - OSE_EVENT_REQ(desc,SO_EVENT_CONNECT_REQUEST); - } - if ((xor_select_state & FD_ACCEPT) && - (INETP(desc)->select_state & FD_ACCEPT)) { - OSE_EVENT_REQ(desc,SO_EVENT_ACCEPT_REQUEST); - } - if ((xor_select_state & SOCK_FD_ERROR) && - (INETP(desc)->select_state & SOCK_FD_ERROR)) { - OSE_EVENT_REQ(desc,SO_EVENT_ERROR_REQUEST); - } - - DEBUGF(("tcp_inet_ose_dispatch_signals(%ld) }\r\n", - (long)INETP(desc)->port)); - } -} - -#endif /* __OSE__ */ +#endif /* __WIN32__ */ /* socket has input: @@ -10935,49 +10425,6 @@ static void tcp_shutdown_async(tcp_descriptor* desc) desc->tcp_add_flags |= TCP_ADDF_SHUTDOWN_WR_DONE; } -#ifdef __OSE__ - -static void tcp_inet_drv_output_ose(ErlDrvData data, ErlDrvEvent event) -{ - union SIGNAL *event_sig = erl_drv_ose_get_signal(event); - - while (event_sig) { - int prev_select_state = INETP((tcp_descriptor*)data)->select_state; - int res = tcp_inet_output((tcp_descriptor*)data, (HANDLE)event_sig); - if (res != -1) { - tcp_inet_ose_dispatch_signals((tcp_descriptor*)data, - prev_select_state,event_sig); - free_buf(&event_sig); - event_sig = erl_drv_ose_get_signal(event); - } else { - /* NOTE: here the event object could have been deallocated!!!! - inet_stop_select is called when doing driver_select(ERL_DRV_USE,0) - */ - free_buf(&event_sig); - return; - } - } -} - -static void tcp_inet_drv_input_ose(ErlDrvData data, ErlDrvEvent event) -{ - union SIGNAL *event_sig = erl_drv_ose_get_signal(event); - - while (event_sig) { - int prev_select_state = INETP((tcp_descriptor*)data)->select_state; - int res = tcp_inet_input((tcp_descriptor*)data, (HANDLE)event); - if (res != -1) { - tcp_inet_ose_dispatch_signals((tcp_descriptor*)data, prev_select_state, - event_sig); - free_buf(&event_sig); - event_sig = erl_drv_ose_get_signal(event); - } else { - free_buf(&event_sig); - return; - } - } -} -#else static void tcp_inet_drv_output(ErlDrvData data, ErlDrvEvent event) { (void)tcp_inet_output((tcp_descriptor*)data, (HANDLE)event); @@ -10987,7 +10434,6 @@ static void tcp_inet_drv_input(ErlDrvData data, ErlDrvEvent event) { (void)tcp_inet_input((tcp_descriptor*)data, (HANDLE)event); } -#endif /* socket ready for ouput: ** 1. INET_STATE_CONNECTING => non block connect ? @@ -11053,13 +10499,6 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event) ssize_t n; SysIOVec* iov; -#ifdef __OSE__ - /* For large size buffers case the amount of data that the stack is - able to send out (received in the .extra field) should be passed - down to writev_fallback */ - n = event ? ((union SIGNAL*)event)->async.event.extra : 0; -#endif - if ((iov = driver_peekq(ix, &vsize)) == NULL) { sock_select(INETP(desc), FD_WRITE, 0); send_empty_out_q_msgs(INETP(desc)); @@ -11087,12 +10526,6 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event) sizes > (max 32 bit signed int) */ size_t howmuch = 0x7FFFFFFF; /* max signed 32 bit */ int x; -#ifdef __OSE__ - /* For EWOULDBLOCK sock_sendv returns 0 so we have to be sure it - wasn't the case */ - if(sock_errno() == ERRNO_BLOCK) - goto done; -#endif for(x = 0; x < vsize && iov[x].iov_len == 0; ++x) ; if (x < vsize) { diff --git a/erts/emulator/drivers/ose/ose_efile.c b/erts/emulator/drivers/ose/ose_efile.c deleted file mode 100644 index c8337a95d5..0000000000 --- a/erts/emulator/drivers/ose/ose_efile.c +++ /dev/null @@ -1,1125 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1997-2012. 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% - */ -/* - * Purpose: Provides file and directory operations for OSE. - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#if defined(HAVE_POSIX_FALLOCATE) && !defined(__sun) && !defined(__sun__) -#define _XOPEN_SOURCE 600 -#endif -#if !defined(_GNU_SOURCE) && defined(HAVE_LINUX_FALLOC_H) -#define _GNU_SOURCE -#endif -#include "sys.h" -#include "erl_driver.h" -#include "erl_efile.h" -#if defined(DARWIN) || defined(HAVE_LINUX_FALLOC_H) || defined(HAVE_POSIX_FALLOCATE) -#include "fcntl.h" -#endif -#include "ose.h" -#include "unistd.h" -#include "sys/stat.h" -#include "dirent.h" -#include "sys/time.h" -#include "time.h" -#include "assert.h" - -/* Find a definition of MAXIOV, that is used in the code later. */ -#if defined IOV_MAX -#define MAXIOV IOV_MAX -#elif defined UIO_MAXIOV -#define MAXIOV UIO_MAXIOV -#else -#define MAXIOV 16 -#endif - -/* - * Macros for testing file types. - */ - -#define ISDIR(st) (((st).st_mode & S_IFMT) == S_IFDIR) -#define ISREG(st) (((st).st_mode & S_IFMT) == S_IFREG) -#define ISDEV(st) \ - (((st).st_mode&S_IFMT) == S_IFCHR || ((st).st_mode&S_IFMT) == S_IFBLK) -#define ISLNK(st) (((st).st_mode & S_IFLNK) == S_IFLNK) -#ifdef NO_UMASK -#define FILE_MODE 0644 -#define DIR_MODE 0755 -#else -#define FILE_MODE 0666 -#define DIR_MODE 0777 -#endif - -#define IS_DOT_OR_DOTDOT(s) \ - (s[0] == '.' && (s[1] == '\0' || (s[1] == '.' && s[2] == '\0'))) - -/* - * Macros for handling local file descriptors - * and mutexes. - * - * Handling of files like this is necessary because OSE - * does not allow seeking after the end of a file. So - * what we do it emulate this by keeping track of the size - * of the file and where the file's positions is. If a - * write happens after eof then we pad it. - * - * Given time this should be rewritten to get rid of the - * mutex and use the port lock to protect the data. This - * could be done be done by adapting the efile api for some - * calls to allow some meta-data to be associated with the - * open file. - */ - -#define L_FD_IS_VALID(fd_data) ((fd_data)->beyond_eof > 0) -#define L_FD_INVALIDATE(fd_data) (fd_data)->beyond_eof = 0 -#define L_FD_CUR(fd_data) (fd_data)->pos -#define L_FD_OFFS_BEYOND_EOF(fd_data, offs) \ - (((fd_data)->size > offs) ? 0 : 1) - -#define L_FD_FAIL -1 -#define L_FD_SUCCESS 1 -#define L_FD_PAD_SIZE 255 - -struct fd_meta { - ErlDrvMutex *meta_mtx; - struct fd_data *fd_data_list; -}; - -struct fd_data { - int fd; - struct fd_data *next; - struct fd_data *prev; - int pos; - int beyond_eof; - size_t size; -#ifdef DEBUG - PROCESS owner; -#endif -}; - -static int l_invalidate_local_fd(int fd); -static int l_pad_file(struct fd_data *fd_data, off_t offset); -static int check_error(int result, Efile_error* errInfo); -static struct fd_data* l_new_fd(void); -static int l_remove_local_fd(int fd); -static struct fd_data* l_find_local_fd(int fd); -static int l_update_local_fd(int fd, int pos, int size); - -static struct fd_meta* fdm = NULL; - - -/***************************************************************************/ - -static int -l_remove_local_fd(int fd) -{ - struct fd_data *fd_data; - fd_data = l_find_local_fd(fd); - - if (fd_data == NULL) { - return L_FD_FAIL; - } -#ifdef DEBUG - assert(fd_data->owner == current_process()); -#endif - erl_drv_mutex_lock(fdm->meta_mtx); - /* head ? */ - if (fd_data == fdm->fd_data_list) { - if (fd_data->next != NULL) { - /* remove link to head */ - fd_data->next->prev = NULL; - /* set new head */ - fdm->fd_data_list = fd_data->next; - } - else { - /* head is lonely */ - fdm->fd_data_list = NULL; - } - } - else { /* not head */ - if (fd_data->prev == NULL) { - erl_drv_mutex_unlock(fdm->meta_mtx); - return L_FD_FAIL; - } - else { - if (fd_data->next != NULL) { - fd_data->next->prev = fd_data->prev; - fd_data->prev->next = fd_data->next; - } - else { - fd_data->prev->next = NULL; - } - } - } - - /* scramble values */ - fd_data->beyond_eof = -1; - fd_data->next = NULL; - fd_data->prev = NULL; - fd_data->fd = -1; - - /* unlock and clean */ - driver_free(fd_data); - erl_drv_mutex_unlock(fdm->meta_mtx); - - return L_FD_SUCCESS; -} - -/***************************************************************************/ - -static int -l_invalidate_local_fd(int fd) { - struct fd_data *fd_data; - - if ((fd_data = l_find_local_fd(fd)) == NULL) { - return L_FD_FAIL; - } - - fd_data->beyond_eof = 0; - return L_FD_SUCCESS; -} - -/****************************************************************************/ - -static struct fd_data* -l_find_local_fd(int fd) { - struct fd_data *fd_data; - - fd_data = NULL; - erl_drv_mutex_lock(fdm->meta_mtx); - for (fd_data = fdm->fd_data_list; fd_data != NULL; ) { - if (fd_data->fd == fd) { -#ifdef DEBUG - assert(fd_data->owner == current_process()); -#endif - break; - } - fd_data = fd_data->next; - } - erl_drv_mutex_unlock(fdm->meta_mtx); - return fd_data; -} - -/***************************************************************************/ - -static struct fd_data* -l_new_fd(void) { - struct fd_data *fd_data; - - fd_data = driver_alloc(sizeof(struct fd_data)); - if (fd_data == NULL) { - return NULL; - } - erl_drv_mutex_lock(fdm->meta_mtx); - if (fdm->fd_data_list == NULL) { - fdm->fd_data_list = fd_data; - fdm->fd_data_list->prev = NULL; - fdm->fd_data_list->next = NULL; - } - else { - fd_data->next = fdm->fd_data_list; - fdm->fd_data_list = fd_data; - fdm->fd_data_list->prev = NULL; - } -#ifdef DEBUG - fd_data->owner = current_process(); -#endif - erl_drv_mutex_unlock(fdm->meta_mtx); - return fd_data; -} - -/***************************************************************************/ - -static int -l_update_local_fd(int fd, int pos, int size) { - struct fd_data *fd_data = NULL; - - fd_data = l_find_local_fd(fd); - /* new fd to handle? */ - if (fd_data == NULL) { - fd_data = l_new_fd(); - if (fd_data == NULL) { - /* out of memory */ - return L_FD_FAIL; - } - } - fd_data->size = size; - fd_data->pos = pos; - fd_data->fd = fd; - fd_data->beyond_eof = 1; - - return L_FD_SUCCESS; -} - -/***************************************************************************/ - -static int -l_pad_file(struct fd_data *fd_data, off_t offset) { - int size_dif; - int written = 0; - int ret_val = L_FD_SUCCESS; - char padding[L_FD_PAD_SIZE]; - - size_dif = (offset - fd_data->size); - memset(&padding, '\0', L_FD_PAD_SIZE); - - while (size_dif > 0) { - written = write(fd_data->fd, padding, - (size_dif < L_FD_PAD_SIZE) ? - size_dif : L_FD_PAD_SIZE); - if (written < 0 && errno != EINTR && errno != EAGAIN) { - ret_val = -1; - break; - } - size_dif -= written; - } - L_FD_INVALIDATE(fd_data); - return ret_val; -} - -/***************************************************************************/ - -static int -check_error(int result, Efile_error *errInfo) { - if (result < 0) { - errInfo->posix_errno = errInfo->os_errno = errno; - return 0; - } - return 1; -} - -/***************************************************************************/ - -int -efile_init() { - fdm = driver_alloc(sizeof(struct fd_meta)); - if (fdm == NULL) { - return L_FD_FAIL; - } - fdm->meta_mtx = erl_drv_mutex_create("ose_efile local fd mutex\n"); - erl_drv_mutex_lock(fdm->meta_mtx); - fdm->fd_data_list = NULL; - erl_drv_mutex_unlock(fdm->meta_mtx); - return L_FD_SUCCESS; -} - -/***************************************************************************/ - -int -efile_mkdir(Efile_error* errInfo, /* Where to return error codes. */ - char* name) /* Name of directory to create. */ -{ -#ifdef NO_MKDIR_MODE - return check_error(mkdir(name), errInfo); -#else - int res = mkdir(name, DIR_MODE); - if (res < 0 && errno == EINVAL) { - errno = ENOENT; - } - return check_error(res, errInfo); -#endif -} - -/***************************************************************************/ - -int -efile_rmdir(Efile_error* errInfo, /* Where to return error codes. */ - char* name) /* Name of directory to delete. */ -{ - if (rmdir(name) == 0) { - return 1; - } - if (errno == ENOTEMPTY) { - errno = EEXIST; - } - if (errno == EEXIST || errno == EINVAL) { - int saved_errno = errno; - struct stat file_stat; - struct stat cwd_stat; - - if(stat(name, &file_stat) != 0) { - errno = ENOENT; - return check_error(-1, errInfo); - } - /* - * The error code might be wrong if this is the current directory. - */ - if (stat(name, &file_stat) == 0 && stat(".", &cwd_stat) == 0 && - file_stat.st_ino == cwd_stat.st_ino && - file_stat.st_dev == cwd_stat.st_dev) { - saved_errno = EACCES; - } - errno = saved_errno; - } - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_delete_file(Efile_error* errInfo, /* Where to return error codes. */ - char* name) /* Name of file to delete. */ -{ - struct stat statbuf; - - if (stat(name, &statbuf) >= 0) { - /* Do not let unlink() remove directories */ - if (ISDIR(statbuf)) { - errno = EPERM; - return check_error(-1, errInfo); - } - - if (unlink(name) == 0) { - return 1; - } - - if (errno == EISDIR) { - errno = EPERM; - return check_error(-1, errInfo); - } - } - else { - if (errno == EINVAL) { - errno = ENOENT; - return check_error(-1, errInfo); - } - } - return check_error(-1, errInfo); -} - -/* - *--------------------------------------------------------------------------- - * - * Changes the name of an existing file or directory, from src to dst. - * If src and dst refer to the same file or directory, does nothing - * and returns success. Otherwise if dst already exists, it will be - * deleted and replaced by src subject to the following conditions: - * If src is a directory, dst may be an empty directory. - * If src is a file, dst may be a file. - * In any other situation where dst already exists, the rename will - * fail. - * - * Results: - * If the directory was successfully created, returns 1. - * Otherwise the return value is 0 and errno is set to - * indicate the error. Some possible values for errno are: - * - * EACCES: src or dst parent directory can't be read and/or written. - * EEXIST: dst is a non-empty directory. - * EINVAL: src is a root directory or dst is a subdirectory of src. - * EISDIR: dst is a directory, but src is not. - * ENOENT: src doesn't exist, or src or dst is "". - * ENOTDIR: src is a directory, but dst is not. - * EXDEV: src and dst are on different filesystems. - * - * Side effects: - * The implementation of rename may allow cross-filesystem renames, - * but the caller should be prepared to emulate it with copy and - * delete if errno is EXDEV. - * - *--------------------------------------------------------------------------- - */ - -int -efile_rename(Efile_error* errInfo, /* Where to return error codes. */ - char* src, /* Original name. */ - char* dst) /* New name. */ -{ - - /* temporary fix AFM does not recognize ./<file name> - * in destination remove pending on adaption of AFM fix - */ - - char *dot_str; - if (dst != NULL) { - dot_str = strchr(dst, '.'); - if (dot_str && dot_str == dst && dot_str[1] == '/') { - dst = dst+2; - } - } - - if (rename(src, dst) == 0) { - return 1; - } - if (errno == ENOTEMPTY) { - errno = EEXIST; - } - if (errno == EINVAL) { - struct stat file_stat; - - if (stat(dst, &file_stat)== 0) { - if (ISDIR(file_stat)) { - errno = EISDIR; - } - else if (ISREG(file_stat)) { - errno = ENOTDIR; - } - else { - errno = EINVAL; - } - } - else { - errno = EINVAL; - } - } - - if (strcmp(src, "/") == 0) { - errno = EINVAL; - } - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_chdir(Efile_error* errInfo, /* Where to return error codes. */ - char* name) /* Name of directory to make current. */ -{ - return check_error(chdir(name), errInfo); -} - -/***************************************************************************/ - -int -efile_getdcwd(Efile_error* errInfo, /* Where to return error codes. */ - int drive, /* 0 - current, 1 - A, 2 - B etc. */ - char* buffer, /* Where to return the current - directory. */ - size_t size) /* Size of buffer. */ -{ - if (drive == 0) { - if (getcwd(buffer, size) == NULL) - return check_error(-1, errInfo); - - return 1; - } - - /* - * Drives other than 0 is not supported on Unix. - */ - - errno = ENOTSUP; - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_readdir(Efile_error* errInfo, /* Where to return error codes. */ - char* name, /* Name of directory to open. */ - EFILE_DIR_HANDLE* p_dir_handle, /* Pointer to directory - handle of - open directory.*/ - char* buffer, /* Pointer to buffer for - one filename. */ - size_t *size) /* in-out Size of buffer, length - of name. */ -{ - DIR *dp; /* Pointer to directory structure. */ - struct dirent* dirp; /* Pointer to directory entry. */ - - /* - * If this is the first call, we must open the directory. - */ - - if (*p_dir_handle == NULL) { - dp = opendir(name); - if (dp == NULL) - return check_error(-1, errInfo); - *p_dir_handle = (EFILE_DIR_HANDLE) dp; - } - - /* - * Retrieve the name of the next file using the directory handle. - */ - - dp = *((DIR **)((void *)p_dir_handle)); - for (;;) { - dirp = readdir(dp); - if (dirp == NULL) { - closedir(dp); - return 0; - } - if (IS_DOT_OR_DOTDOT(dirp->d_name)) - continue; - buffer[0] = '\0'; - strncat(buffer, dirp->d_name, (*size)-1); - *size = strlen(dirp->d_name); - return 1; - } -} - -/***************************************************************************/ - -int -efile_openfile(Efile_error* errInfo, /* Where to return error codes. */ - char* name, /* Name of directory to open. */ - int flags, /* Flags to user for opening. */ - int* pfd, /* Where to store the file - descriptor. */ - Sint64 *pSize) /* Where to store the size of the - file. */ -{ - struct stat statbuf; - int fd; - int mode; /* Open mode. */ - - if (stat(name, &statbuf) >= 0 && !ISREG(statbuf)) { - errno = EISDIR; - return check_error(-1, errInfo); - } - - switch (flags & (EFILE_MODE_READ|EFILE_MODE_WRITE)) { - case EFILE_MODE_READ: - mode = O_RDONLY; - break; - case EFILE_MODE_WRITE: - if (flags & EFILE_NO_TRUNCATE) - mode = O_WRONLY | O_CREAT; - else - mode = O_WRONLY | O_CREAT | O_TRUNC; - break; - case EFILE_MODE_READ_WRITE: - mode = O_RDWR | O_CREAT; - break; - default: - errno = EINVAL; - return check_error(-1, errInfo); - } - - - if (flags & EFILE_MODE_APPEND) { - mode &= ~O_TRUNC; - mode |= O_APPEND; - } - - if (flags & EFILE_MODE_EXCL) { - mode |= O_EXCL; - } - - fd = open(name, mode, FILE_MODE); - - if (!check_error(fd, errInfo)) - return 0; - - *pfd = fd; - if (pSize) { - *pSize = statbuf.st_size; - } - return 1; -} - -/***************************************************************************/ - -int -efile_may_openfile(Efile_error* errInfo, char *name) { - struct stat statbuf; /* Information about the file */ - int result; - - result = stat(name, &statbuf); - if (!check_error(result, errInfo)) - return 0; - if (!ISREG(statbuf)) { - errno = EISDIR; - return check_error(-1, errInfo); - } - return 1; -} - -/***************************************************************************/ - -void -efile_closefile(int fd) -{ - if (l_find_local_fd(fd) != NULL) { - l_remove_local_fd(fd); - } - close(fd); -} - -/***************************************************************************/ - -int -efile_fdatasync(Efile_error *errInfo, /* Where to return error codes. */ - int fd) /* File descriptor for file to sync data. */ -{ - return efile_fsync(errInfo, fd); -} - -/***************************************************************************/ - -int -efile_fsync(Efile_error *errInfo, /* Where to return error codes. */ - int fd) /* File descriptor for file to sync. */ -{ - return check_error(fsync(fd), errInfo); -} - -/***************************************************************************/ - -int -efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo, - char* name, int info_for_link) -{ - struct stat statbuf; /* Information about the file */ - int result; - - result = stat(name, &statbuf); - if (!check_error(result, errInfo)) { - return 0; - } - -#if SIZEOF_OFF_T == 4 - pInfo->size_high = 0; -#else - pInfo->size_high = (Uint32)(statbuf.st_size >> 32); -#endif - pInfo->size_low = (Uint32)statbuf.st_size; - -#ifdef NO_ACCESS - /* Just look at read/write access for owner. */ - - pInfo->access = ((statbuf.st_mode >> 6) & 07) >> 1; - -#else - pInfo->access = FA_NONE; - if (access(name, R_OK) == 0) - pInfo->access |= FA_READ; - if (access(name, W_OK) == 0) - pInfo->access |= FA_WRITE; - -#endif - - if (ISDEV(statbuf)) - pInfo->type = FT_DEVICE; - else if (ISDIR(statbuf)) - pInfo->type = FT_DIRECTORY; - else if (ISREG(statbuf)) - pInfo->type = FT_REGULAR; - else if (ISLNK(statbuf)) - pInfo->type = FT_SYMLINK; - else - pInfo->type = FT_OTHER; - - pInfo->accessTime = statbuf.st_atime; - pInfo->modifyTime = statbuf.st_mtime; - pInfo->cTime = statbuf.st_ctime; - - pInfo->mode = statbuf.st_mode; - pInfo->links = statbuf.st_nlink; - pInfo->major_device = statbuf.st_dev; - pInfo->inode = statbuf.st_ino; - pInfo->uid = statbuf.st_uid; - pInfo->gid = statbuf.st_gid; - - return 1; -} - -/***************************************************************************/ - -int -efile_write_info(Efile_error *errInfo, Efile_info *pInfo, char *name) -{ - /* - * On some systems chown will always fail for a non-root user unless - * POSIX_CHOWN_RESTRICTED is not set. Others will succeed as long as - * you don't try to chown a file to someone besides youself. - */ - if (pInfo->mode != -1) { - mode_t newMode = pInfo->mode & (S_ISUID | S_ISGID | - S_IRWXU | S_IRWXG | S_IRWXO); - if (chmod(name, newMode)) { - newMode &= ~(S_ISUID | S_ISGID); - if (chmod(name, newMode)) { - return check_error(-1, errInfo); - } - } - } - - return 1; -} - -/***************************************************************************/ - -int -efile_write(Efile_error* errInfo, /* Where to return error codes. */ - int flags, /* Flags given when file was - opened. */ - int fd, /* File descriptor to write to. */ - char* buf, /* Buffer to write. */ - size_t count) /* Number of bytes to write. */ -{ - ssize_t written; /* Bytes written in last operation. */ - struct fd_data *fd_data; - - if ((fd_data = l_find_local_fd(fd)) != NULL) { - if (L_FD_IS_VALID(fd_data)) { - /* we are beyond eof and need to pad*/ - if (l_pad_file(fd_data, L_FD_CUR(fd_data)) < 0) { - return check_error(-1, errInfo); - } - } - } - - while (count > 0) { - if ((written = write(fd, buf, count)) < 0) { - if (errno != EINTR) { - return check_error(-1, errInfo); - } - else { - written = 0; - } - } - ASSERT(written <= count); - buf += written; - count -= written; - } - return 1; -} - -/***************************************************************************/ - -int -efile_writev(Efile_error* errInfo, /* Where to return error codes */ - int flags, /* Flags given when file was - * opened */ - int fd, /* File descriptor to write to */ - SysIOVec* iov, /* Vector of buffer structs. - * The structs may be changed i.e. - * due to incomplete writes */ - int iovcnt) /* Number of structs in vector */ -{ - struct fd_data *fd_data; - int cnt = 0; /* Buffers so far written */ - - ASSERT(iovcnt >= 0); - if ((fd_data = l_find_local_fd(fd)) != NULL) { - if (L_FD_IS_VALID(fd_data)) { - /* we are beyond eof and need to pad*/ - if (l_pad_file(fd_data, L_FD_CUR(fd_data)) < 0) { - return check_error(-1, errInfo); - } - } - } - while (cnt < iovcnt) { - if ((! iov[cnt].iov_base) || (iov[cnt].iov_len <= 0)) { - /* Empty buffer - skip */ - cnt++; - } - else { /* Non-empty buffer */ - ssize_t w; /* Bytes written in this call */ - do { - w = write(fd, iov[cnt].iov_base, iov[cnt].iov_len); - } while (w < 0 && errno == EINTR); - - ASSERT(w <= iov[cnt].iov_len || w == -1); - - if (w < 0) { - return check_error(-1, errInfo); - } - /* Move forward to next buffer to write */ - for (; cnt < iovcnt && w > 0; cnt++) { - if (iov[cnt].iov_base && iov[cnt].iov_len > 0) { - if (w < iov[cnt].iov_len) { - /* Adjust the buffer for next write */ - iov[cnt].iov_len -= w; - iov[cnt].iov_base += w; - w = 0; - break; - } - else { - w -= iov[cnt].iov_len; - } - } - } - ASSERT(w == 0); - } /* else Non-empty buffer */ - } /* while (cnt< iovcnt) */ - return 1; -} - -/***************************************************************************/ - -int -efile_read(Efile_error* errInfo, /* Where to return error codes. */ - int flags, /* Flags given when file was opened. */ - int fd, /* File descriptor to read from. */ - char* buf, /* Buffer to read into. */ - size_t count, /* Number of bytes to read. */ - size_t *pBytesRead) /* Where to return number of - bytes read. */ -{ - ssize_t n; - struct fd_data *fd_data; - - if ((fd_data = l_find_local_fd(fd)) != NULL) { - if (L_FD_IS_VALID(fd_data)) { - *pBytesRead = 0; - return 1; - } - } - for (;;) { - if ((n = read(fd, buf, count)) >= 0) { - break; - } - else if (errno != EINTR) { - return check_error(-1, errInfo); - } - } - if (fd_data != NULL && L_FD_IS_VALID(fd_data)) { - L_FD_INVALIDATE(fd_data); - } - *pBytesRead = (size_t) n; - return 1; -} - -/* pread() and pwrite() */ -/* Some unix systems, notably Solaris has these syscalls */ -/* It is especially nice for i.e. the dets module to have support */ -/* for this, even if the underlying OS dosn't support it, it is */ -/* reasonably easy to work around by first calling seek, and then */ -/* calling read(). */ -/* This later strategy however changes the file pointer, which pread() */ -/* does not do. We choose to ignore this and say that the location */ -/* of the file pointer is undefined after a call to any of the p functions*/ - - -int -efile_pread(Efile_error* errInfo, /* Where to return error codes. */ - int fd, /* File descriptor to read from. */ - Sint64 offset, /* Offset in bytes from BOF. */ - char* buf, /* Buffer to read into. */ - size_t count, /* Number of bytes to read. */ - size_t *pBytesRead) /* Where to return - number of bytes read. */ -{ - int res = efile_seek(errInfo, fd, offset, EFILE_SEEK_SET, NULL); - if (res) { - return efile_read(errInfo, 0, fd, buf, count, pBytesRead); - } else { - return res; - } -} - - -/***************************************************************************/ - -int -efile_pwrite(Efile_error* errInfo, /* Where to return error codes. */ - int fd, /* File descriptor to write to. */ - char* buf, /* Buffer to write. */ - size_t count, /* Number of bytes to write. */ - Sint64 offset) /* where to write it */ -{ - int res = efile_seek(errInfo, fd, offset, EFILE_SEEK_SET, NULL); - - if (res) { - return efile_write(errInfo, 0, fd, buf, count); - } else { - return res; - } -} - -/***************************************************************************/ - -int -efile_seek(Efile_error* errInfo, /* Where to return error codes. */ - int fd, /* File descriptor to do the seek on. */ - Sint64 offset, /* Offset in bytes from the given - origin. */ - int origin, /* Origin of seek (SEEK_SET, SEEK_CUR, - SEEK_END). */ - Sint64 *new_location) /* Resulting new location in file. */ -{ - off_t off, result; - off = (off_t) offset; - - switch (origin) { - case EFILE_SEEK_SET: - origin = SEEK_SET; - break; - case EFILE_SEEK_CUR: - origin = SEEK_CUR; - break; - case EFILE_SEEK_END: - origin = SEEK_END; - break; - default: - errno = EINVAL; - return check_error(-1, errInfo); - } - - if (off != offset) { - errno = EINVAL; - return check_error(-1, errInfo); - } - - errno = 0; - result = lseek(fd, off, origin); - - if (result >= 0) { - l_invalidate_local_fd(fd); - } - - if (result < 0) - { - if (errno == ENOSYS) { - int size, cur_pos; - - if (off < 0) { - errno = EINVAL; - return check_error(-1, errInfo); - } - - cur_pos = lseek(fd, 0, SEEK_CUR); - size = lseek(fd, 0, SEEK_END); - - if (origin == SEEK_SET) { - result = offset; - } - else if (origin == SEEK_CUR) { - result = offset + cur_pos; - } - else if (origin == SEEK_END) { - result = size + offset; - } - - /* sanity check our result */ - if (size > result) { - return check_error(-1, errInfo); - } - - /* store the data localy */ - l_update_local_fd(fd, result, size); - - /* reset the original file position */ - if (origin != SEEK_END) { - lseek(fd, cur_pos, SEEK_SET); - } - } - else if (errno == 0) { - errno = EINVAL; - } - } - - if (new_location) { - *new_location = result; - } - - return 1; -} - -/***************************************************************************/ - -int -efile_truncate_file(Efile_error* errInfo, int *fd, int flags) -{ - off_t offset; - struct fd_data *fd_data; - - if ((fd_data = l_find_local_fd(*fd)) != NULL && L_FD_IS_VALID(fd_data)) { - offset = L_FD_CUR(fd_data); - } - else { - offset = lseek(*fd, 0, SEEK_CUR); - } - - return check_error(((offset >= 0) && - (ftruncate(*fd, offset) == 0)) ? 1 : -1, errInfo); -} - -/***************************************************************************/ - -int -efile_readlink(Efile_error* errInfo, char* name, char* buffer, size_t size) -{ - errno = ENOTSUP; - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_altname(Efile_error* errInfo, char* name, char* buffer, size_t size) -{ - errno = ENOTSUP; - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_link(Efile_error* errInfo, char* old, char* new) -{ - errno = ENOTSUP; - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_symlink(Efile_error* errInfo, char* old, char* new) -{ - errno = ENOTSUP; - return check_error(-1, errInfo); -} - -/***************************************************************************/ - -int -efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset, - Sint64 length, int advise) -{ - return check_error(posix_fadvise(fd, offset, length, advise), errInfo); -} - -/***************************************************************************/ - -static int -call_posix_fallocate(int fd, Sint64 offset, Sint64 length) -{ - int ret; - - /* - * On Linux and Solaris for example, posix_fallocate() returns - * a positive error number on error and it does not set errno. - * On FreeBSD however (9.0 at least), it returns -1 on error - * and it sets errno. - */ - do { - ret = posix_fallocate(fd, (off_t) offset, (off_t) length); - if (ret > 0) { - errno = ret; - ret = -1; - } - } while (ret != 0 && errno == EINTR); - - return ret; -} - -/***************************************************************************/ - -int -efile_fallocate(Efile_error* errInfo, int fd, Sint64 offset, Sint64 length) -{ - return check_error(call_posix_fallocate(fd, offset, length), errInfo); -} diff --git a/erts/emulator/drivers/ose/ose_signal_drv.c b/erts/emulator/drivers/ose/ose_signal_drv.c deleted file mode 100644 index 2be9462a47..0000000000 --- a/erts/emulator/drivers/ose/ose_signal_drv.c +++ /dev/null @@ -1,897 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2013-2013. 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% - */ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "errno.h" -#include "stdio.h" -#include "string.h" -#include "stddef.h" - -#include "sys.h" -#include "erl_driver.h" -#include "ose.h" - - -#ifdef HAVE_OSE_SPI_H -#include "ose_spi/ose_spi.h" -#endif - -#define DEBUG_ATTACH 0 -#define DEBUG_HUNT 0 -#define DEBUG_SEND 0 -#define DEBUG_LISTEN 0 - -#if 0 -#define DEBUGP(FMT,...) printf(FMT, __VA_ARGS__) -#else -#define DEBUGP(FMT,...) -#endif - -#if DEBUG_ATTACH -#define DEBUGP_ATTACH(...) DEBUGP( __VA_ARGS__) -#else -#define DEBUGP_ATTACH(...) -#endif - -#if DEBUG_HUNT -#define DEBUGP_HUNT(...) DEBUGP( __VA_ARGS__) -#else -#define DEBUGP_HUNT(...) -#endif - -#if DEBUG_LISTEN -#define DEBUGP_LISTEN(...) DEBUGP( __VA_ARGS__) -#else -#define DEBUGP_LISTEN(...) -#endif - -#if DEBUG_SEND -#define DEBUGP_SEND(...) DEBUGP( __VA_ARGS__) -#else -#define DEBUGP_SEND(...) -#endif - - -#define DRIVER_NAME "ose_signal_drv" -#define GET_SPID 1 -#define GET_NAME 2 -#define HUNT 100 -#define DEHUNT 101 -#define ATTACH 102 -#define DETACH 103 -#define SEND 104 -#define SEND_W_S 105 -#define LISTEN 106 -#define OPEN 200 - -#define REF_SEGMENT_SIZE 8 - -struct async { - SIGSELECT signo; - ErlDrvTermData port; - ErlDrvTermData proc; - PROCESS spid; - PROCESS target; - Uint32 ref; -}; - -/** - * OSE signals - **/ -union SIGNAL { - SIGSELECT signo; - struct async async; -}; - -/** - * The driver's context - **/ -typedef struct _driver_context { - ErlDrvPort port; - PROCESS spid; - ErlDrvEvent perm_events[2]; - ErlDrvEvent *events; - Uint32 event_cnt; - Uint32 ref; - Uint32 *outstanding_refs; - Uint32 outstanding_refs_max; - Uint32 outstanding_refs_cnt; -} driver_context_t; - -/** - * Global variables - **/ -static ErlDrvTermData a_ok; -static ErlDrvTermData a_error; -static ErlDrvTermData a_enomem; -static ErlDrvTermData a_enoent; -static ErlDrvTermData a_badarg; -static ErlDrvTermData a_mailbox_up; -static ErlDrvTermData a_mailbox_down; -static ErlDrvTermData a_ose_drv_reply; -static ErlDrvTermData a_message; -static PROCESS proxy_proc; - - -/** - * Serialize/unserialize unsigned 32-bit values - **/ -static char *put_u32(unsigned int value, char *ptr) { - *ptr++ = (value & 0xff000000) >> 24; - *ptr++ = (value & 0x00ff0000) >> 16; - *ptr++ = (value & 0x0000ff00) >> 8; - *ptr++ = (value & 0xff); - - return ptr; -} - -static unsigned int get_u32(char *ptr) { - unsigned int result = 0; - result += (ptr[0] & 0xff) << 24; - result += (ptr[1] & 0xff) << 16; - result += (ptr[2] & 0xff) << 8; - result += (ptr[3] & 0xff); - - return result; -} - - -/* Stolen from efile_drv.c */ - -/* char EV_CHAR_P(ErlIOVec *ev, int p, int q) */ -#define EV_CHAR_P(ev, p, q) \ - (((char *)(ev)->iov[(q)].iov_base) + (p)) - -/* int EV_GET_CHAR(ErlIOVec *ev, char *p, int *pp, int *qp) */ -#define EV_GET_CHAR(ev, p, pp, qp) ev_get_char(ev, p ,pp, qp) -static int -ev_get_char(ErlIOVec *ev, char *p, int *pp, int *qp) { - if (*(pp)+1 <= (ev)->iov[*(qp)].iov_len) { - *(p) = *EV_CHAR_P(ev, *(pp), *(qp)); - if (*(pp)+1 < (ev)->iov[*(qp)].iov_len) - *(pp) = *(pp)+1; - else { - (*(qp))++; - *pp = 0; - } - return !0; - } - return 0; -} - -/* Uint32 EV_UINT32(ErlIOVec *ev, int p, int q)*/ -#define EV_UINT32(ev, p, q) \ - ((Uint32) *(((unsigned char *)(ev)->iov[(q)].iov_base) + (p))) - -/* int EV_GET_UINT32(ErlIOVec *ev, Uint32 *p, int *pp, int *qp) */ -#define EV_GET_UINT32(ev, p, pp, qp) ev_get_uint32(ev,(Uint32*)(p),pp,qp) -static int -ev_get_uint32(ErlIOVec *ev, Uint32 *p, int *pp, int *qp) { - if (*(pp)+4 <= (ev)->iov[*(qp)].iov_len) { - *(p) = (EV_UINT32(ev, *(pp), *(qp)) << 24) - | (EV_UINT32(ev, *(pp)+1, *(qp)) << 16) - | (EV_UINT32(ev, *(pp)+2, *(qp)) << 8) - | (EV_UINT32(ev, *(pp)+3, *(qp))); - if (*(pp)+4 < (ev)->iov[*(qp)].iov_len) - *(pp) = *(pp)+4; - else { - (*(qp))++; - *pp = 0; - } - return !0; - } - return 0; -} - -/** - * Convinience macros - **/ -#define send_response(port,output) erl_drv_send_term(driver_mk_port(port),\ - driver_caller(port), output, sizeof(output) / sizeof(output[0])); - -void iov_memcpy(void *dest,ErlIOVec *ev,int ind,int off); -void iov_memcpy(void *dest,ErlIOVec *ev,int ind,int off) { - int i; - memcpy(dest,ev->iov[ind].iov_base+off,ev->iov[ind].iov_len-off); - for (i = ind+1; i < ev->vsize; i++) - memcpy(dest,ev->iov[i].iov_base,ev->iov[i].iov_len); -} - -/** - * Reference handling - **/ - -static int add_reference(driver_context_t *ctxt, Uint32 ref) { - - /* - * Premature optimizations may be evil, but they sure are fun. - */ - - if (ctxt->outstanding_refs == NULL) { - /* First ref to be ignored */ - ctxt->outstanding_refs = driver_alloc(REF_SEGMENT_SIZE*sizeof(Uint32)); - if (!ctxt->outstanding_refs) - return 1; - - memset(ctxt->outstanding_refs,0,REF_SEGMENT_SIZE*sizeof(Uint32)); - ctxt->outstanding_refs_max += REF_SEGMENT_SIZE; - ctxt->outstanding_refs[ctxt->outstanding_refs_cnt++] = ref; - } else if (ctxt->outstanding_refs_cnt == ctxt->outstanding_refs_max) { - /* Expand ref array */ - Uint32 *new_array; - ctxt->outstanding_refs_max += REF_SEGMENT_SIZE; - new_array = driver_realloc(ctxt->outstanding_refs, - ctxt->outstanding_refs_max*sizeof(Uint32)); - - if (!new_array) { - ctxt->outstanding_refs_max -= REF_SEGMENT_SIZE; - return 1; - } - - ctxt->outstanding_refs = new_array; - - memset(ctxt->outstanding_refs+ctxt->outstanding_refs_cnt,0, - REF_SEGMENT_SIZE*sizeof(Uint32)); - ctxt->outstanding_refs[ctxt->outstanding_refs_cnt++] = ref; - - } else { - /* Find an empty slot: - * First we try current index, - * then we scan for a slot. - */ - if (!ctxt->outstanding_refs[ctxt->outstanding_refs_cnt]) { - ctxt->outstanding_refs[ctxt->outstanding_refs_cnt++] = ref; - } else { - int i; - ASSERT(ctxt->outstanding_refs_cnt < ctxt->outstanding_refs_max); - for (i = 0; i < ctxt->outstanding_refs_max; i++) - if (!ctxt->outstanding_refs[i]) - break; - ASSERT(ctxt->outstanding_refs[i] == 0); - ctxt->outstanding_refs[i] = ref; - ctxt->outstanding_refs_cnt++; - } - } - return 0; -} - -/* Return 0 if removed, 1 if does not exist, */ -static int remove_reference(driver_context_t *ctxt, Uint32 ref) { - int i,j; - - if (ctxt->outstanding_refs_max == 0 && ctxt->outstanding_refs_cnt == 0) { - ASSERT(ctxt->outstanding_refs == NULL); - return 1; - } - - for (i = 0; i < ctxt->outstanding_refs_max; i++) { - if (ctxt->outstanding_refs[i] == ref) { - ctxt->outstanding_refs[i] = 0; - ctxt->outstanding_refs_cnt--; - i = -1; - break; - } - } - - if (i != -1) - return 1; - - if (ctxt->outstanding_refs_cnt == 0) { - driver_free(ctxt->outstanding_refs); - ctxt->outstanding_refs = NULL; - ctxt->outstanding_refs_max = 0; - } else if (ctxt->outstanding_refs_cnt == (ctxt->outstanding_refs_max - REF_SEGMENT_SIZE)) { - Uint32 *new_array; - for (i = 0, j = 0; i < ctxt->outstanding_refs_cnt; i++) { - if (ctxt->outstanding_refs[i] == 0) { - for (j = i+1; j < ctxt->outstanding_refs_max; j++) - if (ctxt->outstanding_refs[j]) { - ctxt->outstanding_refs[i] = ctxt->outstanding_refs[j]; - ctxt->outstanding_refs[j] = 0; - break; - } - } - } - ctxt->outstanding_refs_max -= REF_SEGMENT_SIZE; - new_array = driver_realloc(ctxt->outstanding_refs, - ctxt->outstanding_refs_max*sizeof(Uint32)); - if (!new_array) { - ctxt->outstanding_refs_max += REF_SEGMENT_SIZE; - return 2; - } - - ctxt->outstanding_refs = new_array; - - } - - return 0; -} - -/** - * The OSE proxy process. This only handles ERTS_SIGNAL_OSE_DRV_ATTACH. - * The process is needed because signals triggered by attach ignore - * redir tables. - * - * We have one global proxy process to save memory. An attempt to make each - * port phantom into a proxy was made, but that used way to much memory. - */ -static OS_PROCESS(driver_proxy_process) { - SIGSELECT sigs[] = {1,ERTS_SIGNAL_OSE_DRV_ATTACH}; - PROCESS master = 0; - - while (1) { - union SIGNAL *sig = receive(sigs); - - if (sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) { - - /* The first message is used to determine who to send messages to. */ - if (master == 0) - master = sender(&sig); - - if (sig->async.target == 0) { - PROCESS from = sender(&sig); - restore(sig); - DEBUGP_ATTACH("0x%x: got attach 0x%x, sending to 0x%x\n", - current_process(),from,master); - sig->async.target = from; - send(&sig,master); - } else { - PROCESS target = sig->async.target; - restore(sig); - sig->async.target = 0; - DEBUGP_ATTACH("0x%x: doing attach on 0x%x\n",current_process(),target); - attach(&sig,target); - } - } - } -} - - -/** - * Init routine for the driver - **/ -static int drv_init(void) { - - a_ok = driver_mk_atom("ok"); - a_error = driver_mk_atom("error"); - a_enomem = driver_mk_atom("enomem"); - a_enoent = driver_mk_atom("enoent"); - a_badarg = driver_mk_atom("badarg"); - a_mailbox_up = driver_mk_atom("mailbox_up"); - a_mailbox_down = driver_mk_atom("mailbox_down"); - a_ose_drv_reply = driver_mk_atom("ose_drv_reply"); - a_message = driver_mk_atom("message"); - - proxy_proc = create_process(get_ptype(current_process()), - "ose_signal_driver_proxy", - driver_proxy_process, 10000, - get_pri(current_process()), - 0, 0, NULL, 0, 0); - -#ifdef DEBUG - efs_clone(proxy_proc); -#endif - start(proxy_proc); - - return 0; -} - -/* Signal resolution callback */ -static ErlDrvOseEventId resolve_signal(union SIGNAL* osig) { - union SIGNAL *sig = osig; - if (sig->signo == ERTS_SIGNAL_OSE_DRV_HUNT || - sig->signo == ERTS_SIGNAL_OSE_DRV_ATTACH) { - return sig->async.spid; - } - DEBUGP("%p: Got signal %d sent to %p from 0x%p\n", - current_process(),sig->signo,addressee(&sig),sender(&sig)); - return addressee(&sig); -} - - -/** - * Start routine for the driver - **/ -static ErlDrvData drv_start(ErlDrvPort port, char *command) -{ - driver_context_t *ctxt = driver_alloc(sizeof(driver_context_t)); - - ctxt->perm_events[0] = NULL; - ctxt->perm_events[1] = NULL; - - ctxt->spid = 0; - ctxt->port = port; - ctxt->event_cnt = 0; - ctxt->events = NULL; - ctxt->ref = 0; - ctxt->outstanding_refs = NULL; - ctxt->outstanding_refs_max = 0; - ctxt->outstanding_refs_cnt = 0; - - - /* Set the communication protocol to Erlang to be binary */ - set_port_control_flags(port, PORT_CONTROL_FLAG_BINARY); - - /* Everything ok */ - return (ErlDrvData)ctxt; -} - -/** - * Stop routine for the driver - **/ -static void drv_stop(ErlDrvData driver_data) -{ - driver_context_t *ctxt = (driver_context_t *)driver_data; - int i; - - /* HUNT + ATTACH */ - if (ctxt->perm_events[0]) - driver_select(ctxt->port, ctxt->perm_events[0], - ERL_DRV_USE|ERL_DRV_READ, 0); - if (ctxt->perm_events[1]) - driver_select(ctxt->port, ctxt->perm_events[1], - ERL_DRV_USE|ERL_DRV_READ, 0); - - for (i = 0; i < ctxt->event_cnt; i++) { - driver_select(ctxt->port, ctxt->events[i], ERL_DRV_USE|ERL_DRV_READ, 0); - } - - if (ctxt->spid != 0) - kill_proc(ctxt->spid); - DEBUGP("0x%x: stopped\n",ctxt->spid); - if (ctxt->events) - driver_free(ctxt->events); - if (ctxt->outstanding_refs) - driver_free(ctxt->outstanding_refs); - - driver_free(ctxt); -} - -/** - * Output from Erlang - **/ -static void outputv(ErlDrvData driver_data, ErlIOVec *ev) -{ - driver_context_t *ctxt = (driver_context_t *)driver_data; - int p = 0, q = 1; - char cmd; - - if (! EV_GET_CHAR(ev,&cmd,&p,&q)) { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_badarg, - ERL_DRV_TUPLE, 3}; - send_response(ctxt->port, output); - return; - } - - /* Command is in the buffer's first byte */ - switch(cmd) { - - case OPEN: { - char *name = driver_alloc(ev->size - 1+1); - struct OS_redir_entry redir[2]; - - redir[0].sig = 1; - redir[0].pid = current_process(); - - iov_memcpy(name,ev,q,p); - name[ev->size-1] = '\0'; - - ctxt->spid = create_process(OS_PHANTOM, name, NULL, 0, - 0, 0, 0, redir, 0, 0); - - DEBUGP("0x%x: open\n",ctxt->spid); - - ctxt->perm_events[1] = - erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH,(int)ctxt->spid, - resolve_signal, NULL); - driver_select(ctxt->port,ctxt->perm_events[1],ERL_DRV_READ|ERL_DRV_USE,1); - - ctxt->perm_events[0] = - erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_HUNT,(int)ctxt->spid, - resolve_signal, NULL); - driver_select(ctxt->port,ctxt->perm_events[0],ERL_DRV_READ|ERL_DRV_USE,1); - - start(ctxt->spid); - - { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_ok, - ERL_DRV_TUPLE, 3}; - - send_response(ctxt->port, output); - } - - break; - - } - - case ATTACH: - case HUNT: - { - union SIGNAL *sig = alloc(sizeof(union SIGNAL), - cmd == HUNT ? ERTS_SIGNAL_OSE_DRV_HUNT:ERTS_SIGNAL_OSE_DRV_ATTACH); - - sig->async.port = driver_mk_port(ctxt->port); - sig->async.proc = driver_caller(ctxt->port); - sig->async.spid = ctxt->spid; - sig->async.ref = ++ctxt->ref; - - if (add_reference(ctxt,ctxt->ref)) { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_enomem, - ERL_DRV_TUPLE, 3}; - send_response(ctxt->port, output); - free_buf(&sig); - } else { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_INT, (ErlDrvUInt)ctxt->ref, - ERL_DRV_TUPLE, 2, - ERL_DRV_TUPLE, 3}; - send_response(ctxt->port, output); - - if (cmd == HUNT) { - char *huntname = driver_alloc(sizeof(char)*((ev->size-1)+1)); - - iov_memcpy(huntname,ev,q,p); - huntname[ev->size-1] = '\0'; - - DEBUGP_HUNT("0x%x: hunt %s -> %u (%u,%u)\n", - ctxt->spid,huntname,ctxt->ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - - hunt(huntname, 0, NULL, &sig); - - driver_free(huntname); - } else { - EV_GET_UINT32(ev,&sig->async.target,&p,&q); - DEBUGP_ATTACH("0x%x: attach %u -> %u (%u,%u)\n", - ctxt->spid,sig->async.target, - ctxt->ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - - send(&sig,proxy_proc); - } - - } - - break; - } - - case DETACH: - case DEHUNT: - { - - Uint32 ref; - - EV_GET_UINT32(ev,&ref,&p,&q); - if (cmd == DETACH) { - DEBUGP_ATTACH("0x%x: detach %u (%u,%u)\n",ctxt->spid,ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - } else { - DEBUGP_HUNT("0x%x: dehunt %u (%u,%u)\n",ctxt->spid,ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - } - - if (remove_reference(ctxt,ref)) { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_error, - ERL_DRV_ATOM, a_enoent, - ERL_DRV_TUPLE, 2, - ERL_DRV_TUPLE, 3}; - - send_response(ctxt->port, output); - } else { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_ok, - ERL_DRV_TUPLE, 3}; - - send_response(ctxt->port, output); - } - - break; - } - - case SEND: - case SEND_W_S: - { - PROCESS spid; - PROCESS sender; - SIGSELECT signo; - OSBUFSIZE size = ev->size-9; - union SIGNAL *sig; - - EV_GET_UINT32(ev,&spid,&p,&q); - - if (cmd == SEND_W_S) { - EV_GET_UINT32(ev,&sender,&p,&q); - size -= 4; - } else { - sender = ctxt->spid; - } - - EV_GET_UINT32(ev,&signo,&p,&q); - - sig = alloc(size + sizeof(SIGSELECT),signo); - - if (cmd == SEND_W_S) { - DEBUGP_SEND("0x%x: send_w_s(%u,%u,%u)\n",ctxt->spid,spid,signo,sender); - } else { - DEBUGP_SEND("0x%x: send(%u,%u)\n",ctxt->spid,spid,signo); - } - - iov_memcpy(((char *)&sig->signo) + sizeof(SIGSELECT),ev,q,p); - - send_w_s(&sig, sender, spid); - - break; - } - - case LISTEN: - { - int i,j,event_cnt = (ev->size - 1)/4; - ErlDrvEvent *events = NULL; - SIGSELECT signo,tmp_signo; - - if (event_cnt == 0) { - for (i = 0; i < ctxt->event_cnt; i++) - driver_select(ctxt->port,ctxt->events[i],ERL_DRV_READ|ERL_DRV_USE,0); - if (ctxt->events) - driver_free(ctxt->events); - } else { - events = driver_alloc(sizeof(ErlDrvEvent)*event_cnt); - EV_GET_UINT32(ev,&signo,&p,&q); - for (i = 0, j = 0; i < event_cnt || j < ctxt->event_cnt; ) { - - if (ctxt->events) - erl_drv_ose_event_fetch(ctxt->events[j],&tmp_signo,NULL,NULL); - - if (signo == tmp_signo) { - events[i++] = ctxt->events[j++]; - EV_GET_UINT32(ev,&signo,&p,&q); - } else if (signo < tmp_signo || !ctxt->events) { - /* New signal to select on */ - events[i] = erl_drv_ose_event_alloc(signo,(int)ctxt->spid, - resolve_signal, NULL); - driver_select(ctxt->port,events[i++],ERL_DRV_READ|ERL_DRV_USE,1); - EV_GET_UINT32(ev,&signo,&p,&q); - } else { - /* Remove old signal to select on */ - driver_select(ctxt->port,ctxt->events[j++],ERL_DRV_READ|ERL_DRV_USE,0); - } - } - if (ctxt->events) - driver_free(ctxt->events); - } - ctxt->events = events; - ctxt->event_cnt = event_cnt; - - { - ErlDrvTermData output[] = { - ERL_DRV_ATOM, a_ose_drv_reply, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_ATOM, a_ok, - ERL_DRV_TUPLE, 3}; - send_response(ctxt->port, output); - } - break; - } - - default: - { - DEBUGP("Warning: 'ose_signal_drv' unknown command '%d'\n", cmd); - break; - } - } -} - -/** - * Handler for when OSE signal arrives - **/ -static void ready_input(ErlDrvData driver_data, ErlDrvEvent event) -{ - driver_context_t *ctxt = (driver_context_t *)driver_data; - union SIGNAL *sig = erl_drv_ose_get_signal(event); - - while (sig != NULL) { - - switch(sig->signo) - { - /* Remote process is available */ - case ERTS_SIGNAL_OSE_DRV_HUNT: - { - const PROCESS spid = sender(&sig); - - if (remove_reference(ctxt,sig->async.ref)) { - DEBUGP_HUNT("0x%x: Got hunt from 0x%x -> %u (CANCELLED) (%u,%u)\n", - ctxt->spid,spid,sig->async.ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - /* Already removed by dehunt */ - } else { - ErlDrvTermData reply[] = { - ERL_DRV_ATOM, a_mailbox_up, - ERL_DRV_PORT, sig->async.port, - ERL_DRV_PORT, sig->async.port, - ERL_DRV_UINT, (ErlDrvUInt)sig->async.ref, - ERL_DRV_TUPLE, 2, - ERL_DRV_UINT, (ErlDrvUInt)spid, - ERL_DRV_TUPLE, 4}; - DEBUGP_HUNT("0x%x: Got hunt from 0x%x -> %u (%u,%u)\n", - ctxt->spid,spid,sig->async.ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - erl_drv_send_term(sig->async.port, sig->async.proc, reply, - sizeof(reply) / sizeof(reply[0])); - } - break; - } - - /* Remote process is down */ - case ERTS_SIGNAL_OSE_DRV_ATTACH: - { - PROCESS spid = sig->async.target; - - if (remove_reference(ctxt,sig->async.ref)) { - DEBUGP_ATTACH("0x%x: Got attach from 0x%x -> %u (CANCELLED) (%u,%u)\n", - ctxt->spid,spid,sig->async.ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - /* Already removed by detach */ - } else { - ErlDrvTermData reply[] = { - ERL_DRV_ATOM, a_mailbox_down, - ERL_DRV_PORT, sig->async.port, - ERL_DRV_PORT, sig->async.port, - ERL_DRV_UINT, sig->async.ref, - ERL_DRV_TUPLE, 2, - ERL_DRV_UINT, (ErlDrvUInt)spid, - ERL_DRV_TUPLE, 4}; - DEBUGP_ATTACH("0x%x: Got attach from 0x%x -> %u (%u,%u)\n", - ctxt->spid,spid,sig->async.ref, - ctxt->outstanding_refs_cnt, - ctxt->outstanding_refs_max); - erl_drv_send_term(sig->async.port, sig->async.proc, reply, - sizeof(reply) / sizeof(reply[0])); - } - break; - } - - /* Received user defined signal */ - default: - { - const PROCESS spid = sender(&sig); - const OSBUFSIZE size = sigsize(&sig) - sizeof(SIGSELECT); - const char *sig_data = ((char *)&sig->signo) + sizeof(SIGSELECT); - - ErlDrvTermData reply[] = { - ERL_DRV_ATOM, a_message, - ERL_DRV_PORT, driver_mk_port(ctxt->port), - ERL_DRV_UINT, (ErlDrvUInt)spid, - ERL_DRV_UINT, (ErlDrvUInt)ctxt->spid, - ERL_DRV_UINT, (ErlDrvUInt)sig->signo, - ERL_DRV_BUF2BINARY, (ErlDrvTermData)sig_data, (ErlDrvUInt)size, - ERL_DRV_TUPLE, 4, - ERL_DRV_TUPLE, 3}; - - DEBUGP_SEND("0x%x: Got 0x%u\r\n", spid, sig->signo); - - erl_drv_output_term(driver_mk_port(ctxt->port), reply, - sizeof(reply) / sizeof(reply[0])); - break; - } - } - - free_buf(&sig); - sig = erl_drv_ose_get_signal(event); - } -} - -/** - * Handler for 'port_control' - **/ -static ErlDrvSSizeT control(ErlDrvData driver_data, unsigned int cmd, - char *buf, ErlDrvSizeT len, - char **rbuf, ErlDrvSizeT rlen) -{ - driver_context_t *ctxt = (driver_context_t *)driver_data; - - switch(cmd) - { - case GET_SPID: - { - const PROCESS spid = ctxt->spid; - put_u32(spid, *rbuf); - return sizeof(PROCESS); - } - -#ifdef HAVE_OSE_SPI_H - case GET_NAME: - { - const PROCESS spid = get_u32(buf); - char *name = (char*)get_pid_info(spid,OSE_PI_NAME); - int n; - if (!name) { - *rbuf = NULL; - return 0; - } - - if (rlen < (n = strlen(name))) { - ErlDrvBinary *bin = driver_alloc_binary(n); - strncpy(bin->orig_bytes,name,n); - *rbuf = (char*)bin; - } else - strncpy(*rbuf,name,n); - free_buf((union SIGNAL**)&name); - - return n; - } -#endif - default: - { - /* Unknown command */ - return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL; - break; - } - } -} - -static void stop_select(ErlDrvEvent event, void *reserved) -{ - erl_drv_ose_event_free(event); -} - -/** - * Setup the driver entry for the Erlang runtime - **/ -ErlDrvEntry ose_signal_driver_entry = { - .init = drv_init, - .start = drv_start, - .stop = drv_stop, - .outputv = outputv, - .ready_input = ready_input, - .driver_name = DRIVER_NAME, - .control = control, - .extended_marker = ERL_DRV_EXTENDED_MARKER, - .major_version = ERL_DRV_EXTENDED_MAJOR_VERSION, - .minor_version = ERL_DRV_EXTENDED_MINOR_VERSION, - .driver_flags = ERL_DRV_FLAG_USE_PORT_LOCKING, - .stop_select = stop_select -}; - diff --git a/erts/emulator/drivers/ose/ttsl_drv.c b/erts/emulator/drivers/ose/ttsl_drv.c deleted file mode 100644 index f759b47984..0000000000 --- a/erts/emulator/drivers/ose/ttsl_drv.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2013. 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% - */ -/* - * Stub tty driver because group/user depend on this. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "erl_driver.h" - -static int ttysl_init(void); -static ErlDrvData ttysl_start(ErlDrvPort, char*); - -/* Define the driver table entry. */ -struct erl_drv_entry ttsl_driver_entry = { - ttysl_init, - ttysl_start, - NULL, - NULL, - NULL, - NULL, - "tty_sl", - NULL, - NULL, - NULL, - NULL, /* timeout */ - NULL, /* outputv */ - NULL, /* ready_async */ - NULL, /* flush */ - NULL, /* call */ - NULL, /* event */ - ERL_DRV_EXTENDED_MARKER, - ERL_DRV_EXTENDED_MAJOR_VERSION, - ERL_DRV_EXTENDED_MINOR_VERSION, - 0, /* ERL_DRV_FLAGs */ - NULL, - NULL, /* process_exit */ - NULL -}; - - -static int ttysl_init(void) -{ - return 0; -} - -static ErlDrvData ttysl_start(ErlDrvPort port, char* buf) -{ - return ERL_DRV_ERROR_GENERAL; -} diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index 105b129065..f87196d724 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -1337,11 +1337,7 @@ print_select_op(erts_dsprintf_buf_t *dsbufp, { Port *pp = erts_drvport2port(ix); erts_dsprintf(dsbufp, -#ifdef __OSE__ - "driver_select(%p, %d,%s%s%s%s | %d, %d) " -#else "driver_select(%p, %d,%s%s%s%s, %d) " -#endif "by ", ix, (int) GET_FD(fd), @@ -1861,25 +1857,6 @@ stale_drv_select(Eterm id, ErtsDrvEventState *state, int mode) #ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS -#ifdef __OSE__ -static SafeHashValue drv_ev_state_hash(void *des) -{ - ErtsSysFdType fd = ((ErtsDrvEventState *) des)->fd; - /* We use hash on signo ^ id in order for steal to happen when the - same signo + fd is selected on by two different ports */ - SafeHashValue val = (SafeHashValue)(fd->signo ^ fd->id); - return val ^ (val >> 8); -} - -static int drv_ev_state_cmp(void *des1, void *des2) -{ - ErtsSysFdType fd1 = ((ErtsDrvEventState *) des1)->fd; - ErtsSysFdType fd2 = ((ErtsDrvEventState *) des2)->fd; - if (fd1->signo == fd2->signo && fd1->id == fd2->id) - return 0; - return 1; -} -#else /* !__OSE__ && !ERTS_SYS_CONTINOUS_FD_NUMBERS i.e. probably windows */ static SafeHashValue drv_ev_state_hash(void *des) { SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd; @@ -1891,7 +1868,6 @@ static int drv_ev_state_cmp(void *des1, void *des2) return ( ((ErtsDrvEventState *) des1)->fd == ((ErtsDrvEventState *) des2)->fd ? 0 : 1); } -#endif static void *drv_ev_state_alloc(void *des_tmpl) { diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h index 19ce582154..6d8aef822e 100644 --- a/erts/emulator/sys/common/erl_poll.h +++ b/erts/emulator/sys/common/erl_poll.h @@ -93,7 +93,7 @@ # if defined(ERTS_USE_POLL) # undef ERTS_POLL_USE_POLL # define ERTS_POLL_USE_POLL 1 -# elif !defined(__WIN32__) && !defined(__OSE__) +# elif !defined(__WIN32__) # undef ERTS_POLL_USE_SELECT # define ERTS_POLL_USE_SELECT 1 # endif @@ -104,31 +104,13 @@ typedef Uint32 ErtsPollEvents; #undef ERTS_POLL_EV_E2N -#if defined(__WIN32__) || defined(__OSE__) /* --- win32 or ose -------- */ +#if defined(__WIN32__) /* --- win32 --------------------------------------- */ #define ERTS_POLL_EV_IN 1 #define ERTS_POLL_EV_OUT 2 #define ERTS_POLL_EV_ERR 4 #define ERTS_POLL_EV_NVAL 8 -#ifdef __OSE__ - -typedef struct ErtsPollOseMsgList_ { - struct ErtsPollOseMsgList_ *next; - union SIGNAL *data; -} ErtsPollOseMsgList; - -struct erts_sys_fd_type { - SIGSELECT signo; - ErlDrvOseEventId id; - ErtsPollOseMsgList *msgs; - ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig); - ethr_mutex mtx; - void *extra; -}; - -#endif - #elif ERTS_POLL_USE_EPOLL /* --- epoll ------------------------------- */ #include <sys/epoll.h> diff --git a/erts/emulator/sys/ose/beam.lmconf b/erts/emulator/sys/ose/beam.lmconf deleted file mode 100644 index 4ad46b01d9..0000000000 --- a/erts/emulator/sys/ose/beam.lmconf +++ /dev/null @@ -1,26 +0,0 @@ -OSE_LM_STACK_SIZES=256,512,1024,2048,4096,8192,16384,65536 -OSE_LM_SIGNAL_SIZES=31,63,127,255,1023,4095,16383,65535 -OSE_LM_POOL_SIZE=0x200000 -OSE_LM_MAIN_NAME=main -OSE_LM_MAIN_STACK_SIZE=0xF000 -OSE_LM_MAIN_PRIORITY=20 -## Has to be of a type that allows MAM -OSE_LM_PROGRAM_TYPE=APP_RAM -OSE_LM_DATA_INIT=YES -OSE_LM_BSS_INIT=YES -OSE_LM_EXEC_MODEL=SHARED -HEAP_MAX_SIZE=1000000000 -HEAP_SMALL_BUF_INIT_SIZE=20971520 -HEAP_LARGE_BUF_THRESHOLD=16000000 -HEAP_LOCK_TYPE=2 - -ERTS_DEFAULT_PRIO=24 -ERTS_SCHEDULER_PRIO=24 -ERTS_ASYNC_PRIO=22 -ERTS_AUX_PRIO=24 -ERTS_SYS_MSG_DISPATCHER_PRIO=21 - -# Setting the environment variable EFS_RESOLVE_TMO on the block to 0. -# This will eliminiate delays when trying to open files on not mounted -# volumes. -EFS_RESOLVE_TMO=0 diff --git a/erts/emulator/sys/ose/driver_int.h b/erts/emulator/sys/ose/driver_int.h deleted file mode 100644 index 4a5b7171d1..0000000000 --- a/erts/emulator/sys/ose/driver_int.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1997-2009. 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% - */ -/* - * System dependant driver declarations - */ - -#ifndef __DRIVER_INT_H__ -#define __DRIVER_INT_H__ - -#ifdef HAVE_SYS_UIO_H -#include <sys/types.h> -#include <sys/uio.h> - -typedef struct iovec SysIOVec; - -#else - -typedef struct { - char* iov_base; - int iov_len; -} SysIOVec; - -#endif - -#endif diff --git a/erts/emulator/sys/ose/erl_main.c b/erts/emulator/sys/ose/erl_main.c deleted file mode 100644 index 877e85f43a..0000000000 --- a/erts/emulator/sys/ose/erl_main.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2000-2009. 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% - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include <stdlib.h> - -#include "sys.h" -#include "erl_vm.h" -#include "global.h" -#include "ose.h" - -int -main(int argc, char **argv) { - - (void)stdin;(void)stdout;(void)stderr; - - /* When starting using pm_create -c ARGV="-- -root ..", argv[0] is the first - part of ARGV and not the name of the executable. So we shuffle some - pointers here to make erl_start happy. */ - if (argv[0][0] == '-') { - int i; - char **tmp_argv = malloc(sizeof(char*)*(argc+1)); - for (i = 0; i < argc; i++) - tmp_argv[i+1] = argv[i]; - tmp_argv[0] = "beam"; - erl_start(argc+1,tmp_argv); - free(tmp_argv); - } else { - erl_start(argc,argv); - } - - stop(current_process()); - - return 0; -} diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h deleted file mode 100644 index d0cd3180bf..0000000000 --- a/erts/emulator/sys/ose/erl_ose_sys.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * %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 */ diff --git a/erts/emulator/sys/ose/erl_ose_sys_ddll.c b/erts/emulator/sys/ose/erl_ose_sys_ddll.c deleted file mode 100644 index 5051f7fcc1..0000000000 --- a/erts/emulator/sys/ose/erl_ose_sys_ddll.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2006-2013. 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% - */ - -/* - * Interface functions to the dynamic linker using dl* functions. - * (No support in OSE, we use static linkage instead) - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "sys.h" -#include "erl_vm.h" -#include "global.h" - - -void erl_sys_ddll_init(void) { -} - -/* - * Open a shared object - */ -int erts_sys_ddll_open(const char *full_name, void **handle, ErtsSysDdllError* err) -{ - return ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY; -} - -int erts_sys_ddll_open_noext(char *dlname, void **handle, ErtsSysDdllError* err) -{ - return ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY; -} - -/* - * Find a symbol in the shared object - */ -int erts_sys_ddll_sym2(void *handle, const char *func_name, void **function, - ErtsSysDdllError* err) -{ - return ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY; -} - -/* XXX:PaN These two will be changed with new driver interface! */ - -/* - * Load the driver init function, might appear under different names depending on object arch... - */ - -int erts_sys_ddll_load_driver_init(void *handle, void **function) -{ - void *fn; - int res; - if ((res = erts_sys_ddll_sym2(handle, "driver_init", &fn, NULL)) != ERL_DE_NO_ERROR) { - res = erts_sys_ddll_sym2(handle, "_driver_init", &fn, NULL); - } - if (res == ERL_DE_NO_ERROR) { - *function = fn; - } - return res; -} - -int erts_sys_ddll_load_nif_init(void *handle, void **function, ErtsSysDdllError* err) -{ - void *fn; - int res; - if ((res = erts_sys_ddll_sym2(handle, "nif_init", &fn, err)) != ERL_DE_NO_ERROR) { - res = erts_sys_ddll_sym2(handle, "_nif_init", &fn, err); - } - if (res == ERL_DE_NO_ERROR) { - *function = fn; - } - return res; -} - -/* - * Call the driver_init function, whatever it's really called, simple on unix... -*/ -void *erts_sys_ddll_call_init(void *function) { - void *(*initfn)(void) = function; - return (*initfn)(); -} -void *erts_sys_ddll_call_nif_init(void *function) { - return erts_sys_ddll_call_init(function); -} - - - -/* - * Close a chared object - */ -int erts_sys_ddll_close2(void *handle, ErtsSysDdllError* err) -{ - return ERL_DE_ERROR_NO_DDLL_FUNCTIONALITY; -} - - -/* - * Return string that describes the (current) error - */ -char *erts_sys_ddll_error(int code) -{ - return "Unspecified error"; -} - -void erts_sys_ddll_free_error(ErtsSysDdllError* err) -{ - if (err->str != NULL) { - erts_free(ERTS_ALC_T_DDLL_TMP_BUF, err->str); - } -} diff --git a/erts/emulator/sys/ose/erl_poll.c b/erts/emulator/sys/ose/erl_poll.c deleted file mode 100644 index 5cee582a00..0000000000 --- a/erts/emulator/sys/ose/erl_poll.c +++ /dev/null @@ -1,818 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2006-2012. 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% - */ - -/* - * Description: Poll interface suitable for ERTS on OSE with or without - * SMP support. - * - * The interface is currently implemented using: - * - receive + receive_fsem - * - * Author: Lukas Larsson - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "erl_thr_progress.h" -#include "erl_driver.h" -#include "erl_alloc.h" -#include "erl_poll.h" - -#define NOFILE 4096 - -/* - * Some debug macros - */ - -/* #define HARDDEBUG -#define HARDTRACE*/ -#ifdef HARDDEBUG -#ifdef HARDTRACE -#define HARDTRACEF(X, ...) { fprintf(stderr, X, __VA_ARGS__); fprintf(stderr,"\r\n"); } -#else -#define HARDTRACEF(...) -#endif - -#else -#define HARDTRACEF(X,...) -#define HARDDEBUGF(...) -#endif - -#if 0 -#define ERTS_POLL_DEBUG_PRINT -#endif - -#if defined(DEBUG) && 0 -#define HARD_DEBUG -#endif - -# define SEL_ALLOC erts_alloc -# define SEL_REALLOC realloc_wrap -# define SEL_FREE erts_free - -#ifdef ERTS_SMP - -#define ERTS_POLLSET_LOCK(PS) \ - erts_smp_mtx_lock(&(PS)->mtx) -#define ERTS_POLLSET_UNLOCK(PS) \ - erts_smp_mtx_unlock(&(PS)->mtx) - -#else - -#define ERTS_POLLSET_LOCK(PS) -#define ERTS_POLLSET_UNLOCK(PS) - -#endif - -/* - * --- Data types ------------------------------------------------------------ - */ - -union SIGNAL { - SIGSELECT sig_no; -}; - -typedef struct erts_sigsel_item_ ErtsSigSelItem; - -struct erts_sigsel_item_ { - ErtsSigSelItem *next; - ErtsSysFdType fd; - ErtsPollEvents events; -}; - -typedef struct erts_sigsel_info_ ErtsSigSelInfo; - -struct erts_sigsel_info_ { - ErtsSigSelInfo *next; - SIGSELECT signo; - ErlDrvOseEventId (*decode)(union SIGNAL* sig); - ErtsSigSelItem *fds; -}; - -struct ErtsPollSet_ { - SIGSELECT *sigs; - ErtsSigSelInfo *info; - Uint sig_count; - Uint item_count; - PROCESS interrupt; - erts_atomic32_t wakeup_state; - erts_atomic64_t timeout_time; -#ifdef ERTS_SMP - erts_smp_mtx_t mtx; -#endif -}; - -static int max_fds = -1; - -static ERTS_INLINE void -init_timeout_time(ErtsPollSet ps) -{ - erts_atomic64_init_nob(&ps->timeout_time, - (erts_aint64_t) ERTS_MONOTONIC_TIME_MAX); -} - -static ERTS_INLINE void -set_timeout_time(ErtsPollSet ps, ErtsMonotonicTime time) -{ - erts_atomic64_set_relb(&ps->timeout_time, - (erts_aint64_t) time); -} - -static ERTS_INLINE ErtsMonotonicTime -get_timeout_time(ErtsPollSet ps) -{ - return (ErtsMonotonicTime) erts_atomic64_read_acqb(&ps->timeout_time); -} - -#define ERTS_POLL_NOT_WOKEN ((erts_aint32_t) (1 << 0)) -#define ERTS_POLL_WOKEN_INTR ((erts_aint32_t) (1 << 1)) -#define ERTS_POLL_WOKEN_TIMEDOUT ((erts_aint32_t) (1 << 2)) -#define ERTS_POLL_WOKEN_IO_READY ((erts_aint32_t) (1 << 3)) -#define ERTS_POLL_SLEEPING ((erts_aint32_t) (1 << 4)) - -/* signal list prototypes */ -static ErtsSigSelInfo *get_sigsel_info(ErtsPollSet ps, SIGSELECT signo); -static ErtsSigSelItem *get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd); -static ErtsSigSelInfo *add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd, - ErlDrvOseEventId (*decode)(union SIGNAL* sig)); -static ErtsSigSelItem *add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd, - ErlDrvOseEventId (*decode)(union SIGNAL* sig)); -static int del_sigsel_info(ErtsPollSet ps, ErtsSigSelInfo *info); -static int del_sigsel_item(ErtsPollSet ps, ErtsSigSelItem *item); -static int update_sigsel(ErtsPollSet ps); - -static ErtsSigSelInfo * -get_sigsel_info(ErtsPollSet ps, SIGSELECT signo) { - ErtsSigSelInfo *curr = ps->info; - while (curr != NULL) { - if (curr->signo == signo) - return curr; - curr = curr->next; - } - return NULL; -} - -static ErtsSigSelItem * -get_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd) { - ErtsSigSelInfo *info = get_sigsel_info(ps,fd->signo); - ErtsSigSelItem *curr; - - if (info == NULL) - return NULL; - - curr = info->fds; - - while (curr != NULL) { - if (curr->fd->id == fd->id) { - ASSERT(curr->fd->signo == fd->signo); - return curr; - } - curr = curr->next; - } - return NULL; -} - -static ErtsSigSelInfo * -add_sigsel_info(ErtsPollSet ps, ErtsSysFdType fd, - ErlDrvOseEventId (*decode)(union SIGNAL* sig)) { - ErtsSigSelInfo *info = SEL_ALLOC(ERTS_ALC_T_POLLSET, - sizeof(ErtsSigSelInfo)); - info->next = ps->info; - info->fds = NULL; - info->signo = fd->signo; - info->decode = decode; - ps->info = info; - ps->sig_count++; - return info; -} - -static ErtsSigSelItem * -add_sigsel_item(ErtsPollSet ps, ErtsSysFdType fd, - ErlDrvOseEventId (*decode)(union SIGNAL* sig)) { - ErtsSigSelInfo *info = get_sigsel_info(ps,fd->signo); - ErtsSigSelItem *item = SEL_ALLOC(ERTS_ALC_T_POLLSET, - sizeof(ErtsSigSelItem)); - if (info == NULL) - info = add_sigsel_info(ps, fd, decode); - if (info->decode != decode) { - erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); - erts_dsprintf(dsbufp, "erts_poll_control() inconsistency: multiple resolve_signal functions for same signal (%d)\n", - fd->signo); - erts_send_error_to_logger_nogl(dsbufp); - } - ASSERT(info->decode == decode); - item->next = info->fds; - item->fd = fd; - item->events = 0; - info->fds = item; - ps->item_count++; - return item; -} - -static int del_sigsel_info(ErtsPollSet ps, ErtsSigSelInfo *info) { - ErtsSigSelInfo *curr, *prev; - - if (ps->info == info) { - ps->info = ps->info->next; - } else { - curr = ps->info->next; - prev = ps->info; - - while (curr != info) { - if (curr == NULL) - return 1; - prev = curr; - curr = curr->next; - } - prev->next = curr->next; - } - - ps->sig_count--; - SEL_FREE(ERTS_ALC_T_POLLSET, info); - return 0; -} - -static int del_sigsel_item(ErtsPollSet ps, ErtsSigSelItem *item) { - ErtsSigSelInfo *info = get_sigsel_info(ps,item->fd->signo); - ErtsSigSelItem *curr, *prev; - - ps->item_count--; - ASSERT(ps->item_count >= 0); - - if (info->fds == item) { - info->fds = info->fds->next; - SEL_FREE(ERTS_ALC_T_POLLSET,item); - if (info->fds == NULL) - return del_sigsel_info(ps,info); - return 0; - } - - curr = info->fds->next; - prev = info->fds; - - while (curr != item) { - if (curr == NULL) { - /* We did not find an item to delete so we have to - * increment item count again. - */ - ps->item_count++; - return 1; - } - prev = curr; - curr = curr->next; - } - prev->next = curr->next; - SEL_FREE(ERTS_ALC_T_POLLSET,item); - return 0; -} - -#ifdef ERTS_SMP - -static void update_redir_tables(ErtsPollSet ps) { - struct OS_redir_entry *redir_table; - PROCESS sched_1 = ERTS_SCHEDULER_IX(0)->tid.id; - int i; - redir_table = SEL_ALLOC(ERTS_ALC_T_POLLSET, - sizeof(struct OS_redir_entry)*(ps->sig_count+1)); - - redir_table[0].sig = ps->sig_count+1; - redir_table[0].pid = 0; - - for (i = 1; i < ps->sig_count+1; i++) { - redir_table[i].sig = ps->sigs[i]; - redir_table[i].pid = sched_1; - } - - for (i = 1; i < erts_no_schedulers; i++) { - ErtsSchedulerData *esdp = ERTS_SCHEDULER_IX(i); - set_redirection(esdp->tid.id,redir_table); - } - - SEL_FREE(ERTS_ALC_T_POLLSET,redir_table); -} - -#endif - -static int update_sigsel(ErtsPollSet ps) { - ErtsSigSelInfo *info = ps->info; - - int i; - - if (ps->sigs != NULL) - SEL_FREE(ERTS_ALC_T_POLLSET,ps->sigs); - - if (ps->sig_count == 0) { - /* If there are no signals we place a non-valid signal to make sure that - * we do not trigger on a any unrelated signals which are sent to the - * process. - */ - ps->sigs = SEL_ALLOC(ERTS_ALC_T_POLLSET,sizeof(SIGSELECT)*(2)); - ps->sigs[0] = 1; - ps->sigs[1] = ERTS_SIGNAL_INVALID; - return 0; - } - - ps->sigs = SEL_ALLOC(ERTS_ALC_T_POLLSET,sizeof(SIGSELECT)*(ps->sig_count+1)); - ps->sigs[0] = ps->sig_count; - - for (i = 1; info != NULL; i++, info = info->next) - ps->sigs[i] = info->signo; - -#ifdef ERTS_SMP - update_redir_tables(ps); -#endif - - return 0; -} - -static ERTS_INLINE void -wake_poller(ErtsPollSet ps) -{ - erts_aint32_t wakeup_state; - - ERTS_THR_MEMORY_BARRIER; - wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state); - while (wakeup_state != ERTS_POLL_WOKEN_IO_READY - && wakeup_state != ERTS_POLL_WOKEN_INTR) { - erts_aint32_t act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_INTR, - wakeup_state); - if (act == wakeup_state) { - wakeup_state = act; - break; - } - wakeup_state = act; - } - if (wakeup_state == ERTS_POLL_SLEEPING) { - /* - * Since we don't know the internals of signal_fsem() we issue - * a memory barrier as a safety precaution ensuring that - * the store we just made to wakeup_state wont be reordered - * with loads in signal_fsem(). - */ - ERTS_THR_MEMORY_BARRIER; - signal_fsem(ps->interrupt); - } -} - -static ERTS_INLINE void -reset_interrupt(ErtsPollSet ps) -{ - /* We need to keep io-ready if set */ - erts_aint32_t wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state); - while (wakeup_state != ERTS_POLL_NOT_WOKEN && - wakeup_state != ERTS_POLL_SLEEPING) { - erts_aint32_t act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_NOT_WOKEN, - wakeup_state); - if (wakeup_state == act) - break; - wakeup_state = act; - } - ERTS_THR_MEMORY_BARRIER; -} - -static ERTS_INLINE void -set_interrupt(ErtsPollSet ps) -{ - wake_poller(ps); -} - -void erts_poll_interrupt(ErtsPollSet ps,int set) { - HARDTRACEF("erts_poll_interrupt called!\n"); - - if (!set) - reset_interrupt(ps); - else - set_interrupt(ps); - -} - -void erts_poll_interrupt_timed(ErtsPollSet ps, - int set, - ErtsTimeoutTime timeout_time) { - HARDTRACEF("erts_poll_interrupt_timed called!\n"); - - if (!set) - reset_interrupt(ps); - else if (get_timeout_time(ps) > timeout_time) - set_interrupt(ps); -} - -ErtsPollEvents erts_poll_control(ErtsPollSet ps, ErtsSysFdType fd, - ErtsPollEvents pe, int on, int* do_wake) { - ErtsSigSelItem *curr; - ErtsPollEvents new_events; - int old_sig_count; - - HARDTRACEF( - "%ux: In erts_poll_control, fd = %d, pe = %d, on = %d, *do_wake = %d, curr = 0x%xu", - ps, fd, pe, on, do_wake, curr); - - ERTS_POLLSET_LOCK(ps); - - if (on && (pe & ERTS_POLL_EV_IN) && (pe & ERTS_POLL_EV_OUT)) { - /* Check to make sure both in and out are not used at the same time */ - new_events = ERTS_POLL_EV_NVAL; - goto done; - } - - curr = get_sigsel_item(ps, fd); - old_sig_count = ps->sig_count; - - if (curr == NULL && on) { - curr = add_sigsel_item(ps, fd, fd->resolve_signal); - } else if (curr == NULL && !on) { - new_events = ERTS_POLL_EV_NVAL; - goto done; - } - - new_events = curr->events; - - if (pe == 0) { - *do_wake = 0; - goto done; - } - - if (on) { - new_events |= pe; - curr->events = new_events; - } else { - new_events &= ~pe; - curr->events = new_events; - if (new_events == 0 && del_sigsel_item(ps, curr)) { - new_events = ERTS_POLL_EV_NVAL; - goto done; - } - } - - if (ps->sig_count != old_sig_count) { - if (update_sigsel(ps)) - new_events = ERTS_POLL_EV_NVAL; - } -done: - ERTS_POLLSET_UNLOCK(ps); - HARDTRACEF("%ux: Out erts_poll_control", ps); - return new_events; -} - -int erts_poll_wait(ErtsPollSet ps, - ErtsPollResFd pr[], - int *len, - ErtsMonotonicTime timeout_time) -{ - int res = ETIMEDOUT, no_fds, currid = 0; - OSTIME timeout; - union SIGNAL *sig; - ErtsMonotonicTime current_time, diff_time, timeout; - // HARDTRACEF("%ux: In erts_poll_wait",ps); - if (ps->interrupt == (PROCESS)0) - ps->interrupt = current_process(); - - ASSERT(current_process() == ps->interrupt); - ASSERT(get_fsem(current_process()) == 0); - ASSERT(erts_atomic32_read_nob(&ps->wakeup_state) & - (ERTS_POLL_NOT_WOKEN | ERTS_POLL_WOKEN_INTR)); - /* Max no of spots avable in pr */ - no_fds = *len; - - *len = 0; - - /* erts_printf("Entering erts_poll_wait(), timeout_time=%bps\n", - timeout_time); */ - - if (timeout_time == ERTS_POLL_NO_TIMEOUT) { - no_timeout: - timeout = (OSTIME) 0; - save_timeout_time = ERTS_MONOTONIC_TIME_MIN; - } - else { - ErtsMonotonicTime current_time, diff_time; - current_time = erts_get_monotonic_time(NULL); - diff_time = timeout_time - current_time; - if (diff_time <= 0) - goto no_timeout; - diff_time = (ERTS_MONOTONIC_TO_MSEC(diff_time - 1) + 1); - if (diff_time > INT_MAX) - diff_time = INT_MAX; - timeout = (OSTIME) diff_time; - save_timeout_time = current_time; - save_timeout_time += ERTS_MSEC_TO_MONOTONIC(diff_time); - } - - set_timeout_time(ps, save_timeout_time); - - while (currid < no_fds) { - if (timeout > 0) { - erts_aint32_t act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_SLEEPING, - ERTS_POLL_NOT_WOKEN); - if (act == ERTS_POLL_NOT_WOKEN) { -#ifdef ERTS_SMP - erts_thr_progress_prepare_wait(NULL); -#endif - sig = receive_fsem(timeout, ps->sigs, 1); -#ifdef ERTS_SMP - erts_thr_progress_finalize_wait(NULL); -#endif - } else { - ASSERT(act == ERTS_POLL_WOKEN_INTR); - sig = OS_RCV_FSEM; - } - } else - sig = receive_w_tmo(0, ps->sigs); - - if (sig == NULL) { - if (timeout > 0) { - erts_aint32_t act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_TIMEDOUT, - ERTS_POLL_SLEEPING); - if (act == ERTS_POLL_WOKEN_INTR) - /* Restore fsem as it was signaled but we got a timeout */ - wait_fsem(1); - } else - erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_TIMEDOUT, - ERTS_POLL_NOT_WOKEN); - break; - } else if (sig == OS_RCV_FSEM) { - ASSERT(erts_atomic32_read_nob(&ps->wakeup_state) == ERTS_POLL_WOKEN_INTR); - break; - } - { - ErtsSigSelInfo *info = get_sigsel_info(ps, sig->sig_no); - struct erts_sys_fd_type fd = { sig->sig_no, info->decode(sig) }; - ErtsSigSelItem *item = get_sigsel_item(ps, &fd); - - ASSERT(sig); - if (currid == 0 && timeout > 0) { - erts_aint32_t act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_IO_READY, - ERTS_POLL_SLEEPING); - if (act == ERTS_POLL_WOKEN_INTR) { - /* Restore fsem as it was signaled but we got a msg */ - wait_fsem(1); - act = erts_atomic32_cmpxchg_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_IO_READY, - ERTS_POLL_WOKEN_INTR); - } - } else if (currid == 0) { - erts_atomic32_set_nob(&ps->wakeup_state, - ERTS_POLL_WOKEN_IO_READY); - } - - if (item == NULL) { - erts_dsprintf_buf_t *dsbufp = erts_create_logger_dsbuf(); - erts_dsprintf( - dsbufp, - "erts_poll_wait() failed: found unkown signal id %d (signo %u) " - "(curr_proc 0x%x)\n", - fd.id, fd.signo, current_process()); - erts_send_error_to_logger_nogl(dsbufp); - timeout = 0; - /* Under normal circumstances the signal is deallocated by the - * driver that issued the select operation. But in this case - * there's no driver waiting for such signal so we have to - * deallocate it here */ - if (sig) - free_buf(&sig); - } else { - int i; - struct erts_sys_fd_type *fd = NULL; - ErtsPollOseMsgList *tl,*new; - - /* Check if this fd has already been triggered by a previous signal */ - for (i = 0; i < currid;i++) { - if (pr[i].fd == item->fd) { - fd = pr[i].fd; - pr[i].events |= item->events; - break; - } - } - - /* First time this fd is triggered */ - if (fd == NULL) { - pr[currid].fd = item->fd; - pr[currid].events = item->events; - fd = item->fd; - timeout = 0; - currid++; - } - - /* Insert new signal in approriate list */ - new = erts_alloc(ERTS_ALC_T_FD_SIG_LIST,sizeof(ErtsPollOseMsgList)); - new->next = NULL; - new->data = sig; - - ethr_mutex_lock(&fd->mtx); - tl = fd->msgs; - - if (tl == NULL) { - fd->msgs = new; - } else { - while (tl->next != NULL) - tl = tl->next; - tl->next = new; - } - ethr_mutex_unlock(&fd->mtx); - } - - } - } - - { - erts_aint32_t wakeup_state = erts_atomic32_read_nob(&ps->wakeup_state); - - switch (wakeup_state) { - case ERTS_POLL_WOKEN_IO_READY: - res = 0; - break; - case ERTS_POLL_WOKEN_INTR: - res = EINTR; - break; - case ERTS_POLL_WOKEN_TIMEDOUT: - res = ETIMEDOUT; - break; - case ERTS_POLL_NOT_WOKEN: - /* This happens when we get an invalid signal only */ - res = EINVAL; - break; - default: - res = 0; - erl_exit(ERTS_ABORT_EXIT, - "%s:%d: Internal error: Invalid wakeup_state=%d\n", - __FILE__, __LINE__, (int) wakeup_state); - } - } - - erts_atomic32_set_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN); - set_timeout_time(ps, ERTS_MONOTONIC_TIME_MAX); - - *len = currid; - - // HARDTRACEF("%ux: Out erts_poll_wait",ps); - return res; -} - -int erts_poll_max_fds(void) -{ - - HARDTRACEF("In/Out erts_poll_max_fds -> %d",max_fds); - return max_fds; -} - -void erts_poll_info(ErtsPollSet ps, - ErtsPollInfo *pip) -{ - Uint size = 0; - Uint num_events = 0; - - size += sizeof(struct ErtsPollSet_); - size += sizeof(ErtsSigSelInfo)*ps->sig_count; - size += sizeof(ErtsSigSelItem)*ps->item_count; - size += sizeof(SIGSELECT)*(ps->sig_count+1); - - pip->primary = "receive_fsem"; - - pip->fallback = NULL; - - pip->kernel_poll = NULL; - - pip->memory_size = size; - - pip->poll_set_size = num_events; - - pip->fallback_poll_set_size = 0; - - pip->lazy_updates = 0; - - pip->pending_updates = 0; - - pip->batch_updates = 0; - - pip->concurrent_updates = 0; - - - pip->max_fds = erts_poll_max_fds(); - HARDTRACEF("%ux: Out erts_poll_info",ps); - -} - -ErtsPollSet erts_poll_create_pollset(void) -{ - ErtsPollSet ps = SEL_ALLOC(ERTS_ALC_T_POLLSET, - sizeof(struct ErtsPollSet_)); - - ps->sigs = NULL; - ps->sig_count = 0; - ps->item_count = 0; - ps->info = NULL; - ps->interrupt = (PROCESS)0; - erts_atomic32_init_nob(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN); - init_timeout_time(ps); -#ifdef ERTS_SMP - erts_smp_mtx_init(&ps->mtx, "pollset"); -#endif - update_sigsel(ps); - HARDTRACEF("%ux: Out erts_poll_create_pollset",ps); - return ps; -} - -void erts_poll_destroy_pollset(ErtsPollSet ps) -{ - ErtsSigSelInfo *info; - for (info = ps->info; ps->info != NULL; info = ps->info, ps->info = ps->info->next) { - ErtsSigSelItem *item; - for (item = info->fds; info->fds != NULL; item = info->fds, info->fds = info->fds->next) - SEL_FREE(ERTS_ALC_T_POLLSET, item); - SEL_FREE(ERTS_ALC_T_POLLSET, info); - } - - SEL_FREE(ERTS_ALC_T_POLLSET,ps->sigs); - -#ifdef ERTS_SMP - erts_smp_mtx_destroy(&ps->mtx); -#endif - - SEL_FREE(ERTS_ALC_T_POLLSET,ps); -} - -void erts_poll_init(void) -{ - HARDTRACEF("In %s", __FUNCTION__); - max_fds = 256; - - HARDTRACEF("Out %s", __FUNCTION__); -} - - -/* OSE driver functions */ - -union SIGNAL *erl_drv_ose_get_signal(ErlDrvEvent drv_ev) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - ethr_mutex_lock(&ev->mtx); - if (ev->msgs == NULL) { - ethr_mutex_unlock(&ev->mtx); - return NULL; - } else { - ErtsPollOseMsgList *msg = ev->msgs; - union SIGNAL *sig = (union SIGNAL*)msg->data; - ASSERT(msg->data); - ev->msgs = msg->next; - ethr_mutex_unlock(&ev->mtx); - erts_free(ERTS_ALC_T_FD_SIG_LIST,msg); - restore(sig); - return sig; - } -} - -ErlDrvEvent -erl_drv_ose_event_alloc(SIGSELECT signo, ErlDrvOseEventId id, - ErlDrvOseEventId (*resolve_signal)(union SIGNAL *sig), void *extra) { - struct erts_sys_fd_type *ev = erts_alloc(ERTS_ALC_T_DRV_EV, - sizeof(struct erts_sys_fd_type)); - ev->signo = signo; - ev->extra = extra; - ev->id = id; - ev->msgs = NULL; - ev->resolve_signal = resolve_signal; - ethr_mutex_init(&ev->mtx); - return (ErlDrvEvent)ev; -} - -void erl_drv_ose_event_free(ErlDrvEvent drv_ev) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - ASSERT(ev->msgs == NULL); - ethr_mutex_destroy(&ev->mtx); - erts_free(ERTS_ALC_T_DRV_EV,ev); -} - -void erl_drv_ose_event_fetch(ErlDrvEvent drv_ev, SIGSELECT *signo, - ErlDrvOseEventId *id, void **extra) { - struct erts_sys_fd_type *ev = (struct erts_sys_fd_type *)drv_ev; - if (signo) - *signo = ev->signo; - if (extra) - *extra = ev->extra; - if (id) - *id = ev->id; -} diff --git a/erts/emulator/sys/ose/erts.sig b/erts/emulator/sys/ose/erts.sig deleted file mode 100644 index 78b883ee6c..0000000000 --- a/erts/emulator/sys/ose/erts.sig +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef ERTS_OSE_SIGNALS -#define ERTS_OSE_SIGNALS - -#ifndef ERTS_OSE_SIGNAL_BASE -#define ERTS_OSE_SIGNAL_BASE 0x01900280 -#endif - -#define ERTS_SIGNAL_INVALID ERTS_OSE_SIGNAL_BASE -#define ERTS_SIGNAL_FD_DRV_CONFIG ERTS_OSE_SIGNAL_BASE+1 -#define ERTS_SIGNAL_FD_DRV_ASYNC ERTS_OSE_SIGNAL_BASE+2 -#define ERTS_SIGNAL_OSE_DRV_ATTACH ERTS_OSE_SIGNAL_BASE+3 -#define ERTS_SIGNAL_OSE_DRV_HUNT ERTS_OSE_SIGNAL_BASE+4 - -#define ERTS_SIGNAL_RUN_ERL_SETUP ERTS_OSE_SIGNAL_BASE+100 -#define ERTS_SIGNAL_RUN_ERL_DAEMON ERTS_OSE_SIGNAL_BASE+101 - -#endif diff --git a/erts/emulator/sys/ose/gcc_4.4.3_lm_ppc.lcf b/erts/emulator/sys/ose/gcc_4.4.3_lm_ppc.lcf deleted file mode 100644 index a19d23facf..0000000000 --- a/erts/emulator/sys/ose/gcc_4.4.3_lm_ppc.lcf +++ /dev/null @@ -1,182 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2013-2014 by Enea Software AB, - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ - -OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") -OUTPUT_ARCH("powerpc") -ENTRY("crt0_lm") -MEMORY -{ - rom : ORIGIN = 0x01000000, LENGTH = 0x01000000 - ram : ORIGIN = 0x02000000, LENGTH = 0x01000000 -} -PHDRS -{ - ph_conf PT_LOAD ; - ph_rom PT_LOAD ; - ph_ram PT_LOAD ; -} -SECTIONS -{ - .text : - { - *(.text_first) - *(.text) - *(.text.*) - *(.stub) - *(oscode) - *(.init*) - *(.fini*) - *(.gnu.warning) - *(.gnu.linkonce.t.*) - *(.glue_7t) - *(.glue_7) - } > rom :ph_rom = 0 - .ose_sfk_biosentry : - { - *(.ose_sfk_biosentry) - } > rom :ph_rom - .ctors : - { - __CTOR_LIST__ = .; - *(.ctors) - *(SORT(.ctors.*)) - __CTOR_END__ = .; - } > rom :ph_rom - .dtors : - { - __DTOR_LIST__ = .; - *(.dtors) - *(SORT(.dtors.*)) - __DTOR_END__ = .; - } > rom :ph_rom - OSESYMS : - { - *(.osesyms) - } > rom :ph_rom - .rodata : - { - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - } > rom :ph_rom - .eh_frame_hdr : - { - *(.eh_frame_hdr) - } > rom :ph_rom - .eh_frame : - { - __EH_FRAME_BEGIN__ = .; - *(.eh_frame) - LONG(0) - __EH_FRAME_END__ = .; - } > rom :ph_rom - .gcc_except_table : - { - *(.gcc_except_table .gcc_except_table.*) - } > rom :ph_rom - .sdata2 : - { - PROVIDE (_SDA2_BASE_ = .); - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - } > rom :ph_rom - .sbss2 : - { - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - } > rom :ph_rom - LMCONF : - { - obj/?*?/ose_confd.o(.rodata) - *(LMCONF) - } > rom :ph_conf - .data : - { - LONG(0xDEADBABE) - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - . = ALIGN(0x10); - } > ram :ph_ram = 0 - .sdata2 : - { - _SDA2_BASE_ = .; - *(.sdata2 .sdata2.* .gnu.linkonce.s2.*) - }> ram :ph_ram - .sdata : - { - PROVIDE (_SDA_BASE_ = .); - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - } > ram :ph_ram - .sbss : - { - *(.sbss) - *(.sbss.*) - *(.scommon) - *(.gnu.linkonce.sb.*) - } > ram :ph_ram - .bss (NOLOAD) : - { - *(.bss) - *(.bss.*) - *(COMMON) - *(.gnu.linkonce.b.*) - *(.osvars) - } > ram :ph_ram - .ignore (NOLOAD) : - { - *(.rel.dyn) - } > ram :ph_ram - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} -__OSESYMS_START = ADDR(OSESYMS); -__OSESYMS_END = ADDR(OSESYMS) + SIZEOF(OSESYMS); diff --git a/erts/emulator/sys/ose/gcc_4.6.3_lm_ppc.lcf b/erts/emulator/sys/ose/gcc_4.6.3_lm_ppc.lcf deleted file mode 100644 index 3440c2961b..0000000000 --- a/erts/emulator/sys/ose/gcc_4.6.3_lm_ppc.lcf +++ /dev/null @@ -1,242 +0,0 @@ -/******************************************************************************* - * Copyright (C) 2013-2014 by Enea Software AB, - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. Neither the name of the copyright holder nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - ******************************************************************************/ - -OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") -OUTPUT_ARCH("powerpc") - -ENTRY("crt0_lm") - -/* Note: - * You may have to increase the length of the "rom" memory region and the - * origin and length of the "ram" memory region below depending on the size - * of the code and data in your load module. - */ - -MEMORY -{ - conf : ORIGIN = 0x00100000, LENGTH = 0x00030000 - rom : ORIGIN = 0x01000000, LENGTH = 0x01000000 - ram : ORIGIN = 0x03000000, LENGTH = 0x01000000 -} - -PHDRS -{ - ph_conf PT_LOAD ; - ph_rom PT_LOAD ; - ph_ram PT_LOAD ; -} - -SECTIONS -{ -/*--------------------------------------------------------------------------- - * Load module configuration area - *-------------------------------------------------------------------------*/ - - /* Load module configuration section. */ - LMCONF : - { - obj/?*?/ose_confd.o(.rodata) - *(LMCONF) - } > conf :ph_conf - -/*--------------------------------------------------------------------------- - * Read-only area - *-------------------------------------------------------------------------*/ - - /* Code section. */ - .text : - { - *(.text) - *(.text.*) - *(.stub) - *(oscode) - *(.init*) - *(.fini*) - *(.gnu.warning) - *(.gnu.linkonce.t.*) - } > rom :ph_rom = 0 - - /* OSE symbols section. */ - OSESYMS : - { - *(.osesyms) - } > rom :ph_rom - - /* Read-only data section. */ - .rodata : - { - *(.rodata) - *(.rodata.*) - *(.gnu.linkonce.r.*) - } > rom :ph_rom - - /* C++ exception handling section. */ - .eh_frame : - { - __EH_FRAME_BEGIN__ = .; - *(.eh_frame) - LONG(0) - __EH_FRAME_END__ = .; - } > rom :ph_rom - - /* C++ exception handling section. */ - .gcc_except_table : - { - *(.gcc_except_table .gcc_except_table.*) - } > rom :ph_rom - - /* PowerPC EABI initialized read-only data section. */ - .sdata2 : - { - PROVIDE (_SDA2_BASE_ = .); - *(.sdata2) - *(.sdata2.*) - *(.gnu.linkonce.s2.*) - } > rom :ph_rom - - /* PowerPC EABI uninitialized read-only data section. */ - .sbss2 : - { - *(.sbss2) - *(.sbss2.*) - *(.gnu.linkonce.sb2.*) - } > rom :ph_rom - -/*--------------------------------------------------------------------------- - * Read-write area - *-------------------------------------------------------------------------*/ - - /*------------------------------------------------------------------- - * Initialized data (copied by PM) - *-----------------------------------------------------------------*/ - - /* Data section. */ - .data : - { - *(.data) - *(.data.*) - *(.gnu.linkonce.d.*) - SORT(CONSTRUCTORS) - } > ram :ph_ram - - /* C++ constructor section. */ - .ctors : - { - __CTOR_LIST__ = .; - *(.ctors) - *(SORT(.ctors.*)) - __CTOR_END__ = .; - } > ram :ph_ram - - /* C++ destructor section. */ - .dtors : - { - __DTOR_LIST__ = .; - *(.dtors) - *(SORT(.dtors.*)) - __DTOR_END__ = .; - } > ram :ph_ram - - - /* Small data section. */ - .sdata ALIGN(0x10) : - { - PROVIDE (_SDA_BASE_ = .); - *(.sdata) - *(.sdata.*) - *(.gnu.linkonce.s.*) - } > ram :ph_ram - - /*------------------------------------------------------------------- - * Uninitialized data (cleared by PM) - *-----------------------------------------------------------------*/ - - /* Small bss section. */ - .sbss : - { - *(.sbss) - *(.sbss.*) - *(.scommon) - *(.gnu.linkonce.sb.*) - } > ram :ph_ram - - /* Bss section. */ - .bss : - { - *(.bss) - *(.bss.*) - *(COMMON) - *(.gnu.linkonce.b.*) - } > ram :ph_ram - -/*--------------------------------------------------------------------------- - * Debug information - *-------------------------------------------------------------------------*/ - - /* - * Stabs debug sections. - */ - - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - - /* - * DWARF debug sections. - */ - - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info) *(.gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} diff --git a/erts/emulator/sys/ose/sys.c b/erts/emulator/sys/ose/sys.c deleted file mode 100644 index bcd0ffa0b6..0000000000 --- a/erts/emulator/sys/ose/sys.c +++ /dev/null @@ -1,1847 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2013. 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% - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include "sys/time.h" -#include "time.h" -#include "sys/uio.h" -#include "termios.h" -#include "ctype.h" -#include "termios.h" - -#ifdef HAVE_FCNTL_H -#include "fcntl.h" -#endif - -#ifdef HAVE_SYS_IOCTL_H -#include "sys/ioctl.h" -#endif - -#define ERTS_WANT_BREAK_HANDLING -#define WANT_NONBLOCKING -#include "sys.h" -#include "erl_thr_progress.h" - -#ifdef USE_THREADS -#include "erl_threads.h" -#endif - -#include "erl_mseg.h" - -#include "unistd.h" -#include "efs.h" -#include "erl_printf.h" -#include "aio.h" -#include "pm.h" -#include "fcntl.h" - -/* Set the define to 1 to get some logging */ -#if 0 -#include "ramlog.h" -#define LOG(output) ramlog_printf output -#else -#define LOG(output) -#endif - -extern char **environ; -static erts_smp_rwmtx_t environ_rwmtx; -static PROCESS sig_proxy_pid = 0; - -#define MAX_VSIZE 16 /* Max number of entries allowed in an I/O - * vector sock_sendv(). - */ -/* - * Don't need global.h, but bif_table.h (included by bif.h), - * won't compile otherwise - */ -#include "global.h" -#include "bif.h" - -#include "erl_sys_driver.h" -#include "erl_check_io.h" -#include "erl_cpu_topology.h" - -/* The priority for reader/writer processes */ -#define FD_PROC_PRI get_pri(current_process()) - -typedef struct ErtsSysReportExit_ ErtsSysReportExit; -struct ErtsSysReportExit_ { - ErtsSysReportExit *next; - Eterm port; - int pid; - int ifd; - int ofd; - ErlDrvEvent attach_event; - ErlDrvEvent input_event; - ErlDrvEvent output_event; -}; - -/* This data is shared by these drivers - initialized by spawn_init() */ -static struct driver_data { - ErlDrvPort port_num; - int ofd; - int ifd; - int packet_bytes; - ErtsSysReportExit *report_exit; - int pid; - int alive; - int status; - ErlDrvEvent input_event; - ErlDrvEvent output_event; - struct aiocb aiocb; - FmHandle handle; - char *install_handle; -} *driver_data; /* indexed by fd */ - -struct async { - SIGSELECT signo; - ErlDrvTermData port; - ErlDrvTermData proc; - PROCESS spid; - PROCESS target; - Uint32 ref; -}; - -static ErtsSysReportExit *report_exit_list; -static ERTS_INLINE void report_exit_status(ErtsSysReportExit *rep, int status); - -extern int driver_interrupt(int, int); -extern void do_break(void); - -extern void erl_sys_args(int*, char**); - -/* The following two defs should probably be moved somewhere else */ - -extern void erts_sys_init_float(void); - -extern void erl_crash_dump(char* file, int line, char* fmt, ...); - -#define DIR_SEPARATOR_CHAR '/' - -#if defined(DEBUG) -#define ERL_BUILD_TYPE_MARKER ".debug" -#else /* opt */ -#define ERL_BUILD_TYPE_MARKER -#endif - -#define CHILD_SETUP_PROG_NAME "child_setup" ERL_BUILD_TYPE_MARKER - -#ifdef DEBUG -static int debug_log = 0; -#endif - -#ifdef ERTS_SMP -static erts_smp_atomic32_t have_prepared_crash_dump; -#define ERTS_PREPARED_CRASH_DUMP \ - ((int) erts_smp_atomic32_xchg_nob(&have_prepared_crash_dump, 1)) -#else -static volatile int have_prepared_crash_dump; -#define ERTS_PREPARED_CRASH_DUMP \ - (have_prepared_crash_dump++) -#endif - -static erts_smp_atomic_t sys_misc_mem_sz; - -#if defined(ERTS_SMP) -erts_mtx_t chld_stat_mtx; -#endif - -#if defined(ERTS_SMP) /* ------------------------------------------------- */ -#define CHLD_STAT_LOCK erts_mtx_lock(&chld_stat_mtx) -#define CHLD_STAT_UNLOCK erts_mtx_unlock(&chld_stat_mtx) - -#else /* ------------------------------------------------------------------- */ -#define CHLD_STAT_LOCK -#define CHLD_STAT_UNLOCK -static volatile int children_died; -#endif - -#define SET_AIO(REQ,FD,SIZE,BUFF) \ - memset(&(REQ),0,sizeof(REQ)); \ - (REQ).aio_fildes = FD; \ - (REQ).aio_offset = FM_POSITION_CURRENT; \ - (REQ).aio_nbytes = SIZE; \ - (REQ).aio_buf = BUFF; \ - (REQ).aio_sigevent.sigev_notify = SIGEV_NONE - -/* the first sizeof(struct aiocb *) bytes of the write buffer - * will contain the pointer to the aiocb struct, this needs - * to be freed between asynchronous writes. - * A write of 0 bytes is ignored. */ -#define WRITE_AIO(FD,SIZE,BUFF) do { \ - if (SIZE > 0) { \ - struct aiocb *write_req = driver_alloc(sizeof(struct aiocb)); \ - char *write_buff = driver_alloc((sizeof(char)*SIZE)+1+ \ - (sizeof(struct aiocb *))); \ - *(struct aiocb **)write_buff = (struct aiocb *)write_req; \ - write_buff += sizeof(struct aiocb *); \ - memcpy(write_buff,BUFF,SIZE+1); \ - SET_AIO(*write_req,FD,SIZE,write_buff); \ - if (aio_write(write_req)) \ - ramlog_printf("%s:%d: write failed with %d\n", \ - __FILE__,__LINE__,errno); \ - } \ -} while(0) - -/* free the write_buffer and write_req - * created in the WRITE_AIO() request macro */ -#define FREE_AIO(ptr) do { \ - struct aiocb *aiocb_ptr; \ - char *buffer_ptr; \ - aiocb_ptr = *(struct aiocb **)((ptr)-sizeof(struct aiocb *)); \ - buffer_ptr = (((char*)ptr)-sizeof(struct aiocb *)); \ - driver_free(aiocb_ptr); \ - driver_free(buffer_ptr); \ -} while(0) - -#define DISPATCH_AIO(sig) do { \ - if (aio_dispatch(sig)) \ - ramlog_printf("%s:%d: dispatch failed with %d\n", \ - __FILE__,__LINE__,errno); \ - } while(0) - -#define AIO_PIPE_SIZE 1024 - -/* debug print macros */ -#define DEBUG_RES 0 - -#ifdef DEBUG_RES -#define DEBUG_CHECK_RES(actual, expected) \ - do { \ - if (actual != expected ) { \ - ramlog_printf("Result check failed" \ - " got: 0x%08x expected:0x%08x\nat: %s:%d\n", \ - actual, expected, __FILE__, __LINE__); \ - abort(); /* This might perhaps be too harsh? */ \ - } \ - } while(0) -#else -#define DEBUG_CHECK_RES -#endif - -static struct fd_data { - char pbuf[4]; /* hold partial packet bytes */ - int psz; /* size of pbuf */ - char *buf; - char *cpos; - int sz; - int remain; /* for input on fd */ -} *fd_data; /* indexed by fd */ - -/********************* General functions ****************************/ - -/* This is used by both the drivers and general I/O, must be set early */ -static int max_files = -1; - -/* - * a few variables used by the break handler - */ -#ifdef ERTS_SMP -erts_smp_atomic32_t erts_break_requested; -#define ERTS_SET_BREAK_REQUESTED \ - erts_smp_atomic32_set_nob(&erts_break_requested, (erts_aint32_t) 1) -#define ERTS_UNSET_BREAK_REQUESTED \ - erts_smp_atomic32_set_nob(&erts_break_requested, (erts_aint32_t) 0) -#else -volatile int erts_break_requested = 0; -#define ERTS_SET_BREAK_REQUESTED (erts_break_requested = 1) -#define ERTS_UNSET_BREAK_REQUESTED (erts_break_requested = 0) -#endif -/* set early so the break handler has access to initial mode */ -static struct termios initial_tty_mode; -static int replace_intr = 0; -/* assume yes initially, ttsl_init will clear it */ -int using_oldshell = 1; -static PROCESS get_signal_proxy_pid(void); - -static void -init_check_io(void) -{ - erts_init_check_io(); - max_files = erts_check_io_max_files(); -} - -#ifdef ERTS_POLL_NEED_ASYNC_INTERRUPT_SUPPORT -#define ERTS_CHK_IO_AS_INTR() erts_check_io_async_sig_interrupt() -#else -#define ERTS_CHK_IO_AS_INTR() erts_check_io_interrupt(1) -#endif -#define ERTS_CHK_IO_INTR erts_check_io_interrupt -#define ERTS_CHK_IO_INTR_TMD erts_check_io_interrupt_timed -#define ERTS_CHK_IO erts_check_io -#define ERTS_CHK_IO_SZ erts_check_io_size - - -void -erts_sys_schedule_interrupt(int set) -{ - ERTS_CHK_IO_INTR(set); -} - -#ifdef ERTS_SMP -void -erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time) -{ - ERTS_CHK_IO_INTR_TMD(set, timeout_time); -} -#endif - -Uint -erts_sys_misc_mem_sz(void) -{ - Uint res = ERTS_CHK_IO_SZ(); - res += erts_smp_atomic_read_mb(&sys_misc_mem_sz); - return res; -} - -/* - * reset the terminal to the original settings on exit - */ -void sys_tty_reset(int exit_code) -{ - if (using_oldshell && !replace_intr) { - SET_BLOCKING(0); - } - else if (isatty(0)) { - tcsetattr(0,TCSANOW,&initial_tty_mode); - } -} - -#ifdef USE_THREADS - -typedef struct { - int sched_bind_data; -} erts_thr_create_data_t; - -/* - * thr_create_prepare() is called in parent thread before thread creation. - * Returned value is passed as argument to thr_create_cleanup(). - */ -static void * -thr_create_prepare(void) -{ - erts_thr_create_data_t *tcdp; - - tcdp = erts_alloc(ERTS_ALC_T_TMP, sizeof(erts_thr_create_data_t)); - - tcdp->sched_bind_data = erts_sched_bind_atthrcreate_prepare(); - - return (void *) tcdp; -} - - -/* thr_create_cleanup() is called in parent thread after thread creation. */ -static void -thr_create_cleanup(void *vtcdp) -{ - erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp; - - erts_sched_bind_atthrcreate_parent(tcdp->sched_bind_data); - - erts_free(ERTS_ALC_T_TMP, tcdp); -} - -static void -thr_create_prepare_child(void *vtcdp) -{ - erts_thr_create_data_t *tcdp = (erts_thr_create_data_t *) vtcdp; - -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_thread_setup(); -#endif - - erts_sched_bind_atthrcreate_child(tcdp->sched_bind_data); -} - -#endif /* #ifdef USE_THREADS */ - -/* The two functions below are stolen from win_con.c - They have to use malloc/free/realloc directly becasue - we want to do able to do erts_printf very early on. - */ -#define VPRINTF_BUF_INC_SIZE 128 -static erts_dsprintf_buf_t * -grow_vprintf_buf(erts_dsprintf_buf_t *dsbufp, size_t need) -{ - char *buf; - size_t size; - - ASSERT(dsbufp); - - if (!dsbufp->str) { - size = (((need + VPRINTF_BUF_INC_SIZE - 1) - / VPRINTF_BUF_INC_SIZE) - * VPRINTF_BUF_INC_SIZE); - buf = (char *) malloc(size * sizeof(char)); - } - else { - size_t free_size = dsbufp->size - dsbufp->str_len; - - if (need <= free_size) - return dsbufp; - - size = need - free_size + VPRINTF_BUF_INC_SIZE; - size = (((size + VPRINTF_BUF_INC_SIZE - 1) - / VPRINTF_BUF_INC_SIZE) - * VPRINTF_BUF_INC_SIZE); - size += dsbufp->size; - buf = (char *) realloc((void *) dsbufp->str, - size * sizeof(char)); - } - if (!buf) - return NULL; - if (buf != dsbufp->str) - dsbufp->str = buf; - dsbufp->size = size; - return dsbufp; -} - -static int erts_sys_ramlog_printf(char *format, va_list arg_list) -{ - int res,i; - erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER(grow_vprintf_buf); - res = erts_vdsprintf(&dsbuf, format, arg_list); - if (res >= 0) { - for (i = 0; i < dsbuf.str_len; i+= 50) - /* We print 50 characters at a time because otherwise - the ramlog looks broken */ - ramlog_printf("%.*s",dsbuf.str_len-50 < 0?dsbuf.str_len:50,dsbuf.str+i); - } - if (dsbuf.str) - free((void *) dsbuf.str); - return res; -} - -void -erts_sys_pre_init(void) -{ - erts_printf_add_cr_to_stdout = 1; - erts_printf_add_cr_to_stderr = 1; -#ifdef USE_THREADS - { - erts_thr_init_data_t eid = ERTS_THR_INIT_DATA_DEF_INITER; - - eid.thread_create_child_func = thr_create_prepare_child; - /* Before creation in parent */ - eid.thread_create_prepare_func = thr_create_prepare; - /* After creation in parent */ - eid.thread_create_parent_func = thr_create_cleanup, - - erts_thr_init(&eid); - - report_exit_list = NULL; - -#ifdef ERTS_ENABLE_LOCK_COUNT - erts_lcnt_init(); -#endif - -#if defined(ERTS_SMP) - erts_mtx_init(&chld_stat_mtx, "child_status"); -#endif - } -#ifdef ERTS_SMP - erts_smp_atomic32_init_nob(&erts_break_requested, 0); - erts_smp_atomic32_init_nob(&have_prepared_crash_dump, 0); -#else - erts_break_requested = 0; - have_prepared_crash_dump = 0; -#endif -#if !defined(ERTS_SMP) - children_died = 0; -#endif -#endif /* USE_THREADS */ - - erts_printf_stdout_func = erts_sys_ramlog_printf; - - erts_smp_atomic_init_nob(&sys_misc_mem_sz, 0); -} - -void -erl_sys_init(void) -{ - -#ifdef USE_SETLINEBUF - setlinebuf(stdout); -#else - setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ); -#endif - - erts_sys_init_float(); - - /* we save this so the break handler can set and reset it properly */ - /* also so that we can reset on exit (break handler or not) */ - if (isatty(0)) { - tcgetattr(0,&initial_tty_mode); - } - tzset(); /* Required at least for NetBSD with localtime_r() */ -} - -static ERTS_INLINE int -prepare_crash_dump(int secs) -{ -#define NUFBUF (3) - int i, max; - char env[21]; /* enough to hold any 64-bit integer */ - size_t envsz; - /*DeclareTmpHeapNoproc(heap,NUFBUF);*/ - /*Eterm *hp = heap;*/ - /*Eterm list = NIL;*/ - int has_heart = 0; - - UseTmpHeapNoproc(NUFBUF); - - if (ERTS_PREPARED_CRASH_DUMP) - return 0; /* We have already been called */ - - - /* Positive secs means an alarm must be set - * 0 or negative means no alarm - * - * Set alarm before we try to write to a port - * we don't want to hang on a port write with - * no alarm. - * - */ - -#if 0 /*ose TBD!!!*/ - if (secs >= 0) { - alarm((unsigned int)secs); - } -#endif - - /* Make sure we unregister at epmd (unknown fd) and get at least - one free filedescriptor (for erl_crash.dump) */ - - max = max_files; - if (max < 1024) - max = 1024; - for (i = 3; i < max; i++) { - close(i); - } - - envsz = sizeof(env); - i = erts_sys_getenv__("ERL_CRASH_DUMP_NICE", env, &envsz); - if (i >= 0) { - int nice_val; - nice_val = i != 0 ? 0 : atoi(env); - if (nice_val > 39) { - nice_val = 39; - } - set_pri(nice_val); - } - - UnUseTmpHeapNoproc(NUFBUF); -#undef NUFBUF - return has_heart; -} - -int erts_sys_prepare_crash_dump(int secs) -{ - return prepare_crash_dump(secs); -} - -static ERTS_INLINE void -break_requested(void) -{ - /* - * just set a flag - checked for and handled by - * scheduler threads erts_check_io() (not signal handler). - */ -#ifdef DEBUG - fprintf(stderr,"break!\n"); -#endif - if (ERTS_BREAK_REQUESTED) - erl_exit(ERTS_INTR_EXIT, ""); - - ERTS_SET_BREAK_REQUESTED; - ERTS_CHK_IO_AS_INTR(); /* Make sure we don't sleep in poll */ -} - -/* Disable break */ -void erts_set_ignore_break(void) { - -} - -/* Don't use ctrl-c for break handler but let it be - used by the shell instead (see user_drv.erl) */ -void erts_replace_intr(void) { - struct termios mode; - - if (isatty(0)) { - tcgetattr(0, &mode); - - /* here's an example of how to replace ctrl-c with ctrl-u */ - /* mode.c_cc[VKILL] = 0; - mode.c_cc[VINTR] = CKILL; */ - - mode.c_cc[VINTR] = 0; /* disable ctrl-c */ - tcsetattr(0, TCSANOW, &mode); - replace_intr = 1; - } -} - -void init_break_handler(void) -{ - -} - -int sys_max_files(void) -{ - return(max_files); -} - - -/************************** OS info *******************************/ - -/* Used by erlang:info/1. */ -/* (This code was formerly in drv.XXX/XXX_os_drv.c) */ - -char os_type[] = "ose"; - -void -os_flavor(char* namebuf, /* Where to return the name. */ - unsigned size) /* Size of name buffer. */ -{ -#if 0 - struct utsname uts; /* Information about the system. */ - char* s; - - (void) uname(&uts); - for (s = uts.sysname; *s; s++) { - if (isupper((int) *s)) { - *s = tolower((int) *s); - } - } - strcpy(namebuf, uts.sysname); -#else - strncpy(namebuf, "release", size); -#endif -} - -void -os_version(pMajor, pMinor, pBuild) -int* pMajor; /* Pointer to major version. */ -int* pMinor; /* Pointer to minor version. */ -int* pBuild; /* Pointer to build number. */ -{ - *pMajor = 5; - *pMinor = 7; - *pBuild = 0; -} - -void init_getenv_state(GETENV_STATE *state) -{ - erts_smp_rwmtx_rlock(&environ_rwmtx); - *state = NULL; -} - -char **environ; /*ose - needs replacement*/ - -char *getenv_string(GETENV_STATE *state0) -{ - char **state = (char **) *state0; - char *cp; - - ERTS_SMP_LC_ASSERT(erts_smp_lc_rwmtx_is_rlocked(&environ_rwmtx)); - - if (state == NULL) - state = environ; - - cp = *state++; - *state0 = (GETENV_STATE) state; - - return cp; -} - -void fini_getenv_state(GETENV_STATE *state) -{ - *state = NULL; - erts_smp_rwmtx_runlock(&environ_rwmtx); -} - - -/************************** Port I/O *******************************/ - -/* I. Common stuff */ - -union SIGNAL { - SIGSELECT sig_no; - struct FmReadPtr fm_read_reply; - struct FmWritePtr fm_write_reply; - struct async async; -}; - -/* II. The spawn/fd drivers */ - -/* - * Decreasing the size of it below 16384 is not allowed. - */ -#define ERTS_SYS_READ_BUF_SZ (64*1024) - -/* Driver interfaces */ -static ErlDrvData spawn_start(ErlDrvPort, char*, SysDriverOpts*); -static ErlDrvData fd_start(ErlDrvPort, char*, SysDriverOpts*); -static ErlDrvSSizeT fd_control(ErlDrvData, unsigned int, char *, ErlDrvSizeT, - char **, ErlDrvSizeT); -static int spawn_init(void); -static void fd_stop(ErlDrvData); -static void erl_stop(ErlDrvData); -static void ready_input(ErlDrvData, ErlDrvEvent); -static void ready_output(ErlDrvData, ErlDrvEvent); -static void output(ErlDrvData, char*, ErlDrvSizeT); -static void stop_select(ErlDrvEvent, void*); - -static PROCESS -get_signal_proxy_pid(void) { - union SIGNAL *sig; - SIGSELECT any_sig[] = {1,ERTS_SIGNAL_OSE_DRV_ATTACH}; - - if (!sig_proxy_pid) { - sig = alloc(sizeof(union SIGNAL), ERTS_SIGNAL_OSE_DRV_ATTACH); - hunt("ose_signal_driver_proxy", 0, NULL, &sig); - sig = receive(any_sig); - sig_proxy_pid = sender(&sig); - free_buf(&sig); - } - ASSERT(sig_proxy_pid); - return sig_proxy_pid; -} - -static ErlDrvOseEventId -resolve_signal(union SIGNAL* sig) { - switch(sig->sig_no) { - - case FM_READ_PTR_REPLY: - return (ErlDrvOseEventId)sig->fm_read_reply.handle; - - case FM_WRITE_PTR_REPLY: - return (ErlDrvOseEventId)sig->fm_write_reply.handle; - - case ERTS_SIGNAL_OSE_DRV_ATTACH: - return (ErlDrvOseEventId)sig->async.target; - - default: - break; - } - return (ErlDrvOseEventId)-1; -} - -struct erl_drv_entry spawn_driver_entry = { - spawn_init, - spawn_start, - NULL, /* erl_stop, */ - output, - ready_input, - ready_output, - "spawn", - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - ERL_DRV_EXTENDED_MARKER, - ERL_DRV_EXTENDED_MAJOR_VERSION, - ERL_DRV_EXTENDED_MINOR_VERSION, - ERL_DRV_FLAG_USE_PORT_LOCKING, - NULL, NULL, - stop_select -}; -struct erl_drv_entry fd_driver_entry = { - NULL, - fd_start, - fd_stop, - output, - ready_input, - ready_output, - "fd", - NULL, - NULL, - fd_control, - NULL, - NULL, - NULL, /* ready_async */ - NULL, /* flush */ - NULL, /* call */ - NULL, /* event */ - ERL_DRV_EXTENDED_MARKER, - ERL_DRV_EXTENDED_MAJOR_VERSION, - ERL_DRV_EXTENDED_MINOR_VERSION, - 0, /* ERL_DRV_FLAGs */ - NULL, /* handle2 */ - NULL, /* process_exit */ - stop_select -}; - -static void -set_spawn_fd(int local_fd, int remote_fd, PROCESS remote_pid) { - PROCESS vm_pid; - FmHandle handle; - char env_val[55]; - char env_name[10]; - EfsStatus efs_res; - - /* get pid of pipevm and handle of chosen fd */ - efs_res = efs_examine_fd(local_fd, FLIB_FD_VMPID, &vm_pid, 0); - DEBUG_CHECK_RES(efs_res, EFS_SUCCESS); - - /* setup the file descriptor to buffer per line */ - efs_res = efs_config_fd(local_fd, FLIB_FD_BUFMODE, FM_BUFF_LINE, - FLIB_FD_BUFSIZE, 80, 0); - DEBUG_CHECK_RES(efs_res, EFS_SUCCESS); - - /* duplicate handle and set spawn pid owner */ - efs_res = efs_dup_to(local_fd, remote_pid, &handle); - DEBUG_CHECK_RES(efs_res, EFS_SUCCESS); - - sprintf(env_name, "FD%d", remote_fd); - - /* Syntax of the environment variable: - * "FD#" "<pid of pipevm>,<handle>,<buffer mode>,<buff size>,<omode>" */ - sprintf(env_val, "0x%lx,0x%lx,%lu,%lu,0x%x", - vm_pid, handle, - FM_BUFF_LINE, 80, - O_APPEND); - - set_env(remote_pid, env_name, env_val); -} - -static ErlDrvData -set_driver_data(ErlDrvPort port_num, - int ifd, - int ofd, - int packet_bytes, - int read_write, - int exit_status, - PROCESS pid) -{ - Port *prt; - ErtsSysReportExit *report_exit; - - prt = erts_drvport2port(port_num); - if (prt != ERTS_INVALID_ERL_DRV_PORT) { - prt->os_pid = pid; - } - - /* READ */ - if (read_write & DO_READ) { - EfsStatus res = efs_examine_fd(ifd, FLIB_FD_HANDLE, - &driver_data[ifd].handle, 0); - if (res != EFS_SUCCESS) - ramlog_printf("%s:%d: efs_examine_fd(%d) failed with %d\n", - __FILE__,__LINE__,ifd,errno); - driver_data[ifd].ifd = ifd; - driver_data[ifd].packet_bytes = packet_bytes; - driver_data[ifd].port_num = port_num; - driver_data[ifd].pid = pid; - - /* async read struct */ - memset(&driver_data[ifd].aiocb, 0, sizeof(struct aiocb)); - driver_data[ifd].aiocb.aio_buf = driver_alloc(AIO_PIPE_SIZE); - driver_data[ifd].aiocb.aio_fildes = ifd; - driver_data[ifd].aiocb.aio_nbytes = (packet_bytes?packet_bytes:AIO_PIPE_SIZE); - driver_data[ifd].alive = 1; - driver_data[ifd].status = 0; - driver_data[ifd].input_event = - erl_drv_ose_event_alloc(FM_READ_PTR_REPLY, - driver_data[ifd].handle, resolve_signal, - &driver_data[ifd].ifd); - - /* READ & WRITE */ - if (read_write & DO_WRITE) { - driver_data[ifd].ofd = ofd; - efs_examine_fd(ofd, FLIB_FD_HANDLE, &driver_data[ofd].handle, 0); - - driver_data[ifd].output_event = - erl_drv_ose_event_alloc(FM_WRITE_PTR_REPLY, - driver_data[ofd].handle, resolve_signal, - &driver_data[ofd].ofd); - driver_data[ofd].pid = pid; - if (ifd != ofd) { - driver_data[ofd] = driver_data[ifd]; - driver_data[ofd].aiocb.aio_buf = NULL; - } - } - else { /* READ ONLY */ - driver_data[ifd].ofd = -1; - } - - /* enable input event */ - (void) driver_select(port_num, driver_data[ifd].input_event, - (ERL_DRV_READ | ERL_DRV_USE), 1); - - if (aio_read(&driver_data[ifd].aiocb)) - ramlog_printf("%s:%d: aio_read(%d) failed with %d\n", - __FILE__,__LINE__,ifd,errno); - } - else { /* WRITE ONLY */ - efs_examine_fd(ofd, FLIB_FD_HANDLE, &driver_data[ofd].handle, 0); - driver_data[ofd].packet_bytes = packet_bytes; - driver_data[ofd].port_num = port_num; - driver_data[ofd].ofd = ofd; - driver_data[ofd].pid = pid; - driver_data[ofd].alive = 1; - driver_data[ofd].status = 0; - driver_data[ofd].output_event = - erl_drv_ose_event_alloc(FM_WRITE_PTR_REPLY, driver_data[ofd].handle, - resolve_signal, &driver_data[ofd].ofd); - driver_data[ofd].input_event = driver_data[ofd].output_event; - } - - /* this is used for spawned load modules, and is needed - * to properly uninstall them */ - if (exit_status) { - struct PmProgramInfo *info; - int install_handle_size; - union SIGNAL *sig; - PmStatus pm_status; - report_exit = erts_alloc(ERTS_ALC_T_PRT_REP_EXIT, - sizeof(ErtsSysReportExit)); - report_exit->next = report_exit_list; - report_exit->port = erts_drvport2id(port_num); - report_exit->pid = pid; - report_exit->ifd = (read_write & DO_READ) ? ifd : -1; - report_exit->ofd = (read_write & DO_WRITE) ? ofd : -1; - report_exit_list = report_exit; - report_exit->attach_event = - erl_drv_ose_event_alloc(ERTS_SIGNAL_OSE_DRV_ATTACH, pid, - resolve_signal, &driver_data[ifd].ifd); - - /* setup ifd and ofd report exit */ - driver_data[ifd].report_exit = report_exit; - driver_data[ofd].report_exit = report_exit; - - pm_status = ose_pm_program_info(pid, &info); - DEBUG_CHECK_RES(pm_status, PM_SUCCESS); - - install_handle_size = strlen(info->install_handle)+1; - driver_data[ifd].install_handle = driver_alloc(install_handle_size); - strcpy(driver_data[ifd].install_handle, - info->install_handle); - - free_buf((union SIGNAL **)&info); - - sig = alloc(sizeof(struct async), ERTS_SIGNAL_OSE_DRV_ATTACH); - sig->async.target = pid; - send(&sig, get_signal_proxy_pid()); - - /* this event will trigger when we receive an attach signal - * from the recently dead load module */ - (void)driver_select(port_num,report_exit->attach_event, DO_READ, 1); - } - else { - report_exit = NULL; - } - - /* the return value is the pointer to the driver_data struct we created - * in this function, it will be used in the drivers input - * and output functions */ - return (ErlDrvData)((!(read_write & DO_READ) && read_write & DO_WRITE) - ? &driver_data[ofd] - : &driver_data[ifd]); -} - -static int spawn_init() -{ - int i; - - driver_data = (struct driver_data *) - erts_alloc(ERTS_ALC_T_DRV_TAB, max_files * sizeof(struct driver_data)); - erts_smp_atomic_add_nob(&sys_misc_mem_sz, - max_files * sizeof(struct driver_data)); - - for (i = 0; i < max_files; i++) - driver_data[i].pid = -1; - - return 1; -} - -static void -init_fd_data(int fd, ErlDrvPort port_num) -{ - fd_data[fd].buf = NULL; - fd_data[fd].cpos = NULL; - fd_data[fd].remain = 0; - fd_data[fd].sz = 0; - fd_data[fd].psz = 0; -} - -/* FIXME write a decent text on pipes on ose */ -static ErlDrvData -spawn_start(ErlDrvPort port_num, char* name, SysDriverOpts* opts) -{ - int ifd[2]; - int ofd[2]; - static uint32_t ticker = 1; - PmStatus pm_status; - OSDOMAIN domain = PM_NEW_DOMAIN; - PROCESS progpid, mainbid, mainpid; - char *handle = NULL; - struct PmProgramInfo *info; - char *args = NULL; - char *tmp_handle; - ErlDrvData res = (ErlDrvData)-1; - int handle_size; - char *ptr; - - - args = driver_alloc(strlen(name)+1); - strcpy(args, name); - /* We need to handle name in three parts - * - install handle (must be unique) - * - install binary (needed for ose_pm_install_load_module()) - * - full path (as argument to the spawned applications env.var - */ - - /* full path including arguments */ - args = driver_alloc(strlen(name)+1); - strcpy(args, name); - - /* handle path */ - tmp_handle = strrchr(name, '/'); - if (tmp_handle == NULL) { - tmp_handle = name; - } - else { - tmp_handle++; - } - - /* handle args */ - ptr = strchr(tmp_handle, ' '); - if (ptr != NULL) { - *ptr = '\0'; - handle_size = ptr - tmp_handle; - } - else { - handle_size = strlen(name)+1; - } - - /* make room for ticker */ - handle_size += (ticker<10)?3:((ticker<100)?4:5); - handle = driver_alloc(handle_size); - - do { - snprintf(handle, handle_size, "%s_%d", tmp_handle, ticker); - pm_status = ose_pm_install_load_module(0, "ELF", name, handle, - 0, 0, NULL); - ticker++; - } while (pm_status == PM_EINSTALL_HANDLE_ALREADY_INSTALLED); - - if (pm_status != PM_SUCCESS) { - errno = ENOSYS; /* FIXME add comment */ - return ERL_DRV_ERROR_ERRNO; - } - - /* Create Program */ - pm_status = ose_pm_create_program(&domain, handle, 0, 0, - NULL, &progpid, &mainbid); - DEBUG_CHECK_RES(pm_status, PM_SUCCESS); - - /* Get the mainpid from the newly created program */ - pm_status = ose_pm_program_info(progpid, &info); - DEBUG_CHECK_RES(pm_status, PM_SUCCESS); - - mainpid = info->main_process; - free_buf ((union SIGNAL **)&info); - - /* pipevm needs to be started - * pipe will return 0 if success, -1 if not, - * errno will be set */ - if (pipe(ifd) != 0 || pipe(ofd) != 0) { - DEBUG_CHECK_RES(0, -1); - ASSERT(0); - } - - /* setup driver data */ - res = set_driver_data(port_num, ofd[0], ifd[1], opts->packet_bytes, - opts->read_write, 1 /* opts->exit_status */, progpid); - - /* init the fd_data array for read/write */ - init_fd_data(ofd[0], port_num); - init_fd_data(ifd[1], port_num); - - /* setup additional configurations - * for the spawned applications environment */ - if (args != NULL) { - set_env(progpid, "ARGV", args); - } - set_env(mainbid, "EFS_RESOLVE_TMO", 0); - set_spawn_fd(ifd[0], 0, mainpid); - set_spawn_fd(ofd[1], 1, mainpid); - set_spawn_fd(ofd[1], 2, mainpid); - - /* start the spawned program */ - pm_status = ose_pm_start_program(mainbid); - DEBUG_CHECK_RES(pm_status, PM_SUCCESS); - - /* close unused fd's */ - close(ifd[0]); - close(ofd[1]); - - if (handle) { - driver_free(handle); - } - - return (ErlDrvData)res; -} - -#define FD_DEF_HEIGHT 24 -#define FD_DEF_WIDTH 80 -/* Control op */ -#define FD_CTRL_OP_GET_WINSIZE 100 - -static int fd_get_window_size(int fd, Uint32 *width, Uint32 *height) -{ -#ifdef TIOCGWINSZ - struct winsize ws; - if (ioctl(fd,TIOCGWINSZ,&ws) == 0) { - *width = (Uint32) ws.ws_col; - *height = (Uint32) ws.ws_row; - return 0; - } -#endif - return -1; -} - -static ErlDrvSSizeT fd_control(ErlDrvData drv_data, - unsigned int command, - char *buf, ErlDrvSizeT len, - char **rbuf, ErlDrvSizeT rlen) -{ - struct driver_data *data = (struct driver_data *)drv_data; - char resbuff[2*sizeof(Uint32)]; - switch (command) { - case FD_CTRL_OP_GET_WINSIZE: - { - Uint32 w,h; - if (fd_get_window_size(data->ifd,&w,&h)) - return 0; - memcpy(resbuff,&w,sizeof(Uint32)); - memcpy(resbuff+sizeof(Uint32),&h,sizeof(Uint32)); - } - break; - default: - return 0; - } - if (rlen < 2*sizeof(Uint32)) { - *rbuf = driver_alloc(2*sizeof(Uint32)); - } - memcpy(*rbuf,resbuff,2*sizeof(Uint32)); - return 2*sizeof(Uint32); -} - -static ErlDrvData fd_start(ErlDrvPort port_num, char* name, - SysDriverOpts* opts) -{ - ErlDrvData res; - - CHLD_STAT_LOCK; - if (opts->read_write & DO_READ) { - init_fd_data(opts->ifd, port_num); - } - if (opts->read_write & DO_WRITE) { - init_fd_data(opts->ofd, port_num); - } - res = set_driver_data(port_num, opts->ifd, opts->ofd, - opts->packet_bytes, - opts->read_write, 0, -1); - CHLD_STAT_UNLOCK; - return res; -} - -static void clear_fd_data(int fd) -{ - if (fd_data[fd].sz > 0) { - erts_free(ERTS_ALC_T_FD_ENTRY_BUF, (void *) fd_data[fd].buf); - ASSERT(erts_smp_atomic_read_nob(&sys_misc_mem_sz) >= fd_data[fd].sz); - erts_smp_atomic_add_nob(&sys_misc_mem_sz, -1*fd_data[fd].sz); - } - fd_data[fd].buf = NULL; - fd_data[fd].sz = 0; - fd_data[fd].remain = 0; - fd_data[fd].cpos = NULL; - fd_data[fd].psz = 0; -} - -static void nbio_stop_fd(ErlDrvPort prt, ErlDrvEvent ev) -{ - int *fd; - driver_select(prt,ev,DO_READ|DO_WRITE,0); - erl_drv_ose_event_fetch(ev, NULL, NULL, (void **)&fd); - clear_fd_data(*fd); - SET_BLOCKING(*fd); -} - -static void fd_stop(ErlDrvData drv_data) /* Does not close the fds */ -{ - struct driver_data *data = (struct driver_data *)drv_data; - - if (data->ofd != -1) { - if (data->ifd != data->ofd) { /* read and write */ - nbio_stop_fd(data->port_num, data->input_event); - nbio_stop_fd(data->port_num, data->output_event); - } - else { /* write only */ - nbio_stop_fd(data->port_num, data->output_event); - } - } - else { /* read only */ - nbio_stop_fd(data->port_num, data->input_event); - } -} - - -static void erl_stop(ErlDrvData drv_data) -{ - struct driver_data *data = (struct driver_data *)drv_data; - - CHLD_STAT_LOCK; - data->pid = -1; - CHLD_STAT_UNLOCK; - - if (data->ofd != -1) { - if (data->ifd != data->ofd) { /* read and write */ - nbio_stop_fd(data->port_num, data->input_event); - nbio_stop_fd(data->port_num, data->output_event); - } - else { /* write only */ - nbio_stop_fd(data->port_num, data->output_event); - } - } - else { /* read only */ - nbio_stop_fd(data->port_num, data->input_event); - } - close(data->ifd); - close(data->ofd); -} - -/* The parameter e is a pointer to the driver_data structure - * related to the fd to be used as output */ -static void output(ErlDrvData drv_data, char* buf, ErlDrvSizeT len) -{ - ErlDrvSizeT sz; - char lb[4]; - char* lbp; - struct driver_data *data = (struct driver_data *)drv_data; - - if (((data->packet_bytes == 2) && - (len > 0xffff)) || (data->packet_bytes == 1 && len > 0xff)) { - driver_failure_posix(data->port_num, EINVAL); - return; /* -1; */ - } - put_int32(len, lb); - lbp = lb + (4-(data->packet_bytes)); - - if ((sz = driver_sizeq(data->port_num)) > 0) { - if (data->packet_bytes != 0) { - driver_enq(data->port_num, lbp, data->packet_bytes); - } - driver_enq(data->port_num, buf, len); - - if (sz + len + data->packet_bytes >= (1 << 13)) - set_busy_port(data->port_num, 1); - } - else { - char *pbbuf; - if (data->packet_bytes != 0) { - pbbuf = malloc(len + data->packet_bytes); - int i; - for (i = 0; i < data->packet_bytes; i++) { - *pbbuf++ = *lbp++; - } - strncpy(pbbuf, buf, len); - pbbuf -= data->packet_bytes; - } - driver_select(data->port_num, data->output_event, - ERL_DRV_WRITE|ERL_DRV_USE, 1); - WRITE_AIO(data->ofd, - (data->packet_bytes ? len+data->packet_bytes : len), - (data->packet_bytes ? pbbuf : buf)); - if (data->packet_bytes != 0) free(pbbuf); - } - return; /* 0; */ -} - -/* This function is being run when we in recieve - * either a read of 0 bytes, or the attach signal from a dying - * spawned load module */ -static int port_inp_failure(ErlDrvPort port_num, ErlDrvEvent ready_fd, int res) - /* Result: 0 (eof) or -1 (error) */ -{ - int *fd; - SIGSELECT sig_no; - ASSERT(res <= 0); - - erl_drv_ose_event_fetch(ready_fd,&sig_no, NULL, (void **)&fd); - /* As we need to handle two signals, we do this in two steps */ - if (driver_data[*fd].alive) { - report_exit_status(driver_data[*fd].report_exit, 0); /* status? */ - } - else { - driver_select(port_num,ready_fd,DO_READ|DO_WRITE,0); - clear_fd_data(*fd); - driver_report_exit(driver_data[*fd].port_num, driver_data[*fd].status); - /* As we do not really know if the spawn has crashed or exited nicely - * we do not check the result status of the following call.. FIXME - * can we handle this in a better way? */ - ose_pm_uninstall_load_module(driver_data[*fd].install_handle); - driver_free(driver_data[*fd].install_handle); - driver_free((void *)driver_data[*fd].aiocb.aio_buf); - - close(*fd); - } - - return 0; -} - -/* The parameter e is a pointer to the driver_data structure - * related to the fd to be used as output. - * ready_fd is the event that triggered this call to ready_input */ -static void ready_input(ErlDrvData drv_data, ErlDrvEvent ready_fd) -{ - int res; - Uint h; - char *buf; - union SIGNAL *sig; - struct driver_data *data = (struct driver_data *)drv_data; - - sig = erl_drv_ose_get_signal(ready_fd); - ASSERT(sig); - - - while (sig) { - /* If we've recieved an attach signal, we need to handle - * it in port_inp_failure */ - if (sig->sig_no == ERTS_SIGNAL_OSE_DRV_ATTACH) { - port_inp_failure(data->port_num, ready_fd, 0); - } - else { - res = sig->fm_read_reply.actual; - if (res == 0) { - port_inp_failure(data->port_num, ready_fd, res); - break; - } - - if (data->packet_bytes == 0) { - if (res < 0) { - if ((errno != EINTR) && (errno != ERRNO_BLOCK)) { - port_inp_failure(data->port_num, ready_fd, res); - } - } - else if (res == 0) { - /* read of 0 bytes, eof, otherside of pipe is assumed dead */ - port_inp_failure(data->port_num, ready_fd, res); - break; - } - else { - buf = driver_alloc(res); - memcpy(buf, (void *)data->aiocb.aio_buf, res); - driver_select(data->port_num, data->output_event, - ERL_DRV_WRITE|ERL_DRV_USE, 1); - driver_output(data->port_num, (char*) buf, res); - driver_free(buf); - } - /* clear the previous read */ - memset(data->aiocb.aio_buf, 0, res); - - /* issue a new read */ - DISPATCH_AIO(sig); - aio_read(&data->aiocb); - } - else if (data->packet_bytes && fd_data[data->ifd].remain > 0) { - /* we've read a partial package, or a header */ - - if (res == fd_data[data->ifd].remain) { /* we are done! */ - char *buf = data->aiocb.aio_buf; - int i; - - /* do we have anything buffered? */ - if (fd_data[data->ifd].buf != NULL) { - memcpy(fd_data[data->ifd].buf + fd_data[data->ifd].sz, - buf, res); - buf = fd_data[data->ifd].buf; - } - - fd_data[data->ifd].sz += res; - driver_output(data->port_num, buf, (fd_data[data->ifd].sz>0?fd_data[data->ifd].sz:res)); - clear_fd_data(data->ifd); - - /* clear the previous read */ - memset(data->aiocb.aio_buf, 0, res); - - /* issue a new read */ - DISPATCH_AIO(sig); - data->aiocb.aio_nbytes = data->packet_bytes; - - if (data->aiocb.aio_buf == NULL) { - port_inp_failure(data->port_num, ready_fd, -1); - } - aio_read(&data->aiocb); - } - else if(res < fd_data[data->ifd].remain) { /* received part of a package */ - if (fd_data[data->ifd].sz == 0) { - - fd_data[data->ifd].sz += res; - memcpy(fd_data[data->ifd].buf, data->aiocb.aio_buf, res); - fd_data[data->ifd].remain -= res; - } - else { - memcpy(fd_data[data->ifd].buf + fd_data[data->ifd].sz, - data->aiocb.aio_buf, res); - fd_data[data->ifd].sz += res; - fd_data[data->ifd].remain -= res; - } - /* clear the previous read */ - memset(data->aiocb.aio_buf, 0, res); - - /* issue a new read */ - DISPATCH_AIO(sig); - data->aiocb.aio_nbytes = fd_data[data->ifd].remain; - - if (data->aiocb.aio_buf == NULL) { - port_inp_failure(data->port_num, ready_fd, -1); - } - aio_read(&data->aiocb); - } - } - else if (data->packet_bytes && fd_data[data->ifd].remain == 0) { /* we've recieved a header */ - - /* analyze the header FIXME */ - switch (data->packet_bytes) { - case 1: h = get_int8(data->aiocb.aio_buf); break; - case 2: h = get_int16(data->aiocb.aio_buf); break; - case 4: h = get_int32(data->aiocb.aio_buf); break; - } - - fd_data[data->ifd].buf = erts_alloc_fnf(ERTS_ALC_T_FD_ENTRY_BUF, h + data->packet_bytes); - fd_data[data->ifd].remain = ((h + data->packet_bytes) - res); - - /* clear the previous read */ - memset(data->aiocb.aio_buf, 0, data->packet_bytes); - - /* issue a new read */ - DISPATCH_AIO(sig); - data->aiocb.aio_nbytes = h; - - if (data->aiocb.aio_buf == NULL) { - port_inp_failure(data->port_num, ready_fd, -1); - } - aio_read(&data->aiocb); - } - } - sig = erl_drv_ose_get_signal(ready_fd); - } -} - - -/* The parameter e is a pointer to the driver_data structure - * related to the fd to be used as output. - * ready_fd is the event that triggered this call to ready_input */ -static void ready_output(ErlDrvData drv_data, ErlDrvEvent ready_fd) -{ - SysIOVec *iov; - int vlen; - int res; - union SIGNAL *sig; - struct driver_data *data = (struct driver_data *)drv_data; - - sig = erl_drv_ose_get_signal(ready_fd); - ASSERT(sig); - - while (sig != NULL) { - if (sig->fm_write_reply.actual <= 0) { - int status; - - status = efs_status_to_errno(sig->fm_write_reply.status); - driver_select(data->port_num, ready_fd, ERL_DRV_WRITE, 0); - DISPATCH_AIO(sig); - FREE_AIO(sig->fm_write_reply.buffer); - - driver_failure_posix(data->port_num, status); - } - else { /* written bytes > 0 */ - iov = driver_peekq(data->port_num, &vlen); - if (vlen > 0) { - DISPATCH_AIO(sig); - FREE_AIO(sig->fm_write_reply.buffer); - res = driver_deq(data->port_num, iov[0].iov_len); - if (res > 0) { - iov = driver_peekq(data->port_num, &vlen); - WRITE_AIO(data->ofd, iov[0].iov_len, iov[0].iov_base); - } - } - else if (vlen == 0) { - DISPATCH_AIO(sig); - FREE_AIO(sig->fm_write_reply.buffer); - } - - } - sig = erl_drv_ose_get_signal(ready_fd); - } -} - -static void stop_select(ErlDrvEvent ready_fd, void* _) -{ - int *fd; - erl_drv_ose_event_fetch(ready_fd, NULL, NULL, (void **)&fd); - erl_drv_ose_event_free(ready_fd); - close(*fd); -} - - -void erts_do_break_handling(void) -{ - struct termios temp_mode; - int saved = 0; - - /* - * Most functions that do_break() calls are intentionally not thread safe; - * therefore, make sure that all threads but this one are blocked before - * proceeding! - */ - erts_smp_thr_progress_block(); - - /* during break we revert to initial settings */ - /* this is done differently for oldshell */ - if (using_oldshell && !replace_intr) { - SET_BLOCKING(1); - } - else if (isatty(0)) { - tcgetattr(0,&temp_mode); - tcsetattr(0,TCSANOW,&initial_tty_mode); - saved = 1; - } - - /* call the break handling function, reset the flag */ - do_break(); - - fflush(stdout); - - /* after break we go back to saved settings */ - if (using_oldshell && !replace_intr) { - SET_NONBLOCKING(1); - } - else if (saved) { - tcsetattr(0,TCSANOW,&temp_mode); - } - - erts_smp_thr_progress_unblock(); -} - -static pid_t -getpid(void) -{ - return get_bid(current_process()); -} - -int getpagesize(void) -{ - return 1024; -} - - -/* Fills in the systems representation of the jam/beam process identifier. -** The Pid is put in STRING representation in the supplied buffer, -** no interpretatione of this should be done by the rest of the -** emulator. The buffer should be at least 21 bytes long. -*/ -void sys_get_pid(char *buffer, size_t buffer_size){ - pid_t p = getpid(); - /* Assume the pid is scalar and can rest in an unsigned long... */ - erts_snprintf(buffer, buffer_size, "%lu",(unsigned long) p); -} - -int -erts_sys_putenv_raw(char *key, char *value) { - return erts_sys_putenv(key, value); -} -int -erts_sys_putenv(char *key, char *value) -{ - int res; - - erts_smp_rwmtx_rwlock(&environ_rwmtx); - res = set_env(get_bid(current_process()), key, - value); - erts_smp_rwmtx_rwunlock(&environ_rwmtx); - return res; -} - - -int -erts_sys_unsetenv(char *key) -{ - int res; - - erts_smp_rwmtx_rwlock(&environ_rwmtx); - res = set_env(get_bid(current_process()),key,NULL); - erts_smp_rwmtx_rwunlock(&environ_rwmtx); - - return res; -} - -int -erts_sys_getenv__(char *key, char *value, size_t *size) -{ - int res; - char *orig_value = get_env(get_bid(current_process()), key); - if (!orig_value) - res = -1; - else { - size_t len = sys_strlen(orig_value); - if (len >= *size) { - *size = len + 1; - res = 1; - } - else { - *size = len; - sys_memcpy((void *) value, (void *) orig_value, len+1); - res = 0; - } - free_buf((union SIGNAL **)&orig_value); - } - return res; -} - -int -erts_sys_getenv_raw(char *key, char *value, size_t *size) { - return erts_sys_getenv(key, value, size); -} - -/* - * erts_sys_getenv - * returns: - * -1, if environment key is not set with a value - * 0, if environment key is set and value fits into buffer res - * 1, if environment key is set but does not fit into buffer res - * res is set with the needed buffer res value - */ - -int -erts_sys_getenv(char *key, char *value, size_t *size) -{ - int res; - erts_smp_rwmtx_rlock(&environ_rwmtx); - res = erts_sys_getenv__(key, value, size); - erts_smp_rwmtx_runlock(&environ_rwmtx); - return res; -} - -void -sys_init_io(void) -{ - fd_data = (struct fd_data *) - erts_alloc(ERTS_ALC_T_FD_TAB, max_files * sizeof(struct fd_data)); - erts_smp_atomic_add_nob(&sys_misc_mem_sz, - max_files * sizeof(struct fd_data)); -} - -extern const char pre_loaded_code[]; -extern Preload pre_loaded[]; - -void erts_sys_alloc_init(void) -{ -} - -void *erts_sys_alloc(ErtsAlcType_t t, void *x, Uint sz) -{ - void *res = malloc((size_t) sz); -#if HAVE_ERTS_MSEG - if (!res) { - erts_mseg_clear_cache(); - return malloc((size_t) sz); - } -#endif - return res; -} - -void *erts_sys_realloc(ErtsAlcType_t t, void *x, void *p, Uint sz) -{ - void *res = realloc(p, (size_t) sz); -#if HAVE_ERTS_MSEG - if (!res) { - erts_mseg_clear_cache(); - return realloc(p, (size_t) sz); - } -#endif - return res; -} - -void erts_sys_free(ErtsAlcType_t t, void *x, void *p) -{ - free(p); -} - -/* Return a pointer to a vector of names of preloaded modules */ - -Preload* -sys_preloaded(void) -{ - return pre_loaded; -} - -/* Return a pointer to preloaded code for module "module" */ -unsigned char* -sys_preload_begin(Preload* p) -{ - return p->code; -} - -/* Clean up if allocated */ -void sys_preload_end(Preload* p) -{ - /* Nothing */ -} - -/* Read a key from console (?) */ - -int sys_get_key(fd) -int fd; -{ - int c; - unsigned char rbuf[64]; - - fflush(stdout); /* Flush query ??? */ - - if ((c = read(fd,rbuf,64)) <= 0) { - return c; - } - - return rbuf[0]; -} - - -#ifdef DEBUG - -extern int erts_initialized; -void -erl_assert_error(const char* expr, const char* func, - const char* file, int line) -{ - fflush(stdout); - fprintf(stderr, "%s:%d:%s() Assertion failed: %s\n", - file, line, func, expr); - fflush(stderr); - ramlog_printf("%s:%d:%s() Assertion failed: %s\n", - file, line, func, expr); - - abort(); -} - -void -erl_debug(char* fmt, ...) -{ - char sbuf[1024]; /* Temporary buffer. */ - va_list va; - - if (debug_log) { - va_start(va, fmt); - vsprintf(sbuf, fmt, va); - va_end(va); - fprintf(stderr, "%s", sbuf); - } -} - -#endif /* DEBUG */ - -static ERTS_INLINE void -report_exit_status(ErtsSysReportExit *rep, int status) -{ - if (rep->ifd >= 0) { - driver_data[rep->ifd].alive = 0; - driver_data[rep->ifd].status = status; - } - if (rep->ofd >= 0) { - driver_data[rep->ofd].alive = 0; - driver_data[rep->ofd].status = status; - } - - erts_free(ERTS_ALC_T_PRT_REP_EXIT, rep); -} - -#define ERTS_REPORT_EXIT_STATUS report_exit_status - -/* - * Called from schedule() when it runs out of runnable processes, - * or when Erlang code has performed INPUT_REDUCTIONS reduction - * steps. runnable == 0 iff there are no runnable Erlang processes. - */ -void -erl_sys_schedule(int runnable) -{ - ASSERT(get_fsem(current_process()) == 0); -#ifdef ERTS_SMP - ASSERT(erts_get_scheduler_data()->no == 1); - ERTS_CHK_IO(!runnable); -#else - ERTS_CHK_IO( 1 ); -#endif - ASSERT(get_fsem(current_process()) == 0); - ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking()); -} - - -#ifdef ERTS_SMP - -void -erts_sys_main_thread(void) -{ - erts_thread_disable_fpe(); - - /* Become signal receiver thread... */ -#ifdef ERTS_ENABLE_LOCK_CHECK - erts_lc_set_thread_name("signal_receiver"); -#endif - - while (1) { - static const SIGSELECT sigsel[] = {0}; - union SIGNAL *msg = receive(sigsel); - - fprintf(stderr,"Main thread got message %d from 0x%x!!\r\n", - msg->sig_no, sender(&msg)); - free_buf(&msg); - } -} - -#endif /* ERTS_SMP */ - -void -erl_sys_args(int* argc, char** argv) -{ - int i, j; - - erts_smp_rwmtx_init(&environ_rwmtx, "environ"); - - init_check_io(); - - /* Handled arguments have been marked with NULL. Slide arguments - not handled towards the beginning of argv. */ - for (i = 0, j = 0; i < *argc; i++) { - if (argv[i]) - argv[j++] = argv[i]; - } - *argc = j; - -} diff --git a/erts/emulator/sys/ose/sys_float.c b/erts/emulator/sys/ose/sys_float.c deleted file mode 100644 index 3d9abc6bd1..0000000000 --- a/erts/emulator/sys/ose/sys_float.c +++ /dev/null @@ -1,845 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2001-2013. 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% - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "sys.h" -#include "global.h" -#include "erl_process.h" - - -#ifdef NO_FPE_SIGNALS - -void -erts_sys_init_float(void) -{ -# ifdef SIGFPE - sys_sigset(SIGFPE, SIG_IGN); /* Ignore so we can test for NaN and Inf */ -# endif -} - -#else /* !NO_FPE_SIGNALS */ - -#ifdef ERTS_SMP -static erts_tsd_key_t fpe_key; - -/* once-only initialisation early in the main thread (via erts_sys_init_float()) */ -static void erts_init_fp_exception(void) -{ - /* XXX: the wrappers prevent using a pthread destructor to - deallocate the key's value; so when/where do we do that? */ - erts_tsd_key_create(&fpe_key); -} - -void erts_thread_init_fp_exception(void) -{ - unsigned long *fpe = erts_alloc(ERTS_ALC_T_FP_EXCEPTION, sizeof(*fpe)); - *fpe = 0L; - erts_tsd_set(fpe_key, fpe); -} - -static ERTS_INLINE volatile unsigned long *erts_thread_get_fp_exception(void) -{ - return (volatile unsigned long*)erts_tsd_get(fpe_key); -} -#else /* !SMP */ -#define erts_init_fp_exception() /*empty*/ -static volatile unsigned long fp_exception; -#define erts_thread_get_fp_exception() (&fp_exception) -#endif /* SMP */ - -volatile unsigned long *erts_get_current_fp_exception(void) -{ - Process *c_p; - - c_p = erts_get_current_process(); - if (c_p) - return &c_p->fp_exception; - return erts_thread_get_fp_exception(); -} - -static void set_current_fp_exception(unsigned long pc) -{ - volatile unsigned long *fpexnp = erts_get_current_fp_exception(); - ASSERT(fpexnp != NULL); - *fpexnp = pc; -} - -void erts_fp_check_init_error(volatile unsigned long *fpexnp) -{ - char buf[64]; - snprintf(buf, sizeof buf, "ERTS_FP_CHECK_INIT at %p: detected unhandled FPE at %p\r\n", - __builtin_return_address(0), (void*)*fpexnp); - if (write(2, buf, strlen(buf)) <= 0) - erl_exit(ERTS_ABORT_EXIT, "%s", buf); - *fpexnp = 0; -#if defined(__i386__) || defined(__x86_64__) - erts_restore_fpu(); -#endif -} - -/* Is there no standard identifier for Darwin/MacOSX ? */ -#if defined(__APPLE__) && defined(__MACH__) && !defined(__DARWIN__) -#define __DARWIN__ 1 -#endif - -#if (defined(__i386__) || defined(__x86_64__)) && defined(__GNUC__) - -static void unmask_x87(void) -{ - unsigned short cw; - - __asm__ __volatile__("fstcw %0" : "=m"(cw)); - cw &= ~(0x01|0x04|0x08); /* unmask IM, ZM, OM */ - __asm__ __volatile__("fldcw %0" : : "m"(cw)); -} - -/* mask x87 FPE, return true if the previous state was unmasked */ -static int mask_x87(void) -{ - unsigned short cw; - int unmasked; - - __asm__ __volatile__("fstcw %0" : "=m"(cw)); - unmasked = (cw & (0x01|0x04|0x08)) == 0; - /* or just set cw = 0x37f */ - cw |= (0x01|0x04|0x08); /* mask IM, ZM, OM */ - __asm__ __volatile__("fldcw %0" : : "m"(cw)); - return unmasked; -} - -static void unmask_sse2(void) -{ - unsigned int mxcsr; - - __asm__ __volatile__("stmxcsr %0" : "=m"(mxcsr)); - mxcsr &= ~(0x003F|0x0680); /* clear exn flags, unmask OM, ZM, IM (not PM, UM, DM) */ - __asm__ __volatile__("ldmxcsr %0" : : "m"(mxcsr)); -} - -/* mask SSE2 FPE, return true if the previous state was unmasked */ -static int mask_sse2(void) -{ - unsigned int mxcsr; - int unmasked; - - __asm__ __volatile__("stmxcsr %0" : "=m"(mxcsr)); - unmasked = (mxcsr & 0x0680) == 0; - /* or just set mxcsr = 0x1f80 */ - mxcsr &= ~0x003F; /* clear exn flags */ - mxcsr |= 0x0680; /* mask OM, ZM, IM (not PM, UM, DM) */ - __asm__ __volatile__("ldmxcsr %0" : : "m"(mxcsr)); - return unmasked; -} - -#if defined(__x86_64__) - -static inline int cpu_has_sse2(void) { return 1; } - -#else /* !__x86_64__ */ - -/* - * Check if an x86-32 processor has SSE2. - */ -static unsigned int xor_eflags(unsigned int mask) -{ - unsigned int eax, edx; - - eax = mask; /* eax = mask */ - __asm__("pushfl\n\t" - "popl %0\n\t" /* edx = original EFLAGS */ - "xorl %0, %1\n\t" /* eax = mask ^ EFLAGS */ - "pushl %1\n\t" - "popfl\n\t" /* new EFLAGS = mask ^ original EFLAGS */ - "pushfl\n\t" - "popl %1\n\t" /* eax = new EFLAGS */ - "xorl %0, %1\n\t" /* eax = new EFLAGS ^ old EFLAGS */ - "pushl %0\n\t" - "popfl" /* restore original EFLAGS */ - : "=d"(edx), "=a"(eax) - : "1"(eax)); - return eax; -} - -static __inline__ unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax, save_ebx; - - /* In PIC mode i386 reserves EBX. So we must save - and restore it ourselves to not upset gcc. */ - __asm__( - "movl %%ebx, %1\n\t" - "cpuid\n\t" - "movl %1, %%ebx" - : "=a"(eax), "=m"(save_ebx) - : "0"(op) - : "cx", "dx"); - return eax; -} - -static __inline__ unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, edx, save_ebx; - - /* In PIC mode i386 reserves EBX. So we must save - and restore it ourselves to not upset gcc. */ - __asm__( - "movl %%ebx, %2\n\t" - "cpuid\n\t" - "movl %2, %%ebx" - : "=a"(eax), "=d"(edx), "=m"(save_ebx) - : "0"(op) - : "cx"); - return edx; -} - -/* The AC bit, bit #18, is a new bit introduced in the EFLAGS - * register on the Intel486 processor to generate alignment - * faults. This bit cannot be set on the Intel386 processor. - */ -static __inline__ int is_386(void) -{ - return ((xor_eflags(1<<18) >> 18) & 1) == 0; -} - -/* Newer x86 processors have a CPUID instruction, as indicated by - * the ID bit (#21) in EFLAGS being modifiable. - */ -static __inline__ int has_CPUID(void) -{ - return (xor_eflags(1<<21) >> 21) & 1; -} - -static int cpu_has_sse2(void) -{ - unsigned int maxlev, features; - static int has_sse2 = -1; - - if (has_sse2 >= 0) - return has_sse2; - has_sse2 = 0; - - if (is_386()) - return 0; - if (!has_CPUID()) - return 0; - maxlev = cpuid_eax(0); - /* Intel A-step Pentium had a preliminary version of CPUID. - It also didn't have SSE2. */ - if ((maxlev & 0xFFFFFF00) == 0x0500) - return 0; - /* If max level is zero then CPUID cannot report any features. */ - if (maxlev == 0) - return 0; - features = cpuid_edx(1); - has_sse2 = (features & (1 << 26)) != 0; - - return has_sse2; -} -#endif /* !__x86_64__ */ - -static void unmask_fpe(void) -{ - __asm__ __volatile__("fnclex"); - unmask_x87(); - if (cpu_has_sse2()) - unmask_sse2(); -} - -static void unmask_fpe_conditional(int unmasked) -{ - if (unmasked) - unmask_fpe(); -} - -/* mask x86 FPE, return true if the previous state was unmasked */ -static int mask_fpe(void) -{ - int unmasked; - - unmasked = mask_x87(); - if (cpu_has_sse2()) - unmasked |= mask_sse2(); - return unmasked; -} - -void erts_restore_fpu(void) -{ - __asm__ __volatile__("fninit"); - unmask_x87(); - if (cpu_has_sse2()) - unmask_sse2(); -} - -#elif defined(__sparc__) && defined(__linux__) - -#if defined(__arch64__) -#define LDX "ldx" -#define STX "stx" -#else -#define LDX "ld" -#define STX "st" -#endif - -static void unmask_fpe(void) -{ - unsigned long fsr; - - __asm__(STX " %%fsr, %0" : "=m"(fsr)); - fsr &= ~(0x1FUL << 23); /* clear FSR[TEM] field */ - fsr |= (0x1AUL << 23); /* enable NV, OF, DZ exceptions */ - __asm__ __volatile__(LDX " %0, %%fsr" : : "m"(fsr)); -} - -static void unmask_fpe_conditional(int unmasked) -{ - if (unmasked) - unmask_fpe(); -} - -/* mask SPARC FPE, return true if the previous state was unmasked */ -static int mask_fpe(void) -{ - unsigned long fsr; - int unmasked; - - __asm__(STX " %%fsr, %0" : "=m"(fsr)); - unmasked = ((fsr >> 23) & 0x1A) == 0x1A; - fsr &= ~(0x1FUL << 23); /* clear FSR[TEM] field */ - __asm__ __volatile__(LDX " %0, %%fsr" : : "m"(fsr)); - return unmasked; -} - -#elif (defined(__powerpc__) && defined(__linux__)) || (defined(__ppc__) && defined(__DARWIN__)) - -#if defined(__linux__) -#include <sys/prctl.h> - -static void set_fpexc_precise(void) -{ - if (prctl(PR_SET_FPEXC, PR_FP_EXC_PRECISE) < 0) { - perror("PR_SET_FPEXC"); - exit(1); - } -} - -#elif defined(__DARWIN__) - -#include <mach/mach.h> -#include <pthread.h> - -/* - * FE0 FE1 MSR bits - * 0 0 floating-point exceptions disabled - * 0 1 floating-point imprecise nonrecoverable - * 1 0 floating-point imprecise recoverable - * 1 1 floating-point precise mode - * - * Apparently: - * - Darwin 5.5 (MacOS X <= 10.1) starts with FE0 == FE1 == 0, - * and resets FE0 and FE1 to 0 after each SIGFPE. - * - Darwin 6.0 (MacOS X 10.2) starts with FE0 == FE1 == 1, - * and does not reset FE0 or FE1 after a SIGFPE. - */ -#define FE0_MASK (1<<11) -#define FE1_MASK (1<<8) - -/* a thread cannot get or set its own MSR bits */ -static void *fpu_fpe_enable(void *arg) -{ - thread_t t = *(thread_t*)arg; - struct ppc_thread_state state; - unsigned int state_size = PPC_THREAD_STATE_COUNT; - - if (thread_get_state(t, PPC_THREAD_STATE, (natural_t*)&state, &state_size) != KERN_SUCCESS) { - perror("thread_get_state"); - exit(1); - } - if ((state.srr1 & (FE1_MASK|FE0_MASK)) != (FE1_MASK|FE0_MASK)) { -#if 1 - /* This would also have to be performed in the SIGFPE handler - to work around the MSR reset older Darwin releases do. */ - state.srr1 |= (FE1_MASK|FE0_MASK); - thread_set_state(t, PPC_THREAD_STATE, (natural_t*)&state, state_size); -#else - fprintf(stderr, "srr1 == 0x%08x, your Darwin is too old\n", state.srr1); - exit(1); -#endif - } - return NULL; /* Ok, we appear to be on Darwin 6.0 or later */ -} - -static void set_fpexc_precise(void) -{ - thread_t self = mach_thread_self(); - pthread_t enabler; - - if (pthread_create(&enabler, NULL, fpu_fpe_enable, &self)) { - perror("pthread_create"); - } else if (pthread_join(enabler, NULL)) { - perror("pthread_join"); - } -} - -#endif - -static void set_fpscr(unsigned int fpscr) -{ - union { - double d; - unsigned int fpscr[2]; - } u; - - u.fpscr[0] = 0xFFF80000; - u.fpscr[1] = fpscr; - __asm__ __volatile__("mtfsf 255,%0" : : "f"(u.d)); -} - -static unsigned int get_fpscr(void) -{ - union { - double d; - unsigned int fpscr[2]; - } u; - - __asm__("mffs %0" : "=f"(u.d)); - return u.fpscr[1]; -} - -static void unmask_fpe(void) -{ - set_fpexc_precise(); - set_fpscr(0x80|0x40|0x10); /* VE, OE, ZE; not UE or XE */ -} - -static void unmask_fpe_conditional(int unmasked) -{ - if (unmasked) - unmask_fpe(); -} - -/* mask PowerPC FPE, return true if the previous state was unmasked */ -static int mask_fpe(void) -{ - int unmasked; - - unmasked = (get_fpscr() & (0x80|0x40|0x10)) == (0x80|0x40|0x10); - set_fpscr(0x00); - return unmasked; -} - -#else - -static void unmask_fpe(void) -{ - fpsetmask(FP_X_INV | FP_X_OFL | FP_X_DZ); -} - -static void unmask_fpe_conditional(int unmasked) -{ - if (unmasked) - unmask_fpe(); -} - -/* mask IEEE FPE, return true if previous state was unmasked */ -static int mask_fpe(void) -{ - const fp_except unmasked_mask = FP_X_INV | FP_X_OFL | FP_X_DZ; - fp_except old_mask; - - old_mask = fpsetmask(0); - return (old_mask & unmasked_mask) == unmasked_mask; -} - -#endif - -#if (defined(__linux__) && (defined(__i386__) || defined(__x86_64__) || defined(__sparc__) || defined(__powerpc__))) || (defined(__DARWIN__) && (defined(__i386__) || defined(__x86_64__) || defined(__ppc__))) || (defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__))) || ((defined(__NetBSD__) || defined(__OpenBSD__)) && defined(__x86_64__)) || (defined(__sun__) && defined(__x86_64__)) - -#if defined(__linux__) && defined(__i386__) -#if !defined(X86_FXSR_MAGIC) -#define X86_FXSR_MAGIC 0x0000 -#endif -#elif defined(__FreeBSD__) && defined(__x86_64__) -#include <sys/types.h> -#include <machine/fpu.h> -#elif defined(__FreeBSD__) && defined(__i386__) -#include <sys/types.h> -#include <machine/npx.h> -#elif defined(__DARWIN__) -#include <machine/signal.h> -#elif defined(__OpenBSD__) && defined(__x86_64__) -#include <sys/types.h> -#include <machine/fpu.h> -#endif -#if !(defined(__OpenBSD__) && defined(__x86_64__)) -#include <ucontext.h> -#endif -#include <string.h> - -#if defined(__linux__) && defined(__x86_64__) -#define mc_pc(mc) ((mc)->gregs[REG_RIP]) -#elif defined(__linux__) && defined(__i386__) -#define mc_pc(mc) ((mc)->gregs[REG_EIP]) -#elif defined(__DARWIN__) && defined(__i386__) -#ifdef DARWIN_MODERN_MCONTEXT -#define mc_pc(mc) ((mc)->__ss.__eip) -#else -#define mc_pc(mc) ((mc)->ss.eip) -#endif -#elif defined(__DARWIN__) && defined(__x86_64__) -#ifdef DARWIN_MODERN_MCONTEXT -#define mc_pc(mc) ((mc)->__ss.__rip) -#else -#define mc_pc(mc) ((mc)->ss.rip) -#endif -#elif defined(__FreeBSD__) && defined(__x86_64__) -#define mc_pc(mc) ((mc)->mc_rip) -#elif defined(__FreeBSD__) && defined(__i386__) -#define mc_pc(mc) ((mc)->mc_eip) -#elif defined(__NetBSD__) && defined(__x86_64__) -#define mc_pc(mc) ((mc)->__gregs[_REG_RIP]) -#elif defined(__NetBSD__) && defined(__i386__) -#define mc_pc(mc) ((mc)->__gregs[_REG_EIP]) -#elif defined(__OpenBSD__) && defined(__x86_64__) -#define mc_pc(mc) ((mc)->sc_rip) -#elif defined(__sun__) && defined(__x86_64__) -#define mc_pc(mc) ((mc)->gregs[REG_RIP]) -#endif - -static void fpe_sig_action(int sig, siginfo_t *si, void *puc) -{ - ucontext_t *uc = puc; - unsigned long pc; - -#if defined(__linux__) -#if defined(__x86_64__) - mcontext_t *mc = &uc->uc_mcontext; - fpregset_t fpstate = mc->fpregs; - pc = mc_pc(mc); - /* A failed SSE2 instruction will restart. To avoid - looping we mask SSE2 exceptions now and unmask them - again later in erts_check_fpe()/erts_restore_fpu(). - On RISCs we update PC to skip the failed instruction, - but the ever increasing complexity of the x86 instruction - set encoding makes that a poor solution here. */ - fpstate->mxcsr = 0x1F80; - fpstate->swd &= ~0xFF; -#elif defined(__i386__) - mcontext_t *mc = &uc->uc_mcontext; - fpregset_t fpstate = mc->fpregs; - pc = mc_pc(mc); - if ((fpstate->status >> 16) == X86_FXSR_MAGIC) - ((struct _fpstate*)fpstate)->mxcsr = 0x1F80; - fpstate->sw &= ~0xFF; -#elif defined(__sparc__) && defined(__arch64__) - /* on SPARC the 3rd parameter points to a sigcontext not a ucontext */ - struct sigcontext *sc = (struct sigcontext*)puc; - pc = sc->sigc_regs.tpc; - sc->sigc_regs.tpc = sc->sigc_regs.tnpc; - sc->sigc_regs.tnpc += 4; -#elif defined(__sparc__) - /* on SPARC the 3rd parameter points to a sigcontext not a ucontext */ - struct sigcontext *sc = (struct sigcontext*)puc; - pc = sc->si_regs.pc; - sc->si_regs.pc = sc->si_regs.npc; - sc->si_regs.npc = (unsigned long)sc->si_regs.npc + 4; -#elif defined(__powerpc__) -#if defined(__powerpc64__) - mcontext_t *mc = &uc->uc_mcontext; - unsigned long *regs = &mc->gp_regs[0]; -#else - mcontext_t *mc = uc->uc_mcontext.uc_regs; - unsigned long *regs = &mc->gregs[0]; -#endif - pc = regs[PT_NIP]; - regs[PT_NIP] += 4; - regs[PT_FPSCR] = 0x80|0x40|0x10; /* VE, OE, ZE; not UE or XE */ -#endif -#elif defined(__DARWIN__) && (defined(__i386__) || defined(__x86_64__)) -#ifdef DARWIN_MODERN_MCONTEXT - mcontext_t mc = uc->uc_mcontext; - pc = mc_pc(mc); - mc->__fs.__fpu_mxcsr = 0x1F80; - *(unsigned short *)&mc->__fs.__fpu_fsw &= ~0xFF; -#else - mcontext_t mc = uc->uc_mcontext; - pc = mc_pc(mc); - mc->fs.fpu_mxcsr = 0x1F80; - *(unsigned short *)&mc->fs.fpu_fsw &= ~0xFF; -#endif /* DARWIN_MODERN_MCONTEXT */ -#elif defined(__DARWIN__) && defined(__ppc__) - mcontext_t mc = uc->uc_mcontext; - pc = mc->ss.srr0; - mc->ss.srr0 += 4; - mc->fs.fpscr = 0x80|0x40|0x10; -#elif defined(__FreeBSD__) && defined(__x86_64__) - mcontext_t *mc = &uc->uc_mcontext; - struct savefpu *savefpu = (struct savefpu*)&mc->mc_fpstate; - struct envxmm *envxmm = &savefpu->sv_env; - pc = mc_pc(mc); - envxmm->en_mxcsr = 0x1F80; - envxmm->en_sw &= ~0xFF; -#elif defined(__FreeBSD__) && defined(__i386__) - mcontext_t *mc = &uc->uc_mcontext; - union savefpu *savefpu = (union savefpu*)&mc->mc_fpstate; - pc = mc_pc(mc); - if (mc->mc_fpformat == _MC_FPFMT_XMM) { - struct envxmm *envxmm = &savefpu->sv_xmm.sv_env; - envxmm->en_mxcsr = 0x1F80; - envxmm->en_sw &= ~0xFF; - } else { - struct env87 *env87 = &savefpu->sv_87.sv_env; - env87->en_sw &= ~0xFF; - } -#elif defined(__NetBSD__) && defined(__x86_64__) - mcontext_t *mc = &uc->uc_mcontext; - struct fxsave64 *fxsave = (struct fxsave64 *)&mc->__fpregs; - pc = mc_pc(mc); - fxsave->fx_mxcsr = 0x1F80; - fxsave->fx_fsw &= ~0xFF; -#elif defined(__NetBSD__) && defined(__i386__) - mcontext_t *mc = &uc->uc_mcontext; - pc = mc_pc(mc); - if (uc->uc_flags & _UC_FXSAVE) { - struct envxmm *envxmm = (struct envxmm *)&mc->__fpregs; - envxmm->en_mxcsr = 0x1F80; - envxmm->en_sw &= ~0xFF; - } else { - struct env87 *env87 = (struct env87 *)&mc->__fpregs; - env87->en_sw &= ~0xFF; - } -#elif defined(__OpenBSD__) && defined(__x86_64__) - struct fxsave64 *fxsave = uc->sc_fpstate; - pc = mc_pc(uc); - fxsave->fx_mxcsr = 0x1F80; - fxsave->fx_fsw &= ~0xFF; -#elif defined(__sun__) && defined(__x86_64__) - mcontext_t *mc = &uc->uc_mcontext; - struct fpchip_state *fpstate = &mc->fpregs.fp_reg_set.fpchip_state; - pc = mc_pc(mc); - fpstate->mxcsr = 0x1F80; - fpstate->sw &= ~0xFF; -#endif -#if 0 - { - char buf[64]; - snprintf(buf, sizeof buf, "%s: FPE at %p\r\n", __FUNCTION__, (void*)pc); - write(2, buf, strlen(buf)); - } -#endif - set_current_fp_exception(pc); -} - -static void erts_thread_catch_fp_exceptions(void) -{ - struct sigaction act; - memset(&act, 0, sizeof act); - act.sa_sigaction = fpe_sig_action; - act.sa_flags = SA_SIGINFO; - sigaction(SIGFPE, &act, NULL); - unmask_fpe(); -} - -#else /* !((__linux__ && (__i386__ || __x86_64__ || __powerpc__)) || (__DARWIN__ && (__i386__ || __x86_64__ || __ppc__))) */ - -static void fpe_sig_handler(int sig) -{ - set_current_fp_exception(1); /* XXX: convert to sigaction so we can get the trap PC */ -} - -static void erts_thread_catch_fp_exceptions(void) -{ - sys_sigset(SIGFPE, fpe_sig_handler); - unmask_fpe(); -} - -#endif /* (__linux__ && (__i386__ || __x86_64__ || __powerpc__)) || (__DARWIN__ && (__i386__ || __x86_64__ || __ppc__))) */ - -/* once-only initialisation early in the main thread */ -void erts_sys_init_float(void) -{ - erts_init_fp_exception(); - erts_thread_catch_fp_exceptions(); - erts_printf_block_fpe = erts_sys_block_fpe; - erts_printf_unblock_fpe = erts_sys_unblock_fpe; -} - -#endif /* NO_FPE_SIGNALS */ - -void erts_thread_init_float(void) -{ -#ifdef ERTS_SMP - /* This allows Erlang schedulers to leave Erlang-process context - and still have working FP exceptions. XXX: is this needed? */ - erts_thread_init_fp_exception(); -#endif - -#ifndef NO_FPE_SIGNALS - /* NOTE: - * erts_thread_disable_fpe() is called in all threads at - * creation. We at least need to call unmask_fpe() - */ -#if defined(__DARWIN__) || defined(__FreeBSD__) - /* Darwin (7.9.0) does not appear to propagate FP exception settings - to a new thread from its parent. So if we want FP exceptions, we - must manually re-enable them in each new thread. - FreeBSD 6.1 appears to suffer from a similar issue. */ - erts_thread_catch_fp_exceptions(); -#else - unmask_fpe(); -#endif - -#endif -} - -void erts_thread_disable_fpe(void) -{ -#if !defined(NO_FPE_SIGNALS) - (void)mask_fpe(); -#endif -} - -#if !defined(NO_FPE_SIGNALS) -int erts_sys_block_fpe(void) -{ - return mask_fpe(); -} - -void erts_sys_unblock_fpe(int unmasked) -{ - unmask_fpe_conditional(unmasked); -} -#endif - -/* The following check is incorporated from the Vee machine */ - -#define ISDIGIT(d) ((d) >= '0' && (d) <= '9') - -/* - ** Convert a double to ascii format 0.dddde[+|-]ddd - ** return number of characters converted or -1 if error. - ** - ** These two functions should maybe use localeconv() to pick up - ** the current radix character, but since it is uncertain how - ** expensive such a system call is, and since no-one has heard - ** of other radix characters than '.' and ',' an ad-hoc - ** low execution time solution is used instead. - */ - -int -sys_double_to_chars_ext(double fp, char *buffer, size_t buffer_size, size_t decimals) -{ - char *s = buffer; - - if (erts_snprintf(buffer, buffer_size, "%.*e", decimals, fp) >= buffer_size) - return -1; - /* Search upto decimal point */ - if (*s == '+' || *s == '-') s++; - while (ISDIGIT(*s)) s++; - if (*s == ',') *s++ = '.'; /* Replace ',' with '.' */ - /* Scan to end of string */ - while (*s) s++; - return s-buffer; /* i.e strlen(buffer) */ -} - -/* Float conversion */ - -int -sys_chars_to_double(char* buf, double* fp) -{ -#ifndef NO_FPE_SIGNALS - volatile unsigned long *fpexnp = erts_get_current_fp_exception(); -#endif - char *s = buf, *t, *dp; - - /* Robert says that something like this is what he really wanted: - * (The [.,] radix test is NOT what Robert wanted - it was added later) - * - * 7 == sscanf(Tbuf, "%[+-]%[0-9][.,]%[0-9]%[eE]%[+-]%[0-9]%s", ....); - * if (*s2 == 0 || *s3 == 0 || *s4 == 0 || *s6 == 0 || *s7) - * break; - */ - - /* Scan string to check syntax. */ - if (*s == '+' || *s == '-') s++; - if (!ISDIGIT(*s)) /* Leading digits. */ - return -1; - while (ISDIGIT(*s)) s++; - if (*s != '.' && *s != ',') /* Decimal part. */ - return -1; - dp = s++; /* Remember decimal point pos just in case */ - if (!ISDIGIT(*s)) - return -1; - while (ISDIGIT(*s)) s++; - if (*s == 'e' || *s == 'E') { - /* There is an exponent. */ - s++; - if (*s == '+' || *s == '-') s++; - if (!ISDIGIT(*s)) - return -1; - while (ISDIGIT(*s)) s++; - } - if (*s) /* That should be it */ - return -1; - -#ifdef NO_FPE_SIGNALS - errno = 0; -#endif - __ERTS_FP_CHECK_INIT(fpexnp); - *fp = strtod(buf, &t); - __ERTS_FP_ERROR_THOROUGH(fpexnp, *fp, return -1); - if (t != s) { /* Whole string not scanned */ - /* Try again with other radix char */ - *dp = (*dp == '.') ? ',' : '.'; - errno = 0; - __ERTS_FP_CHECK_INIT(fpexnp); - *fp = strtod(buf, &t); - __ERTS_FP_ERROR_THOROUGH(fpexnp, *fp, return -1); - } - -#ifdef NO_FPE_SIGNALS - if (errno == ERANGE) { - if (*fp == HUGE_VAL || *fp == -HUGE_VAL) { - /* overflow, should give error */ - return -1; - } else if (t == s && *fp == 0.0) { - /* This should give 0.0 - OTP-7178 */ - errno = 0; - - } else if (*fp == 0.0) { - return -1; - } - } -#endif - return 0; -} - -int -matherr(struct exception *exc) -{ -#if !defined(NO_FPE_SIGNALS) - volatile unsigned long *fpexnp = erts_get_current_fp_exception(); - if (fpexnp != NULL) - *fpexnp = (unsigned long)__builtin_return_address(0); -#endif - return 1; -} diff --git a/erts/emulator/sys/ose/sys_time.c b/erts/emulator/sys/ose/sys_time.c deleted file mode 100644 index 5dac75956a..0000000000 --- a/erts/emulator/sys/ose/sys_time.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * %CopyrightBegin% - * - * Copyright Ericsson AB 2005-2009. 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% - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include "sys.h" -#include "global.h" - -/******************* Routines for time measurement *********************/ - -int erts_ticks_per_sec = 0; /* Will be SYS_CLK_TCK in erl_unix_sys.h */ - -int sys_init_time(void) -{ - return SYS_CLOCK_RESOLUTION; -} - -clock_t sys_times(SysTimes *now) { - now->tms_utime = now->tms_stime = now->tms_cutime = now->tms_cstime = 0; - return 0; -} - -static OSTICK last_tick_count = 0; -static SysHrTime wrap = 0; -static OSTICK us_per_tick; - -void sys_init_hrtime() { - us_per_tick = system_tick(); -} - -SysHrTime sys_gethrtime() { - OSTICK ticks = get_ticks(); - if (ticks < (SysHrTime) last_tick_count) { - wrap += 1ULL << 32; - } - last_tick_count = ticks; - return ((((SysHrTime) ticks) + wrap) * 1000*us_per_tick); -} diff --git a/erts/emulator/test/emulator.spec.ose b/erts/emulator/test/emulator.spec.ose deleted file mode 100644 index 9f494609d9..0000000000 --- a/erts/emulator/test/emulator.spec.ose +++ /dev/null @@ -1,2 +0,0 @@ -{topcase, {dir, "../emulator_test"}}. -{skip, {obsolete_SUITE, "Not on ose"}}. |