From ba93bbc768928bb6213cd583ea91a108fa9d16ca Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Mon, 24 Apr 2017 20:08:53 +0200 Subject: erts: Refactor move check_io interface from sys to check_io # Conflicts: # erts/emulator/beam/erl_process.c # erts/emulator/beam/sys.h # erts/emulator/sys/common/erl_check_io.c # erts/emulator/sys/common/erl_check_io.h # erts/emulator/sys/unix/sys.c --- erts/emulator/beam/erl_bif_info.c | 1 + erts/emulator/beam/erl_port_task.c | 1 + erts/emulator/beam/erl_process.c | 9 +- erts/emulator/beam/sys.h | 4 - erts/emulator/sys/common/erl_check_io.c | 153 ++++++++++++++++++++++++++++---- erts/emulator/sys/common/erl_check_io.h | 33 ------- erts/emulator/sys/unix/sys.c | 129 ++------------------------- erts/emulator/sys/win32/sys.c | 13 --- 8 files changed, 150 insertions(+), 193 deletions(-) diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index 36939d6acc..d296e794d5 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -46,6 +46,7 @@ #include "erl_thr_progress.h" #include "erl_bif_unique.h" #include "erl_map.h" +#include "erl_check_io.h" #define ERTS_PTAB_WANT_DEBUG_FUNCS__ #include "erl_ptab.h" #include "erl_time.h" diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c index 14977dfa17..b9152a7b5e 100644 --- a/erts/emulator/beam/erl_port_task.c +++ b/erts/emulator/beam/erl_port_task.c @@ -36,6 +36,7 @@ #include "erl_check_io.h" #include "dtrace-wrapper.h" #include "lttng-wrapper.h" +#include "erl_check_io.h" #include /* diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 1f696f7ba4..9c92d2a1a4 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -49,6 +49,7 @@ #define ERTS_WANT_TIMER_WHEEL_API #include "erl_time.h" #include "erl_nfunc_sched.h" +#include "erl_check_io.h" #define ERTS_CHECK_TIME_REDS CONTEXT_REDS #define ERTS_DELAYED_WAKEUP_INFINITY (~(Uint64) 0) @@ -1563,14 +1564,14 @@ erts_sched_finish_poke(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flags) { switch (flags & ERTS_SSI_FLGS_SLEEP_TYPE) { case ERTS_SSI_FLG_POLL_SLEEPING: - erts_sys_schedule_interrupt(1); + erts_check_io_interrupt(1); break; case ERTS_SSI_FLG_POLL_SLEEPING|ERTS_SSI_FLG_TSE_SLEEPING: /* * Thread progress blocking while poll sleeping; need * to signal on both... */ - erts_sys_schedule_interrupt(1); + erts_check_io_interrupt(1); /* fall through */ case ERTS_SSI_FLG_TSE_SLEEPING: erts_tse_set(ssi->event); @@ -3084,7 +3085,7 @@ sched_set_sleeptype(ErtsSchedulerSleepInfo *ssi, erts_aint32_t sleep_type) erts_tse_reset(ssi->event); else { ASSERT(sleep_type == ERTS_SSI_FLG_POLL_SLEEPING); - erts_sys_schedule_interrupt(0); + erts_check_io_interrupt(0); } while (1) { @@ -10049,7 +10050,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) fcalls = 0; #if 0 /* Not needed since we wont wait in sys schedule */ - erts_sys_schedule_interrupt(0); + erts_check_io_interrupt(0); #endif erts_runq_unlock(rq); diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h index 68ef0a23f3..3dd6ef333b 100644 --- a/erts/emulator/beam/sys.h +++ b/erts/emulator/beam/sys.h @@ -575,8 +575,6 @@ __decl_noreturn void __noreturn erts_exit(int n, char*, ...); erts_exit(ERTS_ABORT_EXIT, "%s:%d:%s(): Internal error: %s\n", \ __FILE__, __LINE__, __func__, What) -Eterm erts_check_io_info(void *p); - UWord erts_sys_get_page_size(void); /* Size of misc memory allocated from system dependent code */ @@ -739,8 +737,6 @@ extern char *erts_sys_ddll_error(int code); /* * System interfaces for startup. */ -void erts_sys_schedule_interrupt(int set); -void erts_sys_schedule_interrupt_timed(int, ErtsMonotonicTime); void erts_sys_main_thread(void); extern int erts_sys_prepare_crash_dump(int secs); diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index f0854e8730..bed815c64b 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -110,6 +110,23 @@ static struct pollset_info }pollset; #define NUM_OF_POLLSETS 1 + +#ifdef ERTS_ENABLE_KERNEL_POLL +void erts_init_check_io_kp(void); +void erts_init_check_io_nkp(void); +int ERTS_CIO_EXPORT(driver_select)(ErlDrvPort, ErlDrvEvent, int, int); +int ERTS_CIO_EXPORT(enif_select)(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm); +int ERTS_CIO_EXPORT(driver_event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData); +Uint ERTS_CIO_EXPORT(erts_check_io_size)(void); +Eterm ERTS_CIO_EXPORT(erts_check_io_info)(void *); +int ERTS_CIO_EXPORT(erts_check_io_max_files)(void); +void ERTS_CIO_EXPORT(erts_check_io_interrupt)(int); +void ERTS_CIO_EXPORT(erts_check_io_interrupt_timed)(int, ErtsMonotonicTime); +void ERTS_CIO_EXPORT(erts_check_io)(int); +int ERTS_CIO_EXPORT(erts_check_io_debug)(ErtsCheckIoDebugInfo *); +#endif + + typedef struct { #ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS SafeHashBucket hb; @@ -2098,7 +2115,6 @@ eready(Eterm id, ErtsDrvEventState *state, ErlDrvEventData event_data, static void bad_fd_in_pollset(ErtsDrvEventState *, Eterm inport, Eterm outport); - void ERTS_CIO_EXPORT(erts_check_io_interrupt)(int set) { @@ -2142,12 +2158,6 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) erts_do_break_handling(); #endif -#ifdef ERTS_SIGNAL_STATE /* ifndef ERTS_SMP */ - if (ERTS_SIGNAL_STATE) { - erts_handle_signal_state(); - } -#endif - /* Figure out timeout value */ timeout_time = (do_wait ? erts_check_next_timeout_time(esdp) @@ -2186,14 +2196,6 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) erts_do_break_handling(); #endif - -#ifdef ERTS_SIGNAL_STATE /* ifndef ERTS_SMP */ - if (ERTS_SIGNAL_STATE) { - erts_handle_signal_state(); - } -#endif - - if (poll_ret != 0) { erts_atomic_set_nob(&pollset.in_poll_wait, 0); forget_removed(&pollset); @@ -2259,9 +2261,7 @@ ERTS_CIO_EXPORT(erts_check_io)(int do_wait) oready(state->driver.select->outport, state, current_cio_time); } /* Someone might have deselected input since revents - was read (true also on the non-smp emulator since - oready() may have been called); therefore, update - revents... */ + was read therefore, update revents... */ revents &= state->events; if (revents & ERTS_POLL_EV_IN) { iready(state->driver.select->inport, state, current_cio_time); @@ -2502,6 +2502,31 @@ static void drv_ev_state_free(void *des) } #endif + +#ifdef ERTS_ENABLE_KERNEL_POLL + +struct io_functions { + int (*select)(ErlDrvPort, ErlDrvEvent, int, int); + int (*enif_select)(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm); + int (*event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData); + void (*check_io_as_interrupt)(void); + void (*check_io_interrupt)(int); + void (*check_io_interrupt_tmd)(int, ErtsMonotonicTime); + void (*check_io)(int); + int (*max_files)(void); + Uint (*size)(void); + Eterm (*info)(void *); + int (*check_io_debug)(ErtsCheckIoDebugInfo *); +}; + +# ifdef ERTS_KERNEL_POLL_VERSION +struct io_functions erts_io_funcs = {0}; +# else +extern struct io_functions erts_io_funcs; +# endif + +#endif /* ERTS_ENABLE_KERNEL_POLL */ + void ERTS_CIO_EXPORT(erts_init_check_io)(void) { @@ -2512,6 +2537,20 @@ ERTS_CIO_EXPORT(erts_init_check_io)(void) erts_atomic_init_nob(&erts_check_io_time, 0); erts_atomic_init_nob(&pollset.in_poll_wait, 0); +#ifdef ERTS_ENABLE_KERNEL_POLL + ASSERT(erts_io_funcs.select == NULL); + erts_io_funcs.select = ERTS_CIO_EXPORT(driver_select); + erts_io_funcs.enif_select = ERTS_CIO_EXPORT(enif_select); + erts_io_funcs.event = ERTS_CIO_EXPORT(driver_event); + erts_io_funcs.check_io_interrupt = ERTS_CIO_EXPORT(erts_check_io_interrupt); + erts_io_funcs.check_io_interrupt_tmd= ERTS_CIO_EXPORT(erts_check_io_interrupt_timed); + erts_io_funcs.check_io = ERTS_CIO_EXPORT(erts_check_io); + erts_io_funcs.max_files = ERTS_CIO_EXPORT(erts_check_io_max_files); + erts_io_funcs.size = ERTS_CIO_EXPORT(erts_check_io_size); + erts_io_funcs.info = ERTS_CIO_EXPORT(erts_check_io_info); + erts_io_funcs.check_io_debug = ERTS_CIO_EXPORT(erts_check_io_debug); +#endif + ERTS_CIO_POLL_INIT(); pollset.ps = ERTS_CIO_NEW_POLLSET(); @@ -3097,7 +3136,7 @@ ERTS_CIO_EXPORT(erts_check_io_debug)(ErtsCheckIoDebugInfo *ciodip) } #ifdef ERTS_ENABLE_LOCK_COUNT -void ERTS_CIO_EXPORT(erts_lcnt_update_cio_locks)(int enable) { +void erts_lcnt_update_cio_locks(int enable) { #ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS erts_lcnt_enable_hash_lock_count(&drv_ev_state_tab, ERTS_LOCK_FLAGS_CATEGORY_IO, enable); #else @@ -3105,3 +3144,79 @@ void ERTS_CIO_EXPORT(erts_lcnt_update_cio_locks)(int enable) { #endif } #endif /* ERTS_ENABLE_LOCK_COUNT */ + + +#ifdef ERTS_ENABLE_KERNEL_POLL +# ifdef ERTS_KERNEL_POLL_VERSION + +/* + * Compile these only once for kp/nkp + */ + +void erts_init_check_io(void) +{ + if (erts_use_kernel_poll) + erts_init_check_io_kp(); + else + erts_init_check_io_nkp(); +} + +int +driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on) +{ + return (*erts_io_funcs.select)(port, event, mode, on); +} + +int +driver_event(ErlDrvPort port, ErlDrvEvent event, ErlDrvEventData event_data) +{ + return (*erts_io_funcs.event)(port, event, event_data); +} + +int enif_select(ErlNifEnv* env, ErlNifEvent event, + enum ErlNifSelectFlags flags, void* obj, const ErlNifPid* pid, Eterm ref) +{ + return (*erts_io_funcs.enif_select)(env, event, flags, obj, pid, ref); +} + +void erts_check_io(int do_wait) +{ + erts_io_funcs.check_io(do_wait); +} + +Uint erts_check_io_size(void) +{ + return erts_io_funcs.size(); +} + + +Eterm erts_check_io_info(void *p) +{ + return (*erts_io_funcs.info)(p); +} + +int erts_check_io_max_files(void) +{ + return erts_io_funcs.max_files(); +} + +int +erts_check_io_debug(ErtsCheckIoDebugInfo *ip) +{ + return (*erts_io_funcs.check_io_debug)(ip); +} + +void erts_check_io_interrupt(int set) +{ + erts_io_funcs.check_io_interrupt(set); +} + +void erts_check_io_interrupt_timed(int set, + ErtsMonotonicTime timeout_time) +{ + erts_io_funcs.check_io_interrupt_tmd(set, timeout_time); +} + +#endif /* ERTS_KERNEL_POLL_VERSION */ + +#endif /* !ERTS_ENABLE_KERNEL_POLL */ diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h index 777942a473..c4ab22aaff 100644 --- a/erts/emulator/sys/common/erl_check_io.h +++ b/erts/emulator/sys/common/erl_check_io.h @@ -30,38 +30,6 @@ #include "sys.h" #include "erl_sys_driver.h" -#ifdef ERTS_ENABLE_KERNEL_POLL - -int driver_select_kp(ErlDrvPort, ErlDrvEvent, int, int); -int driver_select_nkp(ErlDrvPort, ErlDrvEvent, int, int); -int enif_select_kp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm); -int enif_select_nkp(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm); -int driver_event_kp(ErlDrvPort, ErlDrvEvent, ErlDrvEventData); -int driver_event_nkp(ErlDrvPort, ErlDrvEvent, ErlDrvEventData); -Uint erts_check_io_size_kp(void); -Uint erts_check_io_size_nkp(void); -Eterm erts_check_io_info_kp(void *); -Eterm erts_check_io_info_nkp(void *); -int erts_check_io_max_files_kp(void); -int erts_check_io_max_files_nkp(void); -void erts_check_io_interrupt_kp(int); -void erts_check_io_interrupt_nkp(int); -void erts_check_io_interrupt_timed_kp(int, ErtsMonotonicTime); -void erts_check_io_interrupt_timed_nkp(int, ErtsMonotonicTime); -void erts_check_io_kp(int); -void erts_check_io_nkp(int); -void erts_init_check_io_kp(void); -void erts_init_check_io_nkp(void); -int erts_check_io_debug_kp(ErtsCheckIoDebugInfo *); -int erts_check_io_debug_nkp(ErtsCheckIoDebugInfo *); - -#ifdef ERTS_ENABLE_LOCK_COUNT -void erts_lcnt_update_cio_locks_kp(int enable); -void erts_lcnt_update_cio_locks_nkp(int enable); -#endif - -#else /* !ERTS_ENABLE_KERNEL_POLL */ - Uint erts_check_io_size(void); Eterm erts_check_io_info(void *); int erts_check_io_max_files(void); @@ -69,7 +37,6 @@ void erts_check_io_interrupt(int); void erts_check_io_interrupt_timed(int, ErtsMonotonicTime); void erts_check_io(int); void erts_init_check_io(void); - #ifdef ERTS_ENABLE_LOCK_COUNT void erts_lcnt_update_cio_locks(int enable); #endif diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index d05028cabc..e88d7aa6df 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -131,121 +131,6 @@ static int replace_intr = 0; /* assume yes initially, ttsl_init will clear it */ int using_oldshell = 1; -#ifdef ERTS_ENABLE_KERNEL_POLL - -int erts_use_kernel_poll = 0; - -struct { - int (*select)(ErlDrvPort, ErlDrvEvent, int, int); - int (*enif_select)(ErlNifEnv*, ErlNifEvent, enum ErlNifSelectFlags, void*, const ErlNifPid*, Eterm); - int (*event)(ErlDrvPort, ErlDrvEvent, ErlDrvEventData); - void (*check_io_as_interrupt)(void); - void (*check_io_interrupt)(int); - void (*check_io_interrupt_tmd)(int, ErtsMonotonicTime); - void (*check_io)(int); - Uint (*size)(void); - Eterm (*info)(void *); - int (*check_io_debug)(ErtsCheckIoDebugInfo *); -} io_func = {0}; - - -int -driver_select(ErlDrvPort port, ErlDrvEvent event, int mode, int on) -{ - return (*io_func.select)(port, event, mode, on); -} - -int -driver_event(ErlDrvPort port, ErlDrvEvent event, ErlDrvEventData event_data) -{ - return (*io_func.event)(port, event, event_data); -} - -int enif_select(ErlNifEnv* env, ErlNifEvent event, - enum ErlNifSelectFlags flags, void* obj, const ErlNifPid* pid, Eterm ref) -{ - return (*io_func.enif_select)(env, event, flags, obj, pid, ref); -} - - -Eterm erts_check_io_info(void *p) -{ - return (*io_func.info)(p); -} - -int -erts_check_io_debug(ErtsCheckIoDebugInfo *ip) -{ - return (*io_func.check_io_debug)(ip); -} - - -static void -init_check_io(void) -{ - if (erts_use_kernel_poll) { - io_func.select = driver_select_kp; - io_func.enif_select = enif_select_kp; - io_func.event = driver_event_kp; - io_func.check_io_interrupt = erts_check_io_interrupt_kp; - io_func.check_io_interrupt_tmd = erts_check_io_interrupt_timed_kp; - io_func.check_io = erts_check_io_kp; - io_func.size = erts_check_io_size_kp; - io_func.info = erts_check_io_info_kp; - io_func.check_io_debug = erts_check_io_debug_kp; - erts_init_check_io_kp(); - max_files = erts_check_io_max_files_kp(); - } - else { - io_func.select = driver_select_nkp; - io_func.enif_select = enif_select_nkp; - io_func.event = driver_event_nkp; - io_func.check_io_interrupt = erts_check_io_interrupt_nkp; - io_func.check_io_interrupt_tmd = erts_check_io_interrupt_timed_nkp; - io_func.check_io = erts_check_io_nkp; - io_func.size = erts_check_io_size_nkp; - io_func.info = erts_check_io_info_nkp; - io_func.check_io_debug = erts_check_io_debug_nkp; - erts_init_check_io_nkp(); - max_files = erts_check_io_max_files_nkp(); - } -} - -#define ERTS_CHK_IO_AS_INTR() (*io_func.check_io_interrupt)(1) -#define ERTS_CHK_IO_INTR (*io_func.check_io_interrupt) -#define ERTS_CHK_IO_INTR_TMD (*io_func.check_io_interrupt_tmd) -#define ERTS_CHK_IO (*io_func.check_io) -#define ERTS_CHK_IO_SZ (*io_func.size) - -#else /* !ERTS_ENABLE_KERNEL_POLL */ - -static void -init_check_io(void) -{ - erts_init_check_io(); - max_files = erts_check_io_max_files(); -} - -#define ERTS_CHK_IO_AS_INTR() erts_check_io_interrupt(1) -#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 - -#endif - -void -erts_sys_schedule_interrupt(int set) -{ - ERTS_CHK_IO_INTR(set); -} - -void -erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time) -{ - ERTS_CHK_IO_INTR_TMD(set, timeout_time); -} - UWord erts_sys_get_page_size(void) { @@ -261,7 +146,7 @@ erts_sys_get_page_size(void) Uint erts_sys_misc_mem_sz(void) { - Uint res = ERTS_CHK_IO_SZ(); + Uint res = erts_check_io_size(); res += erts_atomic_read_mb(&sys_misc_mem_sz); return res; } @@ -625,7 +510,7 @@ break_requested(void) erts_exit(ERTS_INTR_EXIT, ""); ERTS_SET_BREAK_REQUESTED; - ERTS_CHK_IO_AS_INTR(); /* Make sure we don't sleep in poll */ + erts_check_io_sig_interrupt(); } static RETSIGTYPE request_break(int signum) @@ -813,7 +698,7 @@ erts_sys_unix_later_init(void) int sys_max_files(void) { - return(max_files); + return max_files; } /************************** OS info *******************************/ @@ -1198,7 +1083,7 @@ erl_debug(char* fmt, ...) void erl_sys_schedule(int runnable) { - ERTS_CHK_IO(!runnable); + erts_check_io(!runnable); ERTS_LC_ASSERT(!erts_thr_progress_is_blocking()); } @@ -1417,6 +1302,8 @@ get_value(char* rest, char** argv, int* ip) return rest; } +int erts_use_kernel_poll = 0; + #endif /* ERTS_ENABLE_KERNEL_POLL */ void @@ -1475,7 +1362,9 @@ erl_sys_args(int* argc, char** argv) } #endif - init_check_io(); + erts_init_check_io(); + max_files = erts_check_io_max_files(); + init_smp_sig_notify(); init_smp_sig_suspend(); diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index b23dbecbac..de391f078b 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -3248,18 +3248,6 @@ erl_sys_late_init(void) /* do nothing */ } -void -erts_sys_schedule_interrupt(int set) -{ - erts_check_io_interrupt(set); -} - -void -erts_sys_schedule_interrupt_timed(int set, ErtsMonotonicTime timeout_time) -{ - erts_check_io_interrupt_timed(set, timeout_time); -} - /* * Called from schedule() when it runs out of runnable processes, * or when Erlang code has performed INPUT_REDUCTIONS reduction @@ -3271,4 +3259,3 @@ erl_sys_schedule(int runnable) erts_check_io(!runnable); ERTS_LC_ASSERT(!erts_thr_progress_is_blocking()); } - -- cgit v1.2.3