diff options
Diffstat (limited to 'erts')
-rw-r--r-- | erts/doc/src/erlang.xml | 108 | ||||
-rw-r--r-- | erts/emulator/Makefile.in | 31 | ||||
-rw-r--r-- | erts/emulator/beam/big.c | 16 | ||||
-rw-r--r-- | erts/emulator/beam/external.c | 3 | ||||
-rw-r--r-- | erts/etc/unix/etp-commands | 32 | ||||
-rw-r--r-- | erts/lib_src/common/erl_misc_utils.c | 2 | ||||
-rw-r--r-- | erts/lib_src/common/ethr_atomics.c | 24 | ||||
-rwxr-xr-x | erts/lib_src/utils/make_atomics_api | 20 | ||||
-rw-r--r-- | erts/test/otp_SUITE.erl | 3 |
9 files changed, 164 insertions, 75 deletions
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index fbe7b36163..8c438b0bd7 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4881,6 +4881,7 @@ true</pre> <v>Type, Res -- see below</v> </type> <desc> + <p>All times are in milliseconds unless otherwise specified.</p> <p>Returns information about the system as specified by <c>Type</c>:</p> <taglist> @@ -4894,15 +4895,20 @@ true</pre> <item> <p>Returns <c>{Total_Exact_Reductions, Exact_Reductions_Since_Last_Call}</c>.</p> - <p><em>NOTE:</em><c>statistics(exact_reductions)</c> is - a more expensive operation than - <seealso marker="#statistics_reductions">statistics(reductions)</seealso> - especially on an Erlang machine with SMP support.</p> + <note><p><c>statistics(exact_reductions)</c> is + a more expensive operation than + <seealso marker="#statistics_reductions">statistics(reductions)</seealso> + especially on an Erlang machine with SMP support.</p> + </note> </item> <tag><c>garbage_collection</c></tag> <item> <p>Returns <c>{Number_of_GCs, Words_Reclaimed, 0}</c>. This information may not be valid for all implementations.</p> + <pre> +> <input>statistics(garbage_collection).</input> +{85,23961,0} +</pre> </item> <tag><c>io</c></tag> <item> @@ -4914,12 +4920,18 @@ true</pre> <tag><marker id="statistics_reductions"><c>reductions</c></marker></tag> <item> <p>Returns - <c>{Total_Reductions, Reductions_Since_Last_Call}</c>.</p> - <p><em>NOTE:</em> From erts version 5.5 (OTP release R11B) - this value does not include reductions performed in current - time slices of currently scheduled processes. If an - exact value is wanted, use - <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p> + <c>{Total_Reductions, Reductions_Since_Last_Call}</c>.</p> + <note> + <p>From erts version 5.5 (OTP release R11B) + this value does not include reductions performed in current + time slices of currently scheduled processes. If an + exact value is wanted, use + <seealso marker="#statistics_exact_reductions">statistics(exact_reductions)</seealso>.</p> + </note> + <pre> +> <input>statistics(reductions).</input> +{2046,11} +</pre> </item> <tag><c>run_queue</c></tag> <item> @@ -4932,20 +4944,72 @@ true</pre> Note that the run-time is the sum of the run-time for all threads in the Erlang run-time system and may therefore be greater than the wall-clock time.</p> + <pre> +> <input>statistics(runtime).</input> +{1690,1620} +</pre> </item> <tag><marker id="statistics_scheduler_wall_time"><c>scheduler_wall_time</c></marker></tag> <item> - <p>Returns - <c>[{Scheduler_Id, Scheduler_Worked_Time, Scheduler_Total_Time}]</c>, time lapses are since the - the system flag <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso> - was set to true. + <p>Returns a list of tuples with + <c>{SchedulerId, ActiveTime, TotalTime}</c>, where <c>SchedulerId</c> is an integer id of the scheduler, <c>ActiveTime</c> is + the duration the scheduler has been busy, <c>TotalTime</c> is the total time duration since + <seealso marker="#system_flag_scheduler_wall_time">scheduler_wall_time</seealso> + activation. The time unit is not defined and may be subject to change + between releases, operating systems and system restarts. + <c>scheduler_wall_time</c> should only be used to calculate relative + values for scheduler-utilization. <c>ActiveTime</c> can never exceed <c>TotalTime</c>. + </p> + + <p>The definition of a busy scheduler is when it is not idle or not + scheduling (selecting) a process or port, meaning; executing process + code, executing linked-in-driver or NIF code, executing + built-in-functions or any other runtime handling, garbage collecting + or handling any other memory management. Note, a scheduler may also be + busy even if the operating system has scheduled out the scheduler + thread. + </p> + + <p> Returns <c>undefined</c> if the system flag <seealso marker="#system_flag_scheduler_wall_time"> - scheduler_wall_time</seealso> is set to false. + scheduler_wall_time</seealso> is turned off. </p> - <p>The list of scheduler information is unsorted and may come in different order - between calls. The time unit is undefined and may be changed and should only be used - to calculate relative utilization. + + <p>The list of scheduler information is unsorted and may appear in different order + between calls. </p> + <p>Using <c>scheduler_wall_time</c> to calculate scheduler utilization.</p> +<pre> +> <input>erlang:system_flag(scheduler_wall_time, true).</input> +false +> <input>Ts0 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input> +ok +</pre> + <p>Some time later we will take another snapshot and calculate scheduler-utilization per scheduler.</p> +<pre> +> <input>Ts1 = lists:sort(erlang:statistics(scheduler_wall_time)), ok.</input> +ok +> <input>lists:map(fun({{I, A0, T0}, {I, A1, T1}}) -> + {I, (A1 - A0)/(T1 - T0)} end, lists:zip(Ts0,Ts1)).</input> +[{1,0.9743474730177548}, + {2,0.9744843782751444}, + {3,0.9995902361669045}, + {4,0.9738012596572161}, + {5,0.9717956667018103}, + {6,0.9739235846420741}, + {7,0.973237033077876}, + {8,0.9741297293248656}] +</pre> + <p>Using the same snapshots to calculate a total scheduler-utilization.</p> +<pre> +> <input>{A, T} = lists:foldl(fun({{_, A0, T0}, {_, A1, T1}}, {Ai,Ti}) -> + {Ai + (A1 - A0), Ti + (T1 - T0)} end, {0, 0}, lists:zip(Ts0,Ts1)), A/T.</input> +0.9769136803764825 +</pre> + + <note> + <p><c>scheduler_wall_time</c> is by default disabled. Use <c>erlang:system_flag(scheduler_wall_time, true)</c> to enable it. </p> + </note> </item> <tag><c>wall_clock</c></tag> @@ -4957,14 +5021,6 @@ true</pre> opposed to runtime or CPU time.</p> </item> </taglist> - <p>All times are in milliseconds.</p> - <pre> -> <input>statistics(runtime).</input> -{1690,1620} -> <input>statistics(reductions).</input> -{2046,11} -> <input>statistics(garbage_collection).</input> -{85,23961,0}</pre> </desc> </func> <func> diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in index 2bd7297231..279844adb2 100644 --- a/erts/emulator/Makefile.in +++ b/erts/emulator/Makefile.in @@ -546,12 +546,17 @@ $(TTF_DIR)/driver_tab.c: Makefile.in LANG=C $(PERL) utils/make_driver_tab -o $@ $(DRV_OBJS) GENERATE += $(TTF_DIR)/driver_tab.c + + # Preloaded code. # # This list must be consistent with PRE_LOADED_MODULES in # lib/kernel/src/Makefile. ifeq ($(TARGET),win32) -$(TARGET)/beams.rc: $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ +# On windows the preloaded objects are in a resource object. +PRELOAD_OBJ = $(OBJDIR)/beams.$(RES_EXT) +PRELOAD_SRC = $(TARGET)/beams.rc +$(PRELOAD_SRC): $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ $(ERL_TOP)/erts/preloaded/ebin/init.beam \ $(ERL_TOP)/erts/preloaded/ebin/prim_inet.beam \ $(ERL_TOP)/erts/preloaded/ebin/prim_file.beam \ @@ -560,9 +565,10 @@ $(TARGET)/beams.rc: $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ $(ERL_TOP)/erts/preloaded/ebin/erl_prim_loader.beam \ $(ERL_TOP)/erts/preloaded/ebin/erlang.beam LANG=C $(PERL) utils/make_preload $(MAKE_PRELOAD_EXTRA) -rc $^ > $@ -GENERATE += $(TARGET)/beams.rc else -$(TARGET)/preload.c: $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ +PRELOAD_OBJ = $(OBJDIR)/preload.o +PRELOAD_SRC = $(TARGET)/preload.c +$(PRELOAD_SRC): $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ $(ERL_TOP)/erts/preloaded/ebin/init.beam \ $(ERL_TOP)/erts/preloaded/ebin/prim_inet.beam \ $(ERL_TOP)/erts/preloaded/ebin/prim_file.beam \ @@ -571,7 +577,6 @@ $(TARGET)/preload.c: $(ERL_TOP)/erts/preloaded/ebin/otp_ring0.beam \ $(ERL_TOP)/erts/preloaded/ebin/erl_prim_loader.beam \ $(ERL_TOP)/erts/preloaded/ebin/erlang.beam LANG=C $(PERL) utils/make_preload -old $^ > $@ -GENERATE += $(TARGET)/preload.c endif .PHONY : generate @@ -579,7 +584,8 @@ ifdef VOID_EMULATOR generate: @echo $(VOID_EMULATOR)' - omitted target generate' else -generate: $(TTF_DIR)/GENERATED +generate: $(TTF_DIR)/GENERATED $(PRELOAD_SRC) + $(TTF_DIR)/GENERATED: $(GENERATE) echo $? >$(TTF_DIR)/GENERATED endif @@ -660,7 +666,7 @@ endif # CS_SRC = sys/$(ERLANG_OSTYPE)/erl_child_setup.c -$(BINDIR)/$(CS_EXECUTABLE): $(TTF_DIR)/GENERATED $(CS_SRC) $(ERTS_LIB) +$(BINDIR)/$(CS_EXECUTABLE): $(TTF_DIR)/GENERATED $(PRELOAD_SRC) $(CS_SRC) $(ERTS_LIB) $(CS_PURIFY) $(CC) $(CS_LDFLAGS) -o $(BINDIR)/$(CS_EXECUTABLE) \ $(CS_CFLAGS) $(COMMON_INCLUDES) $(CS_SRC) $(CS_LIBS) @@ -689,16 +695,7 @@ $(ERL_TOP)/lib/%.beam: # Object files # -# On windows the preloaded objects are in a resource object. - -ifeq ($(TARGET),win32) -PRELOAD = $(OBJDIR)/beams.$(RES_EXT) -else -PRELOAD = $(OBJDIR)/preload.o -endif - - -INIT_OBJS = $(OBJDIR)/erl_main.o $(PRELOAD) +INIT_OBJS = $(OBJDIR)/erl_main.o $(PRELOAD_OBJ) EMU_OBJS = \ $(OBJDIR)/beam_emu.o $(OBJDIR)/beam_opcodes.o \ @@ -1035,7 +1032,7 @@ depend: @echo $(VOID_EMULATOR)' - omitted target depend' else depend: $(TTF_DIR)/depend.mk -$(TTF_DIR)/depend.mk: $(TTF_DIR)/GENERATED +$(TTF_DIR)/depend.mk: $(TTF_DIR)/GENERATED $(PRELOAD_SRC) $(DEP_CC) $(DEP_FLAGS) $(BEAM_SRC) \ | $(SED_DEPEND) > $(TTF_DIR)/depend.mk $(DEP_CC) $(DEP_FLAGS) -DLIBSCTP=$(LIBSCTP) $(DRV_COMMON_SRC) \ diff --git a/erts/emulator/beam/big.c b/erts/emulator/beam/big.c index 976f05c990..25ac790d81 100644 --- a/erts/emulator/beam/big.c +++ b/erts/emulator/beam/big.c @@ -1844,6 +1844,7 @@ dsize_t big_bytes(Eterm x) /* ** Load a bignum from bytes ** xsz is the number of bytes in xp +** *r is untouched if number fits in small */ Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r) { @@ -1852,7 +1853,7 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r) ErtsDigit d; int i; - while(xsz >= sizeof(ErtsDigit)) { + while(xsz > sizeof(ErtsDigit)) { d = 0; for(i = sizeof(ErtsDigit); --i >= 0;) d = (d << 8) | xp[i]; @@ -1867,11 +1868,20 @@ Eterm bytes_to_big(byte *xp, dsize_t xsz, int xsgn, Eterm *r) d = 0; for(i = xsz; --i >= 0;) d = (d << 8) | xp[i]; + if (++rsz == 1 && IS_USMALL(xsgn,d)) { + if (xsgn) d = -d; + return make_small(d); + } *rwp = d; rwp++; - rsz++; } - return big_norm(r, rsz, (short) xsgn); + if (xsgn) { + *r = make_neg_bignum_header(rsz); + } + else { + *r = make_pos_bignum_header(rsz); + } + return make_big(r); } /* diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 152dbcf085..9d52ed4e98 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -3118,6 +3118,9 @@ decoded_size(byte *ep, byte* endp, int internal_tags) case LARGE_BIG_EXT: CHKSIZE(4); n = get_int32(ep); + if (n > BIG_ARITY_MAX*sizeof(ErtsDigit)) { + return -1; + } SKIP2(n,4+1); /* skip, size,sign,digits */ heap_size += 1+1+(n+sizeof(Eterm)-1)/sizeof(Eterm); /* XXX: 1 too much? */ break; diff --git a/erts/etc/unix/etp-commands b/erts/etc/unix/etp-commands index 6a01e0b7e0..79e5d6b1d8 100644 --- a/erts/etc/unix/etp-commands +++ b/erts/etc/unix/etp-commands @@ -1883,6 +1883,28 @@ document etp-ets-tables %--------------------------------------------------------------------------- end +define etp-ets-obj +# Args: DbTerm* +# + set $etp_ets_obj_i = 1 + while $etp_ets_obj_i <= (($arg0)->tpl[0] >> 6) + if $etp_ets_obj_i == 1 + printf "{" + else + printf ", " + end + set $etp_ets_elem = ($arg0)->tpl[$etp_ets_obj_i] + if ($etp_ets_elem & 3) == 0 + printf "<compressed>" + else + etp-1 $etp_ets_elem 0 + end + set $etp_ets_obj_i++ + end + printf "}" +end + + define etp-ets-tabledump # Args: int tableindex # @@ -1896,10 +1918,10 @@ define etp-ets-tabledump if $etp_ets_tabledump_t->common.status & 0x130 # Hash table set $etp_ets_tabledump_h = $etp_ets_tabledump_t->hash - printf "%% nitems=%d\n", $etp_ets_tabledump_t->common.nitems - while $etp_ets_tabledump_i < $etp_ets_tabledump_h->nactive - set $etp_ets_tabledump_l = $etp_ets_tabledump_h->seg \ - [$etp_ets_tabledump_i>>8][$etp_ets_tabledump_i&0xFF] + printf "%% nitems=%d\n", (long) $etp_ets_tabledump_t->common.nitems + while $etp_ets_tabledump_i < (long) $etp_ets_tabledump_h->nactive + set $etp_ets_tabledump_seg = ((struct segment**)$etp_ets_tabledump_h->segtab)[$etp_ets_tabledump_i>>8] + set $etp_ets_tabledump_l = $etp_ets_tabledump_seg->buckets[$etp_ets_tabledump_i&0xFF] if $etp_ets_tabledump_l printf "%% Slot %d:\n", $etp_ets_tabledump_i while $etp_ets_tabledump_l @@ -1909,7 +1931,7 @@ define etp-ets-tabledump printf "[" end set $etp_ets_tabledump_n++ - etp-1 ((Eterm)($etp_ets_tabledump_l->dbterm.tpl)|0x2) 0 + etp-ets-obj &($etp_ets_tabledump_l->dbterm) if $etp_ets_tabledump_l->hvalue == ((unsigned long)-1) printf "% *\n" else diff --git a/erts/lib_src/common/erl_misc_utils.c b/erts/lib_src/common/erl_misc_utils.c index 5e94ff19db..4806311dfe 100644 --- a/erts/lib_src/common/erl_misc_utils.c +++ b/erts/lib_src/common/erl_misc_utils.c @@ -834,8 +834,8 @@ read_topology(erts_cpu_info_t *cpuinfo) ix = -1; if (realpath(ERTS_SYS_NODE_PATH, npath)) { - got_nodes = 1; ndir = opendir(npath); + got_nodes = (ndir != NULL); } do { diff --git a/erts/lib_src/common/ethr_atomics.c b/erts/lib_src/common/ethr_atomics.c index e4213e1eef..d093873841 100644 --- a/erts/lib_src/common/ethr_atomics.c +++ b/erts/lib_src/common/ethr_atomics.c @@ -561,12 +561,12 @@ int ethr_dw_atomic_cmpxchg(ethr_dw_atomic_t *var, ethr_dw_sint_t *val, ethr_dw_s } #endif -int ETHR_DW_ATOMIC_FUNC__(cmpxchg_ddrb)(ethr_dw_atomic_t *var, ethr_dw_sint_t *val, ethr_dw_sint_t *old_val) +int ethr_dw_atomic_cmpxchg_ddrb(ethr_dw_atomic_t *var, ethr_dw_sint_t *val, ethr_dw_sint_t *old_val) { #ifdef ETHR_ORDERED_READ_DEPEND - return ETHR_DW_ATOMIC_FUNC__(cmpxchg)(var, val, old_val); + return ethr_dw_atomic_cmpxchg(var, val, old_val); #else - return ETHR_DW_ATOMIC_FUNC__(cmpxchg_rb)(var, val, old_val); + return ethr_dw_atomic_cmpxchg_rb(var, val, old_val); #endif } @@ -784,12 +784,12 @@ void ethr_dw_atomic_set(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) } #endif -void ETHR_DW_ATOMIC_FUNC__(set_ddrb)(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) +void ethr_dw_atomic_set_ddrb(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) { #ifdef ETHR_ORDERED_READ_DEPEND - ETHR_DW_ATOMIC_FUNC__(set)(var, val); + ethr_dw_atomic_set(var, val); #else - ETHR_DW_ATOMIC_FUNC__(set_rb)(var, val); + ethr_dw_atomic_set_rb(var, val); #endif } @@ -947,12 +947,12 @@ void ethr_dw_atomic_read(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) } #endif -void ETHR_DW_ATOMIC_FUNC__(read_ddrb)(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) +void ethr_dw_atomic_read_ddrb(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) { #ifdef ETHR_ORDERED_READ_DEPEND - ETHR_DW_ATOMIC_FUNC__(read)(var, val); + ethr_dw_atomic_read(var, val); #else - ETHR_DW_ATOMIC_FUNC__(read_rb)(var, val); + ethr_dw_atomic_read_rb(var, val); #endif } @@ -1107,12 +1107,12 @@ void ethr_dw_atomic_init(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) } #endif -void ETHR_DW_ATOMIC_FUNC__(init_ddrb)(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) +void ethr_dw_atomic_init_ddrb(ethr_dw_atomic_t *var, ethr_dw_sint_t *val) { #ifdef ETHR_ORDERED_READ_DEPEND - ETHR_DW_ATOMIC_FUNC__(init)(var, val); + ethr_dw_atomic_init(var, val); #else - ETHR_DW_ATOMIC_FUNC__(init_rb)(var, val); + ethr_dw_atomic_init_rb(var, val); #endif } diff --git a/erts/lib_src/utils/make_atomics_api b/erts/lib_src/utils/make_atomics_api index d8b1a56100..75e88f8a7e 100755 --- a/erts/lib_src/utils/make_atomics_api +++ b/erts/lib_src/utils/make_atomics_api @@ -805,17 +805,17 @@ rtchk_fallback_call(Return, #atomic_context{dw = DW, non_native_barrier(B) -> lists:member(B, ?NON_NATIVE_BARRIERS). -non_native_barrier_impl(AC, Type, Macro, Op, B) -> +non_native_barrier_impl(AC, Type, Op, B) -> [" -", func_header(AC, Type, Macro, Op, B), " +", func_header(AC, Type, false, Op, B), " {", case B of ddrb -> [" #ifdef ETHR_ORDERED_READ_DEPEND - ", func_call(AC, Type, Macro, Op, none, true), " + ", func_call(AC, Type, Op, none, true), " #else - ", func_call(AC, Type, Macro, Op, rb, true), " + ", func_call(AC, Type, Op, rb, true), " #endif " ] @@ -824,12 +824,10 @@ non_native_barrier_impl(AC, Type, Macro, Op, B) -> " ]. -func_call(#atomic_context{'ATMC' = ATMC} = AC, inline_implementation, _Macro, Op, B, RetStatement) -> +func_call(#atomic_context{'ATMC' = ATMC} = AC, inline_implementation, Op, B, RetStatement) -> func_call(AC, Op, ["ETHR_", ATMC, "_FUNC__(", opstr(Op), op_barrier_ext(B), ")"], RetStatement); -func_call(#atomic_context{atomic = Atomic} = AC, implementation, false, Op, B, RetStatement) -> - func_call(AC, Op, [Atomic, "_", opstr(Op), op_barrier_ext(B)], RetStatement); -func_call(AC, implementation, Macro, Op, B, RetStatement) -> - func_call(AC, Op, [Macro, "(", opstr(Op), op_barrier_ext(B), ")"], RetStatement). +func_call(#atomic_context{atomic = Atomic} = AC, implementation, Op, B, RetStatement) -> + func_call(AC, Op, [Atomic, "_", opstr(Op), op_barrier_ext(B)], RetStatement). func_call(#atomic_context{dw = DW, arg1 = Arg1, arg2 = Arg2, arg3 = Arg3} = AC, Op, Func, true) -> op_call(Op, DW, case is_return_op(AC, Op) of @@ -901,7 +899,7 @@ make_implementations(#atomic_context{dw = DW, lists:map(fun (B) -> case non_native_barrier(B) of true -> - non_native_barrier_impl(AC, inline_implementation, false, Op, B); + non_native_barrier_impl(AC, inline_implementation, Op, B); false -> TryBarriers = try_barrier_order(B), [" @@ -1211,7 +1209,7 @@ int ethr_have_native_dw_atomic(void) end, case non_native_barrier(B) of true -> - non_native_barrier_impl(AC, implementation, Macro, Op, B); + non_native_barrier_impl(AC, implementation, Op, B); false -> ["\n", func_header(AC, implementation, Macro, Op, B), diff --git a/erts/test/otp_SUITE.erl b/erts/test/otp_SUITE.erl index 79cd91221f..b34d9a5422 100644 --- a/erts/test/otp_SUITE.erl +++ b/erts/test/otp_SUITE.erl @@ -151,6 +151,9 @@ ssl_crypto_filter(Undef) -> {{error,bad_name},{error,bad_name}} -> filter(fun({_,{ssl,_,_}}) -> false; ({_,{crypto,_,_}}) -> false; + ({_,{ssh,_,_}}) -> false; + ({_,{ssh_connection,_,_}}) -> false; + ({_,{ssh_sftp,_,_}}) -> false; (_) -> true end, Undef); {_,_} -> Undef |