diff options
Diffstat (limited to 'erts/emulator/sys')
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.c | 57 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_check_io.h | 6 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_mmap.c | 13 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_mmap.h | 13 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_osenv.h | 28 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_poll.c | 45 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_poll.h | 11 | ||||
-rw-r--r-- | erts/emulator/sys/common/erl_sys_common_misc.c | 12 | ||||
-rw-r--r-- | erts/emulator/sys/unix/erl_child_setup.c | 34 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys.c | 20 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys_drivers.c | 1 | ||||
-rw-r--r-- | erts/emulator/sys/unix/sys_uds.c | 2 | ||||
-rw-r--r-- | erts/emulator/sys/win32/erl_win_sys.h | 4 | ||||
-rw-r--r-- | erts/emulator/sys/win32/sys.c | 15 | ||||
-rw-r--r-- | erts/emulator/sys/win32/sys_env.c | 1 |
15 files changed, 179 insertions, 83 deletions
diff --git a/erts/emulator/sys/common/erl_check_io.c b/erts/emulator/sys/common/erl_check_io.c index 344d51f768..964f2df27e 100644 --- a/erts/emulator/sys/common/erl_check_io.c +++ b/erts/emulator/sys/common/erl_check_io.c @@ -184,11 +184,14 @@ int ERTS_WRITE_UNLIKELY(erts_no_pollsets) = 1; int ERTS_WRITE_UNLIKELY(erts_no_poll_threads) = 1; struct drv_ev_state_shared drv_ev_state; -static ERTS_INLINE int fd_hash(ErtsSysFdType fd) { +static ERTS_INLINE int fd_hash(ErtsSysFdType fd) +{ +#ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS int hash = (int)fd; -# ifndef ERTS_SYS_CONTINOUS_FD_NUMBERS +#else + int hash = (int)(SWord)fd; hash ^= (hash >> 9); -# endif +#endif return hash; } @@ -1082,7 +1085,7 @@ enif_select_x(ErlNifEnv* env, pid ? pid->pid : THE_NON_VALUE, THE_NON_VALUE); if (mode & ERL_NIF_SELECT_STOP) { - ASSERT(resource->type->stop); + ASSERT(resource->type->fn.stop); if (IS_FD_UNKNOWN(state)) { /* fast track to stop callback */ call_stop = CALL_STOP; @@ -1339,7 +1342,7 @@ print_driver_name(erts_dsprintf_buf_t *dsbufp, Eterm id) static void steal(erts_dsprintf_buf_t *dsbufp, ErtsDrvEventState *state, int mode) { - erts_dsprintf(dsbufp, "stealing control of fd=%d from ", (int) state->fd); + erts_dsprintf(dsbufp, "stealing control of fd=%bpd from ", (SWord) state->fd); switch (state->type) { case ERTS_EV_TYPE_DRV_SEL: { int deselect_mode = 0; @@ -1363,7 +1366,7 @@ steal(erts_dsprintf_buf_t *dsbufp, ErtsDrvEventState *state, int mode) if (deselect_mode) deselect(state, deselect_mode); else { - erts_dsprintf(dsbufp, "no one", (int) state->fd); + erts_dsprintf(dsbufp, "no one"); ASSERT(0); } erts_dsprintf(dsbufp, "\n"); @@ -1394,7 +1397,7 @@ steal(erts_dsprintf_buf_t *dsbufp, ErtsDrvEventState *state, int mode) break; } default: - erts_dsprintf(dsbufp, "no one\n", (int) state->fd); + erts_dsprintf(dsbufp, "no one\n"); ASSERT(0); } } @@ -1405,10 +1408,10 @@ print_drv_select_op(erts_dsprintf_buf_t *dsbufp, { Port *pp = erts_drvport2port(ix); erts_dsprintf(dsbufp, - "driver_select(%p, %d,%s%s%s%s, %d) " + "driver_select(%p, %bpd,%s%s%s%s, %d) " "by ", ix, - (int) fd, + (SWord) fd, mode & ERL_DRV_READ ? " ERL_DRV_READ" : "", mode & ERL_DRV_WRITE ? " ERL_DRV_WRITE" : "", mode & ERL_DRV_USE ? " ERL_DRV_USE" : "", @@ -1424,8 +1427,8 @@ print_nif_select_op(erts_dsprintf_buf_t *dsbufp, ErtsResource* resource, Eterm ref) { erts_dsprintf(dsbufp, - "enif_select(_, %d,%s%s%s, %T:%T, %T) ", - (int) fd, + "enif_select(_, %bpd,%s%s%s, %T:%T, %T) ", + (SWord) fd, mode & ERL_NIF_SELECT_READ ? " READ" : "", mode & ERL_NIF_SELECT_WRITE ? " WRITE" : "", (mode & ERL_NIF_SELECT_STOP ? " STOP" @@ -1655,7 +1658,7 @@ erts_create_pollset_thread(int id, ErtsThrPrgrData *tpd) { } void -erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) +erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time, int poll_only_thread) { int pollres_len; int poll_ret, i; @@ -1669,6 +1672,9 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) pollres_len = psi->pollres_len; + if (poll_only_thread) + erts_thr_progress_active(psi->tpd, 0); + #if ERTS_POLL_USE_FALLBACK if (psi->ps == get_fallback_pollset()) { @@ -1680,6 +1686,9 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) poll_ret = erts_poll_wait(psi->ps, psi->pollres, &pollres_len, psi->tpd, timeout_time); } + if (poll_only_thread) + erts_thr_progress_active(psi->tpd, 1); + #ifdef ERTS_ENABLE_LOCK_CHECK erts_lc_check_exact(NULL, 0); /* No locks should be locked */ #endif @@ -1715,10 +1724,10 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) ErtsDrvEventState *state; ErtsPollEvents revents = ERTS_POLL_RES_GET_EVTS(&psi->pollres[i]); - /* The fd will be set to -1 if a pollset internal fd was triggered + /* The fd will be set to INVALID if a pollset internal fd was triggered that was determined to be too expensive to remove from the result. */ - if (fd == -1) continue; + if (fd == ERTS_SYS_FD_INVALID) continue; erts_mtx_lock(fd_mtx(fd)); @@ -1758,8 +1767,10 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) reactive_events = state->active_events; - if (state->flags & ERTS_EV_FLAG_IN_SCHEDULER) + if (state->flags & ERTS_EV_FLAG_IN_SCHEDULER) { reactive_events &= ~ERTS_POLL_EV_IN; + state->active_events |= ERTS_POLL_EV_IN; + } /* Reactivate the poll op if there are still active events */ if (reactive_events) { @@ -1866,7 +1877,7 @@ erts_check_io(ErtsPollThread *psi, ErtsMonotonicTime timeout_time) dsbufp = erts_create_logger_dsbuf(); erts_dsprintf(dsbufp, "Invalid event request type for fd in erts_poll()! " - "fd=%d, event request type=%d\n", (int) state->fd, + "fd=%bpd, event request type=%d\n", (SWord) state->fd, (int) state->type); ASSERT(0); deselect(state, 0); @@ -1944,8 +1955,8 @@ bad_fd_in_pollset(ErtsDrvEventState *state, Eterm inport, Eterm outport) } } erts_dsprintf(dsbufp, - "Bad %s fd in erts_poll()! fd=%d, ", - io_str, (int) state->fd); + "Bad %s fd in erts_poll()! fd=%bpd, ", + io_str, (SWord) state->fd); if (state->type == ERTS_EV_TYPE_DRV_SEL) { if (is_nil(port)) { ErtsPortNames *ipnp = erts_get_port_names(inport, ERTS_INVALID_ERL_DRV_PORT); @@ -1978,7 +1989,8 @@ bad_fd_in_pollset(ErtsDrvEventState *state, Eterm inport, Eterm outport) } } else { - erts_dsprintf(dsbufp, "Bad fd in erts_poll()! fd=%d\n", (int) state->fd); + erts_dsprintf(dsbufp, "Bad fd in erts_poll()! fd=%bpd\n", + (SWord) state->fd); } erts_send_error_to_logger_nogl(dsbufp); @@ -1997,7 +2009,7 @@ stale_drv_select(Eterm id, ErtsDrvEventState *state, int mode) static SafeHashValue drv_ev_state_hash(void *des) { - SafeHashValue val = (SafeHashValue) ((ErtsDrvEventState *) des)->fd; + SafeHashValue val = (SafeHashValue)(SWord) ((ErtsDrvEventState *) des)->fd; return val ^ (val >> 8); /* Good enough for aligned pointer values? */ } @@ -2548,8 +2560,9 @@ static int erts_debug_print_checkio_state(erts_dsprintf_buf_t *dsbufp, #ifdef ERTS_SYS_CONTINOUS_FD_NUMBERS ErtsPollEvents aio_events = state->active_events; #endif - erts_dsprintf(dsbufp, "pollset=%d fd=%d ", - state->flags & ERTS_EV_FLAG_FALLBACK ? -1 : get_pollset_id(fd), (int) fd); + erts_dsprintf(dsbufp, "pollset=%d fd=%bpd ", + state->flags & ERTS_EV_FLAG_FALLBACK ? -1 : get_pollset_id(fd), + (SWord) fd); #if defined(HAVE_FSTAT) && !defined(NO_FSTAT_ON_SYS_FD_TYPE) if (fstat((int) fd, &stat_buf) < 0) diff --git a/erts/emulator/sys/common/erl_check_io.h b/erts/emulator/sys/common/erl_check_io.h index 2ebcbe2743..ac285119bc 100644 --- a/erts/emulator/sys/common/erl_check_io.h +++ b/erts/emulator/sys/common/erl_check_io.h @@ -67,8 +67,12 @@ int erts_check_io_max_files(void); * not return unless erts_check_io_interrupt(pt, 1) is called by another thread. * * @param pt the poll thread structure to use. + * @param timeout_time timeout + * @param poll_only_thread non zero when poll is the only thing the + * calling thread does */ -void erts_check_io(struct erts_poll_thread *pt, ErtsMonotonicTime timeout_time); +void erts_check_io(struct erts_poll_thread *pt, ErtsMonotonicTime timeout_time, + int poll_only_thread); /** * Initialize the check io framework. This function will parse the arguments * and delete any entries that it is interested in. diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c index b0d9fc0776..78c20ea98d 100644 --- a/erts/emulator/sys/common/erl_mmap.c +++ b/erts/emulator/sys/common/erl_mmap.c @@ -2130,13 +2130,18 @@ void erts_mmap_init(ErtsMemMapper* mm, ErtsMMapInit *init) { static int is_first_call = 1; - int virtual_map = 0; char *start = NULL, *end = NULL; UWord pagesize; + int virtual_map = 0; + + (void)virtual_map; + #if defined(__WIN32__) - SYSTEM_INFO sysinfo; - GetSystemInfo(&sysinfo); - pagesize = (UWord) sysinfo.dwPageSize; + { + SYSTEM_INFO sysinfo; + GetSystemInfo(&sysinfo); + pagesize = (UWord) sysinfo.dwPageSize; + } #elif defined(_SC_PAGESIZE) pagesize = (UWord) sysconf(_SC_PAGESIZE); #elif defined(HAVE_GETPAGESIZE) diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h index a30b7d2f6d..7a3fdd0aa9 100644 --- a/erts/emulator/sys/common/erl_mmap.h +++ b/erts/emulator/sys/common/erl_mmap.h @@ -49,7 +49,8 @@ * See the following message on how MAP_NORESERVE was treated on FreeBSD: * <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150202/122958.html> */ -# if defined(MAP_FIXED) && (defined(MAP_NORESERVE) || defined(__FreeBSD__)) +# if (defined(MAP_FIXED) && (defined(MAP_NORESERVE) || defined(__FreeBSD__)) \ + && !defined(ADDRESS_SANITIZER)) # define ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION 1 # endif #endif @@ -203,16 +204,18 @@ ERTS_GLB_INLINE void erts_mem_discard(void *p, UWord size); data[i] = pattern[i % sizeof(pattern)]; } } -#elif defined(HAVE_SYS_MMAN_H) && !(defined(__sun) || defined(__sun__)) +#elif defined(HAVE_SYS_MMAN_H) && defined(HAVE_MADVISE) && !(defined(__sun) || defined(__sun__)) #include <sys/mman.h> ERTS_GLB_INLINE void erts_mem_discard(void *ptr, UWord size) { + /* Note that we don't fall back to MADV_DONTNEED since it promises that + * the given region will be zeroed on access, which turned out to be + * too much of a performance hit. */ #ifdef MADV_FREE - /* This is preferred as it doesn't necessarily free the pages right - * away, which is a bit faster than MADV_DONTNEED. */ madvise(ptr, size, MADV_FREE); #else - madvise(ptr, size, MADV_DONTNEED); + (void)ptr; + (void)size; #endif } #elif defined(_WIN32) diff --git a/erts/emulator/sys/common/erl_osenv.h b/erts/emulator/sys/common/erl_osenv.h index 4777f2148a..d0902e0ba1 100644 --- a/erts/emulator/sys/common/erl_osenv.h +++ b/erts/emulator/sys/common/erl_osenv.h @@ -35,16 +35,10 @@ # include "config.h" #endif -typedef struct __erts_osenv_data_t erts_osenv_data_t; - -typedef struct __erts_osenv_t { - struct __env_rbtnode_t *tree; - int variable_count; - int content_size; -} erts_osenv_t; - #include "sys.h" +typedef struct __erts_osenv_data_t erts_osenv_data_t; + struct __erts_osenv_data_t { Sint length; void *data; @@ -53,7 +47,7 @@ struct __erts_osenv_data_t { void erts_osenv_init(erts_osenv_t *env); void erts_osenv_clear(erts_osenv_t *env); -/* @brief Merges \c with into \c env +/** @brief Merges \c with into \c env * * @param overwrite Whether to overwrite existing entries or keep them as they * are. */ @@ -61,25 +55,25 @@ void erts_osenv_merge(erts_osenv_t *env, const erts_osenv_t *with, int overwrite /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/* @brief Copies env[key] into \c value +/** @brief Copies env[key] into \c value * * @return 1 on success, 0 if the key couldn't be found, and -1 if the input * was invalid. */ int erts_osenv_get_term(const erts_osenv_t *env, struct process *process, Eterm key, Eterm *value); -/* @brief Copies \c value into \c env[key] +/** @brief Copies \c value into \c env[key] * * @return 1 on success, -1 if the input was invalid. */ int erts_osenv_put_term(erts_osenv_t *env, Eterm key, Eterm value); -/* @brief Removes \c env[key] +/** @brief Removes \c env[key] * * @return 1 on success, 0 if the key couldn't be found, and -1 if the input * was invalid. */ int erts_osenv_unset_term(erts_osenv_t *env, Eterm key); -/* @brief Copies env[key] into \c value +/** @brief Copies env[key] into \c value * * @param value [in,out] The buffer to copy the value into, may be NULL if you * only wish to query presence. @@ -89,13 +83,13 @@ int erts_osenv_unset_term(erts_osenv_t *env, Eterm key); int erts_osenv_get_native(const erts_osenv_t *env, const erts_osenv_data_t *key, erts_osenv_data_t *value); -/* @brief Copies \c value into \c env[key] +/** @brief Copies \c value into \c env[key] * * @return 1 on success, -1 on failure. */ int erts_osenv_put_native(erts_osenv_t *env, const erts_osenv_data_t *key, const erts_osenv_data_t *value); -/* @brief Removes \c key from the env. +/** @brief Removes \c key from the env. * * @return 1 on success, 0 if the key couldn't be found. */ int erts_osenv_unset_native(erts_osenv_t *env, const erts_osenv_data_t *key); @@ -109,8 +103,8 @@ typedef void (*erts_osenv_foreach_native_cb_t)(void *state, const erts_osenv_data_t *key, const erts_osenv_data_t *value); -/* @brief Walks through all environment variables, calling \c callback for each - * one. It's unsafe to modify \c env within the callback. */ +/** @brief Walks through all environment variables, calling \c callback for + * each one. It's unsafe to modify \c env within the callback. */ void erts_osenv_foreach_term(const erts_osenv_t *env, struct process *process, void *state, erts_osenv_foreach_term_cb_t callback); diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c index e669572499..9f0c82dc4b 100644 --- a/erts/emulator/sys/common/erl_poll.c +++ b/erts/emulator/sys/common/erl_poll.c @@ -374,6 +374,7 @@ uint32_t epoll_events(int kp_fd, int fd); #define ERTS_POLL_NOT_WOKEN 0 #define ERTS_POLL_WOKEN -1 #define ERTS_POLL_WOKEN_INTR 1 +#define ERTS_POLL_WSTATE_UNUSED ~0 static ERTS_INLINE void reset_wakeup_state(ErtsPollSet *ps) @@ -384,12 +385,16 @@ reset_wakeup_state(ErtsPollSet *ps) static ERTS_INLINE int is_woken(ErtsPollSet *ps) { + if (!ERTS_POLL_USE_WAKEUP(ps)) + return 0; return erts_atomic32_read_acqb(&ps->wakeup_state) != ERTS_POLL_NOT_WOKEN; } static ERTS_INLINE int is_interrupted_reset(ErtsPollSet *ps) { + if (!ERTS_POLL_USE_WAKEUP(ps)) + return 0; return (erts_atomic32_xchg_acqb(&ps->wakeup_state, ERTS_POLL_NOT_WOKEN) == ERTS_POLL_WOKEN_INTR); } @@ -397,7 +402,10 @@ is_interrupted_reset(ErtsPollSet *ps) static ERTS_INLINE void woke_up(ErtsPollSet *ps) { - erts_aint32_t wakeup_state = erts_atomic32_read_acqb(&ps->wakeup_state); + erts_aint32_t wakeup_state; + if (!ERTS_POLL_USE_WAKEUP(ps)) + return; + wakeup_state = erts_atomic32_read_acqb(&ps->wakeup_state); if (wakeup_state == ERTS_POLL_NOT_WOKEN) (void) erts_atomic32_cmpxchg_nob(&ps->wakeup_state, ERTS_POLL_WOKEN, @@ -450,6 +458,7 @@ cleanup_wakeup_pipe(ErtsPollSet *ps) int intr = 0; int fd = ps->wake_fds[0]; int res; + ASSERT(ERTS_POLL_USE_WAKEUP(ps)); do { char buf[32]; res = read(fd, buf, sizeof(buf)); @@ -475,6 +484,13 @@ create_wakeup_pipe(ErtsPollSet *ps) int wake_fds[2]; ps->wake_fds[0] = -1; ps->wake_fds[1] = -1; + if (!ERTS_POLL_USE_WAKEUP(ps)) { + erts_atomic32_init_nob(&ps->wakeup_state, + (erts_aint32_t) ERTS_POLL_WSTATE_UNUSED); + return; + } + erts_atomic32_init_nob(&ps->wakeup_state, + (erts_aint32_t) ERTS_POLL_NOT_WOKEN); if (pipe(wake_fds) < 0) { fatal_error("%s:%d:create_wakeup_pipe(): " "Failed to create pipe: %s (%d)\n", @@ -483,6 +499,7 @@ create_wakeup_pipe(ErtsPollSet *ps) erl_errno_id(errno), errno); } + SET_NONBLOCKING(wake_fds[0]); SET_NONBLOCKING(wake_fds[1]); @@ -629,12 +646,13 @@ int erts_poll_new_table_len(int old_len, int need_len) } else { new_len = old_len; + if (new_len < ERTS_FD_TABLE_MIN_LENGTH) + new_len = ERTS_FD_TABLE_MIN_LENGTH; do { if (new_len < ERTS_FD_TABLE_EXP_THRESHOLD) new_len *= 2; else new_len += ERTS_FD_TABLE_EXP_THRESHOLD; - } while (new_len < need_len); } ASSERT(new_len >= need_len); @@ -1459,13 +1477,13 @@ ERTS_POLL_EXPORT(save_result)(ErtsPollSet *ps, ErtsPollResFd pr[], int max_res, if (ERTS_POLL_USE_WAKEUP(ps) && fd == wake_fd) { cleanup_wakeup_pipe(ps); - ERTS_POLL_RES_SET_FD(&pr[i], -1); + ERTS_POLL_RES_SET_FD(&pr[i], ERTS_SYS_FD_INVALID); ERTS_POLL_RES_SET_EVTS(&pr[i], ERTS_POLL_EV_NONE); res--; } #if ERTS_POLL_USE_TIMERFD else if (fd == ps->timer_fd) { - ERTS_POLL_RES_SET_FD(&pr[i], -1); + ERTS_POLL_RES_SET_FD(&pr[i], ERTS_SYS_FD_INVALID); ERTS_POLL_RES_SET_EVTS(&pr[i], ERTS_POLL_EV_NONE); res--; } @@ -1955,8 +1973,7 @@ ERTS_POLL_EXPORT(erts_poll_wait)(ErtsPollSet *ps, ERTS_MSACC_SET_STATE_CACHED(ERTS_MSACC_STATE_CHECK_IO); } - if (ERTS_POLL_USE_WAKEUP(ps)) - woke_up(ps); + woke_up(ps); if (res < 0) { #if ERTS_POLL_USE_SELECT @@ -2046,6 +2063,21 @@ ERTS_POLL_EXPORT(erts_poll_init)(int *concurrent_updates) max_fds = OPEN_MAX; #endif + if (max_fds < 0 && errno == 0) { + /* On macOS 11 and higher, it possible to have an unlimited + * number of open files per process. ERTS will need an actual + * limit, though, so we will set it to a largish value. The + * number below is the hard number of file descriptors per + * process as returned by `sysctl kern.maxfilesperproc`, which + * seems to be the limit in practice. + * + * Note: The size of the port table will be based on max_fds, + * so we don't want to set it to a huge value such as + * MAX_INT. + */ + max_fds = 24576; + } + #if ERTS_POLL_USE_SELECT && defined(FD_SETSIZE) && \ !defined(_DARWIN_UNLIMITED_SELECT) if (max_fds > FD_SETSIZE) @@ -2134,7 +2166,6 @@ ERTS_POLL_EXPORT(erts_poll_create_pollset)(int id) ps->oneshot = 1; #endif - erts_atomic32_init_nob(&ps->wakeup_state, (erts_aint32_t) 0); create_wakeup_pipe(ps); #if ERTS_POLL_USE_TIMERFD diff --git a/erts/emulator/sys/common/erl_poll.h b/erts/emulator/sys/common/erl_poll.h index d40dabc529..096c14816e 100644 --- a/erts/emulator/sys/common/erl_poll.h +++ b/erts/emulator/sys/common/erl_poll.h @@ -1,8 +1,8 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2006-2018. All Rights Reserved. - * + * + * Copyright Ericsson AB 2006-2019. 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 @@ -161,7 +161,10 @@ typedef enum { #include <sys/epoll.h> #if ERTS_POLL_USE_EPOLL -#ifdef HAVE_SYS_TIMERFD_H +/* sys/timerfd.h was added in Android 4.4 KitKat. With the Android NDK +Unified Headers, check that the build is targeting at least the +corresponding API level 19. */ +#if defined(HAVE_SYS_TIMERFD_H) && !(defined(__ANDROID__) && (__ANDROID_API__ < 19)) #include <sys/timerfd.h> #undef ERTS_POLL_USE_TIMERFD #define ERTS_POLL_USE_TIMERFD 1 diff --git a/erts/emulator/sys/common/erl_sys_common_misc.c b/erts/emulator/sys/common/erl_sys_common_misc.c index d34e1a9ec0..fd7c3b2cda 100644 --- a/erts/emulator/sys/common/erl_sys_common_misc.c +++ b/erts/emulator/sys/common/erl_sys_common_misc.c @@ -1,8 +1,8 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2006-2018. All Rights Reserved. - * + * + * Copyright Ericsson AB 2006-2020. 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 @@ -49,9 +49,9 @@ static int filename_encoding = ERL_FILENAME_UNKNOWN; static int filename_warning = ERL_FILENAME_WARNING_WARNING; -#if defined(__WIN32__) || defined(__DARWIN__) -/* Default unicode on windows and MacOS X */ -static int user_filename_encoding = ERL_FILENAME_UTF8; +#if defined(__WIN32__) || defined(__DARWIN__) || defined(__ANDROID__) +/* Default to Unicode on Windows, MacOS X and Android */ +static int user_filename_encoding = ERL_FILENAME_UTF8; #else static int user_filename_encoding = ERL_FILENAME_UNKNOWN; #endif diff --git a/erts/emulator/sys/unix/erl_child_setup.c b/erts/emulator/sys/unix/erl_child_setup.c index 129861ebd5..103eb40288 100644 --- a/erts/emulator/sys/unix/erl_child_setup.c +++ b/erts/emulator/sys/unix/erl_child_setup.c @@ -63,10 +63,13 @@ #include "erl_driver.h" #include "sys_uds.h" -#include "hash.h" #include "erl_term.h" #include "erl_child_setup.h" +#undef ERTS_GLB_INLINE_INCL_FUNC_DEF +#define ERTS_GLB_INLINE_INCL_FUNC_DEF 1 +#include "hash.h" + #define SET_CLOEXEC(fd) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) #if defined(__ANDROID__) @@ -75,6 +78,10 @@ #define SHELL "/bin/sh" #endif /* __ANDROID__ */ +#if !defined(MSG_DONTWAIT) && defined(MSG_NONBLOCK) +#define MSG_DONTWAIT MSG_NONBLOCK +#endif + //#define HARD_DEBUG #ifdef HARD_DEBUG #define DEBUG_PRINT(fmt, ...) fprintf(stderr, "%d:" fmt "\r\n", getpid(), ##__VA_ARGS__) @@ -411,6 +418,7 @@ main(int argc, char *argv[]) int uds_fd = 3, max_fd = 3; #ifndef HAVE_CLOSEFROM int i; + DIR *dir; #endif struct sigaction sa; @@ -426,11 +434,29 @@ main(int argc, char *argv[]) #if defined(HAVE_CLOSEFROM) closefrom(4); #else - for (i = 4; i < max_files; i++) + dir = opendir("/dev/fd"); + if (dir == NULL) { /* /dev/fd not available */ + for (i = 4; i < max_files; i++) +#if defined(__ANDROID__) + if (i != system_properties_fd()) +#endif + (void) close(i); + } else { + /* Iterate over fds obtained from /dev/fd */ + struct dirent *entry; + int dir_fd = dirfd(dir); + + while ((entry = readdir(dir)) != NULL) { + i = atoi(entry->d_name); #if defined(__ANDROID__) - if (i != system_properties_fd()) + if (i != system_properties_fd()) #endif - (void) close(i); + if (i >= 4 && i != dir_fd) + (void) close(i); + } + + closedir(dir); + } #endif if (pipe(sigchld_pipe) < 0) { diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c index 6935c0cca9..46a035214b 100644 --- a/erts/emulator/sys/unix/sys.c +++ b/erts/emulator/sys/unix/sys.c @@ -49,6 +49,10 @@ #include <sys/ioctl.h> #endif +#ifdef ADDRESS_SANITIZER +# include <sanitizer/asan_interface.h> +#endif + #define ERTS_WANT_BREAK_HANDLING #define WANT_NONBLOCKING /* must define this to pull in defs from sys.h */ #include "sys.h" @@ -386,6 +390,9 @@ void erts_sys_sigsegv_handler(int signo) { */ int erts_sys_is_area_readable(char *start, char *stop) { +#ifdef ADDRESS_SANITIZER + return __asan_region_is_poisoned(start, stop-start) == NULL; +#else int fds[2]; if (!pipe(fds)) { /* We let write try to figure out if the pointers are readable */ @@ -400,7 +407,7 @@ erts_sys_is_area_readable(char *start, char *stop) { return 1; } return 0; - +#endif } static ERTS_INLINE int @@ -692,6 +699,10 @@ void erts_sys_unix_later_init(void) { sys_signal(SIGTERM, generic_signal_handler); + + /* Ignore SIGCHLD to ensure orphaned processes don't turn into zombies on + * death when we're pid 1. */ + sys_signal(SIGCHLD, SIG_IGN); } int sys_max_files(void) @@ -743,10 +754,17 @@ void os_version(int *pMajor, int *pMinor, int *pBuild) { * X.Y or X.Y.Z. */ (void) uname(&uts); +#ifdef _AIX + /* AIX stores the major in version and minor in release */ + *pMajor = atoi(uts.version); + *pMinor = atoi(uts.release); + *pBuild = 0; /* XXX: get oslevel for AIX or TR on i */ +#else release = uts.release; *pMajor = get_number(&release); /* Pointer to major version. */ *pMinor = get_number(&release); /* Pointer to minor version. */ *pBuild = get_number(&release); /* Pointer to build number. */ +#endif } void erts_do_break_handling(void) diff --git a/erts/emulator/sys/unix/sys_drivers.c b/erts/emulator/sys/unix/sys_drivers.c index a31304a4a7..152d1757ba 100644 --- a/erts/emulator/sys/unix/sys_drivers.c +++ b/erts/emulator/sys/unix/sys_drivers.c @@ -55,6 +55,7 @@ #define WANT_NONBLOCKING /* must define this to pull in defs from sys.h */ #include "sys.h" +#include "erl_osenv.h" #include "erl_threads.h" diff --git a/erts/emulator/sys/unix/sys_uds.c b/erts/emulator/sys/unix/sys_uds.c index c9f73622ba..c3094d20d4 100644 --- a/erts/emulator/sys/unix/sys_uds.c +++ b/erts/emulator/sys/unix/sys_uds.c @@ -23,7 +23,7 @@ #endif #if defined(__sun__) && !defined(_XOPEN_SOURCE) -#define _XOPEN_SOURCE 500 +#define _XOPEN_SOURCE 600 #endif #include <limits.h> diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h index b00ba287e2..4c64494ac0 100644 --- a/erts/emulator/sys/win32/erl_win_sys.h +++ b/erts/emulator/sys/win32/erl_win_sys.h @@ -52,10 +52,6 @@ #include <fcntl.h> #include <time.h> #include <sys/timeb.h> -#pragma comment(linker,"/manifestdependency:\"type='win32' "\ - "name='Microsoft.Windows.Common-Controls' "\ - "version='6.0.0.0' processorArchitecture='*' "\ - "publicKeyToken='6595b64144ccf1df' language='*'\"") #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c index 957ade51c3..244fed720d 100644 --- a/erts/emulator/sys/win32/sys.c +++ b/erts/emulator/sys/win32/sys.c @@ -27,6 +27,7 @@ #endif #include "sys.h" +#include "erl_osenv.h" #include "erl_alloc.h" #include "erl_sys_driver.h" #include "global.h" @@ -1697,7 +1698,7 @@ create_child_process erts_free(ERTS_ALC_T_TMP, qte); } - DEBUGF((stderr,"Creating child process: %S, createFlags = %d\n", newcmdline, createFlags)); + DEBUGF(("Creating child process: %S, createFlags = %d\n", newcmdline, createFlags)); ok = CreateProcessW((wchar_t *) appname, (wchar_t *) newcmdline, NULL, @@ -1995,7 +1996,7 @@ threaded_reader(LPVOID param) aio->bytesTransferred = n; } SetEvent(aio->ov.hEvent); - if ((aio->flags & DF_XLAT_CR) == 0 && aio->bytesTransferred == 0) { + if (aio->bytesTransferred == 0) { break; } if (aio->pendingError != NO_ERROR) { @@ -2111,15 +2112,15 @@ translate_fd(int fd) handle = GetStdHandle(STD_ERROR_HANDLE); break; default: - return (HANDLE) fd; + return (HANDLE)(SWord) fd; } - DEBUGF(("translate_fd(%d) -> std(%d)\n", fd, handle)); + DEBUGF(("translate_fd(%d) -> std(%p)\n", fd, (void*)handle)); if (handle == INVALID_HANDLE_VALUE || handle == 0) { handle = CreateFile("nul", access, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); } - DEBUGF(("translate_fd(%d) -> %d\n", fd, handle)); + DEBUGF(("translate_fd(%d) -> %p\n", fd, (void*)handle)); return handle; } @@ -2924,9 +2925,9 @@ unsigned char* sys_preload_begin(Preload* pp) ASSERT(beam_module != NULL); resource = res_name[pp-preloaded]; - DEBUGF(("Loading name: %s; size: %d; resource: %p\n", + DEBUGF(("Loading name: %s; size: %d; resource: %u\n", pp->name, pp->size, resource)); - hRes = FindResource(beam_module, (char *) resource, "ERLANG_CODE"); + hRes = FindResource(beam_module, (char*)(UWord) resource, "ERLANG_CODE"); return pp->code = LoadResource(beam_module, hRes); } diff --git a/erts/emulator/sys/win32/sys_env.c b/erts/emulator/sys/win32/sys_env.c index c78161b344..36223c2c14 100644 --- a/erts/emulator/sys/win32/sys_env.c +++ b/erts/emulator/sys/win32/sys_env.c @@ -23,6 +23,7 @@ #endif #include "sys.h" +#include "erl_osenv.h" #include "erl_sys_driver.h" #include "erl_alloc.h" |