From c46ba734b6787e254b45b35ea135fc2da23190bb Mon Sep 17 00:00:00 2001
From: Lukas Larsson
Date: Tue, 23 Feb 2016 11:24:12 +0100
Subject: erts: Fix install of suspend handler
This commit makes sure to setup the suspend handler
to matter what +B option is given at the command line.
---
erts/emulator/beam/break.c | 4 ++--
erts/emulator/beam/erl_init.c | 1 +
erts/emulator/sys/unix/erl_unix_sys.h | 1 +
erts/emulator/sys/unix/sys.c | 24 ++++++++++++++++--------
4 files changed, 20 insertions(+), 10 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 0ddf7f4e6d..298b30fff3 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -684,7 +684,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
crash dump. */
erts_thr_progress_fatal_error_block(&tpd_buf);
-#ifdef ERTS_THR_HAVE_SIG_FUNCS
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
/*
* We suspend all scheduler threads so that we can dump some
* data about the currently running processes and scheduler data.
@@ -818,7 +818,7 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
#ifdef ERTS_SMP
-#if defined(ERTS_THR_HAVE_SIG_FUNCS)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
/* We resume all schedulers so that we are in a known safe state
when we write the rest of the crash dump */
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index e729574ec7..1718b23688 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -2134,6 +2134,7 @@ erl_start(int argc, char **argv)
init_break_handler();
if (replace_intr)
erts_replace_intr();
+ sys_init_suspend_handler();
#endif
boot_argc = argc - i; /* Number of arguments to init */
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 8d4e98bf3a..b55180c509 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -311,6 +311,7 @@ extern SIGFUNC sys_signal(int, SIGFUNC);
extern void sys_sigrelease(int);
extern void sys_sigblock(int);
extern void sys_stop_cat(void);
+extern void sys_init_suspend_handler(void);
/*
* Handling of floating point exceptions.
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index d94b37430e..cbd47db37f 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -226,8 +226,10 @@ static erts_smp_atomic_t sys_misc_mem_sz;
static void smp_sig_notify(char c);
static int sig_notify_fds[2] = {-1, -1};
+#if !defined(ETHR_UNUSABLE_SIGUSRX) && defined(ERTS_THR_HAVE_SIG_FUNCS)
static int sig_suspend_fds[2] = {-1, -1};
#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
+#endif
#endif
@@ -872,7 +874,7 @@ sigusr1_exit(void)
#else
-#ifdef ERTS_SMP
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
void
sys_thr_suspend(erts_tid_t tid) {
erts_thr_kill(tid, ERTS_SYS_SUSPEND_SIGNAL);
@@ -900,7 +902,7 @@ static RETSIGTYPE user_signal1(int signum)
#endif
}
-#ifdef ERTS_SMP
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
static RETSIGTYPE suspend_signal(void)
#else
@@ -913,7 +915,7 @@ static RETSIGTYPE suspend_signal(int signum)
res = read(sig_suspend_fds[0], buf, sizeof(int));
} while (res < 0 && errno == EINTR);
}
-#endif /* #ifdef ERTS_SMP */
+#endif /* #ifdef ERTS_SYS_SUSPEND_SIGNAL */
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
@@ -966,13 +968,17 @@ void init_break_handler(void)
sys_signal(SIGINT, request_break);
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_signal(SIGUSR1, user_signal1);
-#ifdef ERTS_SMP
- sys_signal(ERTS_SYS_SUSPEND_SIGNAL, suspend_signal);
-#endif /* #ifdef ERTS_SMP */
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
sys_signal(SIGQUIT, do_quit);
}
+void sys_init_suspend_handler(void)
+{
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
+ sys_signal(ERTS_SYS_SUSPEND_SIGNAL, suspend_signal);
+#endif
+}
+
int sys_max_files(void)
{
return(max_files);
@@ -990,7 +996,7 @@ static void block_signals(void)
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
#endif /* #ifndef ERTS_SMP */
-#if defined(ERTS_SMP) && !defined(ETHR_UNUSABLE_SIGUSRX)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
sys_sigblock(ERTS_SYS_SUSPEND_SIGNAL);
#endif
@@ -1009,7 +1015,7 @@ static void unblock_signals(void)
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
#endif /* #ifndef ERTS_SMP */
-#if defined(ERTS_SMP) && !defined(ETHR_UNUSABLE_SIGUSRX)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
sys_sigrelease(ERTS_SYS_SUSPEND_SIGNAL);
#endif
@@ -3248,12 +3254,14 @@ init_smp_sig_notify(void)
static void
init_smp_sig_suspend(void) {
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
if (pipe(sig_suspend_fds) < 0) {
erts_exit(ERTS_ABORT_EXIT,
"Failed to create sig_suspend pipe: %s (%d)\n",
erl_errno_id(errno),
errno);
}
+#endif
}
#ifdef __DARWIN__
--
cgit v1.2.3
From 23cfe2138c71861684f55a298b55203b4649a645 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Tue, 20 Dec 2016 17:25:18 +0100
Subject: Workaround for buggy android implementation of PTHREAD_STACK_MIN
---
erts/aclocal.m4 | 19 +++++++++++++++++++
erts/lib_src/common/ethr_aux.c | 2 +-
2 files changed, 20 insertions(+), 1 deletion(-)
(limited to 'erts')
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 6c0544da31..5ea4c2ccf3 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -1704,6 +1704,25 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_TIME_WITH_SYS_TIME, 1, \
[Define if you can safely include both and .]))
+ AC_MSG_CHECKING([for usable PTHREAD_STACK_MIN])
+ pthread_stack_min=no
+ AC_TRY_COMPILE([
+#include
+#if defined(ETHR_NEED_NPTL_PTHREAD_H)
+#include
+#elif defined(ETHR_HAVE_MIT_PTHREAD_H)
+#include
+#elif defined(ETHR_HAVE_PTHREAD_H)
+#include
+#endif
+ ],
+ [return PTHREAD_STACK_MIN;],
+ [pthread_stack_min=yes])
+
+ AC_MSG_RESULT([$pthread_stack_min])
+ test $pthread_stack_min != yes || {
+ AC_DEFINE(ETHR_HAVE_USABLE_PTHREAD_STACK_MIN, 1, [Define if you can use PTHREAD_STACK_MIN])
+ }
dnl
dnl Check for functions
diff --git a/erts/lib_src/common/ethr_aux.c b/erts/lib_src/common/ethr_aux.c
index 420efd725f..3501fe335a 100644
--- a/erts/lib_src/common/ethr_aux.c
+++ b/erts/lib_src/common/ethr_aux.c
@@ -220,7 +220,7 @@ ethr_init_common__(ethr_init_data *id)
ethr_min_stack_size__ += ethr_pagesize__;
#endif
/* The system may think that we need more stack */
-#if defined(PTHREAD_STACK_MIN)
+#if defined(ETHR_HAVE_USABLE_PTHREAD_STACK_MIN)
if (ethr_min_stack_size__ < PTHREAD_STACK_MIN)
ethr_min_stack_size__ = PTHREAD_STACK_MIN;
#elif defined(_SC_THREAD_STACK_MIN)
--
cgit v1.2.3
From 1d8dbc7123245a536df6bb09e891d3a075fb70ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?H=C3=A5kan=20Mattsson?=
Date: Thu, 22 Dec 2016 09:57:21 +0100
Subject: escript: Handle symbolic link to a standalone escript
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The code has been rearranged to make use of the actual path
"get_default_emulator(scriptname)" to the escript instead of
the given one "get_default_emulator(argv[0])".
TL;DR
Assume a source system with some Erlang applications (app1, app2 etc.)
and an escript called "mytool". When generating a standalone target
system (with reltool for example), the escript(s) are located in the
same top bin directory as "erl". See mytool* below.
In such a system the original "mytool" escript is given the extension
".escript" and the file with the same name as the original escript is
a copy of the "escript" executable. One purpose of the escript
executable is to determine which "erl" to use to start the system.
In a standalone system we want it to find the runtime system bundled
with the escript(s). This is done by analyzing the path in order to
find the "erl" located in the same directory as the escript.
A dilemma here is that we do not want to put the top bin directory
in the execution path (PATH env var) as we then would cause other
Erlang applications to make use of our bundled run-time system.
One way of solving this is to choose some suitable bin directory in
the execution path (such as /user/local/bin) and put a symbolic link
there to our mytool executable.
Unfortunately this did not work as the escript executable (in this
case called mytool) would try to find "erl" in /usr/local/bin and when
it did not find such a file it resorted to use the command "erl" which
would find some (unwanted) "erl" in the execution path.
My fix solves that problem.
├── bin/
│ ├── erl* (dyn_erl.c)
│ ├── mytool* (escript.c)
│ ├── mytool.escript* (original mytool escript)
│ └── start_clean.boot
├── erts-vsn/
│ └── bin/
│ ├── beam*
│ ├── beam.smp*
│ ├── erl*
│ ├── erl_child_setup*
│ ├── erlexec*
│ └── inet_gethost*
└── lib/
├── app1-vsn
├── app2-vsn
└── ...
---
erts/etc/common/escript.c | 40 +++++++++++++++++++++-------------------
1 file changed, 21 insertions(+), 19 deletions(-)
(limited to 'erts')
diff --git a/erts/etc/common/escript.c b/erts/etc/common/escript.c
index 71c278881c..4134a3ff36 100644
--- a/erts/etc/common/escript.c
+++ b/erts/etc/common/escript.c
@@ -428,14 +428,6 @@ main(int argc, char** argv)
argv[argc] = NULL;
#endif
- emulator = env = get_env("ESCRIPT_EMULATOR");
- if (emulator == NULL) {
- emulator = get_default_emulator(argv[0]);
- }
-
- if (strlen(emulator) >= PMAX)
- error("Value of environment variable ESCRIPT_EMULATOR is too large");
-
/*
* Allocate the argv vector to be used for arguments to Erlang.
* Arrange for starting to pushing information in the middle of
@@ -446,21 +438,10 @@ main(int argc, char** argv)
eargv_base = (char **) emalloc(eargv_size*sizeof(char*));
eargv = eargv_base;
eargc = 0;
- push_words(emulator);
eargc_base = eargc;
eargv = eargv + eargv_size/2;
eargc = 0;
- free_env_val(env);
-
- /*
- * Push initial arguments.
- */
-
- PUSH("+B");
- PUSH2("-boot", "start_clean");
- PUSH("-noshell");
-
/* Determine basename of the executable */
for (basename = argv[0]+strlen(argv[0]);
basename > argv[0] && !(IS_DIRSEP(basename[-1]));
@@ -510,6 +491,27 @@ main(int argc, char** argv)
efree(absname);
}
+ /* Determine path to emulator */
+ emulator = env = get_env("ESCRIPT_EMULATOR");
+
+ if (emulator == NULL) {
+ emulator = get_default_emulator(scriptname);
+ }
+
+ if (strlen(emulator) >= PMAX)
+ error("Value of environment variable ESCRIPT_EMULATOR is too large");
+
+ /*
+ * Push initial arguments.
+ */
+
+ push_words(emulator);
+ free_env_val(env);
+
+ PUSH("+B");
+ PUSH2("-boot", "start_clean");
+ PUSH("-noshell");
+
/*
* Read options from the %%! row in the script and add them as args
*/
--
cgit v1.2.3
From fb4e0f8726d2e3033164fe6e44c49351c6b641de Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Wed, 21 Dec 2016 17:41:43 +0100
Subject: erts: Make erts_dbg_within_proc available
for debug assertions.
---
erts/emulator/beam/erl_gc.c | 12 +++---------
erts/emulator/beam/erl_gc.h | 7 +++----
erts/emulator/hipe/hipe_gc.c | 6 +++---
3 files changed, 9 insertions(+), 16 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 818f89f0e3..d907e7b351 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -3317,8 +3317,8 @@ erts_max_heap_size(Eterm arg, Uint *max_heap_size, Uint *max_heap_flags)
#if defined(DEBUG) || defined(ERTS_OFFHEAP_DEBUG)
-static int
-within2(Eterm *ptr, Process *p, Eterm *real_htop)
+int
+erts_dbg_within_proc(Eterm *ptr, Process *p, Eterm *real_htop)
{
ErlHeapFragment* bp;
ErtsMessage* mp;
@@ -3362,12 +3362,6 @@ within2(Eterm *ptr, Process *p, Eterm *real_htop)
return 0;
}
-int
-within(Eterm *ptr, Process *p)
-{
- return within2(ptr, p, NULL);
-}
-
#endif
#ifdef ERTS_OFFHEAP_DEBUG
@@ -3422,7 +3416,7 @@ erts_check_off_heap2(Process *p, Eterm *htop)
else if (oheap <= u.ep && u.ep < ohtop)
old = 1;
else {
- ERTS_CHK_OFFHEAP_ASSERT(within2(u.ep, p, htop));
+ ERTS_CHK_OFFHEAP_ASSERT(erts_dbg_within_proc(u.ep, p, htop));
}
}
diff --git a/erts/emulator/beam/erl_gc.h b/erts/emulator/beam/erl_gc.h
index 54ea9ca3c0..9684478c1b 100644
--- a/erts/emulator/beam/erl_gc.h
+++ b/erts/emulator/beam/erl_gc.h
@@ -69,10 +69,6 @@ do { \
while (nelts--) *HTOP++ = *PTR++; \
} while(0)
-#if defined(DEBUG) || defined(ERTS_OFFHEAP_DEBUG)
-int within(Eterm *ptr, Process *p);
-#endif
-
#define ErtsInYoungGen(TPtr, Ptr, OldHeap, OldHeapSz) \
(!erts_is_literal((TPtr), (Ptr)) \
& !ErtsInArea((Ptr), (OldHeap), (OldHeapSz)))
@@ -157,5 +153,8 @@ void erts_offset_heap(Eterm*, Uint, Sint, Eterm*, Eterm*);
void erts_free_heap_frags(struct process* p);
Eterm erts_max_heap_size_map(Sint, Uint, Eterm **, Uint *);
int erts_max_heap_size(Eterm, Uint *, Uint *);
+#if defined(DEBUG) || defined(ERTS_OFFHEAP_DEBUG)
+int erts_dbg_within_proc(Eterm *ptr, Process *p, Eterm* real_htop);
+#endif
#endif /* __ERL_GC_H__ */
diff --git a/erts/emulator/hipe/hipe_gc.c b/erts/emulator/hipe/hipe_gc.c
index e6ce7ce628..cf0435adc9 100644
--- a/erts/emulator/hipe/hipe_gc.c
+++ b/erts/emulator/hipe/hipe_gc.c
@@ -99,7 +99,7 @@ Eterm *fullsweep_nstack(Process *p, Eterm *n_htop)
if (IS_MOVED_CONS(val)) {
*nsp_i = ptr[1];
} else if (!erts_is_literal(gval, ptr)) {
- ASSERT(within(ptr, p));
+ ASSERT(erts_dbg_within_proc(ptr, p, NULL));
MOVE_CONS(ptr, val, n_htop, nsp_i);
}
}
@@ -208,7 +208,7 @@ void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop)
} else if (ErtsInArea(ptr, mature, mature_size)) {
MOVE_BOXED(ptr, val, old_htop, nsp_i);
} else if (ErtsInYoungGen(gval, ptr, oh, oh_size)) {
- ASSERT(within(ptr, p));
+ ASSERT(erts_dbg_within_proc(ptr, p, NULL));
MOVE_BOXED(ptr, val, n_htop, nsp_i);
}
} else if (is_list(gval)) {
@@ -219,7 +219,7 @@ void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop)
} else if (ErtsInArea(ptr, mature, mature_size)) {
MOVE_CONS(ptr, val, old_htop, nsp_i);
} else if (ErtsInYoungGen(gval, ptr, oh, oh_size)) {
- ASSERT(within(ptr, p));
+ ASSERT(erts_dbg_within_proc(ptr, p, NULL));
MOVE_CONS(ptr, val, n_htop, nsp_i);
}
}
--
cgit v1.2.3
From dc72c879b68fdf96edfec360e8c311ff7389ecc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 16 Dec 2016 10:08:16 +0100
Subject: erts: Remove whitespace errors
* and some minor refactoring
---
erts/emulator/sys/unix/sys.c | 78 ++++++++++++--------------------------------
1 file changed, 20 insertions(+), 58 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 2fc802a2c6..2ce0d56dde 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -153,7 +153,7 @@ volatile int erts_break_requested = 0;
static struct termios initial_tty_mode;
static int replace_intr = 0;
/* assume yes initially, ttsl_init will clear it */
-int using_oldshell = 1;
+int using_oldshell = 1;
#ifdef ERTS_ENABLE_KERNEL_POLL
@@ -798,11 +798,11 @@ void erts_replace_intr(void) {
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;
@@ -856,10 +856,7 @@ get_number(char **str_ptr)
}
}
-void
-os_flavor(char* namebuf, /* Where to return the name. */
- unsigned size) /* Size of name buffer. */
-{
+void os_flavor(char* namebuf, unsigned size) {
struct utsname uts; /* Information about the system. */
char* s;
@@ -872,22 +869,16 @@ os_flavor(char* namebuf, /* Where to return the name. */
strcpy(namebuf, uts.sysname);
}
-void
-os_version(pMajor, pMinor, pBuild)
-int* pMajor; /* Pointer to major version. */
-int* pMinor; /* Pointer to minor version. */
-int* pBuild; /* Pointer to build number. */
-{
+void os_version(int *pMajor, int *pMinor, int *pBuild) {
struct utsname uts; /* Information about the system. */
char* release; /* Pointer to the release string:
- * X.Y or X.Y.Z.
- */
+ * X.Y or X.Y.Z. */
(void) uname(&uts);
release = uts.release;
- *pMajor = get_number(&release);
- *pMinor = get_number(&release);
- *pBuild = get_number(&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. */
}
void init_getenv_state(GETENV_STATE *state)
@@ -922,7 +913,7 @@ 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
@@ -940,14 +931,14 @@ void erts_do_break_handling(void)
tcsetattr(0,TCSANOW,&initial_tty_mode);
saved = 1;
}
-
+
/* call the break handling function, reset the flag */
do_break();
ERTS_UNSET_BREAK_REQUESTED;
fflush(stdout);
-
+
/* after break we go back to saved settings */
if (using_oldshell && !replace_intr) {
SET_NONBLOCKING(1);
@@ -1055,37 +1046,12 @@ erts_sys_unsetenv(char *key)
return res;
}
-void
-sys_init_io(void)
-{
-}
-
-#if (0) /* unused? */
-static int write_fill(fd, buf, len)
-int fd, len;
-char *buf;
-{
- int i, done = 0;
-
- do {
- if ((i = write(fd, buf+done, len-done)) < 0) {
- if (errno != EINTR)
- return (i);
- i = 0;
- }
- done += i;
- } while (done < len);
- return (len);
-}
-#endif
+void sys_init_io(void) { }
+void erts_sys_alloc_init(void) { }
extern const char pre_loaded_code[];
extern Preload pre_loaded[];
-void erts_sys_alloc_init(void)
-{
-}
-
#if ERTS_HAVE_ERTS_SYS_ALIGNED_ALLOC
void *erts_sys_aligned_alloc(UWord alignment, UWord size)
{
@@ -1186,9 +1152,7 @@ void sys_preload_end(Preload* p)
Here we assume that all schedulers are stopped so that erl_poll
does not interfere with the select below.
*/
-int sys_get_key(fd)
-int fd;
-{
+int sys_get_key(int fd) {
int c, ret;
unsigned char rbuf[64];
fd_set fds;
@@ -1207,15 +1171,14 @@ int fd;
if (c <= 0)
return c;
}
-
- return rbuf[0];
+ return rbuf[0];
}
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);
@@ -1240,7 +1203,7 @@ erl_debug(char* fmt, ...)
{
char sbuf[1024]; /* Temporary buffer. */
va_list va;
-
+
if (debug_log) {
va_start(va, fmt);
vsprintf(sbuf, fmt, va);
@@ -1388,9 +1351,9 @@ init_smp_sig_suspend(void) {
int erts_darwin_main_thread_pipe[2];
int erts_darwin_main_thread_result_pipe[2];
-static void initialize_darwin_main_thread_pipes(void)
+static void initialize_darwin_main_thread_pipes(void)
{
- if (pipe(erts_darwin_main_thread_pipe) < 0 ||
+ if (pipe(erts_darwin_main_thread_pipe) < 0 ||
pipe(erts_darwin_main_thread_result_pipe) < 0) {
erts_exit(ERTS_ERROR_EXIT,"Fatal error initializing Darwin main thread stealing");
}
@@ -1556,5 +1519,4 @@ erl_sys_args(int* argc, char** argv)
argv[j++] = argv[i];
}
*argc = j;
-
}
--
cgit v1.2.3
From c9060f9b4289bf9a669ac651a1a7aeb97a28652c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 13 Apr 2015 18:03:33 +0200
Subject: erts: Add SIGHUP signal handler
A received SIGHUP signal to beam will generate a '{notify, sighup}' message
to the registered process 'erl_signal_server'. 'erl_signal_server' is a
gen_event process.
---
erts/emulator/beam/atom.names | 2 ++
erts/emulator/beam/register.c | 12 ++++++------
erts/emulator/sys/unix/sys.c | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 49 insertions(+), 6 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index b1aeed7889..363b17e27c 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -239,6 +239,7 @@ atom Eq='=:='
atom Eqeq='=='
atom erl_tracer
atom erlang
+atom erl_signal_server
atom ERROR='ERROR'
atom error_handler
atom error_logger
@@ -590,6 +591,7 @@ atom set_tcw
atom set_tcw_fake
atom separate
atom shared
+atom sighup
atom silent
atom size
atom sl_alloc
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index acda51c9fc..7f60710124 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -272,13 +272,13 @@ erts_whereis_name_to_id(Process *c_p, Eterm name)
int ix;
HashBucket* b;
#ifdef ERTS_SMP
- ErtsProcLocks c_p_locks = c_p ? ERTS_PROC_LOCK_MAIN : 0;
-
-#ifdef ERTS_ENABLE_LOCK_CHECK
- if (c_p) ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
-#endif
-
+ ErtsProcLocks c_p_locks = 0;
+ if (c_p) {
+ c_p_locks = ERTS_PROC_LOCK_MAIN;
+ ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(c_p);
+ }
reg_safe_read_lock(c_p, &c_p_locks);
+
if (c_p && !c_p_locks)
erts_smp_proc_lock(c_p, ERTS_PROC_LOCK_MAIN);
#endif
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 2ce0d56dde..a099662b16 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -408,6 +408,7 @@ erts_sys_pre_init(void)
sigemptyset(&thr_create_sigmask);
sigaddset(&thr_create_sigmask, SIGINT); /* block interrupt */
sigaddset(&thr_create_sigmask, SIGTERM); /* block terminate signal */
+ sigaddset(&thr_create_sigmask, SIGHUP); /* block sighups */
sigaddset(&thr_create_sigmask, SIGUSR1); /* block user defined signal */
#endif
@@ -625,6 +626,28 @@ int erts_sys_prepare_crash_dump(int secs)
return prepare_crash_dump(secs);
}
+static void signal_notify_requested(Eterm type) {
+ Process* p = NULL;
+ Eterm msg, *hp;
+ ErtsProcLocks locks = 0;
+ ErlOffHeap *ohp;
+
+ Eterm id = erts_whereis_name_to_id(NULL, am_erl_signal_server);
+
+ if ((p = (erts_pid2proc_opt(NULL, 0, id, 0, ERTS_P2P_FLG_INC_REFC))) != NULL) {
+ ErtsMessage *msgp = erts_alloc_message_heap(p, &locks, 3, &hp, &ohp);
+
+ /* erl_signal_server ! {notify, sighup} */
+ msg = TUPLE2(hp, am_notify, type);
+ erts_queue_message(p, locks, msgp, msg, am_system);
+
+ if (locks)
+ erts_smp_proc_unlock(p, locks);
+ erts_proc_dec_refc(p);
+ }
+}
+
+
static ERTS_INLINE void
break_requested(void)
{
@@ -783,10 +806,24 @@ static RETSIGTYPE do_quit(int signum)
#endif
}
+#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
+static RETSIGTYPE request_sighup(void)
+#else
+static RETSIGTYPE request_sighup(int signum)
+#endif
+{
+#ifdef ERTS_SMP
+ smp_sig_notify('H');
+#else
+ signal_notify_requested(am_sighup);
+#endif
+}
+
/* Disable break */
void erts_set_ignore_break(void) {
sys_signal(SIGINT, SIG_IGN);
sys_signal(SIGTERM, SIG_IGN);
+ sys_signal(SIGHUP, SIG_IGN);
sys_signal(SIGQUIT, SIG_IGN);
sys_signal(SIGTSTP, SIG_IGN);
}
@@ -813,6 +850,7 @@ void init_break_handler(void)
{
sys_signal(SIGINT, request_break);
sys_signal(SIGTERM, request_stop);
+ sys_signal(SIGHUP, request_sighup);
#ifndef ETHR_UNUSABLE_SIGUSRX
sys_signal(SIGUSR1, user_signal1);
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
@@ -1289,6 +1327,9 @@ signal_dispatcher_thread_func(void *unused)
switch (buf[i]) {
case 0: /* Emulator initialized */
break;
+ case 'H': /* SIGHUP */
+ signal_notify_requested(am_sighup);
+ break;
case 'S': /* SIGTERM */
stop_requested();
break;
--
cgit v1.2.3
From 9e9e7bf64fa97663dd4fb645c014880205fb46db Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Mon, 9 Jan 2017 15:13:58 +0100
Subject: erts: Add assertions for correct ErlNifEnv
when constructing container terms.
---
erts/emulator/beam/erl_nif.c | 107 +++++++++++++++++++++++++++++++++++++++++--
erts/emulator/beam/global.h | 7 +++
2 files changed, 110 insertions(+), 4 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 5499512dd1..10514f6b3f 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -89,6 +89,14 @@ static void add_readonly_check(ErlNifEnv*, unsigned char* ptr, unsigned sz);
# define ADD_READONLY_CHECK(ENV,PTR,SIZE) ((void)0)
#endif
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+# define ASSERT_IN_ENV(ENV, TERM, NR, TYPE) dbg_assert_in_env(ENV, TERM, NR, TYPE, __func__)
+static void dbg_assert_in_env(ErlNifEnv*, Eterm term, int nr, const char* type, const char* func);
+# include "erl_gc.h"
+#else
+# define ASSERT_IN_ENV(ENV, TERM, NR, TYPE)
+#endif
+
#ifdef DEBUG
static int is_offheap(const ErlOffHeap* off_heap);
#endif
@@ -196,6 +204,9 @@ void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif,
ASSERT(p->common.id != ERTS_INVALID_PID);
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ env->dbg_disable_assert_in_env = 0;
+#endif
#if defined(DEBUG) && defined(ERTS_DIRTY_SCHEDULERS)
{
ErtsSchedulerData *esdp = erts_get_scheduler_data();
@@ -474,11 +485,15 @@ setup_nif_env(struct enif_msg_environment_t* msg_env,
HEAP_END(&msg_env->phony_proc) = phony_heap;
MBUF(&msg_env->phony_proc) = NULL;
msg_env->phony_proc.common.id = ERTS_INVALID_PID;
+ msg_env->env.tracee = tracee;
+
#ifdef FORCE_HEAP_FRAGS
msg_env->phony_proc.space_verified = 0;
msg_env->phony_proc.space_verified_from = NULL;
#endif
- msg_env->env.tracee = tracee;
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ msg_env->env.dbg_disable_assert_in_env = 0;
+#endif
}
ErlNifEnv* enif_alloc_env(void)
@@ -1586,6 +1601,9 @@ int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
{
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ int nr = 0;
+#endif
Eterm* hp = alloc_heap(env,cnt+1);
Eterm ret = make_tuple(hp);
va_list ap;
@@ -1593,7 +1611,9 @@ ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
*hp++ = make_arityval(cnt);
va_start(ap,cnt);
while (cnt--) {
- *hp++ = va_arg(ap,Eterm);
+ Eterm elem = va_arg(ap,Eterm);
+ ASSERT_IN_ENV(env, elem, ++nr, "tuple");
+ *hp++ = elem;
}
va_end(ap);
return ret;
@@ -1601,12 +1621,16 @@ ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
ERL_NIF_TERM enif_make_tuple_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)
{
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ int nr = 0;
+#endif
Eterm* hp = alloc_heap(env,cnt+1);
Eterm ret = make_tuple(hp);
const Eterm* src = arr;
*hp++ = make_arityval(cnt);
while (cnt--) {
+ ASSERT_IN_ENV(env, *src, ++nr, "tuple");
*hp++ = *src++;
}
return ret;
@@ -1617,6 +1641,8 @@ ERL_NIF_TERM enif_make_list_cell(ErlNifEnv* env, Eterm car, Eterm cdr)
Eterm* hp = alloc_heap(env,2);
Eterm ret = make_list(hp);
+ ASSERT_IN_ENV(env, car, 0, "head of list cell");
+ ASSERT_IN_ENV(env, cdr, 0, "tail of list cell");
CAR(hp) = car;
CDR(hp) = cdr;
return ret;
@@ -1628,6 +1654,9 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
return NIL;
}
else {
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ int nr = 0;
+#endif
Eterm* hp = alloc_heap(env,cnt*2);
Eterm ret = make_list(hp);
Eterm* last = &ret;
@@ -1635,8 +1664,10 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
va_start(ap,cnt);
while (cnt--) {
+ Eterm term = va_arg(ap,Eterm);
*last = make_list(hp);
- *hp = va_arg(ap,Eterm);
+ ASSERT_IN_ENV(env, term, ++nr, "list");
+ *hp = term;
last = ++hp;
++hp;
}
@@ -1648,14 +1679,19 @@ ERL_NIF_TERM enif_make_list(ErlNifEnv* env, unsigned cnt, ...)
ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[], unsigned cnt)
{
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ int nr = 0;
+#endif
Eterm* hp = alloc_heap(env,cnt*2);
Eterm ret = make_list(hp);
Eterm* last = &ret;
const Eterm* src = arr;
while (cnt--) {
+ Eterm term = *src++;
*last = make_list(hp);
- *hp = *src++;
+ ASSERT_IN_ENV(env, term, ++nr, "list");
+ *hp = term;
last = ++hp;
++hp;
}
@@ -2789,6 +2825,10 @@ int enif_make_map_put(ErlNifEnv* env,
if (!is_map(map_in)) {
return 0;
}
+ ASSERT_IN_ENV(env, map_in, 0, "old map");
+ ASSERT_IN_ENV(env, key, 0, "key");
+ ASSERT_IN_ENV(env, value, 0, "value");
+
flush_env(env);
*map_out = erts_maps_put(env->proc, key, value, map_in);
cache_env(env);
@@ -2823,6 +2863,10 @@ int enif_make_map_update(ErlNifEnv* env,
return 0;
}
+ ASSERT_IN_ENV(env, map_in, 0, "old map");
+ ASSERT_IN_ENV(env, key, 0, "key");
+ ASSERT_IN_ENV(env, value, 0, "value");
+
flush_env(env);
res = erts_maps_update(env->proc, key, value, map_in, map_out);
cache_env(env);
@@ -3543,6 +3587,9 @@ Eterm erts_nif_call_function(Process *p, Process *tracee,
clear_offheap(&MSO(p));
erts_pre_nif(&env, p, mod, tracee);
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ env.dbg_disable_assert_in_env = 1;
+#endif
nif_result = (*fun->fptr)(&env, argc, argv);
if (env.exception_thrown)
nif_result = THE_NON_VALUE;
@@ -3565,6 +3612,9 @@ Eterm erts_nif_call_function(Process *p, Process *tracee,
so we create a phony one. */
struct enif_msg_environment_t msg_env;
pre_nif_noproc(&msg_env, mod, tracee);
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ msg_env.env.dbg_disable_assert_in_env = 1;
+#endif
nif_result = (*fun->fptr)(&msg_env.env, argc, argv);
if (msg_env.env.exception_thrown)
nif_result = THE_NON_VALUE;
@@ -3629,6 +3679,55 @@ static unsigned calc_checksum(unsigned char* ptr, unsigned size)
#endif /* READONLY_CHECK */
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+static void dbg_assert_in_env(ErlNifEnv* env, Eterm term,
+ int nr, const char* type, const char* func)
+{
+ Uint saved_used_size;
+ Eterm* real_htop;
+
+ if (is_immed(term)
+ || (is_non_value(term) && env->exception_thrown)
+ || erts_is_literal(term, ptr_val(term)))
+ return;
+
+ if (env->dbg_disable_assert_in_env) {
+ /*
+ * Trace nifs may cheat as built terms are discarded after return.
+ * ToDo: Check if 'term' is part of argv[].
+ */
+ return;
+ }
+
+ if (env->heap_frag) {
+ ASSERT(env->heap_frag == MBUF(env->proc));
+ ASSERT(env->hp >= env->heap_frag->mem);
+ ASSERT(env->hp <= env->heap_frag->mem + env->heap_frag->alloc_size);
+ saved_used_size = env->heap_frag->used_size;
+ env->heap_frag->used_size = env->hp - env->heap_frag->mem;
+ real_htop = NULL;
+ }
+ else {
+ real_htop = env->hp;
+ }
+ if (!erts_dbg_within_proc(ptr_val(term), env->proc, real_htop)) {
+ fprintf(stderr, "\r\nFAILED ASSERTION in %s:\r\n", func);
+ if (nr) {
+ fprintf(stderr, "Term #%d of the %s is not from same ErlNifEnv.",
+ nr, type);
+ }
+ else {
+ fprintf(stderr, "The %s is not from the same ErlNifEnv.", type);
+ }
+ fprintf(stderr, "\r\nABORTING\r\n");
+ abort();
+ }
+ if (env->heap_frag) {
+ env->heap_frag->used_size = saved_used_size;
+ }
+}
+#endif
+
#ifdef HAVE_USE_DTRACE
#define MESSAGE_BUFSIZ 1024
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 2b2f3c5cdc..5d07490152 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -45,6 +45,9 @@
struct enif_func_t;
+#ifdef DEBUG
+# define ERTS_NIF_ASSERT_IN_ENV
+#endif
struct enif_environment_t /* ErlNifEnv */
{
struct erl_module_nif* mod_nif;
@@ -57,6 +60,10 @@ struct enif_environment_t /* ErlNifEnv */
int exception_thrown; /* boolean */
Process *tracee;
int exiting; /* boolean (dirty nifs might return in exiting state) */
+
+#ifdef ERTS_NIF_ASSERT_IN_ENV
+ int dbg_disable_assert_in_env;
+#endif
};
extern void erts_pre_nif(struct enif_environment_t*, Process*,
struct erl_module_nif*, Process* tracee);
--
cgit v1.2.3
From 10ace079fb6d0d626a16a5c6726c6bb8e6bb3878 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Wed, 21 Dec 2016 17:43:28 +0100
Subject: erts: Cleanup enif_make_reverse_list
---
erts/emulator/beam/erl_nif.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 10514f6b3f..cd44eb880e 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1724,13 +1724,9 @@ void enif_system_info(ErlNifSysInfo *sip, size_t si_size)
driver_system_info(sip, si_size);
}
-int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list) {
- Eterm *listptr, ret = NIL, *hp;
-
- if (is_nil(term)) {
- *list = term;
- return 1;
- }
+int enif_make_reverse_list(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM *list)
+{
+ Eterm *listptr, ret, *hp;
ret = NIL;
--
cgit v1.2.3
From 1239d92556cc0a7921648cbd4abd9f9a397b29b8 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Wed, 21 Dec 2016 18:12:14 +0100
Subject: erts: Cleanup and extra assertions in nif_SUITE.c
---
erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 2c93891852..4decb7f418 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -116,7 +116,6 @@ static ERL_NIF_TERM make_pointer(ErlNifEnv* env, void* p)
{
void** bin_data;
ERL_NIF_TERM res;
- ADD_CALL("get_priv_data_ptr");
bin_data = (void**)enif_make_new_binary(env, sizeof(void*), &res);
*bin_data = p;
return res;
@@ -389,8 +388,7 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifSInt64 sint64;
ErlNifUInt64 uint64;
double d;
- ERL_NIF_TERM atom, ref1, ref2, term;
- size_t len;
+ ERL_NIF_TERM atom, ref1, ref2;
sint = INT_MIN;
do {
@@ -1024,6 +1022,7 @@ struct make_term_info
{
ErlNifEnv* caller_env;
ErlNifEnv* dst_env;
+ int dst_env_valid;
ERL_NIF_TERM reuse[MAKE_TERM_REUSE_LEN];
unsigned reuse_push;
unsigned reuse_pull;
@@ -1053,6 +1052,7 @@ static ERL_NIF_TERM pull_term(struct make_term_info* mti)
mti->reuse_push < MAKE_TERM_REUSE_LEN) {
mti->reuse_pull = 0;
if (mti->reuse_push == 0) {
+ assert(mti->dst_env_valid);
mti->reuse[0] = enif_make_list(mti->dst_env, 0);
}
}
@@ -1241,6 +1241,7 @@ static unsigned num_of_make_funcs()
static int make_term_n(struct make_term_info* mti, int n, ERL_NIF_TERM* res)
{
if (n < num_of_make_funcs()) {
+ assert(mti->dst_env_valid);
*res = make_funcs[n](mti, n);
push_term(mti, *res);
return 1;
@@ -1257,6 +1258,7 @@ static ERL_NIF_TERM make_blob(ErlNifEnv* caller_env, ErlNifEnv* dst_env,
struct make_term_info mti;
mti.caller_env = caller_env;
mti.dst_env = dst_env;
+ mti.dst_env_valid = 1;
mti.reuse_push = 0;
mti.reuse_pull = 0;
mti.resource_type = priv->rt_arr[0].t;
@@ -1297,6 +1299,7 @@ static ERL_NIF_TERM alloc_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
sizeof(*mti));
mti->caller_env = NULL;
mti->dst_env = enif_alloc_env();
+ mti->dst_env_valid = 1;
mti->reuse_push = 0;
mti->reuse_pull = 0;
mti->resource_type = priv->rt_arr[0].t;
@@ -1328,6 +1331,7 @@ static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
return enif_make_badarg(env);
}
enif_clear_env(mti.p->dst_env);
+ mti.p->dst_env_valid = 1;
mti.p->reuse_pull = 0;
mti.p->reuse_push = 0;
mti.p->blob = enif_make_list(mti.p->dst_env, 0);
@@ -1362,6 +1366,8 @@ static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
}
copy = enif_make_copy(env, mti.p->blob);
res = enif_send(env, &to, mti.p->dst_env, mti.p->blob);
+ if (res)
+ mti.p->dst_env_valid = 0;
return enif_make_tuple3(env, atom_ok, enif_make_int(env,res), copy);
}
@@ -1369,7 +1375,6 @@ static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
{
mti_t mti;
ErlNifPid to;
- ERL_NIF_TERM copy;
int res;
if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
|| !enif_get_local_pid(env, argv[1], &to)) {
@@ -1379,6 +1384,8 @@ static ERL_NIF_TERM send3_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv
enif_make_copy(mti.p->dst_env, argv[2]),
mti.p->blob);
res = enif_send(env, &to, mti.p->dst_env, mti.p->blob);
+ if (res)
+ mti.p->dst_env_valid = 0;
return enif_make_int(env,res);
}
@@ -1395,6 +1402,8 @@ void* threaded_sender(void *arg)
mti.p->send_it = 0;
enif_mutex_unlock(mti.p->mtx);
mti.p->send_res = enif_send(NULL, &mti.p->to_pid, mti.p->dst_env, mti.p->blob);
+ if (mti.p->send_res)
+ mti.p->dst_env_valid = 0;
return NULL;
}
--
cgit v1.2.3
From 9e862df2bf26b9b1d79ba3b447945b7c0612e3d0 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Thu, 12 Jan 2017 18:12:38 +0100
Subject: erts: Add macro ERTS_PROC_LOCKS_HIGHER_THAN
to safeguard against bugs due to future proc lock changes.
The two places now using ERTS_PROC_LOCKS_HIGHER_THAN were
kind of bugs as BTM and TRACE locks were missing. But there was
probably no way to get there with BTM or TRACE locked.
---
erts/emulator/beam/erl_message.c | 10 ++++++----
erts/emulator/beam/erl_process_lock.h | 4 ++++
2 files changed, 10 insertions(+), 4 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index 118adc0c1b..04f9640a17 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -285,9 +285,11 @@ erts_queue_dist_message(Process *rcvr,
if (!(rcvr_locks & ERTS_PROC_LOCK_MSGQ)) {
if (erts_smp_proc_trylock(rcvr, ERTS_PROC_LOCK_MSGQ) == EBUSY) {
ErtsProcLocks need_locks = ERTS_PROC_LOCK_MSGQ;
- if (rcvr_locks & ERTS_PROC_LOCK_STATUS) {
- erts_smp_proc_unlock(rcvr, ERTS_PROC_LOCK_STATUS);
- need_locks |= ERTS_PROC_LOCK_STATUS;
+ ErtsProcLocks unlocks =
+ rcvr_locks & ERTS_PROC_LOCKS_HIGHER_THAN(ERTS_PROC_LOCK_MSGQ);
+ if (unlocks) {
+ erts_smp_proc_unlock(rcvr, unlocks);
+ need_locks |= unlocks;
}
erts_smp_proc_lock(rcvr, need_locks);
}
@@ -406,7 +408,7 @@ queue_messages(Process* receiver,
if (state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_PENDING_EXIT))
goto exiting;
- need_locks = receiver_locks & (ERTS_PROC_LOCK_STATUS|ERTS_PROC_LOCK_TRACE);
+ need_locks = receiver_locks & ERTS_PROC_LOCKS_HIGHER_THAN(ERTS_PROC_LOCK_MSGQ);
if (need_locks) {
erts_smp_proc_unlock(receiver, need_locks);
}
diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h
index 2cccf0697a..e7d68f0a09 100644
--- a/erts/emulator/beam/erl_process_lock.h
+++ b/erts/emulator/beam/erl_process_lock.h
@@ -219,6 +219,10 @@ typedef struct erts_proc_lock_t_ {
#define ERTS_PROC_LOCKS_ALL_MINOR (ERTS_PROC_LOCKS_ALL \
& ~ERTS_PROC_LOCK_MAIN)
+/* All locks we first must unlock to lock L */
+#define ERTS_PROC_LOCKS_HIGHER_THAN(L) \
+ (ERTS_PROC_LOCKS_ALL & (~(L) & ~((L)-1)))
+
#define ERTS_PIX_LOCKS_BITS 10
#define ERTS_NO_OF_PIX_LOCKS (1 << ERTS_PIX_LOCKS_BITS)
--
cgit v1.2.3
From d74d7a4cc0808e1f6e710e5d17ec55bfe093cdd9 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Fri, 13 Jan 2017 18:19:30 +0100
Subject: erts: Fix enif_send from noproc and no msg_env
Only try direct allocation on receiver heap when called
in a real process context to avoid trylock on our own main lock.
---
erts/emulator/beam/erl_nif.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 6b265a8b80..dd4b88e4a3 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -690,7 +690,7 @@ int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
Uint sz = size_object(msg);
ErlOffHeap *ohp;
Eterm *hp;
- if (env && !env->tracee) {
+ if (c_p && !env->tracee) {
full_flush_env(env);
mp = erts_alloc_message_heap(rp, &rp_locks, sz, &hp, &ohp);
full_cache_env(env);
--
cgit v1.2.3
From 82ba60f0ead61f344e2a7ebd383f62e99cb0375d Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Mon, 16 Jan 2017 18:01:20 +0100
Subject: erts: Fix port_trace_SUITE to join threads
when port is closed before driver may be unloaded.
---
.../emulator/test/port_trace_SUITE_data/echo_drv.c | 39 ++++++++++++++++------
1 file changed, 29 insertions(+), 10 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
index b545523192..20ec33a594 100644
--- a/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
+++ b/erts/emulator/test/port_trace_SUITE_data/echo_drv.c
@@ -2,23 +2,30 @@
#include "erl_driver.h"
#include
#include
+#include
/* -------------------------------------------------------------------------
** Data types
**/
+struct my_thread {
+ struct my_thread* next;
+ ErlDrvTid tid;
+};
typedef struct _erl_drv_data {
ErlDrvPort erlang_port;
ErlDrvTermData caller;
+ struct my_thread* threads;
} EchoDrvData;
struct remote_send_term {
- char *buf;
- int len;
+ struct my_thread thread;
ErlDrvTermData port;
ErlDrvTermData caller;
+ int len;
+ char buf[1]; /* buf[len] */
};
#define ECHO_DRV_NOOP 0
@@ -86,7 +93,7 @@ static ErlDrvEntry echo_drv_entry = {
NULL
};
-static void send_term_thread(void *);
+static void* send_term_thread(void *);
/* -------------------------------------------------------------------------
** Entry functions
@@ -111,10 +118,22 @@ static EchoDrvData *echo_drv_start(ErlDrvPort port, char *command)
EchoDrvData *echo_drv_data_p = driver_alloc(sizeof(EchoDrvData));
echo_drv_data_p->erlang_port = port;
echo_drv_data_p->caller = driver_caller(port);
+ echo_drv_data_p->threads = NULL;
return echo_drv_data_p;
}
-static void echo_drv_stop(EchoDrvData *data_p) {
+static void echo_drv_stop(EchoDrvData *data_p)
+{
+ struct my_thread* thr = data_p->threads;
+
+ while (thr) {
+ struct my_thread* next = thr->next;
+ void* exit_value;
+ int ret = erl_drv_thread_join(thr->tid, &exit_value);
+ assert(ret == 0 && exit_value == NULL);
+ driver_free(thr);
+ thr = next;
+ }
driver_free(data_p);
}
@@ -212,14 +231,14 @@ static void echo_drv_output(ErlDrvData drv_data, char *buf, ErlDrvSizeT len) {
}
case ECHO_DRV_REMOTE_SEND_TERM:
{
- ErlDrvTid tid;
- struct remote_send_term *t = malloc(sizeof(struct remote_send_term));
+ struct remote_send_term *t = driver_alloc(sizeof(struct remote_send_term) + len);
t->len = len-1;
- t->buf = malloc(len-1);
t->port = driver_mk_port(port);
t->caller = data_p->caller;
memcpy(t->buf, buf+1, t->len);
- erl_drv_thread_create("tmp_thread", &tid, send_term_thread, t, NULL);
+ erl_drv_thread_create("tmp_thread", &t->thread.tid, send_term_thread, t, NULL);
+ t->thread.next = data_p->threads;
+ data_p->threads = &t->thread;
break;
}
case ECHO_DRV_SAVE_CALLER:
@@ -262,7 +281,7 @@ static ErlDrvSSizeT echo_drv_call(ErlDrvData drv_data,
return len-command;
}
-static void send_term_thread(void *a)
+static void* send_term_thread(void *a)
{
struct remote_send_term *t = (struct remote_send_term*)a;
ErlDrvTermData term[] = {
@@ -273,5 +292,5 @@ static void send_term_thread(void *a)
ERL_DRV_TUPLE, 3};
erl_drv_send_term(t->port, t->caller,
term, sizeof(term) / sizeof(ErlDrvTermData));
- return;
+ return NULL;
}
--
cgit v1.2.3
From c3fe109d6f631fde600676db7e27209fe12911c1 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 17 Jan 2017 15:12:17 +0100
Subject: erts: Fix zlib crash on mac for inflateGetDictionary
Work around broken build system by checking
actual zlib version in runtime.
---
erts/emulator/drivers/common/zlib_drv.c | 46 ++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 9 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/drivers/common/zlib_drv.c b/erts/emulator/drivers/common/zlib_drv.c
index 066cf87c9d..e8afddb01b 100644
--- a/erts/emulator/drivers/common/zlib_drv.c
+++ b/erts/emulator/drivers/common/zlib_drv.c
@@ -252,9 +252,9 @@ static int zlib_output(ZLibData* d)
return zlib_output_init(d);
}
-#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
static int zlib_inflate_get_dictionary(ZLibData* d)
{
+#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
ErlDrvBinary* dbin = driver_alloc_binary(INFL_DICT_SZ);
uInt dlen = 0;
int res = inflateGetDictionary(&d->s, (unsigned char*)dbin->orig_bytes, &dlen);
@@ -263,8 +263,11 @@ static int zlib_inflate_get_dictionary(ZLibData* d)
}
driver_free_binary(dbin);
return res;
-}
+#else
+ abort(); /* never called, just to silence 'unresolved symbol'
+ for non-optimizing compiler */
#endif
+}
static int zlib_inflate(ZLibData* d, int flush)
{
@@ -448,10 +451,35 @@ static void zlib_free(void* data, void* addr)
driver_free(addr);
}
+#if defined(__APPLE__) && defined(__MACH__) && defined(HAVE_ZLIB_INFLATEGETDICTIONARY)
+
+/* Work around broken build system with runtime version test */
+static int have_inflateGetDictionary;
+
+static int zlib_init()
+{
+ unsigned int v[4] = {0, 0, 0, 0};
+ unsigned hexver;
+
+ sscanf(zlibVersion(), "%u.%u.%u.%u", &v[0], &v[1], &v[2], &v[3]);
+
+ hexver = (v[0] << (8*3)) | (v[1] << (8*2)) | (v[2] << (8)) | v[3];
+
+ have_inflateGetDictionary = (hexver >= 0x1020701); /* 1.2.7.1 */
+
+ return 0;
+}
+#else /* trust configure got it right */
+# ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
+# define have_inflateGetDictionary 1
+# else
+# define have_inflateGetDictionary 0
+# endif
static int zlib_init()
{
return 0;
}
+#endif
static ErlDrvData zlib_start(ErlDrvPort port, char* buf)
{
@@ -605,14 +633,14 @@ static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *bu
return zlib_return(res, rbuf, rlen);
case INFLATE_GETDICT:
-#ifdef HAVE_ZLIB_INFLATEGETDICTIONARY
- if (d->state != ST_INFLATE) goto badarg;
- res = zlib_inflate_get_dictionary(d);
+ if (have_inflateGetDictionary) {
+ if (d->state != ST_INFLATE) goto badarg;
+ res = zlib_inflate_get_dictionary(d);
+ } else {
+ errno = ENOTSUP;
+ res = Z_ERRNO;
+ }
return zlib_return(res, rbuf, rlen);
-#else
- errno = ENOTSUP;
- return zlib_return(Z_ERRNO, rbuf, rlen);
-#endif
case INFLATE_SYNC:
if (d->state != ST_INFLATE) goto badarg;
--
cgit v1.2.3
From 9c69b7ba42a970a8785cf67b4f9168c949396f4b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Tue, 17 Jan 2017 15:49:23 +0100
Subject: Handle unicode in path in test
---
erts/test/install_SUITE.erl | 44 +++++++++++++++++++-------------------------
1 file changed, 19 insertions(+), 25 deletions(-)
(limited to 'erts')
diff --git a/erts/test/install_SUITE.erl b/erts/test/install_SUITE.erl
index 2c7e8972f6..f96dca9563 100644
--- a/erts/test/install_SUITE.erl
+++ b/erts/test/install_SUITE.erl
@@ -18,7 +18,6 @@
%% %CopyrightEnd%
%%
-
%%%-------------------------------------------------------------------
%%% File : install_SUITE.erl
%%% Author : Rickard Green
@@ -63,12 +62,12 @@
erlang_bindir = "",
bindir_symlinks = ""}).
-need_symlink_cases() ->
+need_symlink_cases() ->
[bin_unreachable_absolute, bin_unreachable_relative,
bin_same_dir, bin_ok_symlink, bin_dirname_fail,
bin_no_use_dirname_fail].
-dont_need_symlink_cases() ->
+dont_need_symlink_cases() ->
[bin_default, bin_default_dirty, bin_outside_eprfx,
bin_outside_eprfx_dirty, bin_not_abs,
bin_unreasonable_path, 'bin white space',
@@ -78,10 +77,9 @@ suite() ->
[{ct_hooks,[ts_install_cth]},
{timetrap, {minutes, 1}}].
-all() ->
+all() ->
dont_need_symlink_cases() ++ need_symlink_cases().
-
%%
%% The test cases
%%
@@ -532,22 +530,20 @@ bin_no_srcfile(Config) when is_list(Config) ->
erlang_bindir = "/opt/local/lib/erlang/bin"},
ChkRes).
-%%
%%
%% Auxiliary functions
%%
-%%
expect(X, X) ->
- io:format("result: ~p~n", [X]),
+ io:format("result: ~tp~n", [X]),
io:format("-----------------------------------------------~n", []),
ok;
expect(X, Y) ->
- io:format("expected: ~p~n", [X]),
- io:format("got : ~p~n", [Y]),
+ io:format("expected: ~tp~n", [X]),
+ io:format("got : ~tp~n", [Y]),
io:format("-----------------------------------------------~n", []),
ct:fail({X,Y}).
-
+
init_per_suite(Config) ->
PD = proplists:get_value(priv_dir, Config),
SymLinks = case os:type() of
@@ -630,8 +626,8 @@ install_bin(Config, #inst{mkdirs = MkDirs,
true -> ok;
false -> {comment, "No symlink tests run, since symlinks not working"}
end.
-
-
+
+
install_bin2(Config, Inst, ChkRes) ->
install_bin3(Config, Inst#inst{symlinks = false,
ln_s = "ln"}, ChkRes),
@@ -662,8 +658,6 @@ install_bin2(Config, Inst, ChkRes) ->
false ->
ok
end.
-
-
install_bin3(Config,
#inst{cmd_prefix = CMD_PRFX,
@@ -690,20 +684,20 @@ install_bin3(Config,
++ "\" --exec-prefix \"" ++ EXEC_PREFIX
++ "\" --test-file \"" ++ ResFile ++ "\" erl erlc",
- io:format("CMD_PRFX = \"~s\"~n"
- "LN_S = \"~s\"~n"
- "BINDIR_SYMLINKS = \"~s\"~n"
- "exec_prefix = \"~s\"~n"
- "bindir = \"~s\"~n"
- "erlang_bindir = \"~s\"~n"
- "EXTRA_PREFIX = \"~s\"~n"
- "DESTDIR = \"~s\"~n",
+ io:format("CMD_PRFX = \"~ts\"~n"
+ "LN_S = \"~ts\"~n"
+ "BINDIR_SYMLINKS = \"~ts\"~n"
+ "exec_prefix = \"~ts\"~n"
+ "bindir = \"~ts\"~n"
+ "erlang_bindir = \"~ts\"~n"
+ "EXTRA_PREFIX = \"~ts\"~n"
+ "DESTDIR = \"~ts\"~n",
[CMD_PRFX, LN_S, BINDIR_SYMLINKS, EXEC_PREFIX, BINDIR,
ERLANG_BINDIR, EXTRA_PREFIX, DESTDIR]),
- io:format("$ ~s~n", [Cmd]),
+ io:format("$ ~ts~n", [Cmd]),
CmdOutput = os:cmd(Cmd),
- io:format("~s~n", [CmdOutput]),
+ io:format("~ts~n", [CmdOutput]),
ChkRes(case file:consult(ResFile) of
{ok, [Res]} -> Res;
Err -> exit({result, Err})
--
cgit v1.2.3
From 505305a4b6a6372921808c4e5ec56db51b6a308b Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Wed, 18 Jan 2017 13:30:20 +0100
Subject: Remove double check of NifExport when checking process code
---
erts/emulator/beam/beam_bif_load.c | 5 -----
1 file changed, 5 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/beam_bif_load.c b/erts/emulator/beam/beam_bif_load.c
index c8dde8caf8..a5891a0ec2 100644
--- a/erts/emulator/beam/beam_bif_load.c
+++ b/erts/emulator/beam/beam_bif_load.c
@@ -1117,11 +1117,6 @@ check_process_code(Process* rp, Module* modp, int *redsp, int fcalls)
*redsp += 1;
- if (erts_check_nif_export_in_area(rp, mod_start, mod_size))
- return am_true;
-
- *redsp += 1;
-
if (erts_check_nif_export_in_area(rp, mod_start, mod_size))
return am_true;
--
cgit v1.2.3
From bfcf88311828b93a833ce96ad1a518b8eca08552 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Wed, 18 Jan 2017 14:40:25 +0100
Subject: Change exception for enif_schedule_nif() with dirty flags
---
erts/doc/src/erl_nif.xml | 2 +-
erts/emulator/beam/erl_nif.c | 5 ++++-
2 files changed, 5 insertions(+), 2 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 51b095e6ef..74a551d60b 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -2463,7 +2463,7 @@ enif_map_iterator_destroy(env, &iter);
CPU-bound, or ERL_NIF_DIRTY_JOB_IO_BOUND for
jobs that will be I/O-bound. If dirty scheduler threads are not
available in the emulator, an attempt to schedule such a job
- results in a badarg exception.
+ results in a notsup exception.
argc and argv
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index b860759fa2..af3ca3afa3 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -2506,10 +2506,13 @@ enif_schedule_nif(ErlNifEnv* env, const char* fun_name, int flags,
if (flags == 0)
result = schedule(env, execute_nif, fp, proc->current->module,
fun_name_atom, argc, argv);
+ else if (!(flags & ~(ERL_NIF_DIRTY_JOB_IO_BOUND|ERL_NIF_DIRTY_JOB_CPU_BOUND))) {
#ifdef ERTS_DIRTY_SCHEDULERS
- else if (!(flags & ~(ERL_NIF_DIRTY_JOB_IO_BOUND|ERL_NIF_DIRTY_JOB_CPU_BOUND)))
result = schedule_dirty_nif(env, flags, fp, fun_name_atom, argc, argv);
+#else
+ result = enif_raise_exception(env, am_notsup);
#endif
+ }
else
result = enif_make_badarg(env);
--
cgit v1.2.3
From 40c82769def0cfa59e75669ff1c6fc4abcecd764 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Thu, 15 Dec 2016 18:07:13 +0100
Subject: erts: Handle SIGTERM via signal service instead
---
erts/emulator/beam/atom.names | 1 +
erts/emulator/sys/unix/sys.c | 28 ++++------------------------
2 files changed, 5 insertions(+), 24 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 363b17e27c..52a3413796 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -592,6 +592,7 @@ atom set_tcw_fake
atom separate
atom shared
atom sighup
+atom sigterm
atom silent
atom size
atom sl_alloc
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index a099662b16..cb9ed2de76 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -679,26 +679,6 @@ static RETSIGTYPE request_break(int signum)
#endif
}
-static void stop_requested(void) {
- Process* p = NULL;
- Eterm msg, *hp;
- ErtsProcLocks locks = 0;
- ErlOffHeap *ohp;
- Eterm id = erts_whereis_name_to_id(NULL, am_init);
-
- if ((p = (erts_pid2proc_opt(NULL, 0, id, 0, ERTS_P2P_FLG_INC_REFC))) != NULL) {
- ErtsMessage *msgp = erts_alloc_message_heap(p, &locks, 3, &hp, &ohp);
-
- /* init ! {stop,stop} */
- msg = TUPLE2(hp, am_stop, am_stop);
- erts_queue_message(p, locks, msgp, msg, am_system);
-
- if (locks)
- erts_smp_proc_unlock(p, locks);
- erts_proc_dec_refc(p);
- }
-}
-
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
static RETSIGTYPE request_stop(void)
#else
@@ -706,9 +686,9 @@ static RETSIGTYPE request_stop(int signum)
#endif
{
#ifdef ERTS_SMP
- smp_sig_notify('S');
+ smp_sig_notify('T');
#else
- stop_requested();
+ signal_notify_requested(am_sigterm);
#endif
}
@@ -1330,8 +1310,8 @@ signal_dispatcher_thread_func(void *unused)
case 'H': /* SIGHUP */
signal_notify_requested(am_sighup);
break;
- case 'S': /* SIGTERM */
- stop_requested();
+ case 'T': /* SIGTERM */
+ signal_notify_requested(am_sigterm);
break;
case 'I': /* SIGINT */
break_requested();
--
cgit v1.2.3
From 2d3bf84d8167b50728b0a5411a4e2dfa71d52c10 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 16 Dec 2016 12:24:13 +0100
Subject: erts: Handle SIGUSR1 via signal service instead
---
erts/emulator/beam/atom.names | 1 +
erts/emulator/beam/sys.h | 14 -------------
erts/emulator/sys/common/erl_poll.c | 1 -
erts/emulator/sys/unix/sys.c | 42 ++++---------------------------------
4 files changed, 5 insertions(+), 53 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 52a3413796..668abfaaee 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -593,6 +593,7 @@ atom separate
atom shared
atom sighup
atom sigterm
+atom sigusr1
atom silent
atom size
atom sl_alloc
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 4b3ac594a0..ceea794cc4 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -487,20 +487,6 @@ extern volatile int erts_break_requested;
void erts_do_break_handling(void);
#endif
-#ifdef ERTS_WANT_GOT_SIGUSR1
-# ifndef UNIX
-# define ERTS_GOT_SIGUSR1 0
-# else
-# ifdef ERTS_SMP
-extern erts_smp_atomic32_t erts_got_sigusr1;
-# define ERTS_GOT_SIGUSR1 ((int) erts_smp_atomic32_read_mb(&erts_got_sigusr1))
-# else
-extern volatile int erts_got_sigusr1;
-# define ERTS_GOT_SIGUSR1 erts_got_sigusr1
-# endif
-# endif
-#endif
-
#ifdef ERTS_SMP
extern erts_smp_atomic32_t erts_writing_erl_crash_dump;
extern erts_tsd_key_t erts_is_crash_dumping_key;
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index b8a28bcc18..5e7ae8953a 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -51,7 +51,6 @@
#ifndef WANT_NONBLOCKING
# define WANT_NONBLOCKING
#endif
-#define ERTS_WANT_GOT_SIGUSR1
#include "erl_poll.h"
#if ERTS_POLL_USE_KQUEUE
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index cb9ed2de76..de9c1b2ca0 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -50,7 +50,6 @@
#endif
#define ERTS_WANT_BREAK_HANDLING
-#define ERTS_WANT_GOT_SIGUSR1
#define WANT_NONBLOCKING /* must define this to pull in defs from sys.h */
#include "sys.h"
#include "erl_thr_progress.h"
@@ -96,18 +95,10 @@ static int debug_log = 0;
#endif
#ifdef ERTS_SMP
-erts_smp_atomic32_t erts_got_sigusr1;
-#define ERTS_SET_GOT_SIGUSR1 \
- erts_smp_atomic32_set_mb(&erts_got_sigusr1, 1)
-#define ERTS_UNSET_GOT_SIGUSR1 \
- erts_smp_atomic32_set_mb(&erts_got_sigusr1, 0)
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
-volatile int erts_got_sigusr1;
-#define ERTS_SET_GOT_SIGUSR1 (erts_got_sigusr1 = 1)
-#define ERTS_UNSET_GOT_SIGUSR1 (erts_got_sigusr1 = 0)
static volatile int have_prepared_crash_dump;
#define ERTS_PREPARED_CRASH_DUMP \
(have_prepared_crash_dump++)
@@ -430,11 +421,9 @@ erts_sys_pre_init(void)
#ifdef ERTS_SMP
erts_smp_atomic32_init_nob(&erts_break_requested, 0);
- erts_smp_atomic32_init_nob(&erts_got_sigusr1, 0);
erts_smp_atomic32_init_nob(&have_prepared_crash_dump, 0);
#else
erts_break_requested = 0;
- erts_got_sigusr1 = 0;
have_prepared_crash_dump = 0;
#endif
@@ -692,29 +681,6 @@ static RETSIGTYPE request_stop(int signum)
#endif
}
-
-static ERTS_INLINE void
-sigusr1_exit(void)
-{
- char env[21]; /* enough to hold any 64-bit integer */
- size_t envsz;
- int i, secs = -1;
-
- /* We do this at interrupt level, since the main reason for
- * wanting to generate a crash dump in this way is that the emulator
- * is hung somewhere, so it won't be able to poll any flag we set here.
- */
- ERTS_SET_GOT_SIGUSR1;
-
- envsz = sizeof(env);
- if ((i = erts_sys_getenv_raw("ERL_CRASH_DUMP_SECONDS", env, &envsz)) >= 0) {
- secs = i != 0 ? 0 : atoi(env);
- }
-
- prepare_crash_dump(secs);
- erts_exit(ERTS_DUMP_EXIT, "Received SIGUSR1\n");
-}
-
#ifdef ETHR_UNUSABLE_SIGUSRX
#warning "Unusable SIGUSR1 & SIGUSR2. Disabling use of these signals"
@@ -744,7 +710,7 @@ static RETSIGTYPE user_signal1(int signum)
#ifdef ERTS_SMP
smp_sig_notify('1');
#else
- sigusr1_exit();
+ signal_notify_requested(am_sigusr1);
#endif
}
@@ -1313,15 +1279,15 @@ signal_dispatcher_thread_func(void *unused)
case 'T': /* SIGTERM */
signal_notify_requested(am_sigterm);
break;
+ case '1': /* SIGUSR1 */
+ signal_notify_requested(am_sigusr1);
+ break;
case 'I': /* SIGINT */
break_requested();
break;
case 'Q': /* SIGQUIT */
quit_requested();
break;
- case '1': /* SIGUSR1 */
- sigusr1_exit();
- break;
default:
erts_exit(ERTS_ABORT_EXIT,
"signal-dispatcher thread received unknown "
--
cgit v1.2.3
From eaecd838ebc3410efcbe0f3b1717543d6a4650b0 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Thu, 19 Jan 2017 17:24:14 +0100
Subject: Fix unused warning
---
erts/emulator/beam/erl_process.c | 2 ++
1 file changed, 2 insertions(+)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index f80ebdf31b..641a8fb3e8 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -127,11 +127,13 @@ runq_got_work_to_execute_flags(Uint32 flags)
return !ERTS_IS_RUNQ_EMPTY_FLGS(flags);
}
+#ifdef ERTS_SMP
static ERTS_INLINE int
runq_got_work_to_execute(ErtsRunQueue *rq)
{
return runq_got_work_to_execute_flags(ERTS_RUNQ_FLGS_GET_NOB(rq));
}
+#endif
#undef RUNQ_READ_RQ
#undef RUNQ_SET_RQ
--
cgit v1.2.3
From 1623d7a85908221a118356bec64693901405659d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 20 Jan 2017 16:28:42 +0100
Subject: erts: Fix thread suspend in crashdump
* move signal handler setup
---
erts/emulator/beam/break.c | 2 ++
erts/emulator/beam/erl_init.c | 1 -
erts/emulator/beam/sys.h | 3 +++
erts/emulator/sys/unix/sys.c | 3 +--
4 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index dfbe1ced47..61907cc7ff 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -717,6 +717,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
* We have to be very very careful when doing this as the schedulers
* could be anywhere.
*/
+ sys_init_suspend_handler();
+
for (i = 0; i < erts_no_schedulers; i++) {
erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid;
if (!erts_equal_tids(tid,erts_thr_self()))
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 2fd97208cc..070cc3f2d0 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -2220,7 +2220,6 @@ erl_start(int argc, char **argv)
init_break_handler();
if (replace_intr)
erts_replace_intr();
- sys_init_suspend_handler();
#endif
boot_argc = argc - i; /* Number of arguments to init */
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index 7740dd4373..41a7ff4c16 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -859,9 +859,12 @@ int erts_sys_unsetenv(char *key);
char *erts_read_env(char *key);
void erts_free_read_env(void *value);
+#if defined(ERTS_SMP)
#if defined(ERTS_THR_HAVE_SIG_FUNCS) && !defined(ETHR_UNUSABLE_SIGUSRX)
extern void sys_thr_resume(erts_tid_t tid);
extern void sys_thr_suspend(erts_tid_t tid);
+#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
+#endif
#endif
/* utils.c */
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 2fc802a2c6..e135dbff99 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -119,9 +119,8 @@ erts_smp_atomic_t sys_misc_mem_sz;
static void smp_sig_notify(char c);
static int sig_notify_fds[2] = {-1, -1};
-#if !defined(ETHR_UNUSABLE_SIGUSRX) && defined(ERTS_THR_HAVE_SIG_FUNCS)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
static int sig_suspend_fds[2] = {-1, -1};
-#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
#endif
#endif
--
cgit v1.2.3
From e27119948fc6ab28bea81019720bddaac5b655a7 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Mon, 23 Jan 2017 15:13:19 +0100
Subject: erts: Fix binary_to_term for compressed and zlib >= v1.2.9
Problem: z_stream was incorrectly copied with memcpy
which just happened to work with zlib < v1.2.9.
Solution: Avoid copying z_stream.
---
erts/emulator/beam/external.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 656de7c49a..4491d48683 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1193,6 +1193,7 @@ typedef struct B2TContext_t {
} u;
} B2TContext;
+static B2TContext* b2t_export_context(Process*, B2TContext* src);
static uLongf binary2term_uncomp_size(byte* data, Sint size)
{
@@ -1225,7 +1226,7 @@ static uLongf binary2term_uncomp_size(byte* data, Sint size)
static ERTS_INLINE int
binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size,
- B2TContext* ctx)
+ B2TContext** ctxp, Process* p)
{
byte *bytes = data;
Sint size = data_size;
@@ -1239,8 +1240,8 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size,
size--;
if (size < 5 || *bytes != COMPRESSED) {
state->extp = bytes;
- if (ctx)
- ctx->state = B2TSizeInit;
+ if (ctxp)
+ (*ctxp)->state = B2TSizeInit;
}
else {
uLongf dest_len = (Uint32) get_int32(bytes+1);
@@ -1257,16 +1258,26 @@ binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size,
return -1;
}
state->extp = erts_alloc(ERTS_ALC_T_EXT_TERM_DATA, dest_len);
- ctx->reds -= dest_len;
+ if (ctxp)
+ (*ctxp)->reds -= dest_len;
}
state->exttmp = 1;
- if (ctx) {
+ if (ctxp) {
+ /*
+ * Start decompression by exporting trap context
+ * so we don't have to deal with deep-copying z_stream.
+ */
+ B2TContext* ctx = b2t_export_context(p, *ctxp);
+ ASSERT(state = &(*ctxp)->b2ts);
+ state = &ctx->b2ts;
+
if (erl_zlib_inflate_start(&ctx->u.uc.stream, bytes, size) != Z_OK)
return -1;
ctx->u.uc.dbytes = state->extp;
ctx->u.uc.dleft = dest_len;
ctx->state = B2TUncompressChunk;
+ *ctxp = ctx;
}
else {
uLongf dlen = dest_len;
@@ -1308,7 +1319,7 @@ erts_binary2term_prepare(ErtsBinary2TermState *state, byte *data, Sint data_size
{
Sint res;
- if (binary2term_prepare(state, data, data_size, NULL) < 0 ||
+ if (binary2term_prepare(state, data, data_size, NULL, NULL) < 0 ||
(res=decoded_size(state->extp, state->extp + state->extsize, 0, NULL)) < 0) {
if (state->exttmp)
@@ -1435,7 +1446,7 @@ static Eterm binary_to_term_int(Process* p, Uint32 flags, Eterm bin, Binary* con
if (ctx->aligned_alloc) {
ctx->reds -= bin_size / 8;
}
- if (binary2term_prepare(&ctx->b2ts, bytes, bin_size, ctx) < 0) {
+ if (binary2term_prepare(&ctx->b2ts, bytes, bin_size, &ctx, p) < 0) {
ctx->state = B2TBadArg;
}
break;
--
cgit v1.2.3
From c5d9b970fb5b3a7143ec8bb2e8194514b5b04e25 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 1 Aug 2016 14:35:04 +0200
Subject: erts: Remove broken hash from Erlang
erlang:hash/2 has been deprecated for a while, time to remove it.
---
erts/emulator/beam/bif.c | 19 ---
erts/emulator/beam/bif.tab | 6 -
erts/emulator/beam/erl_utils.h | 1 -
erts/emulator/beam/utils.c | 264 +----------------------------------------
erts/preloaded/src/erlang.erl | 11 +-
5 files changed, 7 insertions(+), 294 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 65c370c55b..a3acf87000 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4723,25 +4723,6 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2)
/**********************************************************************/
-BIF_RETTYPE hash_2(BIF_ALIST_2)
-{
- Uint32 hash;
- Sint range;
-
- if (is_not_small(BIF_ARG_2)) {
- BIF_ERROR(BIF_P, BADARG);
- }
- if ((range = signed_val(BIF_ARG_2)) <= 0) { /* [1..MAX_SMALL] */
- BIF_ERROR(BIF_P, BADARG);
- }
-#if defined(ARCH_64)
- if (range > ((1L << 27) - 1))
- BIF_ERROR(BIF_P, BADARG);
-#endif
- hash = make_broken_hash(BIF_ARG_1);
- BIF_RET(make_small(1 + (hash % range))); /* [1..range] */
-}
-
BIF_RETTYPE phash_2(BIF_ALIST_2)
{
Uint32 hash;
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 47fdcfa7a4..476c4b9632 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -670,9 +670,3 @@ gcbif erlang:ceil/1
bif math:floor/1
bif math:ceil/1
bif math:fmod/2
-
-#
-# Obsolete
-#
-
-bif erlang:hash/2
diff --git a/erts/emulator/beam/erl_utils.h b/erts/emulator/beam/erl_utils.h
index 81800752f0..47289a0af1 100644
--- a/erts/emulator/beam/erl_utils.h
+++ b/erts/emulator/beam/erl_utils.h
@@ -117,7 +117,6 @@ int erts_fit_in_bits_int32(Sint32);
int erts_fit_in_bits_uint(Uint);
Sint erts_list_length(Eterm);
int erts_is_builtin(Eterm, Eterm, int);
-Uint32 make_broken_hash(Eterm);
Uint32 block_hash(byte *, unsigned, Uint32);
Uint32 make_hash2(Eterm);
Uint32 make_hash(Eterm);
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 3fa48da1ec..74a0681dd5 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -700,12 +700,7 @@ erts_bld_atom_2uint_3tup_list(Uint **hpp, Uint *szp, Sint length,
/* make a hash index from an erlang term */
/*
-** There are three hash functions.
-** make_broken_hash: the one used for backward compatibility
-** is called from the bif erlang:hash/2. Should never be used
-** as it a) hashes only a part of binaries, b) hashes bignums really poorly,
-** c) hashes bignums differently on different endian processors and d) hashes
-** small integers with different weights on different bytes.
+** There are two hash functions.
**
** make_hash: A hash function that will give the same values for the same
** terms regardless of the internal representation. Small integers are
@@ -1045,6 +1040,10 @@ tail_recur:
DESTROY_WSTACK(stack);
return hash;
+#undef MAKE_HASH_TUPLE_OP
+#undef MAKE_HASH_TERM_ARRAY_OP
+#undef MAKE_HASH_CDR_PRE_OP
+#undef MAKE_HASH_CDR_POST_OP
#undef UINT32_HASH_STEP
#undef UINT32_HASH_RET
}
@@ -1954,259 +1953,6 @@ make_internal_hash(Eterm term)
#undef HCONST
#undef MIX
-
-Uint32 make_broken_hash(Eterm term)
-{
- Uint32 hash = 0;
- DECLARE_WSTACK(stack);
- unsigned op;
-tail_recur:
- op = tag_val_def(term);
- for (;;) {
- switch (op) {
- case NIL_DEF:
- hash = hash*FUNNY_NUMBER3 + 1;
- break;
- case ATOM_DEF:
- hash = hash*FUNNY_NUMBER1 +
- (atom_tab(atom_val(term))->slot.bucket.hvalue);
- break;
- case SMALL_DEF:
-#if defined(ARCH_64)
- {
- Sint y1 = signed_val(term);
- Uint y2 = y1 < 0 ? -(Uint)y1 : y1;
- Uint32 y3 = (Uint32) (y2 >> 32);
- int arity = 1;
-
-#if defined(WORDS_BIGENDIAN)
- if (!IS_SSMALL28(y1))
- { /* like a bignum */
- Uint32 y4 = (Uint32) y2;
- hash = hash*FUNNY_NUMBER2 + ((y4 << 16) | (y4 >> 16));
- if (y3) {
- hash = hash*FUNNY_NUMBER2 + ((y3 << 16) | (y3 >> 16));
- arity++;
- }
- hash = hash * (y1 < 0 ? FUNNY_NUMBER3 : FUNNY_NUMBER2) + arity;
- } else {
- hash = hash*FUNNY_NUMBER2 + (((Uint) y1) & 0xfffffff);
- }
-#else
- if (!IS_SSMALL28(y1))
- { /* like a bignum */
- hash = hash*FUNNY_NUMBER2 + ((Uint32) y2);
- if (y3)
- {
- hash = hash*FUNNY_NUMBER2 + y3;
- arity++;
- }
- hash = hash * (y1 < 0 ? FUNNY_NUMBER3 : FUNNY_NUMBER2) + arity;
- } else {
- hash = hash*FUNNY_NUMBER2 + (((Uint) y1) & 0xfffffff);
- }
-#endif
- }
-#else
- hash = hash*FUNNY_NUMBER2 + unsigned_val(term);
-#endif
- break;
-
- case BINARY_DEF:
- {
- size_t sz = binary_size(term);
- size_t i = (sz < 15) ? sz : 15;
-
- hash = hash_binary_bytes(term, i, hash);
- hash = hash*FUNNY_NUMBER4 + sz;
- break;
- }
-
- case EXPORT_DEF:
- {
- Export* ep = *((Export **) (export_val(term) + 1));
-
- hash = hash * FUNNY_NUMBER11 + ep->info.mfa.arity;
- hash = hash*FUNNY_NUMBER1 +
- (atom_tab(atom_val(ep->info.mfa.module))->slot.bucket.hvalue);
- hash = hash*FUNNY_NUMBER1 +
- (atom_tab(atom_val(ep->info.mfa.function))->slot.bucket.hvalue);
- break;
- }
-
- case FUN_DEF:
- {
- ErlFunThing* funp = (ErlFunThing *) fun_val(term);
- Uint num_free = funp->num_free;
-
- hash = hash * FUNNY_NUMBER10 + num_free;
- hash = hash*FUNNY_NUMBER1 +
- (atom_tab(atom_val(funp->fe->module))->slot.bucket.hvalue);
- hash = hash*FUNNY_NUMBER2 + funp->fe->old_index;
- hash = hash*FUNNY_NUMBER2 + funp->fe->old_uniq;
- if (num_free > 0) {
- if (num_free > 1) {
- WSTACK_PUSH3(stack, (UWord) &funp->env[1], (num_free-1), MAKE_HASH_TERM_ARRAY_OP);
- }
- term = funp->env[0];
- goto tail_recur;
- }
- break;
- }
-
- case PID_DEF:
- hash = hash*FUNNY_NUMBER5 + internal_pid_number(term);
- break;
- case EXTERNAL_PID_DEF:
- hash = hash*FUNNY_NUMBER5 + external_pid_number(term);
- break;
- case PORT_DEF:
- hash = hash*FUNNY_NUMBER9 + internal_port_number(term);
- break;
- case EXTERNAL_PORT_DEF:
- hash = hash*FUNNY_NUMBER9 + external_port_number(term);
- break;
- case REF_DEF:
- hash = hash*FUNNY_NUMBER9 + internal_ref_numbers(term)[0];
- break;
- case EXTERNAL_REF_DEF:
- hash = hash*FUNNY_NUMBER9 + external_ref_numbers(term)[0];
- break;
- case FLOAT_DEF:
- {
- FloatDef ff;
- GET_DOUBLE(term, ff);
- if (ff.fd == 0.0f) {
- /* ensure positive 0.0 */
- ff.fd = erts_get_positive_zero_float();
- }
- hash = hash*FUNNY_NUMBER6 + (ff.fw[0] ^ ff.fw[1]);
- }
- break;
- case MAKE_HASH_CDR_PRE_OP:
- term = (Eterm) WSTACK_POP(stack);
- if (is_not_list(term)) {
- WSTACK_PUSH(stack, (UWord) MAKE_HASH_CDR_POST_OP);
- goto tail_recur;
- }
- /*fall through*/
- case LIST_DEF:
- {
- Eterm* list = list_val(term);
- WSTACK_PUSH2(stack, (UWord) CDR(list),
- (UWord) MAKE_HASH_CDR_PRE_OP);
- term = CAR(list);
- goto tail_recur;
- }
-
- case MAKE_HASH_CDR_POST_OP:
- hash *= FUNNY_NUMBER8;
- break;
-
- case BIG_DEF:
- {
- Eterm* ptr = big_val(term);
- int is_neg = BIG_SIGN(ptr);
- Uint arity = BIG_ARITY(ptr);
- Uint i = arity;
- ptr++;
-#if D_EXP == 16
- /* hash over 32 bit LE */
-
- while(i--) {
- hash = hash*FUNNY_NUMBER2 + *ptr++;
- }
-#elif D_EXP == 32
-
-#if defined(WORDS_BIGENDIAN)
- while(i--) {
- Uint d = *ptr++;
- hash = hash*FUNNY_NUMBER2 + ((d << 16) | (d >> 16));
- }
-#else
- while(i--) {
- hash = hash*FUNNY_NUMBER2 + *ptr++;
- }
-#endif
-
-#elif D_EXP == 64
- {
- Uint32 h = 0, l;
-#if defined(WORDS_BIGENDIAN)
- while(i--) {
- Uint d = *ptr++;
- l = d & 0xffffffff;
- h = d >> 32;
- hash = hash*FUNNY_NUMBER2 + ((l << 16) | (l >> 16));
- if (h || i)
- hash = hash*FUNNY_NUMBER2 + ((h << 16) | (h >> 16));
- }
-#else
- while(i--) {
- Uint d = *ptr++;
- l = d & 0xffffffff;
- h = d >> 32;
- hash = hash*FUNNY_NUMBER2 + l;
- if (h || i)
- hash = hash*FUNNY_NUMBER2 + h;
- }
-#endif
- /* adjust arity to match 32 bit mode */
- arity = (arity << 1) - (h == 0);
- }
-
-#else
-#error "unsupported D_EXP size"
-#endif
- hash = hash * (is_neg ? FUNNY_NUMBER3 : FUNNY_NUMBER2) + arity;
- }
- break;
-
- case MAP_DEF:
- hash = hash*FUNNY_NUMBER13 + FUNNY_NUMBER14 + make_hash2(term);
- break;
- case TUPLE_DEF:
- {
- Eterm* ptr = tuple_val(term);
- Uint arity = arityval(*ptr);
-
- WSTACK_PUSH3(stack, (UWord) arity, (UWord) (ptr+1), (UWord) arity);
- op = MAKE_HASH_TUPLE_OP;
- }/*fall through*/
- case MAKE_HASH_TUPLE_OP:
- case MAKE_HASH_TERM_ARRAY_OP:
- {
- Uint i = (Uint) WSTACK_POP(stack);
- Eterm* ptr = (Eterm*) WSTACK_POP(stack);
- if (i != 0) {
- term = *ptr;
- WSTACK_PUSH3(stack, (UWord)(ptr+1), (UWord) i-1, (UWord) op);
- goto tail_recur;
- }
- if (op == MAKE_HASH_TUPLE_OP) {
- Uint32 arity = (UWord) WSTACK_POP(stack);
- hash = hash*FUNNY_NUMBER9 + arity;
- }
- break;
- }
-
- default:
- erts_exit(ERTS_ERROR_EXIT, "Invalid tag in make_broken_hash\n");
- return 0;
- }
- if (WSTACK_ISEMPTY(stack)) break;
- op = (Uint) WSTACK_POP(stack);
- }
-
- DESTROY_WSTACK(stack);
- return hash;
-
-#undef MAKE_HASH_TUPLE_OP
-#undef MAKE_HASH_TERM_ARRAY_OP
-#undef MAKE_HASH_CDR_PRE_OP
-#undef MAKE_HASH_CDR_POST_OP
-}
-
static Eterm
do_allocate_logger_message(Eterm gleader, Eterm **hp, ErlOffHeap **ohp,
ErlHeapFragment **bp, Process **p, Uint sz)
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 86ebb4dd4b..be7ceb928b 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -48,7 +48,7 @@
await_sched_wall_time_modifications/2,
gather_gc_info_result/1]).
--deprecated([hash/2, now/0]).
+-deprecated([now/0]).
%% Get rid of autoimports of spawn to avoid clashes with ourselves.
-compile({no_auto_import,[spawn_link/1]}).
@@ -116,7 +116,7 @@
-export([garbage_collect_message_area/0, get/0, get/1, get_keys/0, get_keys/1]).
-export([get_module_info/1, get_stacktrace/0, group_leader/0]).
-export([group_leader/2]).
--export([halt/0, halt/1, halt/2, hash/2,
+-export([halt/0, halt/1, halt/2,
has_prepared_code_on_load/1, hibernate/3]).
-export([insert_element/3]).
-export([integer_to_binary/1, integer_to_list/1]).
@@ -1028,13 +1028,6 @@ halt(Status) ->
halt(_Status, _Options) ->
erlang:nif_error(undefined).
-%% hash/2
--spec erlang:hash(Term, Range) -> pos_integer() when
- Term :: term(),
- Range :: pos_integer().
-hash(_Term, _Range) ->
- erlang:nif_error(undefined).
-
%% has_prepared_code_on_load/1
-spec erlang:has_prepared_code_on_load(PreparedCode) -> boolean() when
PreparedCode :: binary().
--
cgit v1.2.3
From a198f78edcae91366cbd75df7539116ccb85adec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 1 Aug 2016 14:39:33 +0200
Subject: erts: Remove erlang:hash/2 from documentation
---
erts/doc/src/erlang.xml | 23 -----------------------
1 file changed, 23 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 7815bfa510..2859f22bf4 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -1954,26 +1954,6 @@ os_prompt%
-
-
- Hash function (deprecated).
-
-
Returns a hash value for Term within the range
- 1..Range. The maximum range is 1..2^27-1.
-
-
This BIF is deprecated, as the hash value can differ on
- different architectures. The hash values for integer
- terms > 2^27 and large binaries are
- poor. The BIF is retained for backward compatibility
- reasons (it can have been used to hash records into a file),
- but all new code is to use one of the BIFs
- erlang:phash/2 or
- erlang:phash2/1,2
- instead.
-
-
-
-
Head of a list.
@@ -3818,9 +3798,6 @@ RealSystem = system + MissedSystem
Term within the range
1..Range. The maximum value for
Range is 2^32.
-
This BIF can be used instead of the old deprecated BIF
- erlang:hash/2, as it calculates better hashes for
- all data types, but consider using phash2/1,2 instead.
Returns a string corresponding to the text
representation of Pid.
-
-
This BIF is intended for debugging and is not to be used
- in application programs.
-
@@ -4408,10 +4404,6 @@ RealSystem = system + MissedSystem
Returns a string corresponding to the text
representation of the port identifier Port.
-
-
This BIF is intended for debugging. It is not to be used
- in application programs.
-
--
cgit v1.2.3
From 26b59dfe67ef551cd94765557cdd8c79794bcc38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Valim?=
Date: Tue, 31 May 2016 14:28:54 +0200
Subject: Add new AtU8 beam chunk
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The new chunk stores atoms encoded in UTF-8.
beam_lib has also been modified to handle the new
'utf8_atoms' attribute while the 'atoms' attribute
may be a missing chunk from now on.
The binary_to_atom/2 BIF can now encode any utf8
binary with up to 255 characters.
The list_to_atom/1 BIF can now accept codepoints
higher than 255 with up to 255 characters (thanks
to Björn Gustavsson).
---
erts/doc/src/erl_ext_dist.xml | 15 +++----
erts/doc/src/erlang.xml | 35 ++++++-----------
erts/emulator/beam/atom.c | 35 +++++++++++------
erts/emulator/beam/atom.h | 3 ++
erts/emulator/beam/beam_load.c | 66 ++++++++++++++++++++++---------
erts/emulator/beam/bif.c | 14 +++----
erts/emulator/beam/erl_unicode.c | 83 ++++++++++++++++-----------------------
erts/emulator/beam/global.h | 1 +
erts/emulator/beam/utils.c | 62 +++++++++++++++++++++++++++++
erts/emulator/test/bif_SUITE.erl | 47 +++++++++++++++++++---
erts/emulator/test/code_SUITE.erl | 10 ++---
11 files changed, 242 insertions(+), 129 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erl_ext_dist.xml b/erts/doc/src/erl_ext_dist.xml
index 4f799f8f34..a436a9ca74 100644
--- a/erts/doc/src/erl_ext_dist.xml
+++ b/erts/doc/src/erl_ext_dist.xml
@@ -119,16 +119,11 @@
Compressed Data Format when Expanded
-
As from ERTS 5.10 (OTP R16) support
- for UTF-8 encoded atoms has been introduced in the external format.
- However, only characters that can be encoded using Latin-1 (ISO-8859-1)
- are currently supported in atoms. The support for UTF-8 encoded atoms
- in the external format has been implemented to be able to support
- all Unicode characters in atoms in some future release.
- Until full Unicode support for atoms has been introduced,
- it is an error to pass atoms containing
- characters that cannot be encoded in Latin-1, and the behavior is
- undefined.
+
As from ERTS 9.0 (OTP 20), UTF-8 encoded atoms may contain any Unicode
+ character. Although the support for UTF-8 encoded atoms in the external
+ format is available since ERTS 5.10 (OTP R16), passing atoms that cannot
+ be encoded in Latin-1 is an error in versions earlier than
+ Erlang/OTP 20, and the behavior is undefined.
When distribution flag DFLAG_UTF8_ATOMS has been exchanged between both nodes
in the
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index b3fab3874b..cf038c49f0 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -325,16 +325,11 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
is latin1, one byte exists for each character
in the text representation. If Encoding is
utf8 or
- unicode, the characters are encoded using UTF-8
- (that is, characters from 128 through 255 are
- encoded in two bytes).
+ unicode, the characters are encoded using UTF-8 where
+ characters may require multiple bytes.
-
atom_to_binary(Atom, latin1) never
- fails, as the text representation of an atom can only
- contain characters from 0 through 255. In a future release,
- the text representation
- of atoms can be allowed to contain any Unicode character and
- atom_to_binary(Atom, latin1) then fails if the
+
As from Erlang/OTP 20, atoms can contain any Unicode character
+ and atom_to_binary(Atom, latin1) may fail if the
text representation for Atom contains a Unicode
character > 255.
@@ -402,13 +397,11 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
translation of bytes in the binary is done.
If Encoding
is utf8 or unicode, the binary must contain
- valid UTF-8 sequences. Only Unicode characters up
- to 255 are allowed.
+ valid UTF-8 sequences.
-
binary_to_atom(Binary, utf8) fails if
- the binary contains Unicode characters > 255.
- In a future release, such Unicode characters can be allowed and
- binary_to_atom(Binary, utf8) does then not fail.
+
As from Erlang/OTP 20, binary_to_atom(Binary, utf8)
+ is capable of encoding any Unicode character. Earlier versions would
+ fail if the binary contained Unicode characters > 255.
For more information about Unicode support in atoms, see the
note on UTF-8
encoded atoms
@@ -419,9 +412,7 @@ Z = erlang:adler32_combine(X,Y,iolist_size(Data2)).
> binary_to_atom(<<"Erlang">>, latin1).
'Erlang'
> binary_to_atom(<<1024/utf8>>, utf8).
-** exception error: bad argument
- in function binary_to_atom/2
- called as binary_to_atom(<<208,128>>,utf8)
+'Ѐ'
@@ -2401,10 +2392,10 @@ os_prompt%
Returns the atom whose text representation is
String.
-
String can only contain ISO-latin-1
- characters (that is, numbers < 256) as the implementation does not
- allow Unicode characters equal to or above 256 in atoms.
- For more information on Unicode support in atoms, see
+
As from Erlang/OTP 20, String may contain
+ any Unicode character. Earlier versions allowed only ISO-latin-1
+ characters as the implementation did not allow Unicode characters
+ above 255. For more information on Unicode support in atoms, see
note on UTF-8
encoded atoms
in section "External Term Format" in the User's Guide.
diff --git a/erts/emulator/beam/atom.c b/erts/emulator/beam/atom.c
index 2b5ad097a0..2055c29190 100644
--- a/erts/emulator/beam/atom.c
+++ b/erts/emulator/beam/atom.c
@@ -233,10 +233,10 @@ need_convertion:
}
/*
- * erts_atom_put() may fail. If it fails THE_NON_VALUE is returned!
+ * erts_atom_put_index() may fail. Returns negative indexes for errors.
*/
-Eterm
-erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
+int
+erts_atom_put_index(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
{
byte utf8_copy[MAX_ATOM_SZ_FROM_LATIN1];
const byte *text = name;
@@ -253,7 +253,7 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
if (trunc)
tlen = 0;
else
- return THE_NON_VALUE;
+ return ATOM_MAX_CHARS_ERROR;
}
switch (enc) {
@@ -262,7 +262,7 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
if (trunc)
tlen = MAX_ATOM_CHARACTERS;
else
- return THE_NON_VALUE;
+ return ATOM_MAX_CHARS_ERROR;
}
#ifdef DEBUG
for (aix = 0; aix < len; aix++) {
@@ -276,7 +276,7 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
if (trunc)
tlen = MAX_ATOM_CHARACTERS;
else
- return THE_NON_VALUE;
+ return ATOM_MAX_CHARS_ERROR;
}
no_latin1_chars = tlen;
latin1_to_utf8(utf8_copy, &text, &tlen);
@@ -284,7 +284,7 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
case ERTS_ATOM_ENC_UTF8:
/* First sanity check; need to verify later */
if (tlen > MAX_ATOM_SZ_LIMIT && !trunc)
- return THE_NON_VALUE;
+ return ATOM_MAX_CHARS_ERROR;
break;
}
@@ -295,7 +295,7 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
atom_read_unlock();
if (aix >= 0) {
/* Already in table no need to verify it */
- return make_atom(aix);
+ return aix;
}
if (enc == ERTS_ATOM_ENC_UTF8) {
@@ -314,13 +314,13 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
case ERTS_UTF8_OK_MAX_CHARS:
/* Truncated... */
if (!trunc)
- return THE_NON_VALUE;
+ return ATOM_MAX_CHARS_ERROR;
ASSERT(no_chars == MAX_ATOM_CHARACTERS);
tlen = err_pos - text;
break;
default:
/* Bad utf8... */
- return THE_NON_VALUE;
+ return ATOM_BAD_ENCODING_ERROR;
}
}
@@ -333,7 +333,20 @@ erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
atom_write_lock();
aix = index_put(&erts_atom_table, (void*) &a);
atom_write_unlock();
- return make_atom(aix);
+ return aix;
+}
+
+/*
+ * erts_atom_put() may fail. If it fails THE_NON_VALUE is returned!
+ */
+Eterm
+erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc)
+{
+ int aix = erts_atom_put_index(name, len, enc, trunc);
+ if (aix >= 0)
+ return make_atom(aix);
+ else
+ return THE_NON_VALUE;
}
Eterm
diff --git a/erts/emulator/beam/atom.h b/erts/emulator/beam/atom.h
index abd3b44993..be998a46bd 100644
--- a/erts/emulator/beam/atom.h
+++ b/erts/emulator/beam/atom.h
@@ -29,6 +29,8 @@
#define MAX_ATOM_SZ_LIMIT (4*MAX_ATOM_CHARACTERS) /* theoretical byte limit */
#define ATOM_LIMIT (1024*1024)
#define MIN_ATOM_TABLE_SIZE 8192
+#define ATOM_BAD_ENCODING_ERROR -1
+#define ATOM_MAX_CHARS_ERROR -2
#ifndef ARCH_32
/* Internal atom cache needs MAX_ATOM_TABLE_SIZE to be less than an
@@ -133,6 +135,7 @@ int atom_table_sz(void); /* table size in bytes, excluding stored objects */
Eterm am_atom_put(const char*, int); /* ONLY 7-bit ascii! */
Eterm erts_atom_put(const byte *name, int len, ErtsAtomEncoding enc, int trunc);
+int erts_atom_put_index(const byte *name, int len, ErtsAtomEncoding enc, int trunc);
void init_atom_table(void);
void atom_info(fmtfn_t, void *);
void dump_atoms(fmtfn_t, void *);
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 8f1faa6719..1899ffb079 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -157,13 +157,15 @@ typedef struct {
#define STR_CHUNK 2
#define IMP_CHUNK 3
#define EXP_CHUNK 4
-#define NUM_MANDATORY 5
+#define MIN_MANDATORY 1
+#define MAX_MANDATORY 5
#define LAMBDA_CHUNK 5
#define LITERAL_CHUNK 6
#define ATTR_CHUNK 7
#define COMPILE_CHUNK 8
#define LINE_CHUNK 9
+#define UTF8_ATOM_CHUNK 10
#define NUM_CHUNK_TYPES (sizeof(chunk_types)/sizeof(chunk_types[0]))
@@ -173,9 +175,13 @@ typedef struct {
static Uint chunk_types[] = {
/*
- * Mandatory chunk types -- these MUST be present.
+ * Atom chunk types -- Atom or AtU8 MUST be present.
*/
MakeIffId('A', 't', 'o', 'm'), /* 0 */
+
+ /*
+ * Mandatory chunk types -- these MUST be present.
+ */
MakeIffId('C', 'o', 'd', 'e'), /* 1 */
MakeIffId('S', 't', 'r', 'T'), /* 2 */
MakeIffId('I', 'm', 'p', 'T'), /* 3 */
@@ -189,6 +195,7 @@ static Uint chunk_types[] = {
MakeIffId('A', 't', 't', 'r'), /* 7 */
MakeIffId('C', 'I', 'n', 'f'), /* 8 */
MakeIffId('L', 'i', 'n', 'e'), /* 9 */
+ MakeIffId('A', 't', 'U', '8'), /* 10 */
};
/*
@@ -490,9 +497,9 @@ static Eterm stub_insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
#endif
static int init_iff_file(LoaderState* stp, byte* code, Uint size);
static int scan_iff_file(LoaderState* stp, Uint* chunk_types,
- Uint num_types, Uint num_mandatory);
+ Uint num_types);
static int verify_chunks(LoaderState* stp);
-static int load_atom_table(LoaderState* stp);
+static int load_atom_table(LoaderState* stp, ErtsAtomEncoding enc);
static int load_import_table(LoaderState* stp);
static int read_export_table(LoaderState* stp);
static int is_bif(Eterm mod, Eterm func, unsigned arity);
@@ -629,7 +636,7 @@ erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader,
CHKALLOC();
CHKBLK(ERTS_ALC_T_CODE,stp->code);
if (!init_iff_file(stp, code, unloaded_size) ||
- !scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES, NUM_MANDATORY) ||
+ !scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES) ||
!verify_chunks(stp)) {
goto load_error;
}
@@ -674,9 +681,16 @@ erts_prepare_loading(Binary* magic, Process *c_p, Eterm group_leader,
*/
CHKBLK(ERTS_ALC_T_CODE,stp->code);
- define_file(stp, "atom table", ATOM_CHUNK);
- if (!load_atom_table(stp)) {
- goto load_error;
+ if (stp->chunks[UTF8_ATOM_CHUNK].size > 0) {
+ define_file(stp, "utf8 atom table", UTF8_ATOM_CHUNK);
+ if (!load_atom_table(stp, ERTS_ATOM_ENC_UTF8)) {
+ goto load_error;
+ }
+ } else {
+ define_file(stp, "atom table", ATOM_CHUNK);
+ if (!load_atom_table(stp, ERTS_ATOM_ENC_LATIN1)) {
+ goto load_error;
+ }
}
/*
@@ -1212,7 +1226,7 @@ init_iff_file(LoaderState* stp, byte* code, Uint size)
* Scan the IFF file. The header should have been verified by init_iff_file().
*/
static int
-scan_iff_file(LoaderState* stp, Uint* chunk_types, Uint num_types, Uint num_mandatory)
+scan_iff_file(LoaderState* stp, Uint* chunk_types, Uint num_types)
{
Uint count;
Uint id;
@@ -1291,7 +1305,16 @@ verify_chunks(LoaderState* stp)
MD5_CTX context;
MD5Init(&context);
- for (i = 0; i < NUM_MANDATORY; i++) {
+
+ if (stp->chunks[UTF8_ATOM_CHUNK].start != NULL) {
+ MD5Update(&context, stp->chunks[UTF8_ATOM_CHUNK].start, stp->chunks[UTF8_ATOM_CHUNK].size);
+ } else if (stp->chunks[ATOM_CHUNK].start != NULL) {
+ MD5Update(&context, stp->chunks[ATOM_CHUNK].start, stp->chunks[ATOM_CHUNK].size);
+ } else {
+ LoadError0(stp, "mandatory chunk of type 'Atom' or 'AtU8' not found\n");
+ }
+
+ for (i = MIN_MANDATORY; i < MAX_MANDATORY; i++) {
if (stp->chunks[i].start != NULL) {
MD5Update(&context, stp->chunks[i].start, stp->chunks[i].size);
} else {
@@ -1352,7 +1375,7 @@ verify_chunks(LoaderState* stp)
}
static int
-load_atom_table(LoaderState* stp)
+load_atom_table(LoaderState* stp, ErtsAtomEncoding enc)
{
unsigned int i;
@@ -1371,7 +1394,7 @@ load_atom_table(LoaderState* stp)
GetByte(stp, n);
GetString(stp, atom, n);
- stp->atom[i] = erts_atom_put(atom, n, ERTS_ATOM_ENC_LATIN1, 1);
+ stp->atom[i] = erts_atom_put(atom, n, enc, 1);
}
/*
@@ -5937,7 +5960,7 @@ code_get_chunk_2(BIF_ALIST_2)
goto error;
}
if (!init_iff_file(stp, start, binary_size(Bin)) ||
- !scan_iff_file(stp, &chunk, 1, 1) ||
+ !scan_iff_file(stp, &chunk, 1) ||
stp->chunks[0].start == NULL) {
res = am_undefined;
goto done;
@@ -5986,7 +6009,7 @@ code_module_md5_1(BIF_ALIST_1)
}
stp->module = THE_NON_VALUE; /* Suppress diagnostiscs */
if (!init_iff_file(stp, bytes, binary_size(Bin)) ||
- !scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES, NUM_MANDATORY) ||
+ !scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES) ||
!verify_chunks(stp)) {
res = am_undefined;
goto done;
@@ -6335,7 +6358,7 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
if (!init_iff_file(stp, bytes, size)) {
goto error;
}
- if (!scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES, NUM_MANDATORY) ||
+ if (!scan_iff_file(stp, chunk_types, NUM_CHUNK_TYPES) ||
!verify_chunks(stp)) {
goto error;
}
@@ -6343,9 +6366,16 @@ erts_make_stub_module(Process* p, Eterm hipe_magic_bin, Eterm Beam, Eterm Info)
if (!read_code_header(stp)) {
goto error;
}
- define_file(stp, "atom table", ATOM_CHUNK);
- if (!load_atom_table(stp)) {
- goto error;
+ if (stp->chunks[UTF8_ATOM_CHUNK].size > 0) {
+ define_file(stp, "utf8 atom table", UTF8_ATOM_CHUNK);
+ if (!load_atom_table(stp, ERTS_ATOM_ENC_UTF8)) {
+ goto error;
+ }
+ } else {
+ define_file(stp, "atom table", ATOM_CHUNK);
+ if (!load_atom_table(stp, ERTS_ATOM_ENC_LATIN1)) {
+ goto error;
+ }
}
define_file(stp, "export table", EXP_CHUNK);
if (!stub_read_export_table(stp)) {
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index d886c2985e..95bf13c07c 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -3022,8 +3022,8 @@ BIF_RETTYPE atom_to_list_1(BIF_ALIST_1)
BIF_RETTYPE list_to_atom_1(BIF_ALIST_1)
{
Eterm res;
- char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_CHARACTERS);
- Sint i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS);
+ byte *buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_SZ_LIMIT);
+ Sint i = erts_unicode_list_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS);
if (i < 0) {
erts_free(ERTS_ALC_T_TMP, (void *) buf);
@@ -3033,7 +3033,7 @@ BIF_RETTYPE list_to_atom_1(BIF_ALIST_1)
}
BIF_ERROR(BIF_P, BADARG);
}
- res = erts_atom_put((byte *) buf, i, ERTS_ATOM_ENC_LATIN1, 1);
+ res = erts_atom_put(buf, i, ERTS_ATOM_ENC_UTF8, 1);
ASSERT(is_atom(res));
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_RET(res);
@@ -3043,17 +3043,17 @@ BIF_RETTYPE list_to_atom_1(BIF_ALIST_1)
BIF_RETTYPE list_to_existing_atom_1(BIF_ALIST_1)
{
- Sint i;
- char *buf = (char *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_CHARACTERS);
+ byte *buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, MAX_ATOM_SZ_LIMIT);
+ Sint i = erts_unicode_list_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS);
- if ((i = intlist_to_buf(BIF_ARG_1, buf, MAX_ATOM_CHARACTERS)) < 0) {
+ if (i < 0) {
error:
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_ERROR(BIF_P, BADARG);
} else {
Eterm a;
- if (erts_atom_get(buf, i, &a, ERTS_ATOM_ENC_LATIN1)) {
+ if (erts_atom_get((char *) buf, i, &a, ERTS_ATOM_ENC_UTF8)) {
erts_free(ERTS_ALC_T_TMP, (void *) buf);
BIF_RET(a);
} else {
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index bd5e1482fb..8919898181 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -1890,74 +1890,57 @@ binary_to_atom(Process* proc, Eterm bin, Eterm enc, int must_exist)
byte* bytes;
byte *temp_alloc = NULL;
Uint bin_size;
+ Eterm a;
if ((bytes = erts_get_aligned_binary_bytes(bin, &temp_alloc)) == 0) {
BIF_ERROR(proc, BADARG);
}
bin_size = binary_size(bin);
+
if (enc == am_latin1) {
- Eterm a;
- if (bin_size > MAX_ATOM_CHARACTERS) {
- system_limit:
- erts_free_aligned_binary_bytes(temp_alloc);
- BIF_ERROR(proc, SYSTEM_LIMIT);
- }
if (!must_exist) {
- a = erts_atom_put((byte *) bytes,
- bin_size,
- ERTS_ATOM_ENC_LATIN1,
- 0);
- erts_free_aligned_binary_bytes(temp_alloc);
- if (is_non_value(a))
- goto badarg;
- BIF_RET(a);
- } else if (erts_atom_get((char *)bytes, bin_size, &a, ERTS_ATOM_ENC_LATIN1)) {
- erts_free_aligned_binary_bytes(temp_alloc);
- BIF_RET(a);
- } else {
+ int lix = erts_atom_put_index((byte *) bytes,
+ bin_size,
+ ERTS_ATOM_ENC_LATIN1,
+ 0);
+ if (lix == ATOM_BAD_ENCODING_ERROR) {
+ badarg:
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_ERROR(proc, BADARG);
+ } else if (lix == ATOM_MAX_CHARS_ERROR) {
+ system_limit:
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_ERROR(proc, SYSTEM_LIMIT);
+ }
+
+ a = make_atom(lix);
+ } else if (!erts_atom_get((char *)bytes, bin_size, &a, ERTS_ATOM_ENC_LATIN1)) {
goto badarg;
}
- } else if (enc == am_utf8 || enc == am_unicode) {
- Eterm res;
- Uint num_chars = 0;
- const byte* p = bytes;
- Uint left = bin_size;
- while (left) {
- if (++num_chars > MAX_ATOM_CHARACTERS) {
+ } else if (enc == am_utf8 || enc == am_unicode) {
+ if (!must_exist) {
+ int uix = erts_atom_put_index((byte *) bytes,
+ bin_size,
+ ERTS_ATOM_ENC_UTF8,
+ 0);
+ if (uix == ATOM_BAD_ENCODING_ERROR) {
+ goto badarg;
+ } else if (uix == ATOM_MAX_CHARS_ERROR) {
goto system_limit;
}
- if ((p[0] & 0x80) == 0) {
- ++p;
- --left;
- }
- else if (left >= 2
- && (p[0] & 0xFE) == 0xC2 /* only allow latin1 subset */
- && (p[1] & 0xC0) == 0x80) {
- p += 2;
- left -= 2;
- }
- else goto badarg;
- }
- if (!must_exist) {
- res = erts_atom_put((byte *) bytes,
- bin_size,
- ERTS_ATOM_ENC_UTF8,
- 0);
+ a = make_atom(uix);
}
- else if (!erts_atom_get((char*)bytes, bin_size, &res, ERTS_ATOM_ENC_UTF8)) {
+ else if (!erts_atom_get((char*)bytes, bin_size, &a, ERTS_ATOM_ENC_UTF8)) {
goto badarg;
}
- erts_free_aligned_binary_bytes(temp_alloc);
- if (is_non_value(res))
- goto badarg;
- BIF_RET(res);
} else {
- badarg:
- erts_free_aligned_binary_bytes(temp_alloc);
- BIF_ERROR(proc, BADARG);
+ goto badarg;
}
+
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BIF_RET(a);
}
BIF_RETTYPE binary_to_atom_2(BIF_ALIST_2)
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 2b2f3c5cdc..9f2b43d216 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1373,6 +1373,7 @@ int erts_utf8_to_latin1(byte* dest, const byte* source, int slen);
void bin_write(fmtfn_t, void*, byte*, size_t);
Sint intlist_to_buf(Eterm, char*, Sint); /* most callers pass plain char*'s */
+Sint erts_unicode_list_to_buf(Eterm list, byte *buf, Sint len);
struct Sint_buf {
#if defined(ARCH_64)
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index ec502d5a78..36b818505c 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -3923,6 +3923,68 @@ intlist_to_buf(Eterm list, char *buf, Sint len)
return -2; /* not enough space */
}
+/* Fill buf with the contents of the unicode list.
+ * Return the number of bytes in the buffer,
+ * or -1 for type error,
+ * or -2 for not enough buffer space (buffer contains truncated result).
+ */
+Sint
+erts_unicode_list_to_buf(Eterm list, byte *buf, Sint len)
+{
+ Eterm* listptr;
+ Sint sz = 0;
+
+ if (is_nil(list)) {
+ return 0;
+ }
+ if (is_not_list(list)) {
+ return -1;
+ }
+ listptr = list_val(list);
+
+ while (len-- > 0) {
+ Sint val;
+
+ if (is_not_small(CAR(listptr))) {
+ return -1;
+ }
+ val = signed_val(CAR(listptr));
+ if (0 <= val && val < 0x80) {
+ buf[sz] = val;
+ sz++;
+ } else if (val < 0x800) {
+ buf[sz+0] = 0xC0 | (val >> 6);
+ buf[sz+1] = 0x80 | (val & 0x3F);
+ sz += 2;
+ } else if (val < 0x10000UL) {
+ if (0xD800 <= val && val <= 0xDFFF) {
+ return -1;
+ }
+ buf[sz+0] = 0xE0 | (val >> 12);
+ buf[sz+1] = 0x80 | ((val >> 6) & 0x3F);
+ buf[sz+2] = 0x80 | (val & 0x3F);
+ sz += 3;
+ } else if (val < 0x110000) {
+ buf[sz+0] = 0xF0 | (val >> 18);
+ buf[sz+1] = 0x80 | ((val >> 12) & 0x3F);
+ buf[sz+2] = 0x80 | ((val >> 6) & 0x3F);
+ buf[sz+3] = 0x80 | (val & 0x3F);
+ sz += 4;
+ } else {
+ return -1;
+ }
+ list = CDR(listptr);
+ if (is_nil(list)) {
+ return sz;
+ }
+ if (is_not_list(list)) {
+ return -1;
+ }
+ listptr = list_val(list);
+ }
+ return -2; /* not enough space */
+}
+
/*
** Convert an integer to a byte list
** return pointer to converted stuff (need not to be at start of buf!)
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index f70fb0e501..339c827602 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_SUITE.erl
@@ -26,7 +26,7 @@
-export([all/0, suite/0,
display/1, display_huge/0,
erl_bif_types/1,guard_bifs_in_erl_bif_types/1,
- shadow_comments/1,
+ shadow_comments/1,list_to_utf8_atom/1,
specs/1,improper_bif_stubs/1,auto_imports/1,
t_list_to_existing_atom/1,os_env/1,otp_7526/1,
binary_to_atom/1,binary_to_existing_atom/1,
@@ -43,7 +43,7 @@ all() ->
[erl_bif_types, guard_bifs_in_erl_bif_types, shadow_comments,
specs, improper_bif_stubs, auto_imports,
t_list_to_existing_atom, os_env, otp_7526,
- display,
+ display, list_to_utf8_atom,
atom_to_binary, binary_to_atom, binary_to_existing_atom,
erl_crash_dump_bytes, min_max, erlang_halt, is_builtin,
error_stacktrace, error_stacktrace_during_call_trace].
@@ -339,6 +339,38 @@ check_stub({_,F,A}, B) ->
ct:fail(invalid_body)
end.
+list_to_utf8_atom(Config) when is_list(Config) ->
+ 'hello' = atom_roundtrip("hello"),
+ 'こんにちは' = atom_roundtrip("こんにちは"),
+
+ %% Test all edge cases.
+ _ = atom_roundtrip([16#80]),
+ _ = atom_roundtrip([16#7F]),
+ _ = atom_roundtrip([16#FF]),
+ _ = atom_roundtrip([16#100]),
+ _ = atom_roundtrip([16#7FF]),
+ _ = atom_roundtrip([16#800]),
+ _ = atom_roundtrip([16#D7FF]),
+ atom_badarg([16#D800]),
+ atom_badarg([16#DFFF]),
+ _ = atom_roundtrip([16#E000]),
+ _ = atom_roundtrip([16#FFFF]),
+ _ = atom_roundtrip([16#1000]),
+ _ = atom_roundtrip([16#10FFFF]),
+ atom_badarg([16#110000]),
+ ok.
+
+atom_roundtrip(String) ->
+ Atom = list_to_atom(String),
+ Atom = list_to_existing_atom(String),
+ String = atom_to_list(Atom),
+ Atom.
+
+atom_badarg(String) ->
+ {'EXIT',{badarg,_}} = (catch list_to_atom(String)),
+ {'EXIT',{badarg,_}} = (catch list_to_existing_atom(String)),
+ ok.
+
t_list_to_existing_atom(Config) when is_list(Config) ->
all = list_to_existing_atom("all"),
?MODULE = list_to_existing_atom(?MODULE_STRING),
@@ -429,6 +461,8 @@ binary_to_atom(Config) when is_list(Config) ->
Long = lists:seq(0, 254),
LongAtom = list_to_atom(Long),
LongBin = list_to_binary(Long),
+ UnicodeLongAtom = list_to_atom([$é || _ <- lists:seq(0, 254)]),
+ UnicodeLongBin = << <<"é"/utf8>> || _ <- lists:seq(0, 254)>>,
%% latin1
'' = test_binary_to_atom(<<>>, latin1),
@@ -440,12 +474,17 @@ binary_to_atom(Config) when is_list(Config) ->
'' = test_binary_to_atom(<<>>, utf8),
HalfLongAtom = test_binary_to_atom(HalfLongBin, utf8),
HalfLongAtom = test_binary_to_atom(HalfLongBin, unicode),
+ UnicodeLongAtom = test_binary_to_atom(UnicodeLongBin, utf8),
+ UnicodeLongAtom = test_binary_to_atom(UnicodeLongBin, unicode),
[] = [C || C <- lists:seq(128, 255),
begin
list_to_atom([C]) =/=
test_binary_to_atom(<>, utf8)
end],
+ <<"こんにちは"/utf8>> =
+ atom_to_binary(test_binary_to_atom(<<"こんにちは"/utf8>>, utf8), utf8),
+
%% badarg failures.
fail_binary_to_atom(atom),
fail_binary_to_atom(42),
@@ -464,10 +503,6 @@ binary_to_atom(Config) when is_list(Config) ->
?BADARG(binary_to_atom(id(<<255>>), utf8)),
?BADARG(binary_to_atom(id(<<255,0>>), utf8)),
?BADARG(binary_to_atom(id(<<16#C0,16#80>>), utf8)), %Overlong 0.
- [?BADARG(binary_to_atom(<>, utf8)) || C <- lists:seq(256, 16#D7FF)],
- [?BADARG(binary_to_atom(<>, utf8)) || C <- lists:seq(16#E000, 16#FFFD)],
- [?BADARG(binary_to_atom(<>, utf8)) || C <- lists:seq(16#10000, 16#8FFFF)],
- [?BADARG(binary_to_atom(<>, utf8)) || C <- lists:seq(16#90000, 16#10FFFF)],
%% system_limit failures.
?SYS_LIMIT(binary_to_atom(id(<<0:512/unit:8,255>>), utf8)),
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index b29520ab9f..d07166ed98 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -296,16 +296,16 @@ get_chunk(Config) when is_list(Config) ->
{ok,my_code_test,Code} = compile:file(File, [binary]),
%% Should work.
- Chunk = get_chunk_ok("Atom", Code),
- Chunk = get_chunk_ok("Atom", make_sub_binary(Code)),
- Chunk = get_chunk_ok("Atom", make_unaligned_sub_binary(Code)),
+ Chunk = get_chunk_ok("AtU8", Code),
+ Chunk = get_chunk_ok("AtU8", make_sub_binary(Code)),
+ Chunk = get_chunk_ok("AtU8", make_unaligned_sub_binary(Code)),
%% Should fail.
- {'EXIT',{badarg,_}} = (catch code:get_chunk(bit_sized_binary(Code), "Atom")),
+ {'EXIT',{badarg,_}} = (catch code:get_chunk(bit_sized_binary(Code), "AtU8")),
{'EXIT',{badarg,_}} = (catch code:get_chunk(Code, "bad chunk id")),
%% Invalid beam code or missing chunk should return 'undefined'.
- undefined = code:get_chunk(<<"not a beam module">>, "Atom"),
+ undefined = code:get_chunk(<<"not a beam module">>, "AtU8"),
undefined = code:get_chunk(Code, "XXXX"),
ok.
--
cgit v1.2.3
From 4751ac228fc09c6421f521b9e5a1a0f2b2eebade Mon Sep 17 00:00:00 2001
From: Erlang/OTP
Date: Wed, 1 Feb 2017 18:32:57 +0100
Subject: Prepare release
---
erts/doc/src/notes.xml | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
erts/vsn.mk | 2 +-
2 files changed, 51 insertions(+), 1 deletion(-)
(limited to 'erts')
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index f816cdf3a8..09f190aa8d 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -32,6 +32,56 @@
This document describes the changes made to the ERTS application.
+ A bug has been fixed where if erlang was started +B on a
+ unix platform it would be killed by a SIGUSR2 signal when
+ creating a crash dump.
+
+ Own Id: OTP-13425 Aux Id: ERL-94
+
+
+
+ Calls to erl_drv_send_term() or
+ erl_drv_output_term() from a non-scheduler thread
+ while the corresponding port was invalid caused the
+ emulator to enter an inconsistent state which eventually
+ caused an emulator crash.
+
+ Own Id: OTP-13866
+
+
+
Driver and NIF operations accessing processes or ports
+ could cause an emulator crash when used from
+ non-scheduler threads. Those operations are:
+ Fix bug in binary_to_term for binaries created by
+ term_to_binary with option compressed. The
+ bug can cause badarg exception for a valid binary
+ when Erlang VM is linked against a zlib library of
+ version 1.2.9 or newer. Bug exists since OTP 17.0.
+
+ Own Id: OTP-14159 Aux Id: ERL-340
+
+
+
+
+
+
Erts 7.3.1.2Fixed Bugs and Malfunctions
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 48c9aef7f2..f987bbbdb8 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 7.3.1.2
+VSN = 7.3.1.3
# Port number 4365 in 4.2
# Port number 4366 in 4.3
--
cgit v1.2.3
From afbec46949f0d31448386234efa89cec78b905e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 16 Jan 2017 11:52:39 +0100
Subject: erts: Add OS signal tests
---
erts/emulator/test/Makefile | 1 +
erts/emulator/test/os_signal_SUITE.erl | 354 +++++++++++++++++++++
.../test/os_signal_SUITE_data/Makefile.src | 6 +
.../test/os_signal_SUITE_data/os_signal_nif.c | 66 ++++
4 files changed, 427 insertions(+)
create mode 100644 erts/emulator/test/os_signal_SUITE.erl
create mode 100644 erts/emulator/test/os_signal_SUITE_data/Makefile.src
create mode 100644 erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c
(limited to 'erts')
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 2e48c475d5..5ec6ff1901 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -85,6 +85,7 @@ MODULES= \
num_bif_SUITE \
message_queue_data_SUITE \
op_SUITE \
+ os_signal_SUITE \
port_SUITE \
port_bif_SUITE \
process_SUITE \
diff --git a/erts/emulator/test/os_signal_SUITE.erl b/erts/emulator/test/os_signal_SUITE.erl
new file mode 100644
index 0000000000..2b9343663d
--- /dev/null
+++ b/erts/emulator/test/os_signal_SUITE.erl
@@ -0,0 +1,354 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2017. 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%
+%%
+
+%%
+%% File: os_signal_SUITE.erl
+%% Author: Björn-Egil Dahlberg
+%% Created: 2017-01-13
+%%
+
+-module(os_signal_SUITE).
+
+-include_lib("common_test/include/ct.hrl").
+-export([all/0, suite/0]).
+-export([init_per_testcase/2, end_per_testcase/2]).
+-export([init_per_suite/1, end_per_suite/1]).
+
+-export([set_alarm/1, fork/0, get_exit_code/1]).
+
+% Test cases
+-export([set_unset/1,
+ t_sighup/1,
+ t_sigusr1/1,
+ t_sigusr2/1,
+ t_sigterm/1,
+ t_sigalrm/1,
+ t_sigchld/1,
+ t_sigchld_fork/1]).
+
+-define(signal_server, erl_signal_server).
+
+suite() ->
+ [{ct_hooks,[ts_install_cth]},
+ {timetrap, {minutes, 2}}].
+
+all() ->
+ case os:type() of
+ {win32, _} -> [];
+ _ -> [set_unset,
+ t_sighup,
+ t_sigusr1,
+ t_sigusr2,
+ t_sigterm,
+ t_sigalrm,
+ t_sigchld,
+ t_sigchld_fork]
+ end.
+
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Pid = erlang:whereis(?signal_server),
+ true = erlang:unregister(?signal_server),
+ [{signal_server, Pid}|Config].
+
+end_per_testcase(_Func, Config) ->
+ case proplists:get_value(signal_server, Config) of
+ undefined -> ok;
+ Pid ->
+ true = erlang:register(?signal_server, Pid),
+ ok
+ end.
+
+init_per_suite(Config) ->
+ load_nif(Config),
+ Config.
+
+end_per_suite(_Config) ->
+ ok.
+
+%% tests
+
+set_unset(_Config) ->
+ Signals = [sighup, %sigint,
+ sigquit, sigill,
+ sigabrt,
+ sigalrm, sigterm,
+ sigusr1, sigusr2,
+ sigchld,
+ sigstop, sigtstp],
+ F1 = fun(Sig) -> true = erts_internal:set_signal(Sig,handle) end,
+ F2 = fun(Sig) -> true = erts_internal:set_signal(Sig,default) end,
+ F3 = fun(Sig) -> true = erts_internal:set_signal(Sig,ignore) end,
+ %% set handle
+ ok = lists:foreach(F1, Signals),
+ %% set ignore
+ ok = lists:foreach(F2, Signals),
+ %% set default
+ ok = lists:foreach(F3, Signals),
+ ok.
+
+t_sighup(_Config) ->
+ Pid1 = setup_service(),
+ OsPid = os:getpid(),
+ erts_internal:set_signal(sighup, handle),
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sighup},
+ {notify,sighup},
+ {notify,sighup}] = Msgs1,
+ %% no proc
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ %% ignore
+ Pid2 = setup_service(),
+ erts_internal:set_signal(sighup, ignore),
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ ok = kill("HUP", OsPid),
+ Msgs2 = fetch_msgs(Pid2),
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ [] = Msgs2,
+ %% reset to handle (it's the default)
+ erts_internal:set_signal(sighup, handle),
+ ok.
+
+t_sigusr1(_Config) ->
+ Pid1 = setup_service(),
+ OsPid = os:getpid(),
+ erts_internal:set_signal(sigusr1, handle),
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sigusr1},
+ {notify,sigusr1},
+ {notify,sigusr1}] = Msgs1,
+ %% no proc
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ %% ignore
+ Pid2 = setup_service(),
+ erts_internal:set_signal(sigusr1, ignore),
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ ok = kill("USR1", OsPid),
+ Msgs2 = fetch_msgs(Pid2),
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ [] = Msgs2,
+ %% reset to ignore (it's the default)
+ erts_internal:set_signal(sigusr1, handle),
+ ok.
+
+t_sigusr2(_Config) ->
+ Pid1 = setup_service(),
+ OsPid = os:getpid(),
+ erts_internal:set_signal(sigusr2, handle),
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sigusr2},
+ {notify,sigusr2},
+ {notify,sigusr2}] = Msgs1,
+ %% no proc
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ %% ignore
+ Pid2 = setup_service(),
+ erts_internal:set_signal(sigusr2, ignore),
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ ok = kill("USR2", OsPid),
+ Msgs2 = fetch_msgs(Pid2),
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ [] = Msgs2,
+ %% reset to ignore (it's the default)
+ erts_internal:set_signal(sigusr2, ignore),
+ ok.
+
+t_sigterm(_Config) ->
+ Pid1 = setup_service(),
+ OsPid = os:getpid(),
+ erts_internal:set_signal(sigterm, handle),
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sigterm},
+ {notify,sigterm},
+ {notify,sigterm}] = Msgs1,
+ %% no proc
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ %% ignore
+ Pid2 = setup_service(),
+ erts_internal:set_signal(sigterm, ignore),
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ ok = kill("TERM", OsPid),
+ Msgs2 = fetch_msgs(Pid2),
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ [] = Msgs2,
+ %% reset to handle (it's the default)
+ erts_internal:set_signal(sigterm, handle),
+ ok.
+
+t_sigchld(_Config) ->
+ Pid1 = setup_service(),
+ OsPid = os:getpid(),
+ erts_internal:set_signal(sigchld, handle),
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sigchld},
+ {notify,sigchld},
+ {notify,sigchld}] = Msgs1,
+ %% no proc
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ %% ignore
+ Pid2 = setup_service(),
+ erts_internal:set_signal(sigchld, ignore),
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ ok = kill("CHLD", OsPid),
+ Msgs2 = fetch_msgs(Pid2),
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ [] = Msgs2,
+ %% reset to handle (it's the default)
+ erts_internal:set_signal(sigchld, ignore),
+ ok.
+
+
+t_sigalrm(_Config) ->
+ Pid1 = setup_service(),
+ true = erts_internal:set_signal(sigalrm, handle),
+ ok = os_signal_SUITE:set_alarm(1),
+ receive after 3000 -> ok end,
+ Msgs1 = fetch_msgs(Pid1),
+ [{notify,sigalrm}] = Msgs1,
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ erts_internal:set_signal(sigalrm, ignore),
+ Pid2 = setup_service(),
+ ok = os_signal_SUITE:set_alarm(1),
+ receive after 3000 -> ok end,
+ Msgs2 = fetch_msgs(Pid2),
+ [] = Msgs2,
+ io:format("Msgs2: ~p~n", [Msgs2]),
+ Pid3 = setup_service(),
+ erts_internal:set_signal(sigalrm, handle),
+ ok = os_signal_SUITE:set_alarm(1),
+ receive after 3000 -> ok end,
+ Msgs3 = fetch_msgs(Pid3),
+ [{notify,sigalrm}] = Msgs3,
+ io:format("Msgs3: ~p~n", [Msgs3]),
+ erts_internal:set_signal(sigalrm, ignore),
+ ok.
+
+t_sigchld_fork(_Config) ->
+ Pid1 = setup_service(),
+ true = erts_internal:set_signal(sigchld, handle),
+ {ok,OsPid} = os_signal_SUITE:fork(),
+ receive after 3000 -> ok end,
+ Msgs1 = fetch_msgs(Pid1),
+ io:format("Msgs1: ~p~n", [Msgs1]),
+ [{notify,sigchld}] = Msgs1,
+ {ok,Status} = os_signal_SUITE:get_exit_code(OsPid),
+ io:format("exit status from ~w : ~w~n", [OsPid,Status]),
+ 42 = Status,
+ %% reset to ignore (it's the default)
+ erts_internal:set_signal(sigchld, ignore),
+ ok.
+
+
+%% nif stubs
+
+set_alarm(_Secs) -> no.
+fork() -> no.
+get_exit_code(_OsPid) -> no.
+
+%% aux
+
+setup_service() ->
+ Pid = spawn_link(fun msgs/0),
+ true = erlang:register(?signal_server, Pid),
+ Pid.
+
+msgs() ->
+ msgs([]).
+msgs(Ms) ->
+ receive
+ {Pid, fetch_msgs} -> Pid ! {self(), lists:reverse(Ms)};
+ Msg ->
+ msgs([Msg|Ms])
+ end.
+
+fetch_msgs(Pid) ->
+ Pid ! {self(), fetch_msgs},
+ receive {Pid, Msgs} -> Msgs end.
+
+kill(Signal, Pid) ->
+ {0,_} = run("kill", ["-s", Signal, Pid]),
+ receive after 200 -> ok end,
+ ok.
+
+load_nif(Config) ->
+ Path = proplists:get_value(data_dir, Config),
+ ok = erlang:load_nif(filename:join(Path,"os_signal_nif"), 0).
+
+run(Program0, Args) -> run(".", Program0, Args).
+run(Cwd, Program0, Args) when is_list(Cwd) ->
+ Program = case os:find_executable(Program0) of
+ Path when is_list(Path) ->
+ Path;
+ false ->
+ exit(no)
+ end,
+ Options = [{args,Args},binary,exit_status,stderr_to_stdout,
+ {line,4096}, {cd, Cwd}],
+ try open_port({spawn_executable,Program}, Options) of
+ Port ->
+ run_loop(Port, [])
+ catch
+ error:_ ->
+ exit(no)
+ end.
+
+run_loop(Port, Output) ->
+ receive
+ {Port,{exit_status,Status}} ->
+ {Status,lists:reverse(Output)};
+ {Port,{data,{eol,Bin}}} ->
+ run_loop(Port, [Bin|Output]);
+ _Msg ->
+ run_loop(Port, Output)
+ end.
diff --git a/erts/emulator/test/os_signal_SUITE_data/Makefile.src b/erts/emulator/test/os_signal_SUITE_data/Makefile.src
new file mode 100644
index 0000000000..a7f5cdbba5
--- /dev/null
+++ b/erts/emulator/test/os_signal_SUITE_data/Makefile.src
@@ -0,0 +1,6 @@
+
+NIF_LIBS = os_signal_nif@dll@
+
+all: $(NIF_LIBS)
+
+@SHLIB_RULES@
diff --git a/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c b/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c
new file mode 100644
index 0000000000..78e1348383
--- /dev/null
+++ b/erts/emulator/test/os_signal_SUITE_data/os_signal_nif.c
@@ -0,0 +1,66 @@
+#include
+#include
+#include
+#include
+
+#include
+
+static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+{
+ return 0;
+}
+
+static ERL_NIF_TERM set_alarm(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int t;
+ if (!enif_get_int(env, argv[0], &t)) {
+ return enif_make_badarg(env);
+ }
+
+ alarm(t);
+
+ return enif_make_atom(env, "ok");
+}
+
+static ERL_NIF_TERM fork_0(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ pid_t pid;
+
+ pid = fork();
+
+ if (pid == 0) {
+ /* child */
+ exit(42);
+ }
+
+ return enif_make_tuple(env, 2,
+ enif_make_atom(env, "ok"),
+ enif_make_int(env, (int)pid));
+}
+
+static ERL_NIF_TERM get_exit_code(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ int x;
+ pid_t pid;
+ if (!enif_get_int(env, argv[0], &x)) {
+ return enif_make_badarg(env);
+ }
+
+ pid = (pid_t) x;
+
+ waitpid(pid, &x, 0);
+
+ return enif_make_tuple(env, 2,
+ enif_make_atom(env, "ok"),
+ enif_make_int(env, WEXITSTATUS(x)));
+}
+
+
+static ErlNifFunc nif_funcs[] =
+{
+ {"set_alarm", 1, set_alarm},
+ {"fork", 0, fork_0},
+ {"get_exit_code", 1, get_exit_code}
+};
+
+ERL_NIF_INIT(os_signal_SUITE,nif_funcs,load,NULL,NULL,NULL)
--
cgit v1.2.3
From 120f04387ade07ef5b8b6d20a04de7d21e0c40ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Thu, 5 Jan 2017 17:17:52 +0100
Subject: erts: Use generic signal handler
---
erts/emulator/beam/atom.names | 14 ++-
erts/emulator/beam/bif.c | 14 ++-
erts/emulator/beam/bif.tab | 1 +
erts/emulator/beam/global.h | 3 +
erts/emulator/sys/unix/sys.c | 251 ++++++++++++++++++++++--------------------
erts/emulator/sys/win32/sys.c | 4 +
6 files changed, 165 insertions(+), 122 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 668abfaaee..72a7b9e312 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -194,6 +194,7 @@ atom current_stacktrace
atom data
atom debug_flags
atom decimals
+atom default
atom delay_trap
atom dexit
atom depth
@@ -306,6 +307,7 @@ atom global
atom Gt='>'
atom grun
atom group_leader
+atom handle
atom have_dt_utag
atom heap_block_size
atom heap_size
@@ -566,7 +568,7 @@ atom running_procs
atom runtime
atom safe
atom save_calls
-atom scheduler
+atom scheduler
atom scheduler_id
atom schedulers_online
atom scheme
@@ -594,6 +596,16 @@ atom shared
atom sighup
atom sigterm
atom sigusr1
+atom sigusr2
+atom sigill
+atom sigchld
+atom sigabrt
+atom sigalrm
+atom sigstop
+atom sigint
+atom sigsegv
+atom sigtstp
+atom sigquit
atom silent
atom size
atom sl_alloc
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index d886c2985e..452bfef71a 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -5273,7 +5273,7 @@ BIF_RETTYPE dt_restore_tag_1(BIF_ALIST_1)
SEQ_TRACE_TOKEN(BIF_P) = am_have_dt_utag;
}
}
-#else
+#else
if (BIF_ARG_1 != am_true) {
BIF_ERROR(BIF_P,BADARG);
}
@@ -5281,4 +5281,16 @@ BIF_RETTYPE dt_restore_tag_1(BIF_ALIST_1)
BIF_RET(am_true);
}
+BIF_RETTYPE erts_internal_set_signal_2(BIF_ALIST_2) {
+ if (is_atom(BIF_ARG_1) && ((BIF_ARG_2 == am_ignore) ||
+ (BIF_ARG_2 == am_default) ||
+ (BIF_ARG_2 == am_handle))) {
+ if (!erts_set_signal(BIF_ARG_1, BIF_ARG_2))
+ goto error;
+
+ BIF_RET(am_true);
+ }
+error:
+ BIF_ERROR(BIF_P, BADARG);
+}
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 32600f4338..318a4fd264 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -668,6 +668,7 @@ gcbif erlang:ceil/1
bif math:floor/1
bif math:ceil/1
bif math:fmod/2
+bif erts_internal:set_signal/2
#
# Obsolete
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 2b2f3c5cdc..f0f959e97a 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -1070,6 +1070,9 @@ void print_process_info(fmtfn_t, void *, Process*);
void info(fmtfn_t, void *);
void loaded(fmtfn_t, void *);
+/* sighandler sys.c */
+int erts_set_signal(Eterm signal, Eterm type);
+
/* erl_arith.c */
double erts_get_positive_zero_float(void);
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index de9c1b2ca0..4175dc6a41 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -107,7 +107,7 @@ static volatile int have_prepared_crash_dump;
erts_smp_atomic_t sys_misc_mem_sz;
#if defined(ERTS_SMP)
-static void smp_sig_notify(char c);
+static void smp_sig_notify(int signum);
static int sig_notify_fds[2] = {-1, -1};
#if !defined(ETHR_UNUSABLE_SIGUSRX) && defined(ERTS_THR_HAVE_SIG_FUNCS)
@@ -395,14 +395,6 @@ erts_sys_pre_init(void)
/* After creation in parent */
eid.thread_create_parent_func = thr_create_cleanup,
-#ifdef ERTS_THR_HAVE_SIG_FUNCS
- sigemptyset(&thr_create_sigmask);
- sigaddset(&thr_create_sigmask, SIGINT); /* block interrupt */
- sigaddset(&thr_create_sigmask, SIGTERM); /* block terminate signal */
- sigaddset(&thr_create_sigmask, SIGHUP); /* block sighups */
- sigaddset(&thr_create_sigmask, SIGUSR1); /* block user defined signal */
-#endif
-
erts_thr_init(&eid);
#ifdef ERTS_ENABLE_LOCK_CHECK
@@ -654,33 +646,15 @@ break_requested(void)
ERTS_CHK_IO_AS_INTR(); /* Make sure we don't sleep in poll */
}
-/* set up signal handlers for break and quit */
-#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE request_break(void)
-#else
static RETSIGTYPE request_break(int signum)
-#endif
{
#ifdef ERTS_SMP
- smp_sig_notify('I');
+ smp_sig_notify(signum);
#else
break_requested();
#endif
}
-#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE request_stop(void)
-#else
-static RETSIGTYPE request_stop(int signum)
-#endif
-{
-#ifdef ERTS_SMP
- smp_sig_notify('T');
-#else
- signal_notify_requested(am_sigterm);
-#endif
-}
-
#ifdef ETHR_UNUSABLE_SIGUSRX
#warning "Unusable SIGUSR1 & SIGUSR2. Disabling use of these signals"
@@ -701,19 +675,6 @@ sys_thr_resume(erts_tid_t tid) {
}
#endif
-#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE user_signal1(void)
-#else
-static RETSIGTYPE user_signal1(int signum)
-#endif
-{
-#ifdef ERTS_SMP
- smp_sig_notify('1');
-#else
- signal_notify_requested(am_sigusr1);
-#endif
-}
-
#ifdef ERTS_SYS_SUSPEND_SIGNAL
#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
static RETSIGTYPE suspend_signal(void)
@@ -733,43 +694,101 @@ static RETSIGTYPE suspend_signal(int signum)
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
-static void
-quit_requested(void)
+/*
+ Signal Action Comment
+ ─────────────────────────────────────────────────────────────
+ SIGHUP Term Hangup detected on controlling terminal or death of controlling process
+ SIGINT Term Interrupt from keyboard
+ SIGQUIT Core Quit from keyboard
+ SIGILL Core Illegal Instruction
+ SIGABRT Core Abort signal from abort(3)
+ !SIGFPE Core Floating point exception
+ !SIGKILL Term Kill signal
+ !SIGSEGV Core Invalid memory reference
+ !SIGPIPE Term Broken pipe: write to pipe with no readers
+ SIGALRM Term Timer signal from alarm(2)
+ SIGTERM Term Termination signal
+ SIGUSR1 Term User-defined signal 1
+ SIGUSR2 Term User-defined signal 2
+ !SIGCHLD Ign Child stopped or terminated
+ !SIGCONT Cont Continue if stopped
+ SIGSTOP Stop Stop process
+ SIGTSTP Stop Stop typed at terminal
+ !SIGTTIN Stop Terminal input for background process
+ !SIGTTOU Stop Terminal output for background process
+*/
+
+
+static ERTS_INLINE int
+signalterm_to_signum(Eterm signal)
{
- erts_exit(ERTS_INTR_EXIT, "");
+ switch (signal) {
+ case am_sighup: return SIGHUP;
+ case am_sigint: return SIGINT;
+ case am_sigquit: return SIGQUIT;
+ case am_sigill: return SIGILL;
+ case am_sigabrt: return SIGABRT;
+ /* case am_sigsegv: return SIGSEGV; */
+ case am_sigalrm: return SIGALRM;
+ case am_sigterm: return SIGTERM;
+ case am_sigusr1: return SIGUSR1;
+ case am_sigusr2: return SIGUSR2;
+ case am_sigchld: return SIGCHLD;
+ case am_sigstop: return SIGSTOP;
+ case am_sigtstp: return SIGTSTP;
+ default: return 0;
+ }
}
-#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE do_quit(void)
-#else
-static RETSIGTYPE do_quit(int signum)
-#endif
+static ERTS_INLINE Eterm
+signum_to_signalterm(int signum)
{
-#ifdef ERTS_SMP
- smp_sig_notify('Q');
-#else
- quit_requested();
-#endif
+ switch (signum) {
+ case SIGHUP: return am_sighup;
+ case SIGINT: return am_sigint; /* ^c */
+ case SIGILL: return am_sigill;
+ case SIGABRT: return am_sigabrt;
+ /* case SIGSEGV: return am_sigsegv; */
+ case SIGALRM: return am_sigalrm;
+ case SIGTERM: return am_sigterm;
+ case SIGQUIT: return am_sigquit; /* ^\ */
+ case SIGUSR1: return am_sigusr1;
+ case SIGUSR2: return am_sigusr2;
+ case SIGCHLD: return am_sigchld;
+ case SIGSTOP: return am_sigstop;
+ case SIGTSTP: return am_sigtstp; /* ^z */
+ default: return am_error;
+ }
}
-#if (defined(SIG_SIGSET) || defined(SIG_SIGNAL))
-static RETSIGTYPE request_sighup(void)
-#else
-static RETSIGTYPE request_sighup(int signum)
-#endif
+static RETSIGTYPE generic_signal_handler(int signum)
{
#ifdef ERTS_SMP
- smp_sig_notify('H');
+ smp_sig_notify(signum);
#else
- signal_notify_requested(am_sighup);
+ Eterm signal = signum_to_signalterm(signum);
+ signal_notify_requested(signal);
#endif
}
+int erts_set_signal(Eterm signal, Eterm type) {
+ int signum;
+ if ((signum = signalterm_to_signum(signal)) > 0) {
+ if (type == am_ignore) {
+ sys_signal(signum, SIG_IGN);
+ } else if (type == am_default) {
+ sys_signal(signum, SIG_DFL);
+ } else {
+ sys_signal(signum, generic_signal_handler);
+ }
+ return 1;
+ }
+ return 0;
+}
+
/* Disable break */
void erts_set_ignore_break(void) {
sys_signal(SIGINT, SIG_IGN);
- sys_signal(SIGTERM, SIG_IGN);
- sys_signal(SIGHUP, SIG_IGN);
sys_signal(SIGQUIT, SIG_IGN);
sys_signal(SIGTSTP, SIG_IGN);
}
@@ -794,13 +813,13 @@ void erts_replace_intr(void) {
void init_break_handler(void)
{
- sys_signal(SIGINT, request_break);
- sys_signal(SIGTERM, request_stop);
- sys_signal(SIGHUP, request_sighup);
+ sys_signal(SIGINT, request_break);
+ sys_signal(SIGTERM, generic_signal_handler);
+ sys_signal(SIGHUP, generic_signal_handler);
#ifndef ETHR_UNUSABLE_SIGUSRX
- sys_signal(SIGUSR1, user_signal1);
+ sys_signal(SIGUSR1, generic_signal_handler);
#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
- sys_signal(SIGQUIT, do_quit);
+ sys_signal(SIGQUIT, generic_signal_handler);
}
void sys_init_suspend_handler(void)
@@ -1216,14 +1235,14 @@ erl_sys_schedule(int runnable)
static erts_smp_tid_t sig_dispatcher_tid;
static void
-smp_sig_notify(char c)
+smp_sig_notify(int signum)
{
int res;
do {
/* write() is async-signal safe (according to posix) */
- res = write(sig_notify_fds[1], &c, 1);
+ res = write(sig_notify_fds[1], &signum, sizeof(int));
} while (res < 0 && errno == EINTR);
- if (res != 1) {
+ if (res != sizeof(int)) {
char msg[] =
"smp_sig_notify(): Failed to notify signal-dispatcher thread "
"about received signal";
@@ -1239,63 +1258,55 @@ signal_dispatcher_thread_func(void *unused)
erts_lc_set_thread_name("signal_dispatcher");
#endif
while (1) {
- char buf[32];
- int res, i;
+ union {int signum; char buf[4];} sb;
+ Eterm signal;
+ int res, i = 0;
/* Block on read() waiting for a signal notification to arrive... */
- res = read(sig_notify_fds[0], (void *) &buf[0], 32);
+
+ do {
+ res = read(sig_notify_fds[0], (void *) &sb.buf[i], sizeof(int) - i);
+ i += res;
+ } while ((i != sizeof(int) && res >= 0) || (res < 0 && errno == EINTR));
+
if (res < 0) {
- if (errno == EINTR)
- continue;
erts_exit(ERTS_ABORT_EXIT,
"signal-dispatcher thread got unexpected error: %s (%d)\n",
erl_errno_id(errno),
errno);
}
- for (i = 0; i < res; i++) {
- /*
- * NOTE 1: The signal dispatcher thread should not do work
- * that takes a substantial amount of time (except
- * perhaps in test and debug builds). It needs to
- * be responsive, i.e, it should only dispatch work
- * to other threads.
- *
- * NOTE 2: The signal dispatcher thread is not a blockable
- * thread (i.e., not a thread managed by the
- * erl_thr_progress module). This is intentional.
- * We want to be able to interrupt writing of a crash
- * dump by hitting C-c twice. Since it isn't a
- * blockable thread it is important that it doesn't
- * change the state of any data that a blocking thread
- * expects to have exclusive access to (unless the
- * signal dispatcher itself explicitly is blocking all
- * blockable threads).
- */
- switch (buf[i]) {
- case 0: /* Emulator initialized */
- break;
- case 'H': /* SIGHUP */
- signal_notify_requested(am_sighup);
+ /*
+ * NOTE 1: The signal dispatcher thread should not do work
+ * that takes a substantial amount of time (except
+ * perhaps in test and debug builds). It needs to
+ * be responsive, i.e, it should only dispatch work
+ * to other threads.
+ *
+ * NOTE 2: The signal dispatcher thread is not a blockable
+ * thread (i.e., not a thread managed by the
+ * erl_thr_progress module). This is intentional.
+ * We want to be able to interrupt writing of a crash
+ * dump by hitting C-c twice. Since it isn't a
+ * blockable thread it is important that it doesn't
+ * change the state of any data that a blocking thread
+ * expects to have exclusive access to (unless the
+ * signal dispatcher itself explicitly is blocking all
+ * blockable threads).
+ */
+ switch (sb.signum) {
+ case 0: continue;
+ case SIGINT:
+ break_requested();
break;
- case 'T': /* SIGTERM */
- signal_notify_requested(am_sigterm);
- break;
- case '1': /* SIGUSR1 */
- signal_notify_requested(am_sigusr1);
- break;
- case 'I': /* SIGINT */
- break_requested();
- break;
- case 'Q': /* SIGQUIT */
- quit_requested();
- break;
- default:
- erts_exit(ERTS_ABORT_EXIT,
- "signal-dispatcher thread received unknown "
- "signal notification: '%c'\n",
- buf[i]);
- }
- }
- ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking());
+ default:
+ if ((signal = signum_to_signalterm(sb.signum)) == am_error) {
+ erts_exit(ERTS_ABORT_EXIT,
+ "signal-dispatcher thread received unknown "
+ "signal notification: '%d'\n",
+ sb.signum);
+ }
+ signal_notify_requested(signal);
+ }
+ ERTS_SMP_LC_ASSERT(!erts_thr_progress_is_blocking());
}
return NULL;
}
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index f3881e0736..408b4f47ab 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -294,6 +294,10 @@ int erts_sys_prepare_crash_dump(int secs)
return 0;
}
+int erts_set_signal(Eterm signal, Eterm type) {
+ return 0;
+}
+
static void
init_console(void)
{
--
cgit v1.2.3
From d3506c8dc3d355b7a62085da508b41866e431a37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 20 Jan 2017 14:27:40 +0100
Subject: erts: Do not enable SIGINT
---
erts/emulator/sys/unix/sys.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index 4175dc6a41..ce87e3c7a6 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -698,7 +698,7 @@ static RETSIGTYPE suspend_signal(int signum)
Signal Action Comment
─────────────────────────────────────────────────────────────
SIGHUP Term Hangup detected on controlling terminal or death of controlling process
- SIGINT Term Interrupt from keyboard
+ !SIGINT Term Interrupt from keyboard
SIGQUIT Core Quit from keyboard
SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort(3)
@@ -724,7 +724,7 @@ signalterm_to_signum(Eterm signal)
{
switch (signal) {
case am_sighup: return SIGHUP;
- case am_sigint: return SIGINT;
+ /* case am_sigint: return SIGINT; */
case am_sigquit: return SIGQUIT;
case am_sigill: return SIGILL;
case am_sigabrt: return SIGABRT;
@@ -745,7 +745,7 @@ signum_to_signalterm(int signum)
{
switch (signum) {
case SIGHUP: return am_sighup;
- case SIGINT: return am_sigint; /* ^c */
+ /* case SIGINT: return am_sigint; */ /* ^c */
case SIGILL: return am_sigill;
case SIGABRT: return am_sigabrt;
/* case SIGSEGV: return am_sigsegv; */
--
cgit v1.2.3
From 314fddc2e2e4cd8587ce00dfce328245a315832f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 20 Jan 2017 16:28:42 +0100
Subject: erts: Fix thread suspend in crashdump
* move signal handler setup
---
erts/emulator/beam/break.c | 2 ++
erts/emulator/beam/erl_init.c | 1 -
erts/emulator/beam/sys.h | 3 +++
erts/emulator/sys/unix/sys.c | 3 +--
4 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 6e1e94b95b..2fc61ab436 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -717,6 +717,8 @@ erl_crash_dump_v(char *file, int line, char* fmt, va_list args)
* We have to be very very careful when doing this as the schedulers
* could be anywhere.
*/
+ sys_init_suspend_handler();
+
for (i = 0; i < erts_no_schedulers; i++) {
erts_tid_t tid = ERTS_SCHEDULER_IX(i)->tid;
if (!erts_equal_tids(tid,erts_thr_self()))
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index c5904b375e..88bd002a8c 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -2220,7 +2220,6 @@ erl_start(int argc, char **argv)
init_break_handler();
if (replace_intr)
erts_replace_intr();
- sys_init_suspend_handler();
#endif
boot_argc = argc - i; /* Number of arguments to init */
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index ceea794cc4..a11fb16b39 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -851,9 +851,12 @@ int erts_sys_unsetenv(char *key);
char *erts_read_env(char *key);
void erts_free_read_env(void *value);
+#if defined(ERTS_SMP)
#if defined(ERTS_THR_HAVE_SIG_FUNCS) && !defined(ETHR_UNUSABLE_SIGUSRX)
extern void sys_thr_resume(erts_tid_t tid);
extern void sys_thr_suspend(erts_tid_t tid);
+#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
+#endif
#endif
/* utils.c */
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index ce87e3c7a6..a25d865c91 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -110,9 +110,8 @@ erts_smp_atomic_t sys_misc_mem_sz;
static void smp_sig_notify(int signum);
static int sig_notify_fds[2] = {-1, -1};
-#if !defined(ETHR_UNUSABLE_SIGUSRX) && defined(ERTS_THR_HAVE_SIG_FUNCS)
+#ifdef ERTS_SYS_SUSPEND_SIGNAL
static int sig_suspend_fds[2] = {-1, -1};
-#define ERTS_SYS_SUSPEND_SIGNAL SIGUSR2
#endif
#endif
--
cgit v1.2.3
From 9ccb988eeb79815a33e0dd138278e0c29ed3ca6a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Mon, 23 Jan 2017 16:05:07 +0100
Subject: erts: Do not handle SIGILL
* Remove SIGILL from signal whitelist
---
erts/emulator/sys/unix/sys.c | 8 ++++----
erts/emulator/test/os_signal_SUITE.erl | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index a25d865c91..cb20c690b4 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -699,7 +699,7 @@ static RETSIGTYPE suspend_signal(int signum)
SIGHUP Term Hangup detected on controlling terminal or death of controlling process
!SIGINT Term Interrupt from keyboard
SIGQUIT Core Quit from keyboard
- SIGILL Core Illegal Instruction
+ !SIGILL Core Illegal Instruction
SIGABRT Core Abort signal from abort(3)
!SIGFPE Core Floating point exception
!SIGKILL Term Kill signal
@@ -725,7 +725,7 @@ signalterm_to_signum(Eterm signal)
case am_sighup: return SIGHUP;
/* case am_sigint: return SIGINT; */
case am_sigquit: return SIGQUIT;
- case am_sigill: return SIGILL;
+ /* case am_sigill: return SIGILL; */
case am_sigabrt: return SIGABRT;
/* case am_sigsegv: return SIGSEGV; */
case am_sigalrm: return SIGALRM;
@@ -745,12 +745,12 @@ signum_to_signalterm(int signum)
switch (signum) {
case SIGHUP: return am_sighup;
/* case SIGINT: return am_sigint; */ /* ^c */
- case SIGILL: return am_sigill;
+ case SIGQUIT: return am_sigquit; /* ^\ */
+ /* case SIGILL: return am_sigill; */
case SIGABRT: return am_sigabrt;
/* case SIGSEGV: return am_sigsegv; */
case SIGALRM: return am_sigalrm;
case SIGTERM: return am_sigterm;
- case SIGQUIT: return am_sigquit; /* ^\ */
case SIGUSR1: return am_sigusr1;
case SIGUSR2: return am_sigusr2;
case SIGCHLD: return am_sigchld;
diff --git a/erts/emulator/test/os_signal_SUITE.erl b/erts/emulator/test/os_signal_SUITE.erl
index 2b9343663d..7c3950114f 100644
--- a/erts/emulator/test/os_signal_SUITE.erl
+++ b/erts/emulator/test/os_signal_SUITE.erl
@@ -86,7 +86,7 @@ end_per_suite(_Config) ->
set_unset(_Config) ->
Signals = [sighup, %sigint,
- sigquit, sigill,
+ sigquit, %sigill,
sigabrt,
sigalrm, sigterm,
sigusr1, sigusr2,
--
cgit v1.2.3
From d4bd17da9759af54227891a90d9fb83d5bfe6d7e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Tue, 24 Jan 2017 10:59:30 +0100
Subject: erts: Use os module instead of erts_internal for set_signal/2
* Add specs
* Change return signature to 'ok' instead of 'true'
---
erts/emulator/beam/bif.c | 14 ----------
erts/emulator/beam/bif.tab | 2 +-
erts/emulator/beam/erl_bif_os.c | 14 ++++++++++
erts/emulator/test/os_signal_SUITE.erl | 48 +++++++++++++++++-----------------
4 files changed, 39 insertions(+), 39 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 452bfef71a..1048300cf7 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -5280,17 +5280,3 @@ BIF_RETTYPE dt_restore_tag_1(BIF_ALIST_1)
#endif
BIF_RET(am_true);
}
-
-BIF_RETTYPE erts_internal_set_signal_2(BIF_ALIST_2) {
- if (is_atom(BIF_ARG_1) && ((BIF_ARG_2 == am_ignore) ||
- (BIF_ARG_2 == am_default) ||
- (BIF_ARG_2 == am_handle))) {
- if (!erts_set_signal(BIF_ARG_1, BIF_ARG_2))
- goto error;
-
- BIF_RET(am_true);
- }
-
-error:
- BIF_ERROR(BIF_P, BADARG);
-}
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index 318a4fd264..f90fae6041 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -668,7 +668,7 @@ gcbif erlang:ceil/1
bif math:floor/1
bif math:ceil/1
bif math:fmod/2
-bif erts_internal:set_signal/2
+bif os:set_signal/2
#
# Obsolete
diff --git a/erts/emulator/beam/erl_bif_os.c b/erts/emulator/beam/erl_bif_os.c
index 46777d3aa5..edc3c82b23 100644
--- a/erts/emulator/beam/erl_bif_os.c
+++ b/erts/emulator/beam/erl_bif_os.c
@@ -203,3 +203,17 @@ BIF_RETTYPE os_unsetenv_1(BIF_ALIST_1)
}
BIF_RET(am_true);
}
+
+BIF_RETTYPE os_set_signal_2(BIF_ALIST_2) {
+ if (is_atom(BIF_ARG_1) && ((BIF_ARG_2 == am_ignore) ||
+ (BIF_ARG_2 == am_default) ||
+ (BIF_ARG_2 == am_handle))) {
+ if (!erts_set_signal(BIF_ARG_1, BIF_ARG_2))
+ goto error;
+
+ BIF_RET(am_ok);
+ }
+
+error:
+ BIF_ERROR(BIF_P, BADARG);
+}
diff --git a/erts/emulator/test/os_signal_SUITE.erl b/erts/emulator/test/os_signal_SUITE.erl
index 7c3950114f..9aa49a453e 100644
--- a/erts/emulator/test/os_signal_SUITE.erl
+++ b/erts/emulator/test/os_signal_SUITE.erl
@@ -92,9 +92,9 @@ set_unset(_Config) ->
sigusr1, sigusr2,
sigchld,
sigstop, sigtstp],
- F1 = fun(Sig) -> true = erts_internal:set_signal(Sig,handle) end,
- F2 = fun(Sig) -> true = erts_internal:set_signal(Sig,default) end,
- F3 = fun(Sig) -> true = erts_internal:set_signal(Sig,ignore) end,
+ F1 = fun(Sig) -> ok = os:set_signal(Sig,handle) end,
+ F2 = fun(Sig) -> ok = os:set_signal(Sig,default) end,
+ F3 = fun(Sig) -> ok = os:set_signal(Sig,ignore) end,
%% set handle
ok = lists:foreach(F1, Signals),
%% set ignore
@@ -106,7 +106,7 @@ set_unset(_Config) ->
t_sighup(_Config) ->
Pid1 = setup_service(),
OsPid = os:getpid(),
- erts_internal:set_signal(sighup, handle),
+ os:set_signal(sighup, handle),
ok = kill("HUP", OsPid),
ok = kill("HUP", OsPid),
ok = kill("HUP", OsPid),
@@ -121,7 +121,7 @@ t_sighup(_Config) ->
ok = kill("HUP", OsPid),
%% ignore
Pid2 = setup_service(),
- erts_internal:set_signal(sighup, ignore),
+ os:set_signal(sighup, ignore),
ok = kill("HUP", OsPid),
ok = kill("HUP", OsPid),
ok = kill("HUP", OsPid),
@@ -129,13 +129,13 @@ t_sighup(_Config) ->
io:format("Msgs2: ~p~n", [Msgs2]),
[] = Msgs2,
%% reset to handle (it's the default)
- erts_internal:set_signal(sighup, handle),
+ os:set_signal(sighup, handle),
ok.
t_sigusr1(_Config) ->
Pid1 = setup_service(),
OsPid = os:getpid(),
- erts_internal:set_signal(sigusr1, handle),
+ os:set_signal(sigusr1, handle),
ok = kill("USR1", OsPid),
ok = kill("USR1", OsPid),
ok = kill("USR1", OsPid),
@@ -150,7 +150,7 @@ t_sigusr1(_Config) ->
ok = kill("USR1", OsPid),
%% ignore
Pid2 = setup_service(),
- erts_internal:set_signal(sigusr1, ignore),
+ os:set_signal(sigusr1, ignore),
ok = kill("USR1", OsPid),
ok = kill("USR1", OsPid),
ok = kill("USR1", OsPid),
@@ -158,13 +158,13 @@ t_sigusr1(_Config) ->
io:format("Msgs2: ~p~n", [Msgs2]),
[] = Msgs2,
%% reset to ignore (it's the default)
- erts_internal:set_signal(sigusr1, handle),
+ os:set_signal(sigusr1, handle),
ok.
t_sigusr2(_Config) ->
Pid1 = setup_service(),
OsPid = os:getpid(),
- erts_internal:set_signal(sigusr2, handle),
+ os:set_signal(sigusr2, handle),
ok = kill("USR2", OsPid),
ok = kill("USR2", OsPid),
ok = kill("USR2", OsPid),
@@ -179,7 +179,7 @@ t_sigusr2(_Config) ->
ok = kill("USR2", OsPid),
%% ignore
Pid2 = setup_service(),
- erts_internal:set_signal(sigusr2, ignore),
+ os:set_signal(sigusr2, ignore),
ok = kill("USR2", OsPid),
ok = kill("USR2", OsPid),
ok = kill("USR2", OsPid),
@@ -187,13 +187,13 @@ t_sigusr2(_Config) ->
io:format("Msgs2: ~p~n", [Msgs2]),
[] = Msgs2,
%% reset to ignore (it's the default)
- erts_internal:set_signal(sigusr2, ignore),
+ os:set_signal(sigusr2, ignore),
ok.
t_sigterm(_Config) ->
Pid1 = setup_service(),
OsPid = os:getpid(),
- erts_internal:set_signal(sigterm, handle),
+ os:set_signal(sigterm, handle),
ok = kill("TERM", OsPid),
ok = kill("TERM", OsPid),
ok = kill("TERM", OsPid),
@@ -208,7 +208,7 @@ t_sigterm(_Config) ->
ok = kill("TERM", OsPid),
%% ignore
Pid2 = setup_service(),
- erts_internal:set_signal(sigterm, ignore),
+ os:set_signal(sigterm, ignore),
ok = kill("TERM", OsPid),
ok = kill("TERM", OsPid),
ok = kill("TERM", OsPid),
@@ -216,13 +216,13 @@ t_sigterm(_Config) ->
io:format("Msgs2: ~p~n", [Msgs2]),
[] = Msgs2,
%% reset to handle (it's the default)
- erts_internal:set_signal(sigterm, handle),
+ os:set_signal(sigterm, handle),
ok.
t_sigchld(_Config) ->
Pid1 = setup_service(),
OsPid = os:getpid(),
- erts_internal:set_signal(sigchld, handle),
+ os:set_signal(sigchld, handle),
ok = kill("CHLD", OsPid),
ok = kill("CHLD", OsPid),
ok = kill("CHLD", OsPid),
@@ -237,7 +237,7 @@ t_sigchld(_Config) ->
ok = kill("CHLD", OsPid),
%% ignore
Pid2 = setup_service(),
- erts_internal:set_signal(sigchld, ignore),
+ os:set_signal(sigchld, ignore),
ok = kill("CHLD", OsPid),
ok = kill("CHLD", OsPid),
ok = kill("CHLD", OsPid),
@@ -245,19 +245,19 @@ t_sigchld(_Config) ->
io:format("Msgs2: ~p~n", [Msgs2]),
[] = Msgs2,
%% reset to handle (it's the default)
- erts_internal:set_signal(sigchld, ignore),
+ os:set_signal(sigchld, ignore),
ok.
t_sigalrm(_Config) ->
Pid1 = setup_service(),
- true = erts_internal:set_signal(sigalrm, handle),
+ ok = os:set_signal(sigalrm, handle),
ok = os_signal_SUITE:set_alarm(1),
receive after 3000 -> ok end,
Msgs1 = fetch_msgs(Pid1),
[{notify,sigalrm}] = Msgs1,
io:format("Msgs1: ~p~n", [Msgs1]),
- erts_internal:set_signal(sigalrm, ignore),
+ os:set_signal(sigalrm, ignore),
Pid2 = setup_service(),
ok = os_signal_SUITE:set_alarm(1),
receive after 3000 -> ok end,
@@ -265,18 +265,18 @@ t_sigalrm(_Config) ->
[] = Msgs2,
io:format("Msgs2: ~p~n", [Msgs2]),
Pid3 = setup_service(),
- erts_internal:set_signal(sigalrm, handle),
+ os:set_signal(sigalrm, handle),
ok = os_signal_SUITE:set_alarm(1),
receive after 3000 -> ok end,
Msgs3 = fetch_msgs(Pid3),
[{notify,sigalrm}] = Msgs3,
io:format("Msgs3: ~p~n", [Msgs3]),
- erts_internal:set_signal(sigalrm, ignore),
+ os:set_signal(sigalrm, ignore),
ok.
t_sigchld_fork(_Config) ->
Pid1 = setup_service(),
- true = erts_internal:set_signal(sigchld, handle),
+ ok = os:set_signal(sigchld, handle),
{ok,OsPid} = os_signal_SUITE:fork(),
receive after 3000 -> ok end,
Msgs1 = fetch_msgs(Pid1),
@@ -286,7 +286,7 @@ t_sigchld_fork(_Config) ->
io:format("exit status from ~w : ~w~n", [OsPid,Status]),
42 = Status,
%% reset to ignore (it's the default)
- erts_internal:set_signal(sigchld, ignore),
+ os:set_signal(sigchld, ignore),
ok.
--
cgit v1.2.3
From 808b2f4d53e446aed07f85716c5c4b85abb3d18a Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Thu, 2 Feb 2017 16:08:38 +0100
Subject: erts: Add size of literals to module code size
in crash dump and (l)oaded command in break menu.
---
erts/emulator/beam/break.c | 26 ++++++++++++++++++--------
1 file changed, 18 insertions(+), 8 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 61907cc7ff..5d34c83c1a 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -379,6 +379,16 @@ info(fmtfn_t to, void *to_arg)
}
+static int code_size(struct erl_module_instance* modi)
+{
+ ErtsLiteralArea* lit = modi->code_hdr->literal_area;
+ int size = modi->code_length;
+ if (lit) {
+ size += (lit->end - lit->start) * sizeof(Eterm);
+ }
+ return size;
+}
+
void
loaded(fmtfn_t to, void *to_arg)
{
@@ -399,9 +409,9 @@ loaded(fmtfn_t to, void *to_arg)
if ((modp = module_code(i, code_ix)) != NULL &&
((modp->curr.code_length != 0) ||
(modp->old.code_length != 0))) {
- cur += modp->curr.code_length;
+ cur += code_size(&modp->curr);
if (modp->old.code_length != 0) {
- old += modp->old.code_length;
+ old += code_size(&modp->old);
}
}
}
@@ -422,12 +432,12 @@ loaded(fmtfn_t to, void *to_arg)
((modp->curr.code_length != 0) ||
(modp->old.code_length != 0))) {
erts_print(to, to_arg, "%T", make_atom(modp->module));
- cur += modp->curr.code_length;
- erts_print(to, to_arg, " %d", modp->curr.code_length );
+ cur += code_size(&modp->curr);
+ erts_print(to, to_arg, " %d", code_size(&modp->curr));
if (modp->old.code_length != 0) {
erts_print(to, to_arg, " (%d old)",
- modp->old.code_length );
- old += modp->old.code_length;
+ code_size(&modp->old));
+ old += code_size(&modp->old);
}
erts_print(to, to_arg, "\n");
}
@@ -442,7 +452,7 @@ loaded(fmtfn_t to, void *to_arg)
erts_print(to, to_arg, "%T", make_atom(modp->module));
erts_print(to, to_arg, "\n");
erts_print(to, to_arg, "Current size: %d\n",
- modp->curr.code_length);
+ code_size(&modp->curr));
code = modp->curr.code_hdr;
if (code != NULL && code->attr_ptr) {
erts_print(to, to_arg, "Current attributes: ");
@@ -456,7 +466,7 @@ loaded(fmtfn_t to, void *to_arg)
}
if (modp->old.code_length != 0) {
- erts_print(to, to_arg, "Old size: %d\n", modp->old.code_length);
+ erts_print(to, to_arg, "Old size: %d\n", code_size(&modp->old));
code = modp->old.code_hdr;
if (code->attr_ptr) {
erts_print(to, to_arg, "Old attributes: ");
--
cgit v1.2.3
From 9d927001ba16517042d3099612a2c9b130c6f62a Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Thu, 2 Feb 2017 19:21:36 +0100
Subject: Dirty schedulers should not touch scheduler data pointed to by
process struct
---
erts/emulator/beam/erl_process.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index b345c35a7e..cfa2b62061 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -9598,7 +9598,8 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls)
esdp->current_process = NULL;
#ifdef ERTS_SMP
- p->scheduler_data = NULL;
+ if (is_normal_sched)
+ p->scheduler_data = NULL;
#endif
erts_smp_proc_unlock(p, (ERTS_PROC_LOCK_MAIN
@@ -10013,8 +10014,8 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls)
state = erts_smp_atomic32_read_nob(&p->state);
- ASSERT(!p->scheduler_data);
#ifndef ERTS_DIRTY_SCHEDULERS
+ ASSERT(!p->scheduler_data);
p->scheduler_data = esdp;
#else /* ERTS_DIRTY_SCHEDULERS */
if (is_normal_sched) {
@@ -10025,6 +10026,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls)
erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS);
goto sched_out_proc;
}
+ ASSERT(!p->scheduler_data);
p->scheduler_data = esdp;
}
else {
--
cgit v1.2.3
From ea530357b27635278ae8a3260e735ea39df5c283 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn-Egil=20Dahlberg?=
Date: Fri, 3 Feb 2017 12:05:49 +0100
Subject: Fix merge commit
This fixes commit f0867aa2ccbbf5677e0577bba08f8b7bc53ec0ed
---
erts/emulator/beam/erl_init.c | 1 -
erts/emulator/sys/unix/sys.c | 46 -------------------------------------------
2 files changed, 47 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 2fd97208cc..070cc3f2d0 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -2220,7 +2220,6 @@ erl_start(int argc, char **argv)
init_break_handler();
if (replace_intr)
erts_replace_intr();
- sys_init_suspend_handler();
#endif
boot_argc = argc - i; /* Number of arguments to init */
diff --git a/erts/emulator/sys/unix/sys.c b/erts/emulator/sys/unix/sys.c
index fa95473db8..e135dbff99 100644
--- a/erts/emulator/sys/unix/sys.c
+++ b/erts/emulator/sys/unix/sys.c
@@ -819,61 +819,15 @@ void init_break_handler(void)
}
void sys_init_suspend_handler(void)
-<<<<<<< HEAD
{
#ifdef ERTS_SYS_SUSPEND_SIGNAL
sys_signal(ERTS_SYS_SUSPEND_SIGNAL, suspend_signal);
-=======
-{
-#ifdef ERTS_SYS_SUSPEND_SIGNAL
- sys_signal(ERTS_SYS_SUSPEND_SIGNAL, suspend_signal);
-#endif
-}
-
-int sys_max_files(void)
-{
- return(max_files);
-}
-
-static void block_signals(void)
-{
-#if !CHLDWTHR
- sys_sigblock(SIGCHLD);
-#endif
-#ifndef ERTS_SMP
- sys_sigblock(SIGINT);
-#ifndef ETHR_UNUSABLE_SIGUSRX
- sys_sigblock(SIGUSR1);
-#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
-#endif /* #ifndef ERTS_SMP */
-
-#ifdef ERTS_SYS_SUSPEND_SIGNAL
- sys_sigblock(ERTS_SYS_SUSPEND_SIGNAL);
->>>>>>> maint-18
#endif
}
int sys_max_files(void)
{
-<<<<<<< HEAD
return(max_files);
-=======
- /* Update erl_child_setup.c if changed */
-#if !CHLDWTHR
- sys_sigrelease(SIGCHLD);
-#endif
-#ifndef ERTS_SMP
- sys_sigrelease(SIGINT);
-#ifndef ETHR_UNUSABLE_SIGUSRX
- sys_sigrelease(SIGUSR1);
-#endif /* #ifndef ETHR_UNUSABLE_SIGUSRX */
-#endif /* #ifndef ERTS_SMP */
-
-#ifdef ERTS_SYS_SUSPEND_SIGNAL
- sys_sigrelease(ERTS_SYS_SUSPEND_SIGNAL);
-#endif
-
->>>>>>> maint-18
}
/************************** OS info *******************************/
--
cgit v1.2.3
From 7eff21e2b0b86f798cce29835cd85a414d3d1be5 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Thu, 2 Feb 2017 18:19:49 +0100
Subject: Use a hole-marker that cannot be mistaken for a valid term on the
heap
---
erts/emulator/beam/erl_init.c | 5 +++++
erts/emulator/beam/erl_vm.h | 17 +++++++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 2fd97208cc..6c744553c3 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -117,6 +117,11 @@ const int etp_big_endian = 1;
const int etp_big_endian = 0;
#endif
const Eterm etp_the_non_value = THE_NON_VALUE;
+#ifdef ERTS_HOLE_MARKER
+const Eterm etp_hole_marker = ERTS_HOLE_MARKER;
+#else
+const Eterm etp_hole_marker = 0;
+#endif
/*
* Note about VxWorks: All variables must be initialized by executable code,
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index f97716d030..899e2a275a 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -110,8 +110,21 @@
#define HeapWordsLeft(p) (HEAP_LIMIT(p) - HEAP_TOP(p))
#if defined(DEBUG) || defined(CHECK_FOR_HOLES)
-# define ERTS_HOLE_MARKER (((0xdeadbeef << 24) << 8) | 0xdeadbeef)
-#endif /* egil: 32-bit ? */
+
+/*
+ * ERTS_HOLE_MARKER must *not* be mistaken for a valid term
+ * on the heap...
+ */
+# ifdef ARCH_64
+# define ERTS_HOLE_MARKER \
+ make_catch(UWORD_CONSTANT(0xdeadbeaf00000000) >> _TAG_IMMED2_SIZE)
+/* Will (at the time of writing) appear as 0xdeadbeaf0000001b */
+# else
+# define ERTS_HOLE_MARKER \
+ make_catch(UWORD_CONSTANT(0xdead0000) >> _TAG_IMMED2_SIZE)
+/* Will (at the time of writing) appear as 0xdead001b */
+# endif
+#endif
/*
* Allocate heap memory on the ordinary heap, NEVER in a heap
--
cgit v1.2.3
From fc0477a67641b9ba344de595b7fec2431208f8e6 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Tue, 24 Jan 2017 19:50:25 +0100
Subject: Atomic reference count of binaries also in non-SMP
NIF resources was not handled in a thread-safe manner in the runtime
system without SMP support.
As a consequence of this fix, the following driver functions are now
thread-safe also in the runtime system without SMP support:
- driver_free_binary()
- driver_realloc_binary()
- driver_binary_get_refc()
- driver_binary_inc_refc()
- driver_binary_dec_refc()
---
erts/doc/src/erl_driver.xml | 15 ++--
erts/emulator/beam/beam_bp.c | 18 ++---
erts/emulator/beam/beam_bp.h | 6 +-
erts/emulator/beam/beam_emu.c | 2 +-
erts/emulator/beam/beam_load.c | 4 +-
erts/emulator/beam/break.c | 2 +-
erts/emulator/beam/copy.c | 12 ++--
erts/emulator/beam/dist.c | 4 +-
erts/emulator/beam/erl_bif_ddll.c | 22 +++---
erts/emulator/beam/erl_bif_info.c | 2 +-
erts/emulator/beam/erl_db.c | 20 +++---
erts/emulator/beam/erl_db_util.c | 2 +-
erts/emulator/beam/erl_db_util.h | 4 +-
erts/emulator/beam/erl_fun.c | 20 +++---
erts/emulator/beam/erl_fun.h | 2 +-
erts/emulator/beam/erl_gc.c | 6 +-
erts/emulator/beam/erl_message.c | 2 +-
erts/emulator/beam/erl_monitors.c | 2 +-
erts/emulator/beam/erl_node_tables.c | 50 ++++++-------
erts/emulator/beam/erl_node_tables.h | 8 +--
erts/emulator/beam/erl_process_dump.c | 2 +-
erts/emulator/beam/external.c | 2 +-
erts/emulator/beam/global.h | 2 +-
erts/emulator/beam/io.c | 31 ++------
erts/emulator/beam/sys.h | 128 +++++++++++++++++++++++++++++++---
erts/emulator/beam/utils.c | 2 +-
erts/emulator/hipe/hipe_bif0.c | 2 +-
erts/emulator/hipe/hipe_native_bif.c | 2 +-
28 files changed, 226 insertions(+), 148 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml
index d8bf45c523..7fbe97bc0b 100644
--- a/erts/doc/src/erl_driver.xml
+++ b/erts/doc/src/erl_driver.xml
@@ -1103,8 +1103,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]>
Decrements the reference count on bin and returns
the reference count reached after the decrement.
-
This function is only thread-safe when the emulator with SMP
- support is used.
+
This function is thread-safe.
The reference count of driver binary is normally to be decremented
by calling
@@ -1124,8 +1123,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]>
Returns the current reference count on bin.
-
This function is only thread-safe when the emulator with SMP
- support is used.
Increments the reference count on bin and returns
the reference count reached after the increment.
-
This function is only thread-safe when the emulator with SMP
- support is used.
+
This function is thread-safe.
@@ -1434,8 +1431,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]>
driver_alloc_binary. As binaries
in Erlang are reference counted, the binary can still be around.
-
This function is only thread-safe when the emulator with SMP
- support is used.
This document describes the changes made to the ERTS application.
+Erts 8.2.2
+
+ Fixed Bugs and Malfunctions
+
+
+
+ Fix bug in binary_to_term for binaries created by
+ term_to_binary with option compressed. The
+ bug can cause badarg exception for a valid binary
+ when Erlang VM is linked against a zlib library of
+ version 1.2.9 or newer. Bug exists since OTP 17.0.
+
+ Own Id: OTP-14159 Aux Id: ERL-340
+
+
+
+ The driver efile_drv when opening a file now use fstat()
+ on the open file instead of stat() before opening, if
+ fstat() exists. This avoids a race when the file happens
+ to change between stat() and open().
+
+ Own Id: OTP-14184 Aux Id: seq-13266
+
+
+
+
+
+
Erts 8.2.1Fixed Bugs and Malfunctions
diff --git a/erts/vsn.mk b/erts/vsn.mk
index 028b114068..a0a991f5a9 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 8.2.1
+VSN = 8.2.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3
--
cgit v1.2.3
From a205dbb70d4712855c7271fd9cbd3c186863aba8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Wed, 8 Feb 2017 12:36:52 +0100
Subject: Include more otp_SUITE tests cases in the smoke test
For the benefit of Travis CI, include more test cases from
otp_SUITE in the smoke test. That will avoid having to run
a pull request through the daily builds to find those kind
of minor issues.
---
erts/test/system_smoke.spec | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
(limited to 'erts')
diff --git a/erts/test/system_smoke.spec b/erts/test/system_smoke.spec
index 933d1ba22d..99092c1dab 100644
--- a/erts/test/system_smoke.spec
+++ b/erts/test/system_smoke.spec
@@ -1,3 +1,8 @@
{suites,"../system_test",[ethread_SUITE]}.
-{cases,"../system_test",otp_SUITE,[undefined_functions]}.
+{cases,"../system_test",otp_SUITE,
+ [undefined_functions,
+ deprecated_not_in_obsolete,
+ obsolete_but_not_deprecated,
+ call_to_size_1,
+ call_to_now_0]}.
{skip_cases,"../system_test",ethread_SUITE,[max_threads],"Skip"}.
--
cgit v1.2.3
From 7e9f0932f9d06edca0c30d4a2b9d57f34677344c Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Tue, 31 Jan 2017 13:30:20 +0100
Subject: Magic indirection
---
erts/emulator/beam/erl_alloc.c | 2 ++
erts/emulator/beam/erl_alloc.types | 1 +
erts/emulator/beam/erl_binary.h | 44 ++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_alloc.c b/erts/emulator/beam/erl_alloc.c
index e433de0f35..6708d96d56 100644
--- a/erts/emulator/beam/erl_alloc.c
+++ b/erts/emulator/beam/erl_alloc.c
@@ -684,6 +684,8 @@ erts_alloc_init(int *argc, char **argv, ErtsAllocInitOpts *eaiop)
= sizeof(NifExportTrace);
fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MREF_NSCHED_ENT)]
= sizeof(ErtsNSchedMagicRefTableEntry);
+ fix_type_sizes[ERTS_ALC_FIX_TYPE_IX(ERTS_ALC_T_MINDIRECTION)]
+ = ERTS_MAGIC_BIN_UNALIGNED_SIZE(sizeof(ErtsMagicIndirectionWord));
#ifdef HARD_DEBUG
hdbg_init();
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index c253ea82c8..f88985b7f5 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -284,6 +284,7 @@ type MREF_NSCHED_ENT FIXED_SIZE SYSTEM nsched_magic_ref_entry
type MREF_ENT STANDARD SYSTEM magic_ref_entry
type MREF_TAB_BKTS STANDARD SYSTEM magic_ref_table_buckets
type MREF_TAB LONG_LIVED SYSTEM magic_ref_table
+type MINDIRECTION FIXED_SIZE SYSTEM magic_indirection
+if threads_no_smp
# Need thread safe allocs, but std_alloc and fix_alloc are not;
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index c811a002ce..4d9c4d6eac 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -300,6 +300,17 @@ BIF_RETTYPE erts_gc_binary_part(Process *p, Eterm *reg, Eterm live, int range_is
BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen);
+typedef union {
+ /*
+ * These two are almost always of
+ * the same size, but when fallback
+ * atomics are used they might
+ * differ in size.
+ */
+ erts_smp_atomic_t smp_atomic_word;
+ erts_atomic_t atomic_word;
+} ErtsMagicIndirectionWord;
+
#if defined(__i386__) || !defined(__GNUC__)
/*
* Doubles aren't required to be 8-byte aligned on intel x86.
@@ -329,6 +340,9 @@ ERTS_GLB_INLINE Binary *erts_create_magic_binary_x(Uint size,
int unaligned);
ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
void (*destructor)(Binary *));
+ERTS_GLB_INLINE Binary *erts_create_magic_indirection(void (*destructor)(Binary *));
+ERTS_GLB_INLINE erts_smp_atomic_t *erts_smp_binary_to_magic_indirection(Binary *bp);
+ERTS_GLB_INLINE erts_atomic_t *erts_binary_to_magic_indirection(Binary *bp);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
@@ -496,6 +510,36 @@ erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
ERTS_ALC_T_BINARY, 0);
}
+ERTS_GLB_INLINE Binary *
+erts_create_magic_indirection(void (*destructor)(Binary *))
+{
+ return erts_create_magic_binary_x(sizeof(ErtsMagicIndirectionWord),
+ destructor,
+ ERTS_ALC_T_MINDIRECTION,
+ 1); /* Not 64-bit aligned,
+ but word aligned */
+}
+
+ERTS_GLB_INLINE erts_smp_atomic_t *
+erts_smp_binary_to_magic_indirection(Binary *bp)
+{
+ ErtsMagicIndirectionWord *mip;
+ ASSERT(bp->flags & BIN_FLAG_MAGIC);
+ ASSERT(ERTS_MAGIC_BIN_ATYPE(bp) == ERTS_ALC_T_MINDIRECTION);
+ mip = ERTS_MAGIC_BIN_UNALIGNED_DATA(bp);
+ return &mip->smp_atomic_word;
+}
+
+ERTS_GLB_INLINE erts_atomic_t *
+erts_binary_to_magic_indirection(Binary *bp)
+{
+ ErtsMagicIndirectionWord *mip;
+ ASSERT(bp->flags & BIN_FLAG_MAGIC);
+ ASSERT(ERTS_MAGIC_BIN_ATYPE(bp) == ERTS_ALC_T_MINDIRECTION);
+ mip = ERTS_MAGIC_BIN_UNALIGNED_DATA(bp);
+ return &mip->atomic_word;
+}
+
#endif /* #if ERTS_GLB_INLINE_INCL_FUNC_DEF */
#endif /* !ERL_BINARY_H__ */
--
cgit v1.2.3
From 7c06ca6231b812965305522284dd9f2653ced98d Mon Sep 17 00:00:00 2001
From: Andrew Dryga
Date: Tue, 14 Feb 2017 11:30:41 +0200
Subject: Fixed typos in erts
---
erts/doc/src/erl.xml | 6 +++---
erts/doc/src/erl_tracer.xml | 2 +-
erts/doc/src/erlang.xml | 2 +-
erts/doc/src/erts_alloc.xml | 2 +-
erts/doc/src/notes.xml | 14 +++++++-------
erts/emulator/beam/beam_emu.c | 10 +++++-----
erts/emulator/beam/bif.c | 4 ++--
erts/emulator/beam/binary.c | 4 ++--
erts/emulator/beam/dist.c | 4 ++--
erts/emulator/beam/dist.h | 4 ++--
erts/emulator/beam/dtrace-wrapper.h | 2 +-
erts/emulator/beam/erl_alloc.types | 2 +-
erts/emulator/beam/erl_alloc_util.c | 4 ++--
erts/emulator/beam/erl_bif_binary.c | 2 +-
erts/emulator/beam/erl_gc.c | 2 +-
erts/emulator/beam/erl_lock_count.h | 2 +-
erts/emulator/beam/erl_monitors.c | 4 ++--
erts/emulator/beam/erl_process.c | 2 +-
erts/emulator/beam/erl_ptab.c | 2 +-
erts/emulator/beam/erl_time_sup.c | 2 +-
erts/emulator/beam/io.c | 2 +-
erts/emulator/drivers/common/efile_drv.c | 6 +++---
erts/emulator/drivers/common/gzio.c | 2 +-
erts/emulator/drivers/common/inet_drv.c | 4 ++--
erts/emulator/drivers/unix/sig_drv.c | 2 +-
erts/emulator/internal_doc/DelayedDealloc.md | 18 +++++++++---------
erts/emulator/internal_doc/PortSignals.md | 2 +-
erts/emulator/internal_doc/SuperCarrier.md | 2 +-
erts/emulator/internal_doc/ThreadProgress.md | 8 ++++----
erts/emulator/internal_doc/Tracing.md | 2 +-
erts/emulator/pcre/pcre_exec.c | 2 +-
erts/emulator/sys/common/erl_mseg.c | 2 +-
erts/emulator/sys/unix/erl_child_setup.h | 2 +-
erts/emulator/sys/win32/erl_poll.c | 6 +++---
erts/emulator/sys/win32/sys.c | 8 ++++----
erts/emulator/test/binary_SUITE.erl | 2 +-
erts/emulator/test/bs_match_int_SUITE.erl | 2 +-
erts/emulator/test/call_trace_SUITE.erl | 2 +-
erts/emulator/test/ddll_SUITE.erl | 2 +-
erts/emulator/test/dirty_nif_SUITE.erl | 2 +-
erts/emulator/test/estone_SUITE.erl | 2 +-
erts/emulator/test/float_SUITE.erl | 2 +-
erts/emulator/test/hibernate_SUITE.erl | 2 +-
erts/emulator/test/match_spec_SUITE.erl | 2 +-
erts/emulator/test/node_container_SUITE.erl | 2 +-
erts/emulator/test/num_bif_SUITE.erl | 2 +-
erts/emulator/test/port_SUITE.erl | 2 +-
erts/emulator/test/port_SUITE_data/port_test.c | 2 +-
erts/emulator/test/port_bif_SUITE_data/port_test.c | 2 +-
erts/emulator/test/system_info_SUITE.erl | 2 +-
erts/emulator/test/time_SUITE.erl | 2 +-
erts/emulator/test/z_SUITE.erl | 2 +-
erts/epmd/test/epmd_SUITE.erl | 2 +-
erts/etc/common/inet_gethost.c | 2 +-
erts/etc/unix/README | 2 +-
erts/etc/unix/etp-commands.in | 2 +-
erts/etc/unix/run_erl.c | 2 +-
erts/include/internal/gcc/ethr_atomic.h | 2 +-
erts/include/internal/gcc/ethr_dw_atomic.h | 2 +-
59 files changed, 96 insertions(+), 96 deletions(-)
(limited to 'erts')
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index 4e32118405..29fef7348b 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -638,7 +638,7 @@
this value also applies to command-line parameters and environment
variables (see section
- Unicode in Enviroment and Parameters in the STDLIB
+ Unicode in Environment and Parameters in the STDLIB
User's Guide).
@@ -674,7 +674,7 @@
this value also applies to command-line parameters and environment
variables (see section
- Unicode in Enviroment and Parameters in the STDLIB
+ Unicode in Environment and Parameters in the STDLIB
User's Guide).
@@ -695,7 +695,7 @@
this value also applies to command-line parameters and environment
variables (see section
- Unicode in Enviroment and Parameters in the STDLIB
+ Unicode in Environment and Parameters in the STDLIB
User's Guide).
diff --git a/erts/doc/src/erl_tracer.xml b/erts/doc/src/erl_tracer.xml
index 43613c31b1..2681a19da0 100644
--- a/erts/doc/src/erl_tracer.xml
+++ b/erts/doc/src/erl_tracer.xml
@@ -103,7 +103,7 @@
If set the tracer has been requested to include a
time stamp.extra
- If set the tracepoint has included additonal data about
+ If set the tracepoint has included additional data about
the trace event. What the additional data is depends on which
TraceTag has been triggered. The extra trace data
corresponds to the fifth element in the trace tuples described in
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 8d340a15f5..352d30f3b4 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -4591,7 +4591,7 @@ RealSystem = system + MissedSystem
If the process potentially can get many messages,
you are advised to set the flag to off_heap. This
because a garbage collection with many messages placed on
- the heap can become extremly expensive and the process can
+ the heap can become extremely expensive and the process can
consume large amounts of memory. Performance of the
actual message passing is however generally better when not
using flag off_heap.
diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml
index 8ab35851c1..49dadfb42c 100644
--- a/erts/doc/src/erts_alloc.xml
+++ b/erts/doc/src/erts_alloc.xml
@@ -452,7 +452,7 @@
utilization value > 0 is used, allocator instances
are allowed to abandon multiblock carriers. If de (default
enabled) is passed instead of a ]]>,
- a recomended non-zero utilization value is used. The value
+ a recommended non-zero utilization value is used. The value
chosen depends on the allocator type and can be changed between
ERTS versions. Defaults to de, but this
can be changed in the future.
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index ae1d2b1d93..05142c9338 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -564,7 +564,7 @@
- Fixed a VM crash that occured in a garbage collection of
+ Fixed a VM crash that occurred in a garbage collection of
a process when it had received binaries. This bug was
introduced in ERTS version 8.0 (OTP 19.0).
@@ -581,7 +581,7 @@
- Fixed a VM crash that occured in garbage collection of a
+ Fixed a VM crash that occurred in garbage collection of a
process when it had received maps over the distribution.
This bug was introduced in ERTS version 8.0 (OTP 19.0).
@@ -5682,7 +5682,7 @@
dependent, so applications aiming to be portable should
consider using {ipv6_v6only,true} when creating an
inet6 listening/destination socket, and if
- neccesary also create an inet socket on the same
+ necessary also create an inet socket on the same
port for IPv4 traffic. See the documentation.
Own Id: OTP-8928 Aux Id: kunagi-193 [104]
@@ -6063,7 +6063,7 @@
This change of default value will reduce lock contention
on ETS tables using the read_concurrency option at
the expense of memory consumption when the amount of
- schedulers and logical processors are beween 8 and 64.
+ schedulers and logical processors are between 8 and 64.
For more information, see documentation of the +rg
command line argument of erl(1).
@@ -7040,7 +7040,7 @@
For the subsection about process_flag(save_calls, N)
there's an unrelated paragraph about process priorities
- which was copied from the preceeding subsection regarding
+ which was copied from the preceding subsection regarding
process_flag(priority, Level). (Thanks to Filipe David
Manana)
@@ -8255,7 +8255,7 @@
Wx on MacOS X generated complains on stderr about certain
- cocoa functions not beeing called from the "Main thread".
+ cocoa functions not being called from the "Main thread".
This is now corrected.
Own Id: OTP-9081
@@ -9246,7 +9246,7 @@
The empd program could loop and consume 100%
- CPU time if an unexpected error ocurred in
+ CPU time if an unexpected error occurred in
listen() or accept(). Now epmd will
terminate if a non-recoverable error occurs. (Thanks to
Michael Santos.)
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 5e275c8fc5..49f932a1c2 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -126,7 +126,7 @@ do { \
/*
* We reuse some of fields in the save area in the process structure.
- * This is safe to do, since this space is only activly used when
+ * This is safe to do, since this space is only actively used when
* the process is switched out.
*/
#define REDS_IN(p) ((p)->def_arg_reg[5])
@@ -220,7 +220,7 @@ BeamInstr* em_call_bif_e;
/* NOTE These should be the only variables containing trace instructions.
** Sometimes tests are form the instruction value, and sometimes
-** for the refering variable (one of these), and rouge references
+** for the referring variable (one of these), and rouge references
** will most likely cause chaos.
*/
BeamInstr beam_return_to_trace[1]; /* OpCode(i_return_to_trace) */
@@ -2993,7 +2993,7 @@ do { \
}
/*
- * An error occured in an arithmetic operation or test that could
+ * An error occurred in an arithmetic operation or test that could
* appear either in a head or in a body.
* In a head, execution should continue at failure address in Arg(0).
* In a body, Arg(0) == 0 and an exception should be raised.
@@ -6268,7 +6268,7 @@ apply_bif_error_adjustment(Process *p, Export *ep,
* stackframe correct. Without the following adjustment,
* 'p->cp' will point into the function that called
* current function when handling the error. We add a
- * dummy stackframe in order to achive this.
+ * dummy stackframe in order to achieve this.
*
* Note that these BIFs unconditionally will cause
* an exception to be raised. That is, our modifications
@@ -6612,7 +6612,7 @@ erts_hibernate(Process* c_p, Eterm module, Eterm function, Eterm args, Eterm* re
#ifndef ERTS_SMP
if (ERTS_PROC_IS_EXITING(c_p)) {
/*
- * See comment in the begining of the function...
+ * See comment in the beginning of the function...
*
* This second test is needed since gc might be traced.
*/
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 2190c47262..4c9b9887c1 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -467,7 +467,7 @@ demonitor_local_port(Process *origin, Eterm ref, Eterm target)
}
/* Can return atom true, false, yield, internal_error, badarg or
- * THE_NON_VALUE if error occured or trap has been set up
+ * THE_NON_VALUE if error occurred or trap has been set up
*/
static
BIF_RETTYPE demonitor(Process *c_p, Eterm ref, Eterm *multip)
@@ -597,7 +597,7 @@ BIF_RETTYPE demonitor_2(BIF_ALIST_2)
switch (demonitor(BIF_P, BIF_ARG_1, &multi)) {
case THE_NON_VALUE:
- /* If other error occured or trap has been set up - pass through */
+ /* If other error occurred or trap has been set up - pass through */
BIF_RET(THE_NON_VALUE);
case am_false:
if (info)
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index d38097fb12..8f907ee8a2 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -102,7 +102,7 @@ new_binary(Process *p, byte *buf, Uint len)
pb->flags = 0;
/*
- * Miscellanous updates. Return the tagged binary.
+ * Miscellaneous updates. Return the tagged binary.
*/
OH_OVERHEAD(&(MSO(p)), pb->size / sizeof(Eterm));
return make_binary(pb);
@@ -139,7 +139,7 @@ Eterm erts_new_mso_binary(Process *p, byte *buf, Uint len)
pb->flags = 0;
/*
- * Miscellanous updates. Return the tagged binary.
+ * Miscellaneous updates. Return the tagged binary.
*/
OH_OVERHEAD(&(MSO(p)), pb->size / sizeof(Eterm));
return make_binary(pb);
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 390f2a0db3..0d25eb123e 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -264,7 +264,7 @@ static void doit_monitor_net_exits(ErtsMonitor *mon, void *vnecp)
goto done;
if (mon->type == MON_ORIGIN) {
- /* local pid is beeing monitored */
+ /* local pid is being monitored */
rmon = erts_remove_monitor(&ERTS_P_MONITORS(rp), mon->ref);
/* ASSERT(rmon != NULL); nope, can happen during process exit */
if (rmon != NULL) {
@@ -795,7 +795,7 @@ erts_dsig_send_unlink(ErtsDSigData *dsdp, Eterm local, Eterm remote)
}
-/* A local process that's beeing monitored by a remote one exits. We send:
+/* A local process that's being monitored by a remote one exits. We send:
{DOP_MONITOR_P_EXIT, Local pid or name, Remote pid, ref, reason},
which is rather sad as only the ref is needed, no pid's... */
int
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index e82b416286..39670de506 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -115,8 +115,8 @@ extern int erts_is_alive;
* erts_dsig_prepare() prepares a send of a distributed signal.
* One of the values defined below are returned. If the returned
* value is another than ERTS_DSIG_PREP_CONNECTED, the
- * distributed signal cannot be sent before apropriate actions
- * have been taken. Apropriate actions would typically be setting
+ * distributed signal cannot be sent before appropriate actions
+ * have been taken. Appropriate actions would typically be setting
* up the connection.
*/
diff --git a/erts/emulator/beam/dtrace-wrapper.h b/erts/emulator/beam/dtrace-wrapper.h
index 6f70d5961e..f6fc28b801 100644
--- a/erts/emulator/beam/dtrace-wrapper.h
+++ b/erts/emulator/beam/dtrace-wrapper.h
@@ -74,7 +74,7 @@
#if defined(_SDT_PROBE) && !defined(STAP_PROBE11)
/* SLF: This is Ubuntu 11-style SystemTap hackery */
-/* work arround for missing STAP macro */
+/* workaround for missing STAP macro */
#define STAP_PROBE11(provider,name,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11) \
_SDT_PROBE(provider, name, 11, \
(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9,arg10,arg11))
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index f88985b7f5..295db2fe9b 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -65,7 +65,7 @@
# --- Allocator declarations -------------------------------------------------
#
-# If, and only if, the same thread performes *all* allocations,
+# If, and only if, the same thread performs *all* allocations,
# reallocations and deallocations of all memory types that are handled
# by a specific allocator ( in type declaration), set
# for this specific allocator to false; otherwise, set
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index d346f8c8b6..a6bac06478 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -5186,7 +5186,7 @@ erts_alcu_sz_info(Allctr_t *allctr,
ERTS_ALCU_DBG_CHK_THR_ACCESS(allctr);
- /* Update sbc values not continously updated */
+ /* Update sbc values not continuously updated */
allctr->sbcs.blocks.curr.no
= allctr->sbcs.curr.norm.mseg.no + allctr->sbcs.curr.norm.sys_alloc.no;
allctr->sbcs.blocks.max.no = allctr->sbcs.max.no;
@@ -5272,7 +5272,7 @@ erts_alcu_info(Allctr_t *allctr,
ERTS_ALCU_DBG_CHK_THR_ACCESS(allctr);
- /* Update sbc values not continously updated */
+ /* Update sbc values not continuously updated */
allctr->sbcs.blocks.curr.no
= allctr->sbcs.curr.norm.mseg.no + allctr->sbcs.curr.norm.sys_alloc.no;
allctr->sbcs.blocks.max.no = allctr->sbcs.max.no;
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index e57cd06cec..64a5c1cb29 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -380,7 +380,7 @@ static void ac_compute_failure_functions(ACTrie *act, ACNode **qbuff)
qbuff[qt++] = child;
/* Search for correct failure function, follow the parent's
failure function until you find a similar transition
- funtion to this child's */
+ function to this child's */
r = parent->h;
while (r != NULL && r->g[i] == NULL) {
r = r->h;
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index cb3a189e8f..8cc7fc0142 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -2834,7 +2834,7 @@ sweep_off_heap(Process *p, int fullsweep)
prev = &MSO(p).first;
ptr = MSO(p).first;
- /* Firts part of the list will reside on the (old) new-heap.
+ /* First part of the list will reside on the (old) new-heap.
* Keep if moved, otherwise deref.
*/
while (ptr) {
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index 4f838f7faa..71cd73ee27 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -129,7 +129,7 @@ typedef struct {
typedef struct erts_lcnt_lock_stats_s {
/* "tries" and "colls" needs to be atomic since
- * trylock busy does not aquire a lock and there
+ * trylock busy does not acquire a lock and there
* is no post action to rectify the situation
*/
diff --git a/erts/emulator/beam/erl_monitors.c b/erts/emulator/beam/erl_monitors.c
index bdfc7f30d9..f813f19dbc 100644
--- a/erts/emulator/beam/erl_monitors.c
+++ b/erts/emulator/beam/erl_monitors.c
@@ -24,7 +24,7 @@
* key in the monitor case and the pid of the linked process as key in the
* link case. Lookups the order of the references is somewhat special. Local
* references are strictly smaller than remote references and are sorted
- * by inlined comparision functionality. Remote references are handled by the
+ * by inlined comparison functionality. Remote references are handled by the
* usual cmp function.
* Each Monitor is tagged with different tags depending on which end of the
* monitor it is.
@@ -154,7 +154,7 @@ static ErtsMonitor *create_monitor(Uint type, Eterm ref, Eterm pid, Eterm name)
n->type = (Uint16) type;
n->balance = 0; /* Always the same initial value */
n->name = name; /* atom() or [] */
- CP_LINK_VAL(n->ref, hp, ref); /*XXX Unneccesary check, never immediate*/
+ CP_LINK_VAL(n->ref, hp, ref); /*XXX Unnecessary check, never immediate*/
CP_LINK_VAL(n->pid, hp, pid);
return n;
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 87d71fdd22..c5a7b67764 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -5050,7 +5050,7 @@ check_balance(ErtsRunQueue *c_rq)
sched_util_balancing = 1;
/*
* In order to avoid renaming a large amount of fields
- * we write utilization values instead of lenght values
+ * we write utilization values instead of length values
* in the 'max_len' and 'migration_limit' fields...
*/
for (qix = 0; qix < blnc_no_rqs; qix++) {
diff --git a/erts/emulator/beam/erl_ptab.c b/erts/emulator/beam/erl_ptab.c
index a132b1d334..828a029e84 100644
--- a/erts/emulator/beam/erl_ptab.c
+++ b/erts/emulator/beam/erl_ptab.c
@@ -474,7 +474,7 @@ erts_ptab_init_table(ErtsPTab *ptab,
* we don't want to shrink the size to ERTS_PTAB_MAX_SIZE/2.
*
* In order to fix this, we insert a pointer from the table
- * to the invalid_element, wich will be interpreted as a
+ * to the invalid_element, which will be interpreted as a
* slot currently being modified. This way we will be able to
* have ERTS_PTAB_MAX_SIZE-1 valid elements in the table while
* still having a table size of the power of 2.
diff --git a/erts/emulator/beam/erl_time_sup.c b/erts/emulator/beam/erl_time_sup.c
index 1d747e5fab..ed40539b78 100644
--- a/erts/emulator/beam/erl_time_sup.c
+++ b/erts/emulator/beam/erl_time_sup.c
@@ -1502,7 +1502,7 @@ static time_t gregday(int year, int month, int day)
pyear = gyear - 1;
ndays = (pyear/4) - (pyear/100) + (pyear/400) + pyear*365 + 366;
}
- /* number of days in all months preceeding month */
+ /* number of days in all months preceding month */
for (m = 1; m < month; m++)
ndays += mdays[m];
/* Extra day if leap year and March or later */
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index dad24d7ef6..7e49e9c48f 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -3431,7 +3431,7 @@ void erts_init_io(int port_tab_size,
NULL,
(ErtsPTabElementCommon *) &erts_invalid_port.common,
port_tab_size,
- common_element_size, /* Doesn't need to be excact */
+ common_element_size, /* Doesn't need to be exact */
"port_table",
legacy_port_tab,
1);
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index d64f015a6a..173a39533d 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -2331,9 +2331,9 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
free_read(data);
break;
case FILE_READ_LINE:
- /* The read_line stucture differs from the read structure.
- The data->read_offset and d->c.read_line.read_offset are copies, as are
- data->read_size and d->c.read_line.read_size
+ /* The read_line structure differs from the read structure.
+ The data->read_offset and d->c.read_line.read_offset are copies, as are
+ data->read_size and d->c.read_line.read_size
The read_line function does not kniow in advance how large the binary has to be,
why new allocation (but not reallocation of the old binary, for obvious reasons)
may happen in the worker thread. */
diff --git a/erts/emulator/drivers/common/gzio.c b/erts/emulator/drivers/common/gzio.c
index 1ef1602ec9..f60c781894 100644
--- a/erts/emulator/drivers/common/gzio.c
+++ b/erts/emulator/drivers/common/gzio.c
@@ -308,7 +308,7 @@ ErtsGzFile erts_gzopen (path, mode)
/* ===========================================================================
Read a byte from a gz_stream; update next_in and avail_in. Return EOF
for end of file.
- IN assertion: the stream s has been sucessfully opened for reading.
+ IN assertion: the stream s has been successfully opened for reading.
*/
local int get_byte(s)
gz_stream *s;
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 1885338ce5..278abe4e00 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -728,7 +728,7 @@ static int is_nonzero(const char *s, size_t n)
#define TCP_ADDF_PENDING_SHUTDOWN \
(TCP_ADDF_PENDING_SHUT_WR | TCP_ADDF_PENDING_SHUT_RDWR)
#define TCP_ADDF_SHOW_ECONNRESET 64 /* Tell user about incoming RST */
-#define TCP_ADDF_DELAYED_ECONNRESET 128 /* An ECONNRESET error occured on send or shutdown */
+#define TCP_ADDF_DELAYED_ECONNRESET 128 /* An ECONNRESET error occurred on send or shutdown */
#define TCP_ADDF_SHUTDOWN_WR_DONE 256 /* A shutdown(sock, SHUT_WR) or SHUT_RDWR was made */
#define TCP_ADDF_LINGER_ZERO 512 /* Discard driver queue on port close */
@@ -4132,8 +4132,8 @@ static char *inet_set_faddress(int family, inet_address* dst,
/* Get a inaddr structure
** src = inaddr structure
-** *len is the lenght of structure
** dst is filled with [F,P1,P0,X1,....]
+** *len is the length of structure
** where F is the family code (coded)
** and *len is the length of dst on return
** (suitable to deliver to erlang)
diff --git a/erts/emulator/drivers/unix/sig_drv.c b/erts/emulator/drivers/unix/sig_drv.c
index 68ad6b9156..18f2038431 100644
--- a/erts/emulator/drivers/unix/sig_drv.c
+++ b/erts/emulator/drivers/unix/sig_drv.c
@@ -18,7 +18,7 @@
* %CopyrightEnd%
*/
-/* Purpose: demonstrate how to include interupt handlers in erlang */
+/* Purpose: demonstrate how to include interrupt handlers in erlang */
#ifdef HAVE_CONFIG_H
# include "config.h"
diff --git a/erts/emulator/internal_doc/DelayedDealloc.md b/erts/emulator/internal_doc/DelayedDealloc.md
index b7d87b839f..4b7c774141 100644
--- a/erts/emulator/internal_doc/DelayedDealloc.md
+++ b/erts/emulator/internal_doc/DelayedDealloc.md
@@ -19,7 +19,7 @@ the Erlang VM where memory allocation/deallocation is frequent and
references to memory also are passed around between threads this
solution will also scale poorly due to lock contention.
-Functionality Used to Adress This problem
+Functionality Used to Address This problem
-----------------------------------------
In order to reduce contention due to locking of allocator instances we
@@ -44,12 +44,12 @@ deallocation.
The "message box" is implemented using a lock free single linked list
through the memory blocks to deallocate. The order of the elements in
this list is not important. Insertion of new free blocks will be made
-somewhere near the end of this list. Requirering that the new blocks
+somewhere near the end of this list. Requiring that the new blocks
need to be inserted at the end would cause unnecessary contention when
large amount of memory blocks are inserted simultaneous by multiple
threads.
-The data structure refering to this single linked list cover two cache
+The data structure referring to this single linked list cover two cache
lines. One cache line containing information about the head of the
list, and one cache line containing information about the tail of the
list. This in order to reduce cache line ping ponging of this data
@@ -65,21 +65,21 @@ list. In the uncontended case it will point to the end of the list,
but when simultaneous insert operations are performed it will point to
something near the end of the list.
-When insterting an element one will try to write a pointer to the new
+When inserting an element one will try to write a pointer to the new
element in the next pointer of the element pointed to by the last
pointer. This is done using an atomic compare and swap that expects
-the next pointer to be `NULL`. If this succeds the thread performing
+the next pointer to be `NULL`. If this succeeds the thread performing
this operation moves the last pointer to point to the newly inserted
element.
If the atomic compare and swap described above failed, the last
pointer didn't point to the last element. In this case we need to
-insert the new element somewhere inbetween the element that the last
+insert the new element somewhere between the element that the last
pointer pointed to and the actual last element. If we do it this way
the last pointer will eventually end up at the last element when
threads stop adding new elements. When trying to insert somewhere near
the end and failing to do so, the inserting thread sometimes moves to
-the next element and somtimes tries with the same element again. This
+the next element and sometimes tries with the same element again. This
in order to spread the inserted elements during heavy contention. That
is, we try to spread the modifications of memory to different
locations instead of letting all threads continue to try to modify the
@@ -87,7 +87,7 @@ same location in memory.
### Head ###
-The head contains pointers to begining of the list (`head.first`), and
+The head contains pointers to beginning of the list (`head.first`), and
to the first block which other threads may refer to
(`head.unref_end`). Blocks between these pointers are only refered to
by the head part of the data structure which is only used by the
@@ -142,7 +142,7 @@ contains this "marker" element.
### Contention ###
-When elements are continously inserted by threads not owning the
+When elements are continuously inserted by threads not owning the
allocator instance, the thread owning the allocator instance will be
able to work more or less undisturbed by other threads at the head end
of the list. At the tail end large amounts of simultaneous inserts may
diff --git a/erts/emulator/internal_doc/PortSignals.md b/erts/emulator/internal_doc/PortSignals.md
index b1afb7c5cb..8782ae4e17 100644
--- a/erts/emulator/internal_doc/PortSignals.md
+++ b/erts/emulator/internal_doc/PortSignals.md
@@ -204,7 +204,7 @@ high limit is 8 KB and the low limit is 4 KB.
Previously all operations sending signals to ports began by acquiring
the port lock, then performed preparations for sending the signal, and
-then finaly sent the signal. The preparations typically included
+then finally sent the signal. The preparations typically included
inspecting the state of the port, and preparing the data to pass along
with the signal. The preparation of data is frequently quite time
consuming, and did not really depend on the port. That is we would
diff --git a/erts/emulator/internal_doc/SuperCarrier.md b/erts/emulator/internal_doc/SuperCarrier.md
index 0ad6af41de..acf722ea37 100644
--- a/erts/emulator/internal_doc/SuperCarrier.md
+++ b/erts/emulator/internal_doc/SuperCarrier.md
@@ -151,7 +151,7 @@ To find the smallest free segment that will satisfy a carrier allocation
size (`stree`). We search in this tree at allocation. If no free segment of
sufficient size was found, the area (`sa` or `sua`) is instead expanded.
If two or more free segments with equal size exist, the one at lowest
-address is choosen for `sa` and highest address for `sua`.
+address is chosen for `sa` and highest address for `sua`.
At carrier deallocation, we want to coalesce with any adjacent free
segments, to form one large free segment. To do that, all free
diff --git a/erts/emulator/internal_doc/ThreadProgress.md b/erts/emulator/internal_doc/ThreadProgress.md
index 6118bcf0f6..03a802f904 100644
--- a/erts/emulator/internal_doc/ThreadProgress.md
+++ b/erts/emulator/internal_doc/ThreadProgress.md
@@ -60,7 +60,7 @@ threads are managed threads.
### Thread Progress Events ###
Any thread in the system may use the thread progress functionality in
-order to determine when the following events have occured at least
+order to determine when the following events have occurred at least
once in all managed threads:
1. The thread has returned from other code to a known state in the
@@ -160,7 +160,7 @@ calling the following functions:
* `int erts_thr_progress_leader_update(ErtsSchedulerData *esdp)` -
Leader update thread progress.
-Unmanaged threads can delay thread progress beeing made:
+Unmanaged threads can delay thread progress being made:
* `ErtsThrPrgrDelayHandle erts_thr_progress_unmanaged_delay(void)` -
Delay thread progress.
@@ -251,7 +251,7 @@ doing so. If not zero, the leader isn't allowed to increment the
global counter, and needs to wait before it can do this. When it is
zero, it swaps the `waiting` and `current` counters before increasing
the global counter. From now on the new `waiting` counter will
-decrease, so that it eventualy will reach zero, making it possible to
+decrease, so that it eventually will reach zero, making it possible to
increment the global counter the next time. If we only used one
reference counter it would potentially be held above zero for ever by
different unmanaged threads.
@@ -261,7 +261,7 @@ prevent the next increment of the global counter, but instead the
increment after that. This is sufficient since the global counter
needs to be incremented two times before thread progress has been
made. It is also desirable not to prevent the first increment, since
-the likelyhood increases that the delay is withdrawn before any
+the likelihood increases that the delay is withdrawn before any
increment of the global counter is delayed. That is, the operation
will cause as little disruption as possible.
diff --git a/erts/emulator/internal_doc/Tracing.md b/erts/emulator/internal_doc/Tracing.md
index 728f315263..7f97f64765 100644
--- a/erts/emulator/internal_doc/Tracing.md
+++ b/erts/emulator/internal_doc/Tracing.md
@@ -51,7 +51,7 @@ the new instrumented code. Normally loaded code can only be reached
through external functions calls. Trace settings must be activated
instantaneously without the need of external function calls.
-The choosen solution is instead for tracing to use the technique of
+The chosen solution is instead for tracing to use the technique of
replication applied on the data structures for breakpoints. Two
generations of breakpoints are kept and indentified by index of 0 and
1. The global atomic variables `erts_active_bp_index` will determine
diff --git a/erts/emulator/pcre/pcre_exec.c b/erts/emulator/pcre/pcre_exec.c
index 1cab78cdd8..07e662ff07 100644
--- a/erts/emulator/pcre/pcre_exec.c
+++ b/erts/emulator/pcre/pcre_exec.c
@@ -1134,7 +1134,7 @@ for (;;)
the result of a recursive call to match() whatever happened so it was
possible to reduce stack usage by turning this into a tail recursion,
except in the case of a possibly empty group. However, now that there is
- the possiblity of (*THEN) occurring in the final alternative, this
+ the possibility of (*THEN) occurring in the final alternative, this
optimization is no longer always possible.
We can optimize if we know there are no (*THEN)s in the pattern; at present
diff --git a/erts/emulator/sys/common/erl_mseg.c b/erts/emulator/sys/common/erl_mseg.c
index 4dd986f4c8..1e05fd3490 100644
--- a/erts/emulator/sys/common/erl_mseg.c
+++ b/erts/emulator/sys/common/erl_mseg.c
@@ -378,7 +378,7 @@ static ERTS_INLINE int cache_bless_segment(ErtsMsegAllctr_t *ma, void *seg, UWor
ASSERT(!MSEG_FLG_IS_2POW(flags) || (MSEG_FLG_IS_2POW(flags) && MAP_IS_ALIGNED(seg) && IS_2POW(size)));
- /* The idea is that sbc caching is prefered over mbc caching.
+ /* The idea is that sbc caching is preferred over mbc caching.
* Blocks are normally allocated in mb carriers and thus cached there.
* Large blocks has no such cache and it is up to mseg to cache them to speed things up.
*/
diff --git a/erts/emulator/sys/unix/erl_child_setup.h b/erts/emulator/sys/unix/erl_child_setup.h
index a28b136bfc..b61e557ddf 100644
--- a/erts/emulator/sys/unix/erl_child_setup.h
+++ b/erts/emulator/sys/unix/erl_child_setup.h
@@ -17,7 +17,7 @@
*
* %CopyrightEnd%
*
- * This file defines the interface inbetween erts and child_setup.
+ * This file defines the interface between erts and child_setup.
*/
#ifndef _ERL_UNIX_FORKER_H
diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c
index f23c7ab03d..93013a412b 100644
--- a/erts/emulator/sys/win32/erl_poll.c
+++ b/erts/emulator/sys/win32/erl_poll.c
@@ -842,9 +842,9 @@ event_happened:
ASSERT(WAIT_OBJECT_0 < i && i < WAIT_OBJECT_0+w->active_events);
notify_io_ready(ps);
- /*
- * The main thread wont start working on our arrays untill we're
- * stopped, so we can work in peace although the main thread runs
+ /*
+ * The main thread wont start working on our arrays until we're
+ * stopped, so we can work in peace although the main thread runs
*/
ASSERT(i >= WAIT_OBJECT_0+1);
i -= WAIT_OBJECT_0;
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 408b4f47ab..40e5595533 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -496,7 +496,7 @@ struct driver_data {
int outBufSize; /* Size of output buffer. */
byte *outbuf; /* Buffer to use for overlapped write. */
ErlDrvPort port_num; /* The port handle. */
- int packet_bytes; /* 0: continous stream, 1, 2, or 4: the number
+ int packet_bytes; /* 0: continuous stream, 1, 2, or 4: the number
* of bytes in the packet header.
*/
HANDLE port_pid; /* PID of the port process. */
@@ -1427,7 +1427,7 @@ int parse_command(wchar_t* cmd){
*
* If new == NULL we just calculate the length.
*
- * The reason for having to quote all of the is becasue CreateProcessW removes
+ * The reason for having to quote all of the is because CreateProcessW removes
* one level of escaping since it takes a single long command line rather
* than the argument chunks that unix uses.
*/
@@ -2486,7 +2486,7 @@ output(ErlDrvData drv_data, char* buf, ErlDrvSizeT len)
* event object has been signaled, indicating that there is
* something to read on the corresponding file handle.
*
- * If the port is working in the continous stream mode (packet_bytes == 0),
+ * If the port is working in the continuous stream mode (packet_bytes == 0),
* whatever data read will be sent straight to Erlang.
*
* Results:
@@ -2527,7 +2527,7 @@ ready_input(ErlDrvData drv_data, ErlDrvEvent ready_event)
#endif
if (error == NO_ERROR) {
- if (pb == 0) { /* Continous stream. */
+ if (pb == 0) { /* Continuous stream. */
#ifdef DEBUG
DEBUGF(("ready_input: %d: ", bytesRead));
erl_bin_write(dp->inbuf, 16, bytesRead);
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 238a8aa42d..324730d562 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -1008,7 +1008,7 @@ ordering(Config) when is_list(Config) ->
ok.
-%% Test that comparisions between binaries with different alignment work.
+%% Test that comparison between binaries with different alignment work.
unaligned_order(Config) when is_list(Config) ->
L = lists:seq(0, 7),
[test_unaligned_order(I, J) || I <- L, J <- L],
diff --git a/erts/emulator/test/bs_match_int_SUITE.erl b/erts/emulator/test/bs_match_int_SUITE.erl
index a7bd4b8ac3..32bfa2f1fa 100644
--- a/erts/emulator/test/bs_match_int_SUITE.erl
+++ b/erts/emulator/test/bs_match_int_SUITE.erl
@@ -247,7 +247,7 @@ match_huge_int(Config) when is_list(Config) ->
8 ->
%% An attempt will be made to allocate heap space for
%% the bignum (which will probably fail); only if the
- %% allocation succeds will the matching fail because
+ %% allocation succeeds will the matching fail because
%% the binary is too small.
ok
end,
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index 2e303ba9a8..e74631e916 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -233,7 +233,7 @@ basic() ->
trace_func({'_','_','_'}, false),
[b,a] = lists:reverse([a,b]),
- %% Read out the remaing trace messages.
+ %% Read out the remaining trace messages.
?MODULE:expect({trace,Self,call,{lists,seq,[1,10]}}),
?MODULE:expect({trace,Self,call,{erlang,list_to_integer,["777"]}}),
diff --git a/erts/emulator/test/ddll_SUITE.erl b/erts/emulator/test/ddll_SUITE.erl
index 93b6f2d956..e7e518f82b 100644
--- a/erts/emulator/test/ddll_SUITE.erl
+++ b/erts/emulator/test/ddll_SUITE.erl
@@ -805,7 +805,7 @@ reference_count(Config) when is_list(Config) ->
Pid1 ! {self(), die},
test_server:sleep(200), % Give time to unload.
- % Verify that the driver was automaticly unloaded when the
+ % Verify that the driver was automatically unloaded when the
% process died.
{error, not_loaded}=erl_ddll:unload_driver(echo_drv),
ok.
diff --git a/erts/emulator/test/dirty_nif_SUITE.erl b/erts/emulator/test/dirty_nif_SUITE.erl
index 991ba0acc8..5ba0d85ff3 100644
--- a/erts/emulator/test/dirty_nif_SUITE.erl
+++ b/erts/emulator/test/dirty_nif_SUITE.erl
@@ -214,7 +214,7 @@ dirty_call_while_terminated(Config) when is_list(Config) ->
undefined = process_info(Dirty, status),
false = erlang:is_process_alive(Dirty),
false = lists:member(Dirty, processes()),
- %% Binary still refered by Dirty process not yet cleaned up
+ %% Binary still referred by Dirty process not yet cleaned up
%% since the dirty nif has not yet returned...
{value, {BinAddr, 4711, 2}} = lists:keysearch(4711, 2,
element(2,
diff --git a/erts/emulator/test/estone_SUITE.erl b/erts/emulator/test/estone_SUITE.erl
index 3ce849b88e..35f695ffe5 100644
--- a/erts/emulator/test/estone_SUITE.erl
+++ b/erts/emulator/test/estone_SUITE.erl
@@ -708,7 +708,7 @@ alloc(I) ->
%% Time to call bif's
%% Lot's of element stuff which reflects the record code which
-%% is becomming more and more common
+%% is becoming more and more common
bif_dispatch(0) ->
0;
bif_dispatch(I) ->
diff --git a/erts/emulator/test/float_SUITE.erl b/erts/emulator/test/float_SUITE.erl
index 36b1f9179f..ad33ad705b 100644
--- a/erts/emulator/test/float_SUITE.erl
+++ b/erts/emulator/test/float_SUITE.erl
@@ -208,7 +208,7 @@ span_cmp(Axis, Incr, Length) ->
%% for both negative and positive numbers.
%%
%% Axis: The number around which to do the tests eg. (1 bsl 58) - 1.0
-%% Incr: How much to increment the test numbers inbetween each test.
+%% Incr: How much to increment the test numbers in-between each test.
%% Length: Length/2 is the number of Incr away from Axis to test on the
%% negative and positive plane.
%% Diff: How much the float and int should differ when comparing
diff --git a/erts/emulator/test/hibernate_SUITE.erl b/erts/emulator/test/hibernate_SUITE.erl
index 6f8ce02266..90693595a7 100644
--- a/erts/emulator/test/hibernate_SUITE.erl
+++ b/erts/emulator/test/hibernate_SUITE.erl
@@ -349,7 +349,7 @@ clean_dict() ->
lists:foreach(fun ({Key, _}) -> erase(Key) end, Dict).
%%
-%% Wake up and then immediatly bif trap with a lengthy computation.
+%% Wake up and then immediately bif trap with a lengthy computation.
%%
wake_up_and_bif_trap(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 34e956bc21..971a047309 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -646,7 +646,7 @@ destructive_in_test_bif(Config) when is_list(Config) ->
([],[{'_',[],[{message,{get_tcw}}]}],trace),
ok.
-%% Test that the comparision between boxed and small does not crash emulator
+%% Test that the comparison between boxed and small does not crash emulator
boxed_and_small(Config) when is_list(Config) ->
{ok, Node} = start_node(match_spec_suite_other),
ok = rpc:call(Node,?MODULE,do_boxed_and_small,[]),
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index 7356f31b75..291d3ee30d 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -153,7 +153,7 @@ ttbtteq_do_remote(RNode) ->
%%
%% Test case: round_trip_eq
%%
-%% Tests that node containers that are sent beteen nodes stay equal to themselves.
+%% Tests that node containers that are sent between nodes stay equal to themselves.
round_trip_eq(Config) when is_list(Config) ->
ThisNode = {node(), erlang:system_info(creation)},
NodeFirstName = get_nodefirstname(),
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index 1a1ab0e5e0..8016a21424 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -108,7 +108,7 @@ t_float(Config) when is_list(Config) ->
4294967305.0 = float(id(4294967305)),
-4294967305.0 = float(id(-4294967305)),
- %% Extremly big bignums.
+ %% Extremely big bignums.
Big = id(list_to_integer(id(lists:duplicate(2000, $1)))),
{'EXIT', {badarg, _}} = (catch float(Big)),
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 2a13b2d2f4..c117554f90 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -2131,7 +2131,7 @@ ping(Config, Sizes, HSize, CmdLine, Options) ->
%% Sizes = Size of packets to generated.
%% HSize = Header size: 1, 2, or 4
%% CmdLine = Additional command line options.
-%% Options = Addtional port options.
+%% Options = Additional port options.
expect_input(Config, Sizes, HSize, CmdLine, Options) ->
expect_input1(Config, Sizes, {HSize, CmdLine, Options}, [], []).
diff --git a/erts/emulator/test/port_SUITE_data/port_test.c b/erts/emulator/test/port_SUITE_data/port_test.c
index e199a0fc13..fa97b4c9d0 100644
--- a/erts/emulator/test/port_SUITE_data/port_test.c
+++ b/erts/emulator/test/port_SUITE_data/port_test.c
@@ -41,7 +41,7 @@ extern int errno;
typedef struct {
char* progname; /* Name of this program (from argv[0]). */
int header_size; /* Number of bytes in each packet header:
- * 1, 2, or 4, or 0 for a continous byte stream. */
+ * 1, 2, or 4, or 0 for a continuous byte stream. */
int fd_from_erl; /* File descriptor from Erlang. */
int fd_to_erl; /* File descriptor to Erlang. */
unsigned char* io_buf; /* Buffer for file i/o. */
diff --git a/erts/emulator/test/port_bif_SUITE_data/port_test.c b/erts/emulator/test/port_bif_SUITE_data/port_test.c
index 28324a56a6..923ab99ccc 100644
--- a/erts/emulator/test/port_bif_SUITE_data/port_test.c
+++ b/erts/emulator/test/port_bif_SUITE_data/port_test.c
@@ -39,7 +39,7 @@ extern int errno;
typedef struct {
char* progname; /* Name of this program (from argv[0]). */
int header_size; /* Number of bytes in each packet header:
- * 1, 2, or 4, or 0 for a continous byte stream. */
+ * 1, 2, or 4, or 0 for a continuous byte stream. */
int fd_from_erl; /* File descriptor from Erlang. */
int fd_to_erl; /* File descriptor to Erlang. */
unsigned char* io_buf; /* Buffer for file i/o. */
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 6a772bf7c9..6bd1eb1e1e 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -174,7 +174,7 @@ memory(Config) when is_list(Config) ->
%%
erts_debug:set_internal_state(available_internal_state, true),
- %% Use a large heap size on the controling process in
+ %% Use a large heap size on the controlling process in
%% order to avoid changes in its heap size during
%% comparisons.
MinHeapSize = process_flag(min_heap_size, 1024*1024),
diff --git a/erts/emulator/test/time_SUITE.erl b/erts/emulator/test/time_SUITE.erl
index 9501569814..c13d03bcc4 100644
--- a/erts/emulator/test/time_SUITE.erl
+++ b/erts/emulator/test/time_SUITE.erl
@@ -132,7 +132,7 @@ local_to_univ_utc(Config) when is_list(Config) ->
end.
-%% Tests conversion from univeral to local time.
+%% Tests conversion from universal to local time.
univ_to_local(Config) when is_list(Config) ->
test_univ_to_local(test_data()).
diff --git a/erts/emulator/test/z_SUITE.erl b/erts/emulator/test/z_SUITE.erl
index d663cc548c..a90701c5d2 100644
--- a/erts/emulator/test/z_SUITE.erl
+++ b/erts/emulator/test/z_SUITE.erl
@@ -226,7 +226,7 @@ pollset_size(Config) when is_list(Config) ->
"Pollset size information not available"}
end;
false ->
- %% Somtimes we have fewer descriptors in the
+ %% Sometimes we have fewer descriptors in the
%% pollset at the end than when we started, but
%% that is ok as long as there are at least 2
%% descriptors (dist listen socket and
diff --git a/erts/epmd/test/epmd_SUITE.erl b/erts/epmd/test/epmd_SUITE.erl
index 0f0a5acde7..81433c39c4 100644
--- a/erts/epmd/test/epmd_SUITE.erl
+++ b/erts/epmd/test/epmd_SUITE.erl
@@ -838,7 +838,7 @@ no_live_killing(Config) when is_list(Config) ->
%% sends TCP RST at wrong time
socket_reset_before_alive2_reply_is_written(Config) when is_list(Config) ->
%% - delay_write for easier triggering of race condition
- %% - relaxed_command_check for gracefull shutdown of epmd even if there
+ %% - relaxed_command_check for graceful shutdown of epmd even if there
%% is stuck node.
ok = epmdrun("-delay_write 1 -relaxed_command_check"),
diff --git a/erts/etc/common/inet_gethost.c b/erts/etc/common/inet_gethost.c
index bc4893b0eb..ccafd95e51 100644
--- a/erts/etc/common/inet_gethost.c
+++ b/erts/etc/common/inet_gethost.c
@@ -2717,7 +2717,7 @@ BOOL close_mesq(MesQ *q)
LeaveCriticalSection(&(q->crit));
return FALSE;
}
- /* Noone else is supposed to use this object any more */
+ /* No one else is supposed to use this object any more */
LeaveCriticalSection(&(q->crit));
DeleteCriticalSection(&(q->crit));
CloseHandle(q->data_present);
diff --git a/erts/etc/unix/README b/erts/etc/unix/README
index adc6db4300..9985f2675d 100644
--- a/erts/etc/unix/README
+++ b/erts/etc/unix/README
@@ -42,7 +42,7 @@ Note that the Install script will terminate if it detects problems -
you will have to correct them and re-run the script. If everything
goes well, the last printout should be:
-Erlang installation sucessfully completed
+Erlang installation successfully completed
If it isn't, something went wrong - check the printouts to find out
what it was.
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index 2bf04a6518..c689d495e6 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -2875,7 +2875,7 @@ document etp-disasm
%---------------------------------------------------------------------------
% etp-disasm StartI EndI
%
-% Disassemble the code inbetween StartI and EndI
+% Disassemble the code between StartI and EndI
%---------------------------------------------------------------------------
end
diff --git a/erts/etc/unix/run_erl.c b/erts/etc/unix/run_erl.c
index 447720af7e..8f87c59131 100644
--- a/erts/etc/unix/run_erl.c
+++ b/erts/etc/unix/run_erl.c
@@ -553,7 +553,7 @@ static void pass_on(pid_t childpid)
FD_ZERO(&readfds);
FD_ZERO(&writefds);
} else {
- /* Some error occured */
+ /* Some error occurred */
ERRNO_ERR0(LOG_ERR,"Error in select.");
exit(1);
}
diff --git a/erts/include/internal/gcc/ethr_atomic.h b/erts/include/internal/gcc/ethr_atomic.h
index 231eaa6927..4e252ec3f9 100644
--- a/erts/include/internal/gcc/ethr_atomic.h
+++ b/erts/include/internal/gcc/ethr_atomic.h
@@ -28,7 +28,7 @@
*
* Due to this we cannot use the __ATOMIC_SEQ_CST
* memory model. For more information see the comment
- * in the begining of ethr_membar.h in this directory.
+ * in the beginning of ethr_membar.h in this directory.
*/
#undef ETHR_INCLUDE_ATOMIC_IMPL__
diff --git a/erts/include/internal/gcc/ethr_dw_atomic.h b/erts/include/internal/gcc/ethr_dw_atomic.h
index 675912d86e..df20d0f1ef 100644
--- a/erts/include/internal/gcc/ethr_dw_atomic.h
+++ b/erts/include/internal/gcc/ethr_dw_atomic.h
@@ -28,7 +28,7 @@
*
* Due to this we cannot use the __ATOMIC_SEQ_CST
* memory model. For more information see the comment
- * in the begining of ethr_membar.h in this directory.
+ * in the beginning of ethr_membar.h in this directory.
*/
#undef ETHR_INCLUDE_DW_ATOMIC_IMPL__
--
cgit v1.2.3
From d73423cdba178c166f25e00a4608ccc8d0465937 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 14 Feb 2017 15:53:04 +0100
Subject: erts: Fix round/1 for large floats
1> round(6209607916799025.0).
6209607916799026
Problem: Adding/subtracting 0.5 and large double floats between
(1 bsl 52) and (1 bsl 53) does not give reliable results.
Solution: Use round() function in math.h.
---
erts/emulator/beam/erl_bif_guard.c | 5 ++---
erts/emulator/test/guard_SUITE.erl | 1 +
erts/emulator/test/num_bif_SUITE.erl | 3 +++
3 files changed, 6 insertions(+), 3 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c
index b42d2dc28b..74cf7cf11a 100644
--- a/erts/emulator/beam/erl_bif_guard.c
+++ b/erts/emulator/beam/erl_bif_guard.c
@@ -157,7 +157,7 @@ BIF_RETTYPE round_1(BIF_ALIST_1)
GET_DOUBLE(BIF_ARG_1, f);
/* round it and return the resultant integer */
- res = double_to_integer(BIF_P, (f.fd > 0.0) ? f.fd + 0.5 : f.fd - 0.5);
+ res = double_to_integer(BIF_P, round(f.fd));
BIF_RET(res);
}
@@ -597,8 +597,7 @@ Eterm erts_gc_round_1(Process* p, Eterm* reg, Uint live)
}
GET_DOUBLE(arg, f);
- return gc_double_to_integer(p, (f.fd > 0.0) ? f.fd + 0.5 : f.fd - 0.5,
- reg, live);
+ return gc_double_to_integer(p, round(f.fd), reg, live);
}
Eterm erts_gc_trunc_1(Process* p, Eterm* reg, Uint live)
diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl
index e155e5f49f..54ee710363 100644
--- a/erts/emulator/test/guard_SUITE.erl
+++ b/erts/emulator/test/guard_SUITE.erl
@@ -317,6 +317,7 @@ guard_bifs(Config) when is_list(Config) ->
try_gbif('float/1', Big, float(id(Big))),
try_gbif('trunc/1', Float, 387924.0),
try_gbif('round/1', Float, 387925.0),
+ try_gbif('round/1', 6209607916799025.0, 6209607916799025),
try_gbif('length/1', [], 0),
try_gbif('length/1', [a], 1),
diff --git a/erts/emulator/test/num_bif_SUITE.erl b/erts/emulator/test/num_bif_SUITE.erl
index d1c9648017..bb85738454 100644
--- a/erts/emulator/test/num_bif_SUITE.erl
+++ b/erts/emulator/test/num_bif_SUITE.erl
@@ -293,6 +293,9 @@ t_round(Config) when is_list(Config) ->
4294967297 = round(id(4294967296.9)),
-4294967296 = -round(id(4294967296.1)),
-4294967297 = -round(id(4294967296.9)),
+
+ 6209607916799025 = round(id(6209607916799025.0)),
+ -6209607916799025 = round(id(-6209607916799025.0)),
ok.
t_trunc(Config) when is_list(Config) ->
--
cgit v1.2.3
From 118de47d703e303aea7f4575849a37c11416ba14 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson
Date: Tue, 14 Feb 2017 18:26:31 +0100
Subject: erts: Add deallocation veto for magic destructors
A magic destructor can return 0 and thereby take control
and prolong the lifetime of a magic binary.
---
erts/emulator/beam/beam_load.c | 5 +++--
erts/emulator/beam/binary.c | 6 ++++--
erts/emulator/beam/dist.c | 4 +++-
erts/emulator/beam/dist.h | 2 +-
erts/emulator/beam/erl_bif_binary.c | 15 ++++++++-------
erts/emulator/beam/erl_bif_info.c | 4 ++--
erts/emulator/beam/erl_bif_re.c | 3 ++-
erts/emulator/beam/erl_binary.h | 19 +++++++++++--------
erts/emulator/beam/erl_db_util.c | 5 +++--
erts/emulator/beam/erl_db_util.h | 2 +-
erts/emulator/beam/erl_map.c | 3 ++-
erts/emulator/beam/erl_nif.c | 3 ++-
erts/emulator/beam/erl_ptab.c | 6 ++++--
erts/emulator/beam/erl_unicode.c | 3 ++-
erts/emulator/beam/external.c | 6 ++++--
erts/emulator/hipe/hipe_load.c | 3 ++-
16 files changed, 54 insertions(+), 35 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index e75e7afd54..48206a75a8 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -488,7 +488,7 @@ typedef struct LoaderState {
static void free_loader_state(Binary* magic);
static ErlHeapFragment* new_literal_fragment(Uint size);
static void free_literal_fragment(ErlHeapFragment*);
-static void loader_state_dtor(Binary* magic);
+static int loader_state_dtor(Binary* magic);
#ifdef HIPE
static Eterm stub_insert_new_code(Process *c_p, ErtsProcLocks c_p_locks,
Eterm group_leader, Eterm module,
@@ -1026,7 +1026,7 @@ static void free_literal_fragment(ErlHeapFragment* bp)
/*
* This destructor function can safely be called multiple times.
*/
-static void
+static int
loader_state_dtor(Binary* magic)
{
LoaderState* stp = ERTS_MAGIC_BIN_DATA(magic);
@@ -1111,6 +1111,7 @@ loader_state_dtor(Binary* magic)
*/
ASSERT(stp->genop_blocks == 0);
+ return 1;
}
#ifdef HIPE
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index d38097fb12..be43f6e1ac 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -350,9 +350,10 @@ typedef struct {
Uint bitoffs;
} ErtsB2LState;
-static void b2l_state_destructor(Binary *mbp)
+static int b2l_state_destructor(Binary *mbp)
{
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == b2l_state_destructor);
+ return 1;
}
static BIF_RETTYPE
@@ -723,12 +724,13 @@ list_to_binary_engine(ErtsL2BState *sp)
}
}
-static void
+static int
l2b_state_destructor(Binary *mbp)
{
ErtsL2BState *sp = ERTS_MAGIC_BIN_DATA(mbp);
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(mbp) == l2b_state_destructor);
DESTROY_SAVED_ESTACK(&sp->buf.iolist.estack);
+ return 1;
}
static ERTS_INLINE Eterm
diff --git a/erts/emulator/beam/dist.c b/erts/emulator/beam/dist.c
index 390f2a0db3..da1083100b 100644
--- a/erts/emulator/beam/dist.c
+++ b/erts/emulator/beam/dist.c
@@ -713,7 +713,7 @@ static void clear_dist_entry(DistEntry *dep)
}
}
-void erts_dsend_context_dtor(Binary* ctx_bin)
+int erts_dsend_context_dtor(Binary* ctx_bin)
{
ErtsSendContext* ctx = ERTS_MAGIC_BIN_DATA(ctx_bin);
switch (ctx->dss.phase) {
@@ -730,6 +730,8 @@ void erts_dsend_context_dtor(Binary* ctx_bin)
}
if (ctx->dep_to_deref)
erts_deref_dist_entry(ctx->dep_to_deref);
+
+ return 1;
}
Eterm erts_dsend_export_trap_context(Process* p, ErtsSendContext* ctx)
diff --git a/erts/emulator/beam/dist.h b/erts/emulator/beam/dist.h
index e82b416286..8799e54057 100644
--- a/erts/emulator/beam/dist.h
+++ b/erts/emulator/beam/dist.h
@@ -375,7 +375,7 @@ extern int erts_dsig_send_monitor(ErtsDSigData *, Eterm, Eterm, Eterm);
extern int erts_dsig_send_m_exit(ErtsDSigData *, Eterm, Eterm, Eterm, Eterm);
extern int erts_dsig_send(ErtsDSigData *dsdp, struct erts_dsig_send_context* ctx);
-extern void erts_dsend_context_dtor(Binary*);
+extern int erts_dsend_context_dtor(Binary*);
extern Eterm erts_dsend_export_trap_context(Process* p, ErtsSendContext* ctx);
extern int erts_dist_command(Port *prt, int reds);
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
index e57cd06cec..deab371e3e 100644
--- a/erts/emulator/beam/erl_bif_binary.c
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -239,13 +239,13 @@ static void dump_ac_node(ACNode *node, int indent, int ch);
/*
* Callback for the magic binary
*/
-static void cleanup_my_data_ac(Binary *bp)
+static int cleanup_my_data_ac(Binary *bp)
{
- return;
+ return 1;
}
-static void cleanup_my_data_bm(Binary *bp)
+static int cleanup_my_data_bm(Binary *bp)
{
- return;
+ return 1;
}
/*
@@ -2067,7 +2067,7 @@ static int do_search_backward(CommonData *cd, Uint *posp, Uint *redsp)
}
}
-static void cleanup_common_data(Binary *bp)
+static int cleanup_common_data(Binary *bp)
{
int i;
CommonData *cd;
@@ -2084,7 +2084,7 @@ static void cleanup_common_data(Binary *bp)
break;
}
}
- return;
+ return 1;
}
static BIF_RETTYPE do_longest_common(Process *p, Eterm list, int direction)
@@ -2563,7 +2563,7 @@ typedef struct {
#define BINARY_COPY_LOOP_FACTOR 100
-static void cleanup_copy_bin_state(Binary *bp)
+static int cleanup_copy_bin_state(Binary *bp)
{
CopyBinState *cbs = (CopyBinState *) ERTS_MAGIC_BIN_DATA(bp);
if (cbs->result != NULL) {
@@ -2583,6 +2583,7 @@ static void cleanup_copy_bin_state(Binary *bp)
break;
}
cbs->source_type = BC_TYPE_EMPTY;
+ return 1;
}
/*
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index be113b7c88..5a8776076e 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -3567,9 +3567,9 @@ BIF_RETTYPE error_logger_warning_map_0(BIF_ALIST_0)
static erts_smp_atomic_t available_internal_state;
-static void empty_magic_ref_destructor(Binary *bin)
+static int empty_magic_ref_destructor(Binary *bin)
{
-
+ return 1;
}
BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
diff --git a/erts/emulator/beam/erl_bif_re.c b/erts/emulator/beam/erl_bif_re.c
index ba183f24e8..a66b05c6ff 100644
--- a/erts/emulator/beam/erl_bif_re.c
+++ b/erts/emulator/beam/erl_bif_re.c
@@ -600,10 +600,11 @@ static void cleanup_restart_context(RestartContext *rc)
}
}
-static void cleanup_restart_context_bin(Binary *bp)
+static int cleanup_restart_context_bin(Binary *bp)
{
RestartContext *rc = ERTS_MAGIC_BIN_DATA(bp);
cleanup_restart_context(rc);
+ return 1;
}
/*
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 4d9c4d6eac..db259be2a7 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -65,7 +65,7 @@ typedef struct magic_binary ErtsMagicBinary;
struct magic_binary {
ERTS_INTERNAL_BINARY_FIELDS
SWord orig_size;
- void (*destructor)(Binary *);
+ int (*destructor)(Binary *);
Uint32 refn[ERTS_REF_NUMBERS];
ErtsAlcType_t alloc_type;
union {
@@ -335,12 +335,12 @@ ERTS_GLB_INLINE Binary *erts_bin_realloc_fnf(Binary *bp, Uint size);
ERTS_GLB_INLINE Binary *erts_bin_realloc(Binary *bp, Uint size);
ERTS_GLB_INLINE void erts_bin_free(Binary *bp);
ERTS_GLB_INLINE Binary *erts_create_magic_binary_x(Uint size,
- void (*destructor)(Binary *),
+ int (*destructor)(Binary *),
ErtsAlcType_t alloc_type,
int unaligned);
ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
- void (*destructor)(Binary *));
-ERTS_GLB_INLINE Binary *erts_create_magic_indirection(void (*destructor)(Binary *));
+ int (*destructor)(Binary *));
+ERTS_GLB_INLINE Binary *erts_create_magic_indirection(int (*destructor)(Binary *));
ERTS_GLB_INLINE erts_smp_atomic_t *erts_smp_binary_to_magic_indirection(Binary *bp);
ERTS_GLB_INLINE erts_atomic_t *erts_binary_to_magic_indirection(Binary *bp);
@@ -471,7 +471,10 @@ ERTS_GLB_INLINE void
erts_bin_free(Binary *bp)
{
if (bp->flags & BIN_FLAG_MAGIC) {
- ERTS_MAGIC_BIN_DESTRUCTOR(bp)(bp);
+ if (!ERTS_MAGIC_BIN_DESTRUCTOR(bp)(bp)) {
+ /* Destructor took control of the deallocation */
+ return;
+ }
erts_magic_ref_remove_bin(ERTS_MAGIC_BIN_REFN(bp));
erts_free(ERTS_MAGIC_BIN_ATYPE(bp), (void *) bp);
}
@@ -482,7 +485,7 @@ erts_bin_free(Binary *bp)
}
ERTS_GLB_INLINE Binary *
-erts_create_magic_binary_x(Uint size, void (*destructor)(Binary *),
+erts_create_magic_binary_x(Uint size, int (*destructor)(Binary *),
ErtsAlcType_t alloc_type,
int unaligned)
{
@@ -504,14 +507,14 @@ erts_create_magic_binary_x(Uint size, void (*destructor)(Binary *),
}
ERTS_GLB_INLINE Binary *
-erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
+erts_create_magic_binary(Uint size, int (*destructor)(Binary *))
{
return erts_create_magic_binary_x(size, destructor,
ERTS_ALC_T_BINARY, 0);
}
ERTS_GLB_INLINE Binary *
-erts_create_magic_indirection(void (*destructor)(Binary *))
+erts_create_magic_indirection(int (*destructor)(Binary *))
{
return erts_create_magic_binary_x(sizeof(ErtsMagicIndirectionWord),
destructor,
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 070e29578f..3ac2bdd3d6 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1702,17 +1702,18 @@ error: /* Here is were we land when compilation failed. */
/*
** Free a match program (in a binary)
*/
-void erts_db_match_prog_destructor(Binary *bprog)
+int erts_db_match_prog_destructor(Binary *bprog)
{
MatchProg *prog;
if (bprog == NULL)
- return;
+ return 1;
prog = Binary2MatchProg(bprog);
if (prog->term_save != NULL) {
free_message_buffer(prog->term_save);
}
if (prog->saved_program_buf != NULL)
free_message_buffer(prog->saved_program_buf);
+ return 1;
}
void
diff --git a/erts/emulator/beam/erl_db_util.h b/erts/emulator/beam/erl_db_util.h
index b2a3bb6c20..471fefe3cb 100644
--- a/erts/emulator/beam/erl_db_util.h
+++ b/erts/emulator/beam/erl_db_util.h
@@ -356,7 +356,7 @@ Eterm db_add_counter(Eterm** hpp, Wterm counter, Eterm incr);
Eterm db_match_set_lint(Process *p, Eterm matchexpr, Uint flags);
Binary *db_match_set_compile(Process *p, Eterm matchexpr,
Uint flags);
-void erts_db_match_prog_destructor(Binary *);
+int erts_db_match_prog_destructor(Binary *);
typedef struct match_prog {
ErlHeapFragment *term_save; /* Only if needed, a list of message
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index 990be8efb2..9062e44b10 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -1188,12 +1188,13 @@ typedef struct HashmapMergeContext_ {
#endif
} HashmapMergeContext;
-static void hashmap_merge_ctx_destructor(Binary* ctx_bin)
+static int hashmap_merge_ctx_destructor(Binary* ctx_bin)
{
HashmapMergeContext* ctx = (HashmapMergeContext*) ERTS_MAGIC_BIN_DATA(ctx_bin);
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(ctx_bin) == hashmap_merge_ctx_destructor);
PSTACK_DESTROY_SAVED(&ctx->pstack);
+ return 1;
}
BIF_RETTYPE maps_merge_trap_1(BIF_ALIST_1) {
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 3674a29bf8..61ae57a7f0 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -2140,7 +2140,7 @@ static void rollback_opened_resource_types(void)
}
-static void nif_resource_dtor(Binary* bin)
+static int nif_resource_dtor(Binary* bin)
{
ErlNifResource* resource = (ErlNifResource*) ERTS_MAGIC_BIN_UNALIGNED_DATA(bin);
ErlNifResourceType* type = resource->type;
@@ -2159,6 +2159,7 @@ static void nif_resource_dtor(Binary* bin)
steal_resource_type(type);
erts_free(ERTS_ALC_T_NIF, type);
}
+ return 1;
}
void* enif_alloc_resource(ErlNifResourceType* type, size_t size)
diff --git a/erts/emulator/beam/erl_ptab.c b/erts/emulator/beam/erl_ptab.c
index a132b1d334..ce28708ece 100644
--- a/erts/emulator/beam/erl_ptab.c
+++ b/erts/emulator/beam/erl_ptab.c
@@ -733,7 +733,7 @@ erts_ptab_delete_element(ErtsPTab *ptab,
* erts_ptab_list() implements BIFs listing the content of the table,
* e.g. erlang:processes/0.
*/
-static void cleanup_ptab_list_bif_data(Binary *bp);
+static int cleanup_ptab_list_bif_data(Binary *bp);
static int ptab_list_bif_engine(Process *c_p, Eterm *res_accp, Binary *mbp);
@@ -787,7 +787,7 @@ erts_ptab_list(Process *c_p, ErtsPTab *ptab)
return ret_val;
}
-static void
+static int
cleanup_ptab_list_bif_data(Binary *bp)
{
ErtsPTabListBifData *ptlbdp = ERTS_MAGIC_BIN_DATA(bp);
@@ -875,6 +875,8 @@ cleanup_ptab_list_bif_data(Binary *bp)
ERTS_PTAB_LIST_DBG_TRACE(ptlbdp->debug.caller, return);
ERTS_PTAB_LIST_DBG_CLEANUP(ptlbdp);
+
+ return 1;
}
static int
diff --git a/erts/emulator/beam/erl_unicode.c b/erts/emulator/beam/erl_unicode.c
index dd7c589c3d..01629db9ad 100644
--- a/erts/emulator/beam/erl_unicode.c
+++ b/erts/emulator/beam/erl_unicode.c
@@ -123,10 +123,11 @@ static void cleanup_restart_context(RestartContext *rc)
}
}
-static void cleanup_restart_context_bin(Binary *bp)
+static int cleanup_restart_context_bin(Binary *bp)
{
RestartContext *rc = ERTS_MAGIC_BIN_DATA(bp);
cleanup_restart_context(rc);
+ return 1;
}
static RestartContext *get_rc_from_bin(Eterm mref)
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index f9cba0aec0..205a7711ec 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -1398,12 +1398,13 @@ static void b2t_destroy_context(B2TContext* context)
}
}
-static void b2t_context_destructor(Binary *context_bin)
+static int b2t_context_destructor(Binary *context_bin)
{
B2TContext* ctx = (B2TContext*) ERTS_MAGIC_BIN_DATA(context_bin);
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(context_bin) == b2t_context_destructor);
b2t_destroy_context(ctx);
+ return 1;
}
static BIF_RETTYPE binary_to_term_trap_1(BIF_ALIST_1)
@@ -1808,7 +1809,7 @@ erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags) {
#endif
#define TERM_TO_BINARY_MEMCPY_FACTOR 8
-static void ttb_context_destructor(Binary *context_bin)
+static int ttb_context_destructor(Binary *context_bin)
{
TTBContext *context = ERTS_MAGIC_BIN_DATA(context_bin);
if (context->alive) {
@@ -1842,6 +1843,7 @@ static void ttb_context_destructor(Binary *context_bin)
break;
}
}
+ return 1;
}
static Eterm erts_term_to_binary_int(Process* p, Eterm Term, int level, Uint flags,
diff --git a/erts/emulator/hipe/hipe_load.c b/erts/emulator/hipe/hipe_load.c
index 2998ed87a2..87c5004d2b 100644
--- a/erts/emulator/hipe/hipe_load.c
+++ b/erts/emulator/hipe/hipe_load.c
@@ -61,7 +61,7 @@ void hipe_free_loader_state(HipeLoaderState *stp)
stp->module = NIL;
}
-static void
+static int
hipe_loader_state_dtor(Binary* magic)
{
HipeLoaderState* stp = ERTS_MAGIC_BIN_DATA(magic);
@@ -69,6 +69,7 @@ hipe_loader_state_dtor(Binary* magic)
ASSERT(ERTS_MAGIC_BIN_DESTRUCTOR(magic) == hipe_loader_state_dtor);
hipe_free_loader_state(stp);
+ return 1;
}
Binary *hipe_alloc_loader_state(Eterm module)
--
cgit v1.2.3
From fc5a4a227968001cb031802c5a122cdbb0323b25 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Thu, 16 Feb 2017 19:11:54 +0100
Subject: Handle magic refs in db_cleanup_offheap_comp()
---
erts/emulator/beam/erl_db_util.c | 5 +++++
1 file changed, 5 insertions(+)
(limited to 'erts')
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index 3ac2bdd3d6..6f30b1d3dd 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -3104,6 +3104,11 @@ void db_cleanup_offheap_comp(DbTerm* obj)
erts_erase_fun_entry(u.fun->fe);
}
break;
+ case REF_SUBTAG:
+ ASSERT(is_magic_ref_thing(u.hdr));
+ if (erts_refc_dectest(&u.mref->mb->refc, 0) == 0)
+ erts_bin_free((Binary *)u.mref->mb);
+ break;
default:
ASSERT(is_external_header(u.hdr->thing_word));
ASSERT(u.pb != &tmp);
--
cgit v1.2.3
From 5263d10ba361cf0666cb6b2730132a018ba67bd6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?=
Date: Fri, 17 Feb 2017 12:03:08 +0100
Subject: Teach make_preload to handle the new 'AtU8' chunk
26b59dfe67 introduced the new 'AtU8' chunk to support
Unicode atoms.
make_preload strips the pre-loaded BEAM files so that they
only contain essential chunks. It expects to find the old
'Atom' chunk.
Teach make_preload to read the new 'AtU8' chunk instead of the old
chunk. Also produce a nice error message if someone by mistake
compiles the pre-loaded modules with an OTP 19 compiler.
---
erts/emulator/utils/make_preload | 18 +++++++++++++-----
erts/preloaded/ebin/erl_prim_loader.beam | Bin 55840 -> 55820 bytes
erts/preloaded/ebin/erl_tracer.beam | Bin 2176 -> 2160 bytes
erts/preloaded/ebin/erlang.beam | Bin 106232 -> 106104 bytes
erts/preloaded/ebin/erts_code_purger.beam | Bin 11472 -> 11456 bytes
.../ebin/erts_dirty_process_code_checker.beam | Bin 2108 -> 2092 bytes
erts/preloaded/ebin/erts_internal.beam | Bin 10892 -> 10876 bytes
.../ebin/erts_literal_area_collector.beam | Bin 3280 -> 3264 bytes
erts/preloaded/ebin/init.beam | Bin 50016 -> 49996 bytes
erts/preloaded/ebin/otp_ring0.beam | Bin 1420 -> 1404 bytes
erts/preloaded/ebin/prim_eval.beam | Bin 1292 -> 1276 bytes
erts/preloaded/ebin/prim_file.beam | Bin 44428 -> 44408 bytes
erts/preloaded/ebin/prim_inet.beam | Bin 76464 -> 76440 bytes
erts/preloaded/ebin/prim_zip.beam | Bin 23132 -> 23112 bytes
erts/preloaded/ebin/zlib.beam | Bin 14304 -> 14288 bytes
15 files changed, 13 insertions(+), 5 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/utils/make_preload b/erts/emulator/utils/make_preload
index 8b629d9517..bcb2e42614 100755
--- a/erts/emulator/utils/make_preload
+++ b/erts/emulator/utils/make_preload
@@ -90,7 +90,7 @@ foreach $file (@ARGV) {
open(FILE, $file) or error("failed to read $file: $!");
binmode(FILE);
$_ = ;
- $_ = beam_strip($_);
+ $_ = beam_strip($_, $file);
close(FILE);
push(@modules, " {\"$module\", " . length($_) . ", preloaded_$module},\n");
@@ -147,20 +147,20 @@ sub error {
}
sub beam_strip {
- my($beam) = @_;
+ my($beam,$file) = @_;
my $size_left = length($beam);
my %chunk;
my %needed_chunk = ('Code' => 1,
- 'Atom' => 1,
+ 'AtU8' => 1,
'ImpT' => 1,
'ExpT' => 1,
'StrT' => 1,
'FunT' => 1,
'LitT' => 1);
- die "can't read Beam files for OTP R4 or earlier (sorry)"
+ die "$file: can't read Beam files for OTP R4 or earlier (sorry)"
if $beam =~ /^\x7fBEAM!/;
#
@@ -177,7 +177,7 @@ sub beam_strip {
die "form size $size greater than size ", $size_left, " of module"
if $size > $size_left;
$size_left -= 4;
- die "not a BEAM file: IFF form type is not 'BEAM'"
+ die "$file: not a BEAM file: IFF form type is not 'BEAM'"
unless $beam_id eq 'BEAM';
#
@@ -196,6 +196,14 @@ sub beam_strip {
$size_left = length($beam);
}
+ #
+ # Abort if there is no new-style 'AtU8' atom chunk.
+ #
+
+ exists $chunk{'AtU8'} or
+ die "$file: no 'AtU8' chunk (re-compile with " .
+ "OTP 20 or later)\n";
+
#
# Create a new beam file with only the useful chunk types.
#
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index 4f4027c74e..5b03019d8e 100644
Binary files a/erts/preloaded/ebin/erl_prim_loader.beam and b/erts/preloaded/ebin/erl_prim_loader.beam differ
diff --git a/erts/preloaded/ebin/erl_tracer.beam b/erts/preloaded/ebin/erl_tracer.beam
index c05bc813f0..4cf1b5ed82 100644
Binary files a/erts/preloaded/ebin/erl_tracer.beam and b/erts/preloaded/ebin/erl_tracer.beam differ
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index 7cdf2931a1..149d30d299 100644
Binary files a/erts/preloaded/ebin/erlang.beam and b/erts/preloaded/ebin/erlang.beam differ
diff --git a/erts/preloaded/ebin/erts_code_purger.beam b/erts/preloaded/ebin/erts_code_purger.beam
index 1b28a929ce..0a318b70bb 100644
Binary files a/erts/preloaded/ebin/erts_code_purger.beam and b/erts/preloaded/ebin/erts_code_purger.beam differ
diff --git a/erts/preloaded/ebin/erts_dirty_process_code_checker.beam b/erts/preloaded/ebin/erts_dirty_process_code_checker.beam
index e5381d3574..20ee82a134 100644
Binary files a/erts/preloaded/ebin/erts_dirty_process_code_checker.beam and b/erts/preloaded/ebin/erts_dirty_process_code_checker.beam differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index 57b3023ea6..fe99cc769b 100644
Binary files a/erts/preloaded/ebin/erts_internal.beam and b/erts/preloaded/ebin/erts_internal.beam differ
diff --git a/erts/preloaded/ebin/erts_literal_area_collector.beam b/erts/preloaded/ebin/erts_literal_area_collector.beam
index 2fab34318e..e925636787 100644
Binary files a/erts/preloaded/ebin/erts_literal_area_collector.beam and b/erts/preloaded/ebin/erts_literal_area_collector.beam differ
diff --git a/erts/preloaded/ebin/init.beam b/erts/preloaded/ebin/init.beam
index 8123d63a9e..fdd87ef739 100644
Binary files a/erts/preloaded/ebin/init.beam and b/erts/preloaded/ebin/init.beam differ
diff --git a/erts/preloaded/ebin/otp_ring0.beam b/erts/preloaded/ebin/otp_ring0.beam
index 3c6a6d4f41..b91fa63e7d 100644
Binary files a/erts/preloaded/ebin/otp_ring0.beam and b/erts/preloaded/ebin/otp_ring0.beam differ
diff --git a/erts/preloaded/ebin/prim_eval.beam b/erts/preloaded/ebin/prim_eval.beam
index 133fda4b13..66cc919bf1 100644
Binary files a/erts/preloaded/ebin/prim_eval.beam and b/erts/preloaded/ebin/prim_eval.beam differ
diff --git a/erts/preloaded/ebin/prim_file.beam b/erts/preloaded/ebin/prim_file.beam
index 99ad863b8b..b5e5ff9f88 100644
Binary files a/erts/preloaded/ebin/prim_file.beam and b/erts/preloaded/ebin/prim_file.beam differ
diff --git a/erts/preloaded/ebin/prim_inet.beam b/erts/preloaded/ebin/prim_inet.beam
index e52e442f8e..994677872c 100644
Binary files a/erts/preloaded/ebin/prim_inet.beam and b/erts/preloaded/ebin/prim_inet.beam differ
diff --git a/erts/preloaded/ebin/prim_zip.beam b/erts/preloaded/ebin/prim_zip.beam
index 122406c834..6f1c82509f 100644
Binary files a/erts/preloaded/ebin/prim_zip.beam and b/erts/preloaded/ebin/prim_zip.beam differ
diff --git a/erts/preloaded/ebin/zlib.beam b/erts/preloaded/ebin/zlib.beam
index c683d395f3..eb9e07af7e 100644
Binary files a/erts/preloaded/ebin/zlib.beam and b/erts/preloaded/ebin/zlib.beam differ
--
cgit v1.2.3
From 7dc39b7f02bf1e12541e91298a44d09d052d8fde Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Thu, 16 Feb 2017 19:23:51 +0100
Subject: Fix driver monitor implementation
---
erts/emulator/beam/io.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
(limited to 'erts')
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 7e49e9c48f..e0cc756887 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -7609,10 +7609,21 @@ erl_drv_convert_time_unit(ErlDrvTime val,
static void ref_to_driver_monitor(Eterm ref, ErlDrvMonitor *mon)
{
- ERTS_CT_ASSERT(sizeof(ErtsOIRefStorage) <= sizeof(ErlDrvMonitor));
- erts_oiref_storage_save((ErtsOIRefStorage *) mon, ref);
+ ERTS_CT_ASSERT(ERTS_REF_THING_SIZE*sizeof(Uint) <= sizeof(ErlDrvMonitor));
+ ASSERT(is_internal_ordinary_ref(ref));
+ sys_memcpy((void *) mon, (void *) internal_ref_val(ref),
+ ERTS_REF_THING_SIZE*sizeof(Uint));
}
+static Eterm driver_monitor_to_ref(Eterm *hp, const ErlDrvMonitor *mon)
+{
+ Eterm ref;
+ ERTS_CT_ASSERT(ERTS_REF_THING_SIZE*sizeof(Uint) <= sizeof(ErlDrvMonitor));
+ sys_memcpy((void *) hp, (void *) mon, ERTS_REF_THING_SIZE*sizeof(Uint));
+ ref = make_internal_ref(hp);
+ ASSERT(is_internal_ordinary_ref(ref));
+ return ref;
+}
static int do_driver_monitor_process(Port *prt,
ErlDrvTermData process,
@@ -7669,13 +7680,12 @@ int driver_monitor_process(ErlDrvPort drvport,
static int do_driver_demonitor_process(Port *prt, const ErlDrvMonitor *monitor)
{
Eterm heap[ERTS_REF_THING_SIZE];
- Eterm *hp = &heap[0];
Process *rp;
Eterm ref;
ErtsMonitor *mon;
Eterm to;
- ref = erts_oiref_storage_make_ref((ErtsOIRefStorage *) monitor, &hp),
+ ref = driver_monitor_to_ref(heap, monitor);
mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref);
if (mon == NULL) {
@@ -7731,9 +7741,8 @@ static ErlDrvTermData do_driver_get_monitored_process(Port *prt,const ErlDrvMoni
ErtsMonitor *mon;
Eterm to;
Eterm heap[ERTS_REF_THING_SIZE];
- Eterm *hp = &heap[0];
- ref = erts_oiref_storage_make_ref((ErtsOIRefStorage *) monitor, &hp),
+ ref = driver_monitor_to_ref(heap, monitor);
mon = erts_lookup_monitor(ERTS_P_MONITORS(prt), ref);
if (mon == NULL) {
@@ -7767,12 +7776,11 @@ ErlDrvTermData driver_get_monitored_process(ErlDrvPort drvport,
return ret;
}
-
int driver_compare_monitors(const ErlDrvMonitor *monitor1,
const ErlDrvMonitor *monitor2)
{
- return erts_oiref_storage_cmp((ErtsOIRefStorage *) monitor1,
- (ErtsOIRefStorage *) monitor2);
+ return sys_memcmp((void *) monitor1, (void *) monitor2,
+ ERTS_REF_THING_SIZE*sizeof(Eterm));
}
void erts_fire_port_monitor(Port *prt, Eterm ref)
--
cgit v1.2.3