aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/Makefile.in1
-rw-r--r--erts/emulator/beam/beam_emu.c2
-rw-r--r--erts/emulator/beam/erl_nif.c52
-rw-r--r--erts/emulator/beam/erl_process.c15
-rw-r--r--erts/emulator/beam/erl_term.h12
-rw-r--r--erts/emulator/drivers/common/inet_drv.c6
-rw-r--r--erts/emulator/test/binary_SUITE.erl4
-rw-r--r--erts/emulator/test/match_spec_SUITE.erl2
-rw-r--r--erts/emulator/test/port_SUITE.erl9
9 files changed, 59 insertions, 44 deletions
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 58639c7190..7145824f91 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -1039,7 +1039,6 @@ $(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS) $(LCF)
else
$(BINDIR)/$(EMULATOR_EXECUTABLE): $(INIT_OBJS) $(OBJS) $(DEPLIBS)
- echo $(DEPLIBS)
$(ld_verbose)$(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE) \
$(HIPEBEAMLDFLAGS) $(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS) \
$(STATIC_NIF_LIBS) $(STATIC_DRIVER_LIBS) $(LIBS)
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 9634faff1d..1026e5f649 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -3525,7 +3525,7 @@ get_map_elements_fail:
erts_post_nif(&env);
#ifdef ERTS_DIRTY_SCHEDULERS
if (is_non_value(nif_bif_result) && c_p->freason == TRAP) {
- Export* ep = (Export*) c_p->psd->data[ERTS_PSD_DIRTY_SCHED_TRAP_EXPORT];
+ Export* ep = ERTS_PROC_GET_DIRTY_SCHED_TRAP_EXPORT(c_p);
ep->code[0] = I[-3];
ep->code[1] = I[-2];
}
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 063dba056e..ff551ea3af 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -1515,26 +1515,35 @@ int enif_consume_timeslice(ErlNifEnv* env, int percent)
#ifdef ERTS_DIRTY_SCHEDULERS
+/* NIFs exports need one more item than the Export struct provides, the
+ * erl_module_nif*, so the DirtyNifExport below adds that. The Export
+ * member must be first in the struct.
+ */
+typedef struct {
+ Export exp;
+ struct erl_module_nif* m;
+} DirtyNifExport;
+
static void
-alloc_proc_psd(Process* proc, Export **ep)
+alloc_proc_psd(Process* proc, DirtyNifExport **ep)
{
int i;
if (!*ep) {
- *ep = erts_alloc(ERTS_ALC_T_PSD, sizeof(Export));
- sys_memset((void*) *ep, 0, sizeof(Export));
+ *ep = erts_alloc(ERTS_ALC_T_PSD, sizeof(DirtyNifExport));
+ sys_memset((void*) *ep, 0, sizeof(DirtyNifExport));
for (i=0; i<ERTS_NUM_CODE_IX; i++) {
- (*ep)->addressv[i] = &(*ep)->code[3];
+ (*ep)->exp.addressv[i] = &(*ep)->exp.code[3];
}
- (*ep)->code[3] = (BeamInstr) em_call_nif;
+ (*ep)->exp.code[3] = (BeamInstr) em_call_nif;
}
- (void) ERTS_PROC_SET_DIRTY_SCHED_TRAP_EXPORT(proc, ERTS_PROC_LOCK_MAIN, *ep);
+ (void) ERTS_PROC_SET_DIRTY_SCHED_TRAP_EXPORT(proc, ERTS_PROC_LOCK_MAIN, &(*ep)->exp);
}
static ERL_NIF_TERM
execute_dirty_nif_finalizer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
Eterm* reg = ERTS_PROC_GET_SCHDATA(env->proc)->x_reg_array;
- ERL_NIF_TERM result = (ERL_NIF_TERM) reg[0];
+ ERL_NIF_TERM result, dirty_result = (ERL_NIF_TERM) reg[0];
typedef ERL_NIF_TERM (*FinalizerFP)(ErlNifEnv*, ERL_NIF_TERM);
FinalizerFP fp;
#if HAVE_INT64 && SIZEOF_LONG != 8
@@ -1544,7 +1553,11 @@ execute_dirty_nif_finalizer(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(sizeof(fp) <= sizeof(unsigned long));
enif_get_ulong(env, reg[1], (unsigned long *) &fp);
#endif
- return (*fp)(env, result);
+ result = (*fp)(env, dirty_result);
+ if (erts_refc_dectest(&env->mod_nif->rt_dtor_cnt, 0) == 0
+ && env->mod_nif->mod == NULL)
+ close_lib(env->mod_nif);
+ return result;
}
#endif /* ERTS_DIRTY_SCHEDULERS */
@@ -1560,7 +1573,7 @@ enif_schedule_dirty_nif(ErlNifEnv* env, int flags,
erts_aint32_t state, n, a;
Process* proc = env->proc;
Eterm* reg = ERTS_PROC_GET_SCHDATA(proc)->x_reg_array;
- Export* ep = NULL;
+ DirtyNifExport* ep = NULL;
int i;
int chkflgs = (flags & (ERL_NIF_DIRTY_JOB_IO_BOUND|ERL_NIF_DIRTY_JOB_CPU_BOUND));
@@ -1585,17 +1598,20 @@ enif_schedule_dirty_nif(ErlNifEnv* env, int flags,
if (a == state)
break;
}
- if (!(ep = ERTS_PROC_GET_DIRTY_SCHED_TRAP_EXPORT(proc)))
+ if (!(ep = (DirtyNifExport*) ERTS_PROC_GET_DIRTY_SCHED_TRAP_EXPORT(proc)))
alloc_proc_psd(proc, &ep);
ERTS_VBUMP_ALL_REDS(proc);
- ep->code[2] = argc;
+ ep->exp.code[2] = argc;
for (i = 0; i < argc; i++) {
reg[i] = (Eterm) argv[i];
}
- proc->i = (BeamInstr*) ep->addressv[0];
- ep->code[4] = (BeamInstr) fp;
+ proc->i = (BeamInstr*) ep->exp.addressv[0];
+ ep->exp.code[4] = (BeamInstr) fp;
+ ep->m = env->mod_nif;
proc->freason = TRAP;
+ erts_refc_inc(&env->mod_nif->rt_dtor_cnt, 1);
+
return THE_NON_VALUE;
#else
return (*fp)(env, argc, argv);
@@ -1609,17 +1625,17 @@ enif_schedule_dirty_nif_finalizer(ErlNifEnv* env, ERL_NIF_TERM result,
#ifdef USE_THREADS
Process* proc = env->proc;
Eterm* reg = ERTS_PROC_GET_SCHDATA(proc)->x_reg_array;
- Export* ep;
+ DirtyNifExport* ep;
erts_smp_atomic32_read_band_mb(&proc->state,
~(ERTS_PSFLG_DIRTY_CPU_PROC
|ERTS_PSFLG_DIRTY_IO_PROC
|ERTS_PSFLG_DIRTY_CPU_PROC_IN_Q
|ERTS_PSFLG_DIRTY_IO_PROC_IN_Q));
- if (!(ep = ERTS_PROC_GET_DIRTY_SCHED_TRAP_EXPORT(proc)))
+ if (!(ep = (DirtyNifExport*) ERTS_PROC_GET_DIRTY_SCHED_TRAP_EXPORT(proc)))
alloc_proc_psd(proc, &ep);
ERTS_VBUMP_ALL_REDS(proc);
- ep->code[2] = 2;
+ ep->exp.code[2] = 2;
reg[0] = (Eterm) result;
#if HAVE_INT64 && SIZEOF_LONG != 8
ASSERT(sizeof(fp) <= sizeof(ErlNifUInt64));
@@ -1628,8 +1644,8 @@ enif_schedule_dirty_nif_finalizer(ErlNifEnv* env, ERL_NIF_TERM result,
ASSERT(sizeof(fp) <= sizeof(unsigned long));
reg[1] = (Eterm) enif_make_ulong(env, (unsigned long) fp);
#endif
- proc->i = (BeamInstr*) ep->addressv[0];
- ep->code[4] = (BeamInstr) execute_dirty_nif_finalizer;
+ proc->i = (BeamInstr*) ep->exp.addressv[0];
+ ep->exp.code[4] = (BeamInstr) execute_dirty_nif_finalizer;
proc->freason = TRAP;
return THE_NON_VALUE;
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 8bf0cc9491..b4b97d7df1 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -9207,7 +9207,6 @@ Process *schedule(Process *p, int calls)
*/
pick_next_process: {
erts_aint32_t psflg_band_mask;
- erts_aint32_t running_flag;
int prio_q;
int qmask;
@@ -9269,12 +9268,6 @@ Process *schedule(Process *p, int calls)
state = erts_smp_atomic32_read_nob(&p->state);
}
-
- if (state & ERTS_PSFLG_ACTIVE_SYS)
- running_flag = ERTS_PSFLG_RUNNING_SYS;
- else
- running_flag = ERTS_PSFLG_RUNNING;
-
while (1) {
erts_aint32_t exp, new, tmp;
tmp = new = exp = state;
@@ -9284,8 +9277,12 @@ Process *schedule(Process *p, int calls)
tmp = state & (ERTS_PSFLG_SUSPENDED
| ERTS_PSFLG_PENDING_EXIT
| ERTS_PSFLG_ACTIVE_SYS);
- if (tmp != ERTS_PSFLG_SUSPENDED)
- new |= running_flag;
+ if (tmp != ERTS_PSFLG_SUSPENDED) {
+ if (state & ERTS_PSFLG_ACTIVE_SYS)
+ new |= ERTS_PSFLG_RUNNING_SYS;
+ else
+ new |= ERTS_PSFLG_RUNNING;
+ }
}
state = erts_smp_atomic32_cmpxchg_relb(&p->state, new, exp);
if (state == exp) {
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index f10a3a9d38..37014ccf94 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -112,11 +112,11 @@ struct erl_node_; /* Declared in erl_node_tables.h */
* 1000 REFC_BINARY | |
* 1001 HEAP_BINARY | BINARIES |
* 1010 SUB_BINARY | |
- * 1011 Not used
+ * 1011 Not used; see comment below
* 1100 EXTERNAL_PID | |
* 1101 EXTERNAL_PORT | EXTERNAL THINGS |
* 1110 EXTERNAL_REF | |
- * 1111 Not used
+ * 1111 MAP
*
* COMMENTS:
*
@@ -140,10 +140,11 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#define REFC_BINARY_SUBTAG (0x8 << _TAG_PRIMARY_SIZE) /* BINARY */
#define HEAP_BINARY_SUBTAG (0x9 << _TAG_PRIMARY_SIZE) /* BINARY */
#define SUB_BINARY_SUBTAG (0xA << _TAG_PRIMARY_SIZE) /* BINARY */
-#define MAP_SUBTAG (0xB << _TAG_PRIMARY_SIZE) /* MAP */
+/* _BINARY_XXX_MASK depends on 0xB being unused */
#define EXTERNAL_PID_SUBTAG (0xC << _TAG_PRIMARY_SIZE) /* EXTERNAL_PID */
#define EXTERNAL_PORT_SUBTAG (0xD << _TAG_PRIMARY_SIZE) /* EXTERNAL_PORT */
#define EXTERNAL_REF_SUBTAG (0xE << _TAG_PRIMARY_SIZE) /* EXTERNAL_REF */
+#define MAP_SUBTAG (0xF << _TAG_PRIMARY_SIZE) /* MAP */
#define _TAG_HEADER_ARITYVAL (TAG_PRIMARY_HEADER|ARITYVAL_SUBTAG)
@@ -156,11 +157,11 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#define _TAG_HEADER_REFC_BIN (TAG_PRIMARY_HEADER|REFC_BINARY_SUBTAG)
#define _TAG_HEADER_HEAP_BIN (TAG_PRIMARY_HEADER|HEAP_BINARY_SUBTAG)
#define _TAG_HEADER_SUB_BIN (TAG_PRIMARY_HEADER|SUB_BINARY_SUBTAG)
-#define _TAG_HEADER_MAP (TAG_PRIMARY_HEADER|MAP_SUBTAG)
#define _TAG_HEADER_EXTERNAL_PID (TAG_PRIMARY_HEADER|EXTERNAL_PID_SUBTAG)
#define _TAG_HEADER_EXTERNAL_PORT (TAG_PRIMARY_HEADER|EXTERNAL_PORT_SUBTAG)
#define _TAG_HEADER_EXTERNAL_REF (TAG_PRIMARY_HEADER|EXTERNAL_REF_SUBTAG)
#define _TAG_HEADER_BIN_MATCHSTATE (TAG_PRIMARY_HEADER|BIN_MATCHSTATE_SUBTAG)
+#define _TAG_HEADER_MAP (TAG_PRIMARY_HEADER|MAP_SUBTAG)
#define _TAG_HEADER_MASK 0x3F
@@ -892,7 +893,8 @@ typedef struct external_thing_ {
(((x) & _TAG_HEADER_MASK) == _TAG_HEADER_EXTERNAL_REF)
#define is_external_header(x) \
- (((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID)
+ (((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID \
+ && ((x) & _TAG_HEADER_MASK) != _TAG_HEADER_MAP)
#define is_external(x) (is_boxed((x)) && is_external_header(*boxed_val((x))))
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index e33594b026..09bada457d 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -9717,13 +9717,13 @@ static int tcp_remain(tcp_descriptor* desc, int* len)
int n = desc->i_ptr - ptr; /* number of bytes read */
int tlen;
- DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n",
- (long)desc->inet.port, desc->inet.s, n, nfill, nsz, tlen));
-
tlen = packet_get_length(desc->inet.htype, ptr, n,
desc->inet.psize, desc->i_bufsz,
&desc->http_state);
+ DEBUGF(("tcp_remain(%ld): s=%d, n=%d, nfill=%d nsz=%d, tlen %d\r\n",
+ (long)desc->inet.port, desc->inet.s, n, nfill, nsz, tlen));
+
if (tlen > 0) {
if (tlen <= n) { /* got a packet */
*len = tlen;
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 938aac6a0e..7aba367e33 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -64,7 +64,7 @@
-export([sleeper/0,trapping_loop/4]).
suite() -> [{ct_hooks,[ts_install_cth]},
- {timetrap,{minutes,2}}].
+ {timetrap,{minutes,4}}].
all() ->
[copy_terms, conversions, deep_lists, deep_bitstr_lists,
@@ -1266,7 +1266,7 @@ deep(Config) when is_list(Config) ->
deep_roundtrip(T) ->
B = term_to_binary(T),
- T = binary_to_term_stress(B).
+ T = binary_to_term(B).
obsolete_funs(Config) when is_list(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
diff --git a/erts/emulator/test/match_spec_SUITE.erl b/erts/emulator/test/match_spec_SUITE.erl
index 330bef7104..8038888796 100644
--- a/erts/emulator/test/match_spec_SUITE.erl
+++ b/erts/emulator/test/match_spec_SUITE.erl
@@ -42,7 +42,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
- Dog=?t:timetrap(?t:seconds(10)),
+ Dog=?t:timetrap(?t:seconds(30)),
[{watchdog, Dog}|Config].
end_per_testcase(_Func, Config) ->
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index 202a8b7537..e01b2f253b 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -1698,12 +1698,13 @@ otp_5119(Config) when is_list(Config) ->
Path = ?config(data_dir, Config),
ok = load_driver(Path, "exit_drv"),
PI1 = port_ix(otp_5119_fill_empty_port_tab([])),
- PI2 = port_ix(erlang:open_port({spawn, "exit_drv"}, [])),
+ Port2 = erlang:open_port({spawn, "exit_drv"}, []),
+ PI2 = port_ix(Port2),
{PortIx1, PortIx2} = case PI2 > PI1 of
true ->
{PI1, PI2};
false ->
- {port_ix(otp_5119_fill_empty_port_tab([PI2])),
+ {port_ix(otp_5119_fill_empty_port_tab([Port2])),
port_ix(erlang:open_port({spawn, "exit_drv"}, []))}
end,
MaxPorts = max_ports(),
@@ -2318,7 +2319,7 @@ close_deaf_port(Config) when is_list(Config) ->
test_server:timetrap_cancel(Dog),
Res.
-close_deaf_port_1(1000, _) ->
+close_deaf_port_1(200, _) ->
ok;
close_deaf_port_1(N, Cmd) ->
Timeout = integer_to_list(random:uniform(5*1000)),