aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/configure.in23
-rw-r--r--erts/doc/src/absform.xml3
-rw-r--r--erts/doc/src/erl_nif.xml2
-rw-r--r--erts/doc/src/erlang.xml22
-rw-r--r--erts/doc/src/notes.xml28
-rw-r--r--erts/emulator/beam/beam_debug.c2
-rw-r--r--erts/emulator/beam/erl_alloc_util.c84
-rw-r--r--erts/emulator/drivers/common/inet_drv.c9
-rw-r--r--erts/preloaded/src/erlang.erl8
-rw-r--r--erts/vsn.mk2
10 files changed, 91 insertions, 92 deletions
diff --git a/erts/configure.in b/erts/configure.in
index 9e8ffd5ec5..2b3d97cfdd 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -2012,29 +2012,6 @@ esac
AC_CHECK_DECLS([posix2time, time2posix],,,[#include <time.h>])
-disable_vfork=false
-if test "x$EMU_THR_LIB_NAME" != "x"; then
- AC_MSG_CHECKING([if vfork is known to hang multithreaded applications])
- case $host_os in
- osf*)
- AC_MSG_RESULT(yes)
- disable_vfork=true;;
- *)
- AC_MSG_RESULT(no);;
- esac
-fi
-
-if test $disable_vfork = false; then
- AC_FUNC_VFORK
- if test $ac_cv_func_vfork_works = no; then
- disable_vfork=true
- fi
-fi
-
-if test $disable_vfork = true; then
- AC_DEFINE(DISABLE_VFORK, 1, [Define if you want to disable vfork.])
-fi
-
AC_FUNC_VPRINTF
dnl The AC_DEFINEs are necessary for autoheader to work. :-(
diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml
index 158f4dc4e8..f29bb7b8f9 100644
--- a/erts/doc/src/absform.xml
+++ b/erts/doc/src/absform.xml
@@ -801,7 +801,8 @@
<c>{ann_type,LINE,[Rep(A),Rep(T_0)]}</c>.</p>
</item>
<item>
- <p>If T is an atom or integer literal L, then Rep(T) = Rep(L).</p>
+ <p>If T is an atom, a character, or an integer literal L,
+ then Rep(T) = Rep(L).</p>
</item>
<item>
<p>If T is a bitstring type <c>&lt;&lt;_:M,_:_*N>></c>,
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index a8eff43623..0fff8f7cad 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -194,7 +194,7 @@ ok
<p>Binaries are sequences of whole bytes. Bitstrings with an arbitrary
bit length have no support yet.</p>
</item>
- <tag>Resource objects</tag>
+ <tag><marker id="resource_objects"/>Resource objects</tag>
<item>
<p>The use of resource objects is a safe way to return pointers to
native data structures from a NIF. A resource object is
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 29b1d106cd..8e014c3010 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -197,6 +197,15 @@
</desc>
</datatype>
+ <datatype>
+ <name name="nif_resource"></name>
+ <desc>
+ <p>An opaque handle identifing a
+ <seealso marker="erl_nif#resource_objects">NIF resource object
+ </seealso>.</p>
+ </desc>
+ </datatype>
+
</datatypes>
<funcs>
@@ -3772,13 +3781,6 @@ RealSystem = system + MissedSystem</code>
If found, that driver is started. A driver runs in the Erlang
work space, which means that it is linked with the Erlang
runtime system.</p>
- <p>When starting external programs on Solaris, the system
- call <c>vfork</c> is used in preference to <c>fork</c>
- for performance reasons, although it has a history of
- being less robust. If there are problems using
- <c>vfork</c>, setting environment variable
- <c>ERL_NO_VFORK</c> to any value causes <c>fork</c>
- to be used instead.</p>
<p>For external programs, <c>PATH</c> is searched
(or an equivalent method is used to find programs,
depending on the OS). This is done by invoking
@@ -5295,10 +5297,10 @@ RealSystem = system + MissedSystem</code>
<p><c><anno>MinBinVHeapSize</anno></c> is the minimum binary virtual
heap size for the process.</p>
</item>
- <tag><c>{monitored_by, <anno>Pids</anno>}</c></tag>
+ <tag><c>{monitored_by, <anno>MonitoredBy</anno>}</c></tag>
<item>
- <p>A list of process identifiers monitoring the process (with
- <c>monitor/2</c>).</p>
+ <p>A list of identifiers for all the processes, ports and NIF
+ resources, that are monitoring the process.</p>
</item>
<tag><c>{monitors, <anno>Monitors</anno>}</c></tag>
<item>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index 3b300c8c72..1531935f36 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -31,6 +31,34 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 10.0.2</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>Fixed a rare bug that could cause processes to be
+ scheduled after they had been freed.</p>
+ <p>
+ Own Id: OTP-15067 Aux Id: ERL-573 </p>
+ </item>
+ </list>
+ </section>
+
+
+ <section><title>Known Bugs and Problems</title>
+ <list>
+ <item>
+ <p>Fixed a race condition in the inet driver that could
+ cause receive to hang when the emulator was compiled with
+ gcc 8.</p>
+ <p>
+ Own Id: OTP-15158 Aux Id: ERL-654 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 10.0.1</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/beam_debug.c b/erts/emulator/beam/beam_debug.c
index 6d3b99c43e..10d20c8f3f 100644
--- a/erts/emulator/beam/beam_debug.c
+++ b/erts/emulator/beam/beam_debug.c
@@ -667,7 +667,7 @@ print_op(fmtfn_t to, void *to_arg, int op, int size, BeamInstr* addr)
ap++;
break;
case 'l': /* fr(N) */
- erts_print(to, to_arg, "fr(%d)", loader_reg_index(ap[0]));
+ erts_print(to, to_arg, "fr(%d)", ap[0] / sizeof(FloatDef));
ap++;
break;
default:
diff --git a/erts/emulator/beam/erl_alloc_util.c b/erts/emulator/beam/erl_alloc_util.c
index 77f52a5fe6..b7a8b9c2d0 100644
--- a/erts/emulator/beam/erl_alloc_util.c
+++ b/erts/emulator/beam/erl_alloc_util.c
@@ -586,6 +586,7 @@ do { \
STAT_MSEG_MBC_ALLOC((AP), csz__); \
else \
STAT_SYS_ALLOC_MBC_ALLOC((AP), csz__); \
+ set_new_allctr_abandon_limit(AP); \
(AP)->mbcs.blocks.curr.no += (CRR)->cpool.blocks[(AP)->alloc_no]; \
if ((AP)->mbcs.blocks.max.no < (AP)->mbcs.blocks.curr.no) \
(AP)->mbcs.blocks.max.no = (AP)->mbcs.blocks.curr.no; \
@@ -613,7 +614,7 @@ do { \
DEBUG_CHECK_CARRIER_NO_SZ((AP)); \
} while (0)
-#define STAT_MBC_ABANDON(AP, CRR) \
+#define STAT_MBC_FREE(AP, CRR) \
do { \
UWord csz__ = CARRIER_SZ((CRR)); \
if (IS_MSEG_CARRIER((CRR))) { \
@@ -621,6 +622,12 @@ do { \
} else { \
STAT_SYS_ALLOC_MBC_FREE((AP), csz__); \
} \
+ set_new_allctr_abandon_limit(AP); \
+} while (0)
+
+#define STAT_MBC_ABANDON(AP, CRR) \
+do { \
+ STAT_MBC_FREE(AP, CRR); \
ERTS_ALC_CPOOL_ASSERT((AP)->mbcs.blocks.curr.no \
>= (CRR)->cpool.blocks[(AP)->alloc_no]); \
(AP)->mbcs.blocks.curr.no -= (CRR)->cpool.blocks[(AP)->alloc_no]; \
@@ -1705,6 +1712,7 @@ dealloc_mbc(Allctr_t *allctr, Carrier_t *crr)
}
+static UWord allctr_abandon_limit(Allctr_t *allctr);
static void set_new_allctr_abandon_limit(Allctr_t*);
static void abandon_carrier(Allctr_t*, Carrier_t*);
static void poolify_my_carrier(Allctr_t*, Carrier_t*);
@@ -2262,10 +2270,7 @@ check_abandon_carrier(Allctr_t *allctr, Block_t *fblk, Carrier_t **busy_pcrr_pp)
if (!ERTS_ALC_IS_CPOOL_ENABLED(allctr))
return;
- allctr->cpool.check_limit_count--;
- if (--allctr->cpool.check_limit_count <= 0)
- set_new_allctr_abandon_limit(allctr);
-
+ ASSERT(allctr->cpool.abandon_limit == allctr_abandon_limit(allctr));
ASSERT(erts_thr_progress_is_managed_thread());
if (allctr->cpool.disable_abandon)
@@ -3007,7 +3012,6 @@ mbc_realloc(Allctr_t *allctr, ErtsAlcType_t type, void *p, Uint size,
#define ERTS_ALC_MAX_DEALLOC_CARRIER 10
#define ERTS_ALC_CPOOL_MAX_FETCH_INSPECT 100
-#define ERTS_ALC_CPOOL_CHECK_LIMIT_COUNT 100
#define ERTS_ALC_CPOOL_MAX_FAILED_STAT_READS 3
#define ERTS_ALC_CPOOL_PTR_MOD_MRK (((erts_aint_t) 1) << 0)
@@ -3371,8 +3375,7 @@ cpool_delete(Allctr_t *allctr, Allctr_t *prev_allctr, Carrier_t *crr)
static Carrier_t *
cpool_fetch(Allctr_t *allctr, UWord size)
{
- enum { IGNORANT, HAS_SEEN_SENTINEL, THE_LAST_ONE } loop_state;
- int i;
+ int i, seen_sentinel;
Carrier_t *crr;
Carrier_t *reinsert_crr = NULL;
ErtsAlcCPoolData_t *cpdp;
@@ -3486,43 +3489,34 @@ cpool_fetch(Allctr_t *allctr, UWord size)
/*
* We saw a pooled carried above, use it as entrance into the pool
*/
- cpdp = cpool_entrance;
}
else {
/*
- * No pooled carried seen above. Start search at cpool sentinel,
+ * No pooled carrier seen above. Start search at cpool sentinel,
* but begin by passing one element before trying to fetch.
* This in order to avoid contention with threads inserting elements.
*/
- cpool_entrance = sentinel;
- cpdp = cpool_aint2cpd(cpool_read(&cpool_entrance->prev));
- if (cpdp == sentinel)
+ cpool_entrance = cpool_aint2cpd(cpool_read(&sentinel->prev));
+ if (cpool_entrance == sentinel)
goto check_dc_list;
}
- loop_state = IGNORANT;
+ cpdp = cpool_entrance;
+ seen_sentinel = 0;
do {
erts_aint_t exp;
cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
- if (cpdp == cpool_entrance) {
- if (cpool_entrance == sentinel) {
- cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
- if (cpdp == sentinel)
- break;
- }
- loop_state = THE_LAST_ONE;
- }
- else if (cpdp == sentinel) {
- if (loop_state == HAS_SEEN_SENTINEL) {
+ if (cpdp == sentinel) {
+ if (seen_sentinel) {
/* We been here before. cpool_entrance must have been removed */
INC_CC(allctr->cpool.stat.entrance_removed);
break;
}
- cpdp = cpool_aint2cpd(cpool_read(&cpdp->prev));
- if (cpdp == sentinel)
- break;
- loop_state = HAS_SEEN_SENTINEL;
+ seen_sentinel = 1;
+ continue;
}
+ ASSERT(cpdp != cpool_entrance || seen_sentinel);
+
crr = ErtsContainerStruct(cpdp, Carrier_t, cpool);
exp = erts_atomic_read_rb(&crr->allctr);
@@ -3555,7 +3549,7 @@ cpool_fetch(Allctr_t *allctr, UWord size)
INC_CC(allctr->cpool.stat.fail_shared);
return NULL;
}
- }while (loop_state != THE_LAST_ONE);
+ }while (cpdp != cpool_entrance);
check_dc_list:
/* Last; check our own pending dealloc carrier list... */
@@ -3751,14 +3745,14 @@ cpool_init_carrier_data(Allctr_t *allctr, Carrier_t *crr)
crr->cpool.state = ERTS_MBC_IS_HOME;
}
-static void
-set_new_allctr_abandon_limit(Allctr_t *allctr)
+
+
+static UWord
+allctr_abandon_limit(Allctr_t *allctr)
{
UWord limit;
UWord csz;
- allctr->cpool.check_limit_count = ERTS_ALC_CPOOL_CHECK_LIMIT_COUNT;
-
csz = allctr->mbcs.curr.norm.mseg.size;
csz += allctr->mbcs.curr.norm.sys_alloc.size;
@@ -3768,7 +3762,13 @@ set_new_allctr_abandon_limit(Allctr_t *allctr)
else
limit = (csz/100)*allctr->cpool.util_limit;
- allctr->cpool.abandon_limit = limit;
+ return limit;
+}
+
+static void ERTS_INLINE
+set_new_allctr_abandon_limit(Allctr_t *allctr)
+{
+ allctr->cpool.abandon_limit = allctr_abandon_limit(allctr);
}
static void
@@ -3780,7 +3780,6 @@ abandon_carrier(Allctr_t *allctr, Carrier_t *crr)
unlink_carrier(&allctr->mbc_list, crr);
allctr->remove_mbc(allctr, crr);
- set_new_allctr_abandon_limit(allctr);
cpool_insert(allctr, crr);
@@ -4112,6 +4111,7 @@ create_carrier(Allctr_t *allctr, Uint umem_sz, UWord flags)
#if HAVE_ERTS_MSEG
mbc_final_touch:
#endif
+ set_new_allctr_abandon_limit(allctr);
blk = MBC_TO_FIRST_BLK(allctr, crr);
@@ -4330,7 +4330,6 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
else {
ASSERT(IS_MBC_FIRST_FBLK(allctr, blk));
crr = FIRST_BLK_TO_MBC(allctr, blk);
- crr_sz = CARRIER_SZ(crr);
#ifdef DEBUG
if (!allctr->stopped) {
@@ -4362,15 +4361,7 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
else
{
unlink_carrier(&allctr->mbc_list, crr);
-#if HAVE_ERTS_MSEG
- if (IS_MSEG_CARRIER(crr)) {
- ASSERT(crr_sz % ERTS_SACRR_UNIT_SZ == 0);
- STAT_MSEG_MBC_FREE(allctr, crr_sz);
- }
- else
-#endif
- STAT_SYS_ALLOC_MBC_FREE(allctr, crr_sz);
-
+ STAT_MBC_FREE(allctr, crr);
if (allctr->remove_mbc)
allctr->remove_mbc(allctr, crr);
}
@@ -4384,7 +4375,7 @@ destroy_carrier(Allctr_t *allctr, Block_t *blk, Carrier_t **busy_pcrr_pp)
LTTNG5(carrier_destroy,
ERTS_ALC_A2AD(allctr->alloc_no),
allctr->ix,
- crr_sz,
+ CARRIER_SZ(crr),
mbc_stats,
sbc_stats);
}
@@ -6479,7 +6470,6 @@ erts_alcu_start(Allctr_t *allctr, AllctrInit_t *init)
}
erts_atomic_init_nob(&allctr->cpool.stat.carriers_size, 0);
erts_atomic_init_nob(&allctr->cpool.stat.no_carriers, 0);
- allctr->cpool.check_limit_count = ERTS_ALC_CPOOL_CHECK_LIMIT_COUNT;
if (!init->ts && init->acul && init->acnl) {
allctr->cpool.util_limit = init->acul;
allctr->cpool.in_pool_limit = init->acnl;
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index 6fd3bb9fbf..5e9afdc5ca 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -1034,6 +1034,7 @@ typedef struct {
inet_async_op* oph; /* queue head or NULL */
inet_async_op* opt; /* queue tail or NULL */
inet_async_op op_queue[INET_MAX_ASYNC]; /* call queue */
+ int op_ref; /* queue reference generator */
int active; /* 0 = passive, 1 = active, 2 = active once */
Sint16 active_count; /* counter for {active,N} */
@@ -1299,8 +1300,7 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event);
/* convert descriptor pointer to inet_descriptor pointer */
#define INETP(d) (&(d)->inet)
-static int async_ref = 0; /* async reference id generator */
-#define NEW_ASYNC_ID() ((async_ref++) & 0xffff)
+#define NEW_ASYNC_ID(desc) ((desc)->op_ref++ & 0xffff)
/* check for transition from active to passive */
#define INET_CHECK_ACTIVE_TO_PASSIVE(inet) \
@@ -1955,7 +1955,7 @@ static void enq_multi_op(tcp_descriptor *desc, char *buf, int req,
ErlDrvTermData caller, MultiTimerData *timeout,
ErlDrvMonitor *monitorp)
{
- int id = NEW_ASYNC_ID();
+ int id = NEW_ASYNC_ID(INETP(desc));
enq_old_multi_op(desc,id,req,caller,timeout,monitorp);
if (buf != NULL)
put_int16(id, buf);
@@ -2024,7 +2024,7 @@ static int remove_multi_op(tcp_descriptor *desc, int *id_p, int *req_p,
static int enq_async_w_tmo(inet_descriptor* desc, char* buf, int req, unsigned timeout,
ErlDrvMonitor *monitorp)
{
- int id = NEW_ASYNC_ID();
+ int id = NEW_ASYNC_ID(desc);
inet_async_op* opp;
if ((opp = desc->oph) == NULL) /* queue empty */
@@ -8461,6 +8461,7 @@ static ErlDrvData inet_start(ErlDrvPort port, int size, int protocol)
desc->delimiter = '\n'; /* line delimiting char */
desc->oph = NULL;
desc->opt = NULL;
+ desc->op_ref = 0;
desc->peer_ptr = NULL;
desc->name_ptr = NULL;
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index fd8a35aabf..261b731900 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -86,15 +86,15 @@
| 'nano_seconds'.
-opaque prepared_code() :: reference().
-
-export_type([prepared_code/0]).
--opaque dist_handle() :: atom().
+-opaque nif_resource() :: reference().
+-export_type([nif_resource/0]).
+-opaque dist_handle() :: atom().
-export_type([dist_handle/0]).
-type iovec() :: [binary()].
-
-export_type([iovec/0]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2316,7 +2316,7 @@ process_flag(_Flag, _Value) ->
{min_heap_size, MinHeapSize :: non_neg_integer()} |
{min_bin_vheap_size, MinBinVHeapSize :: non_neg_integer()} |
{max_heap_size, MaxHeapSize :: max_heap_size()} |
- {monitored_by, Pids :: [pid()]} |
+ {monitored_by, MonitoredBy :: [pid() | port() | nif_resource()]} |
{monitors,
Monitors :: [{process | port, Pid :: pid() | port() |
{RegName :: atom(), Node :: node()}}]} |
diff --git a/erts/vsn.mk b/erts/vsn.mk
index e60405215a..1df1b9142b 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -18,7 +18,7 @@
# %CopyrightEnd%
#
-VSN = 10.0.1
+VSN = 10.0.2
# Port number 4365 in 4.2
# Port number 4366 in 4.3