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/erl_thr_progress.h | 13 | ||||
-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 | 144 | ||||
-rwxr-xr-x | erts/lib_src/utils/make_atomics_api | 45 | ||||
-rw-r--r-- | erts/test/otp_SUITE.erl | 3 |
8 files changed, 273 insertions, 105 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/erl_thr_progress.h b/erts/emulator/beam/erl_thr_progress.h index 1bbc49993e..a71724b813 100644 --- a/erts/emulator/beam/erl_thr_progress.h +++ b/erts/emulator/beam/erl_thr_progress.h @@ -138,6 +138,7 @@ ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_acqb__(ERTS_THR_PRGR_ATOMIC *a ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_prgr_read_mb__(ERTS_THR_PRGR_ATOMIC *atmc); ERTS_GLB_INLINE int erts_thr_progress_is_managed_thread(void); +ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_progress_current_to_later__(ErtsThrPrgrVal val); ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_progress_later_than(ErtsThrPrgrVal val); ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_progress_later(void); ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_progress_current(void); @@ -218,9 +219,8 @@ erts_thr_progress_is_managed_thread(void) } ERTS_GLB_INLINE ErtsThrPrgrVal -erts_thr_progress_later_than(ErtsThrPrgrVal val) +erts_thr_progress_current_to_later__(ErtsThrPrgrVal val) { - ERTS_THR_MEMORY_BARRIER; if (val == (ERTS_THR_PRGR_VAL_WAITING-((ErtsThrPrgrVal)2))) return ((ErtsThrPrgrVal) 0); else if (val == (ERTS_THR_PRGR_VAL_WAITING-((ErtsThrPrgrVal)1))) @@ -230,10 +230,17 @@ erts_thr_progress_later_than(ErtsThrPrgrVal val) } ERTS_GLB_INLINE ErtsThrPrgrVal +erts_thr_progress_later_than(ErtsThrPrgrVal val) +{ + ERTS_THR_MEMORY_BARRIER; + return erts_thr_progress_current_to_later__(val); +} + +ERTS_GLB_INLINE ErtsThrPrgrVal erts_thr_progress_later(void) { ErtsThrPrgrVal val = erts_thr_prgr_read_mb__(&erts_thr_prgr__.current); - return erts_thr_progress_later_than(val); + return erts_thr_progress_current_to_later__(val); } ERTS_GLB_INLINE ErtsThrPrgrVal 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..c52166a7ec 100644 --- a/erts/lib_src/common/ethr_atomics.c +++ b/erts/lib_src/common/ethr_atomics.c @@ -561,12 +561,14 @@ 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); +#if defined(ETHR_HAVE_DOUBLE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_dw_atomic_cmpxchg_ddrb__(var, val, old_val); +#elif defined(ETHR_ORDERED_READ_DEPEND) + 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 +786,14 @@ 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); +#if defined(ETHR_HAVE_DOUBLE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_dw_atomic_set_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) + 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 +951,14 @@ 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); +#if defined(ETHR_HAVE_DOUBLE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_dw_atomic_read_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) + 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 +1113,14 @@ 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); +#if defined(ETHR_HAVE_DOUBLE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_dw_atomic_init_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) + ethr_dw_atomic_init(var, val); #else - ETHR_DW_ATOMIC_FUNC__(init_rb)(var, val); + ethr_dw_atomic_init_rb(var, val); #endif } @@ -1278,7 +1286,9 @@ ethr_sint_t ethr_atomic_cmpxchg(ethr_atomic_t *var, ethr_sint_t val, ethr_sint_t ethr_sint_t ethr_atomic_cmpxchg_ddrb(ethr_atomic_t *var, ethr_sint_t val, ethr_sint_t old_val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_cmpxchg_ddrb__(var, val, old_val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_cmpxchg(var, val, old_val); #else return ethr_atomic_cmpxchg_rb(var, val, old_val); @@ -1398,7 +1408,9 @@ ethr_sint_t ethr_atomic_xchg(ethr_atomic_t *var, ethr_sint_t val) ethr_sint_t ethr_atomic_xchg_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_xchg_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_xchg(var, val); #else return ethr_atomic_xchg_rb(var, val); @@ -1512,7 +1524,9 @@ void ethr_atomic_set(ethr_atomic_t *var, ethr_sint_t val) void ethr_atomic_set_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_atomic_set_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic_set(var, val); #else ethr_atomic_set_rb(var, val); @@ -1620,7 +1634,9 @@ void ethr_atomic_init(ethr_atomic_t *var, ethr_sint_t val) void ethr_atomic_init_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_atomic_init_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic_init(var, val); #else ethr_atomic_init_rb(var, val); @@ -1725,7 +1741,9 @@ ethr_sint_t ethr_atomic_add_read(ethr_atomic_t *var, ethr_sint_t val) ethr_sint_t ethr_atomic_add_read_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_add_read_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_add_read(var, val); #else return ethr_atomic_add_read_rb(var, val); @@ -1840,7 +1858,9 @@ ethr_sint_t ethr_atomic_read(ethr_atomic_t *var) ethr_sint_t ethr_atomic_read_ddrb(ethr_atomic_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_read(var); #else return ethr_atomic_read_rb(var); @@ -1954,7 +1974,9 @@ ethr_sint_t ethr_atomic_inc_read(ethr_atomic_t *var) ethr_sint_t ethr_atomic_inc_read_ddrb(ethr_atomic_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_inc_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_inc_read(var); #else return ethr_atomic_inc_read_rb(var); @@ -2069,7 +2091,9 @@ ethr_sint_t ethr_atomic_dec_read(ethr_atomic_t *var) ethr_sint_t ethr_atomic_dec_read_ddrb(ethr_atomic_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_dec_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_dec_read(var); #else return ethr_atomic_dec_read_rb(var); @@ -2183,7 +2207,9 @@ void ethr_atomic_add(ethr_atomic_t *var, ethr_sint_t val) void ethr_atomic_add_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_atomic_add_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic_add(var, val); #else ethr_atomic_add_rb(var, val); @@ -2292,7 +2318,9 @@ void ethr_atomic_inc(ethr_atomic_t *var) void ethr_atomic_inc_ddrb(ethr_atomic_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_atomic_inc_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic_inc(var); #else ethr_atomic_inc_rb(var); @@ -2401,7 +2429,9 @@ void ethr_atomic_dec(ethr_atomic_t *var) void ethr_atomic_dec_ddrb(ethr_atomic_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + ethr_atomic_dec_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic_dec(var); #else ethr_atomic_dec_rb(var); @@ -2511,7 +2541,9 @@ ethr_sint_t ethr_atomic_read_band(ethr_atomic_t *var, ethr_sint_t val) ethr_sint_t ethr_atomic_read_band_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_read_band_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_read_band(var, val); #else return ethr_atomic_read_band_rb(var, val); @@ -2626,7 +2658,9 @@ ethr_sint_t ethr_atomic_read_bor(ethr_atomic_t *var, ethr_sint_t val) ethr_sint_t ethr_atomic_read_bor_ddrb(ethr_atomic_t *var, ethr_sint_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_WORD_SZ_NATIVE_ATOMIC_OPS) + return ethr_atomic_read_bor_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic_read_bor(var, val); #else return ethr_atomic_read_bor_rb(var, val); @@ -2761,7 +2795,9 @@ ethr_sint32_t ethr_atomic32_cmpxchg(ethr_atomic32_t *var, ethr_sint32_t val, eth ethr_sint32_t ethr_atomic32_cmpxchg_ddrb(ethr_atomic32_t *var, ethr_sint32_t val, ethr_sint32_t old_val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_cmpxchg_ddrb__(var, val, old_val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_cmpxchg(var, val, old_val); #else return ethr_atomic32_cmpxchg_rb(var, val, old_val); @@ -2858,7 +2894,9 @@ ethr_sint32_t ethr_atomic32_xchg(ethr_atomic32_t *var, ethr_sint32_t val) ethr_sint32_t ethr_atomic32_xchg_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_xchg_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_xchg(var, val); #else return ethr_atomic32_xchg_rb(var, val); @@ -2954,7 +2992,9 @@ void ethr_atomic32_set(ethr_atomic32_t *var, ethr_sint32_t val) void ethr_atomic32_set_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + ethr_atomic32_set_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic32_set(var, val); #else ethr_atomic32_set_rb(var, val); @@ -3044,7 +3084,9 @@ void ethr_atomic32_init(ethr_atomic32_t *var, ethr_sint32_t val) void ethr_atomic32_init_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + ethr_atomic32_init_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic32_init(var, val); #else ethr_atomic32_init_rb(var, val); @@ -3131,7 +3173,9 @@ ethr_sint32_t ethr_atomic32_add_read(ethr_atomic32_t *var, ethr_sint32_t val) ethr_sint32_t ethr_atomic32_add_read_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_add_read_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_add_read(var, val); #else return ethr_atomic32_add_read_rb(var, val); @@ -3228,7 +3272,9 @@ ethr_sint32_t ethr_atomic32_read(ethr_atomic32_t *var) ethr_sint32_t ethr_atomic32_read_ddrb(ethr_atomic32_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_read(var); #else return ethr_atomic32_read_rb(var); @@ -3325,7 +3371,9 @@ ethr_sint32_t ethr_atomic32_inc_read(ethr_atomic32_t *var) ethr_sint32_t ethr_atomic32_inc_read_ddrb(ethr_atomic32_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_inc_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_inc_read(var); #else return ethr_atomic32_inc_read_rb(var); @@ -3422,7 +3470,9 @@ ethr_sint32_t ethr_atomic32_dec_read(ethr_atomic32_t *var) ethr_sint32_t ethr_atomic32_dec_read_ddrb(ethr_atomic32_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_dec_read_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_dec_read(var); #else return ethr_atomic32_dec_read_rb(var); @@ -3518,7 +3568,9 @@ void ethr_atomic32_add(ethr_atomic32_t *var, ethr_sint32_t val) void ethr_atomic32_add_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + ethr_atomic32_add_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic32_add(var, val); #else ethr_atomic32_add_rb(var, val); @@ -3609,7 +3661,9 @@ void ethr_atomic32_inc(ethr_atomic32_t *var) void ethr_atomic32_inc_ddrb(ethr_atomic32_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + ethr_atomic32_inc_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic32_inc(var); #else ethr_atomic32_inc_rb(var); @@ -3700,7 +3754,9 @@ void ethr_atomic32_dec(ethr_atomic32_t *var) void ethr_atomic32_dec_ddrb(ethr_atomic32_t *var) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + ethr_atomic32_dec_ddrb__(var); +#elif defined(ETHR_ORDERED_READ_DEPEND) ethr_atomic32_dec(var); #else ethr_atomic32_dec_rb(var); @@ -3792,7 +3848,9 @@ ethr_sint32_t ethr_atomic32_read_band(ethr_atomic32_t *var, ethr_sint32_t val) ethr_sint32_t ethr_atomic32_read_band_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_read_band_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_read_band(var, val); #else return ethr_atomic32_read_band_rb(var, val); @@ -3889,7 +3947,9 @@ ethr_sint32_t ethr_atomic32_read_bor(ethr_atomic32_t *var, ethr_sint32_t val) ethr_sint32_t ethr_atomic32_read_bor_ddrb(ethr_atomic32_t *var, ethr_sint32_t val) { -#ifdef ETHR_ORDERED_READ_DEPEND +#if defined(ETHR_HAVE_32BIT_NATIVE_ATOMIC_OPS) + return ethr_atomic32_read_bor_ddrb__(var, val); +#elif defined(ETHR_ORDERED_READ_DEPEND) return ethr_atomic32_read_bor(var, val); #else return ethr_atomic32_read_bor_rb(var, val); diff --git a/erts/lib_src/utils/make_atomics_api b/erts/lib_src/utils/make_atomics_api index d8b1a56100..74736c5a2d 100755 --- a/erts/lib_src/utils/make_atomics_api +++ b/erts/lib_src/utils/make_atomics_api @@ -805,17 +805,40 @@ 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, inline_implementation = 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 +" + ] + end, + "} +" + ]; +non_native_barrier_impl(#atomic_context{have_native_atomic_ops = HaveNative} = AC, + implementation = Type, + Op, + B) -> + [" +", func_header(AC, Type, false, Op, B), " +{", + case B of + ddrb -> + [" +#if defined(", HaveNative, ") + ", func_call(AC, Type, Op, B, true), " +#elif defined(ETHR_ORDERED_READ_DEPEND) + ", func_call(AC, symbol_implementation, Op, none, true), " +#else + ", func_call(AC, symbol_implementation, Op, rb, true), " #endif " ] @@ -824,12 +847,12 @@ 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{atomic = Atomic} = AC, symbol_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 +924,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 +1234,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 |