summaryrefslogtreecommitdiff
path: root/erts/emulator/sys
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/sys')
-rw-r--r--erts/emulator/sys/common/erl_check_io.c57
-rw-r--r--erts/emulator/sys/common/erl_check_io.h6
-rw-r--r--erts/emulator/sys/common/erl_mmap.c13
-rw-r--r--erts/emulator/sys/common/erl_mmap.h13
-rw-r--r--erts/emulator/sys/common/erl_osenv.h28
-rw-r--r--erts/emulator/sys/common/erl_poll.c45
-rw-r--r--erts/emulator/sys/common/erl_poll.h11
-rw-r--r--erts/emulator/sys/common/erl_sys_common_misc.c12
-rw-r--r--erts/emulator/sys/unix/erl_child_setup.c34
-rw-r--r--erts/emulator/sys/unix/sys.c20
-rw-r--r--erts/emulator/sys/unix/sys_drivers.c1
-rw-r--r--erts/emulator/sys/unix/sys_uds.c2
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h4
-rw-r--r--erts/emulator/sys/win32/sys.c15
-rw-r--r--erts/emulator/sys/win32/sys_env.c1
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"