diff options
Diffstat (limited to 'erts')
24 files changed, 376 insertions, 284 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4 index 86799186fd..013bfe5652 100644 --- a/erts/aclocal.m4 +++ b/erts/aclocal.m4 @@ -128,13 +128,13 @@ MIXED_MSYS=no AC_MSG_CHECKING(for mixed cygwin or msys and native VC++ environment) if test "X$host" = "Xwin32" -a "x$GCC" != "xyes"; then if test -x /usr/bin/msys-?.0.dll; then - CFLAGS="-O2" + CFLAGS="$CFLAGS -O2" MIXED_MSYS=yes AC_MSG_RESULT([MSYS and VC]) MIXED_MSYS_VC=yes CPPFLAGS="$CPPFLAGS -DERTS_MIXED_MSYS_VC" elif test -x /usr/bin/cygpath; then - CFLAGS="-O2" + CFLAGS="$CFLAGS -O2" MIXED_CYGWIN=yes AC_MSG_RESULT([Cygwin and VC]) MIXED_CYGWIN_VC=yes @@ -162,7 +162,7 @@ if test "x$MIXED_MSYS" != "xyes"; then AC_MSG_CHECKING(for mixed cygwin and native MinGW environment) if test "X$host" = "Xwin32" -a "x$GCC" = x"yes"; then if test -x /usr/bin/cygpath; then - CFLAGS="-O2" + CFLAGS="$CFLAGS -O2" MIXED_CYGWIN=yes AC_MSG_RESULT([yes]) MIXED_CYGWIN_MINGW=yes diff --git a/erts/doc/src/absform.xml b/erts/doc/src/absform.xml index bfabb7f042..0b04f8f70e 100644 --- a/erts/doc/src/absform.xml +++ b/erts/doc/src/absform.xml @@ -152,9 +152,11 @@ <list type="bulleted"> <item>If L is an atom literal, then Rep(L) = <c>{atom,LINE,L}</c>.</item> + <item>If L is a character literal, then + Rep(L) = <c>{char,LINE,L}</c>.</item> <item>If L is a float literal, then Rep(L) = <c>{float,LINE,L}</c>.</item> - <item>If L is an integer or character literal, then + <item>If L is an integer literal, then Rep(L) = <c>{integer,LINE,L}</c>.</item> <item>If L is a string literal consisting of the characters <c>C_1</c>, ..., <c>C_k</c>, then diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 5d5bfb141f..7b90a1ccca 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -643,8 +643,7 @@ <p>Sets the default binary virtual heap size of processes to the size <c><![CDATA[Size]]></c>.</p> </item> - <marker id="+hmax"/> - <tag><c><![CDATA[+hmax Size]]></c></tag> + <tag><marker id="+hmax"/><c><![CDATA[+hmax Size]]></c></tag> <item> <p>Sets the default maximum heap size of processes to the size <c><![CDATA[Size]]></c>. If <c>+hmax</c> is not given, the default is <c>0</c> @@ -653,8 +652,7 @@ <seealso marker="erlang#process_flag_max_heap_size"> <c>process_flag(max_heap_size, MaxHeapSize)</c></seealso>.</p> </item> - <marker id="+hmaxel"/> - <tag><c><![CDATA[+hmaxel true|false]]></c></tag> + <tag><marker id="+hmaxel"/><c><![CDATA[+hmaxel true|false]]></c></tag> <item> <p>Sets whether to send an error logger message for processes that reach the maximum heap size or not. If <c>+hmaxel</c> is not given, the default is <c>true</c>. @@ -662,8 +660,7 @@ <seealso marker="erlang#process_flag_max_heap_size"> <c>process_flag(max_heap_size, MaxHeapSize)</c></seealso>.</p> </item> - <marker id="+hmaxk"/> - <tag><c><![CDATA[+hmaxk true|false]]></c></tag> + <tag><marker id="+hmaxk"/><c><![CDATA[+hmaxk true|false]]></c></tag> <item> <p>Sets whether to kill processes that reach the maximum heap size or not. If <c>+hmaxk</c> is not given, the default is <c>true</c>. For more information, @@ -676,7 +673,7 @@ <p>Sets the initial process dictionary size of processes to the size <c><![CDATA[Size]]></c>.</p> </item> - <tag><marker id="+hmqd"><c>+hmqd off_heap|on_heap</c></marker></tag> + <tag><marker id="+hmqd"/><c>+hmqd off_heap|on_heap</c></tag> <item><p> Sets the default value for the process flag <c>message_queue_data</c>. If <c>+hmqd</c> is not diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index 175b7f6bfb..82215ead46 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -348,14 +348,14 @@ all will work as before.</p> </item> <tag><marker id="time_measurement"/>Time Measurement</tag> - <item><p>Support for time measurement in drivers: + <item><p>Support for time measurement in drivers:</p> <list> <item><seealso marker="#ErlDrvTime"><c>ErlDrvTime</c></seealso></item> <item><seealso marker="#ErlDrvTimeUnit"><c>ErlDrvTimeUnit</c></seealso></item> <item><seealso marker="#erl_drv_monotonic_time"><c>erl_drv_monotonic_time()</c></seealso></item> <item><seealso marker="#erl_drv_time_offset"><c>erl_drv_time_offset()</c></seealso></item> <item><seealso marker="#erl_drv_convert_time_unit"><c>erl_drv_convert_time_unit()</c></seealso></item> - </list></p> + </list> </item> </taglist> </section> diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index b2e2254a65..8b02b3bae1 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -518,13 +518,15 @@ ok </item> <tag><marker id="reload"/>int (*reload)(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)</tag> - <note><p>The reload mechanism is <em>deprecated</em>. It was only intended - as a development feature. Do not use it as an upgrade method for - live production systems. It might be removed in future releases. Be sure - to pass <c>reload</c> as <c>NULL</c> to <seealso marker="#ERL_NIF_INIT">ERL_NIF_INIT</seealso> - to disable it when not used.</p> - </note> - <item><p><c>reload</c> is called when the NIF library is loaded + + <item> + <note><p>The reload mechanism is <em>deprecated</em>. It was only intended + as a development feature. Do not use it as an upgrade method for + live production systems. It might be removed in future releases. Be sure + to pass <c>reload</c> as <c>NULL</c> to <seealso marker="#ERL_NIF_INIT">ERL_NIF_INIT</seealso> + to disable it when not used.</p> + </note> + <p><c>reload</c> is called when the NIF library is loaded and there is already a previously loaded library for this module code.</p> <p>Works the same as <c>load</c>. The only difference is that @@ -583,9 +585,9 @@ ok <p/> <code type="none"> typedef struct { - const char* <em>name</em>; - unsigned <em>arity</em>; - ERL_NIF_TERM (*<em>fptr</em>)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); + const char* name; + unsigned arity; + ERL_NIF_TERM (*fptr)(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]); unsigned flags; } ErlNifFunc; </code> @@ -618,8 +620,8 @@ typedef struct { <p/> <code type="none"> typedef struct { - unsigned <em>size</em>; - unsigned char* <em>data</em>; + unsigned size; + unsigned char* data; } ErlNifBinary; </code> <p><c>ErlNifBinary</c> contains transient information about an @@ -1812,23 +1814,23 @@ enif_map_iterator_destroy(env, &iter); </p></desc> </func> <func><name><ret>int</ret><nametext>enif_thread_type(void)</nametext></name> - <fsummary>Determine type of current thread</fsummary> - <desc> - <p>Determine the type of currently executing thread. A positive value - indicates a scheduler thread while a negative value or zero indicates - another type of thread. Currently the following specific types exist - (which may be extended in the future):</p> - <taglist> - <tag><c>ERL_NIF_THR_UNDEFINED</c></tag> - <value><p>Undefined thread that is not a scheduler thread.</p></value> - <tag><c>ERL_NIF_THR_NORMAL_SCHEDULER</c></tag> - <value><p>A normal scheduler thread.</p></value> - <tag><c>ERL_NIF_THR_DIRTY_CPU_SCHEDULER</c></tag> - <value><p>A dirty CPU scheduler thread.</p></value> - <tag><c>ERL_NIF_THR_DIRTY_IO_SCHEDULER</c></tag> - <value><p>A dirty I/O scheduler thread.</p></value> - </taglist> - </desc> + <fsummary>Determine type of current thread</fsummary> + <desc> + <p>Determine the type of currently executing thread. A positive value + indicates a scheduler thread while a negative value or zero indicates + another type of thread. Currently the following specific types exist + (which may be extended in the future):</p> + <taglist> + <tag><c>ERL_NIF_THR_UNDEFINED</c></tag> + <item><p>Undefined thread that is not a scheduler thread.</p></item> + <tag><c>ERL_NIF_THR_NORMAL_SCHEDULER</c></tag> + <item><p>A normal scheduler thread.</p></item> + <tag><c>ERL_NIF_THR_DIRTY_CPU_SCHEDULER</c></tag> + <item><p>A dirty CPU scheduler thread.</p></item> + <tag><c>ERL_NIF_THR_DIRTY_IO_SCHEDULER</c></tag> + <item><p>A dirty I/O scheduler thread.</p></item> + </taglist> + </desc> </func> <func> <name><ret>ErlNifTime</ret><nametext>enif_time_offset(ErlNifTimeUnit time_unit)</nametext></name> diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index fa13e4c142..6289f033b2 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -4361,86 +4361,86 @@ os_prompt% </pre> <marker id="process_flag_max_heap_size"/> <func> <name name="process_flag" arity="2" clause_i="5"/> - <type name="max_heap_size"/> <fsummary>Sets process flag <c>max_heap_size</c> for the calling process.</fsummary> + <type name="max_heap_size"/> <desc> <p> This flag sets the maximum heap size for the calling process. If <c><anno>MaxHeapSize</anno></c> is an integer, the system default values for <c>kill</c> and <c>error_logger</c> are used. - <taglist> - <tag><c>size</c></tag> - <item> - <p> - The maximum size in words of the process. If set to zero, the - heap size limit is disabled. Badarg will be thrown if the value is - smaller than - <seealso marker="#process_flag_min_heap_size"><c>min_heap_size</c></seealso>. - The size check is only done when a garbage collection is triggered. - </p> - <p> - <c>size</c> is the entire heap of the process when garbage collection - is triggered, this includes all generational heaps, the process stack, - any <seealso marker="#process_flag_message_queue_data"> - messages that are considered to be part of the heap</seealso> and any - extra memory that the garbage collector needs during collection. - </p> - <p> - <c>size</c> is the same as can be retrieved using - <seealso marker="#process_info_total_heap_size"> - <c>erlang:process_info(Pid, total_heap_size)</c></seealso>, - or by adding <c>heap_block_size</c>, <c>old_heap_block_size</c> - and <c>mbuf_size</c> from <seealso marker="#process_info_garbage_collection_info"> - <c>erlang:process_info(Pid, garbage_collection_info)</c></seealso>. - </p> - </item> - <tag><c>kill</c></tag> - <item> - <p> - When set to <c>true</c> the runtime system will send an - untrappable exit signal with reason <c>kill</c> to the process - if the maximum heap size is reached. The garbage collection - that triggered the <c>kill</c> will not be completed, instead the - process will exit as soon as is possible. When set to <c>false</c> - no exit signal will be sent to the process, instead it will - continue executing. - </p> - <p> - If <c>kill</c> is not defined in the map - the system default will be used. The default system default - is <c>true</c>. It can be changed by either the erl - <seealso marker="erl#+hmaxk">+hmaxk</seealso> option, - or <seealso marker="#system_flag_max_heap_size"><c> - erlang:system_flag(max_heap_size, MaxHeapSize)</c></seealso>. - </p> - </item> - <tag><c>error_logger</c></tag> - <item> - <p> - When set to <c>true</c> the runtime system will send a - message to the current <seealso marker="kernel:error_logger"><c>error_logger</c></seealso> - containing details about the process when the maximum - heap size is reached. One <c>error_logger</c> report will - be sent each time the limit is reached. - </p> - <p> - If <c>error_logger</c> is not defined in the map the system - default will be used. The default system default is <c>true</c>. - It can be changed by either the erl <seealso marker="erl#+hmaxel">+hmaxel</seealso> - option, or <seealso marker="#system_flag_max_heap_size"><c> - erlang:system_flag(max_heap_size, MaxHeapSize)</c></seealso>. - </p> - </item> + </p> + <taglist> + <tag><c>size</c></tag> + <item> + <p> + The maximum size in words of the process. If set to zero, the + heap size limit is disabled. Badarg will be thrown if the value is + smaller than + <seealso marker="#process_flag_min_heap_size"><c>min_heap_size</c></seealso>. + The size check is only done when a garbage collection is triggered. + </p> + <p> + <c>size</c> is the entire heap of the process when garbage collection + is triggered, this includes all generational heaps, the process stack, + any <seealso marker="#process_flag_message_queue_data"> + messages that are considered to be part of the heap</seealso> and any + extra memory that the garbage collector needs during collection. + </p> + <p> + <c>size</c> is the same as can be retrieved using + <seealso marker="#process_info_total_heap_size"> + <c>erlang:process_info(Pid, total_heap_size)</c></seealso>, + or by adding <c>heap_block_size</c>, <c>old_heap_block_size</c> + and <c>mbuf_size</c> from <seealso marker="#process_info_garbage_collection_info"> + <c>erlang:process_info(Pid, garbage_collection_info)</c></seealso>. + </p> + </item> + <tag><c>kill</c></tag> + <item> + <p> + When set to <c>true</c> the runtime system will send an + untrappable exit signal with reason <c>kill</c> to the process + if the maximum heap size is reached. The garbage collection + that triggered the <c>kill</c> will not be completed, instead the + process will exit as soon as is possible. When set to <c>false</c> + no exit signal will be sent to the process, instead it will + continue executing. + </p> <p> - The heap size of a process is quite hard to predict, especially the - amount of memory that is used during the garbage collection. When - contemplating using this option, it is recommended to first run - it in production with <c>kill</c> set to <c>false</c> and inspect - the <c>error_logger</c> reports to see what the normal peak sizes - of the processes in the system is and then tune the value - accordingly. + If <c>kill</c> is not defined in the map + the system default will be used. The default system default + is <c>true</c>. It can be changed by either the erl + <seealso marker="erl#+hmaxk">+hmaxk</seealso> option, + or <seealso marker="#system_flag_max_heap_size"><c> + erlang:system_flag(max_heap_size, MaxHeapSize)</c></seealso>. </p> - </taglist> + </item> + <tag><c>error_logger</c></tag> + <item> + <p> + When set to <c>true</c> the runtime system will send a + message to the current <seealso marker="kernel:error_logger"><c>error_logger</c></seealso> + containing details about the process when the maximum + heap size is reached. One <c>error_logger</c> report will + be sent each time the limit is reached. + </p> + <p> + If <c>error_logger</c> is not defined in the map the system + default will be used. The default system default is <c>true</c>. + It can be changed by either the erl <seealso marker="erl#+hmaxel">+hmaxel</seealso> + option, or <seealso marker="#system_flag_max_heap_size"><c> + erlang:system_flag(max_heap_size, MaxHeapSize)</c></seealso>. + </p> + </item> + </taglist> + <p> + The heap size of a process is quite hard to predict, especially the + amount of memory that is used during the garbage collection. When + contemplating using this option, it is recommended to first run + it in production with <c>kill</c> set to <c>false</c> and inspect + the <c>error_logger</c> reports to see what the normal peak sizes + of the processes in the system is and then tune the value + accordingly. </p> </desc> </func> @@ -4797,8 +4797,10 @@ os_prompt% </pre> The content of <c><anno>GCInfo</anno></c> can be changed without prior notice.</p> </item> - <marker id="process_info_garbage_collection_info"/> - <tag><c>{garbage_collection_info, <anno>GCInfo</anno>}</c></tag> + <tag> + <marker id="process_info_garbage_collection_info"/> + <c>{garbage_collection_info, <anno>GCInfo</anno>}</c> + </tag> <item> <p><c><anno>GCInfo</anno></c> is a list containing miscellaneous detailed information about garbage collection for this process. @@ -4986,8 +4988,10 @@ os_prompt% </pre> total suspend count on <c><anno>Suspendee</anno></c>, only the parts contributed by <c><anno>Pid</anno></c>.</p> </item> - <marker id="process_info_total_heap_size"/> - <tag><c>{total_heap_size, <anno>Size</anno>}</c></tag> + <tag> + <marker id="process_info_total_heap_size"/> + <c>{total_heap_size, <anno>Size</anno>}</c> + </tag> <item> <p><c><anno>Size</anno></c> is the total size, in words, of all heap fragments of the process. This includes the process stack and @@ -6631,8 +6635,8 @@ ok <marker id="system_flag_max_heap_size"></marker> <func> <name name="system_flag" arity="2" clause_i="8"/> - <type name="max_heap_size"/> <fsummary>Sets system flag <c>max_heap_size</c></fsummary> + <type name="max_heap_size"/> <desc> <p> Sets the default maximum heap size settings for processes. @@ -7136,9 +7140,9 @@ ok <name name="system_info" arity="1" clause_i="37"/> <name name="system_info" arity="1" clause_i="38"/> <name name="system_info" arity="1" clause_i="39"/> + <fsummary>Information about the default process heap settings.</fsummary> <type name="message_queue_data"/> <type name="max_heap_size"/> - <fsummary>Information about the default process heap settings.</fsummary> <desc> <taglist> <tag><c>fullsweep_after</c></tag> @@ -7183,7 +7187,7 @@ ok where <c><anno>MinHeapSize</anno></c> is the current system-wide minimum heap size for spawned processes.</p> </item> - <tag><marker id="system_info_message_queue_data"><c>message_queue_data</c></marker></tag> + <tag><marker id="system_info_message_queue_data"/><c>message_queue_data</c></tag> <item> <p>Returns the default value of the <c>message_queue_data</c> process flag which is either <c>off_heap</c>, or <c>on_heap</c>. @@ -7664,7 +7668,7 @@ ok and <seealso marker="#system_info_schedulers">erlang:system_info(schedulers)</seealso>.</p> </item> - <tag><marker id="system_info_otp_release"><c>otp_release</c></marker></tag> + <tag><marker id="system_info_otp_release"/><c>otp_release</c></tag> <item> <marker id="system_info_otp_release"></marker> <p>Returns a string containing the OTP release number of the @@ -8617,21 +8621,21 @@ timestamp() -> <tag><c>send</c></tag> <item> <p>Traces sending of messages.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_send">send</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_send_to_non_existing_process">send_to_non_existing_process</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_send"><c>send</c></seealso> and + <seealso marker="#trace_3_trace_messages_send_to_non_existing_process"><c>send_to_non_existing_process</c></seealso>.</p> </item> <tag><c>'receive'</c></tag> <item> <p>Traces receiving of messages.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_receive">'receive'</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_receive"><c>'receive'</c></seealso>.</p> </item> <tag><c>call</c></tag> <item> <p>Traces certain function calls. Specify which function calls to trace by calling <seealso marker="#trace_pattern/3">erlang:trace_pattern/3</seealso>.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_call">call</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_return_from">return_from</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_call"><c>call</c></seealso> and + <seealso marker="#trace_3_trace_messages_return_from"><c>return_from</c></seealso>.</p> </item> <tag><c>silent</c></tag> <item> @@ -8649,9 +8653,9 @@ timestamp() -> specification function <c>{silent,Bool}</c>, giving a high degree of control of which functions with which arguments that trigger the trace.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_call">call</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_return_from">return_from</seealso></c>, and - <c><seealso marker="#trace_3_trace_messages_return_to">return_to</seealso></c>. Or rather, the absence of.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_call"><c>call</c></seealso>, + <seealso marker="#trace_3_trace_messages_return_from"><c>return_from</c></seealso>, and + <seealso marker="#trace_3_trace_messages_return_to"><c>return_to</c></seealso>. Or rather, the absence of.</p> </item> <tag><c>return_to</c></tag> <item> @@ -8672,43 +8676,43 @@ timestamp() -> <p>To get trace messages containing return values from functions, use the <c>{return_trace}</c> match specification action instead.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_return_to">return_to</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_return_to"><c>return_to</c></seealso>.</p> </item> <tag><c>procs</c></tag> <item> <p>Traces process-related events.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_spawn">spawn</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_spawned">spawned</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_exit">exit</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_register">register</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_unregister">unregister</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_link">link</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_unlink">unlink</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_getting_linked">getting_linked</seealso></c>, and - <c><seealso marker="#trace_3_trace_messages_getting_unlinked">getting_unlinked</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_spawn"><c>spawn</c></seealso>, + <seealso marker="#trace_3_trace_messages_spawned"><c>spawned</c></seealso>, + <seealso marker="#trace_3_trace_messages_exit"><c>exit</c></seealso>, + <seealso marker="#trace_3_trace_messages_register"><c>register</c></seealso>, + <seealso marker="#trace_3_trace_messages_unregister"><c>unregister</c></seealso>, + <seealso marker="#trace_3_trace_messages_link"><c>link</c></seealso>, + <seealso marker="#trace_3_trace_messages_unlink"><c>unlink</c></seealso>, + <seealso marker="#trace_3_trace_messages_getting_linked"><c>getting_linked</c></seealso>, and + <seealso marker="#trace_3_trace_messages_getting_unlinked"><c>getting_unlinked</c></seealso>.</p> </item> <tag><c>ports</c></tag> <item> <p>Traces port-related events.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_open">open</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_closed">closed</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_register">register</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_unregister">unregister</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_getting_linked">getting_linked</seealso></c>, and - <c><seealso marker="#trace_3_trace_messages_getting_unlinked">getting_unlinked</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_open"><c>open</c></seealso>, + <seealso marker="#trace_3_trace_messages_closed"><c>closed</c></seealso>, + <seealso marker="#trace_3_trace_messages_register"><c>register</c></seealso>, + <seealso marker="#trace_3_trace_messages_unregister"><c>unregister</c></seealso>, + <seealso marker="#trace_3_trace_messages_getting_linked"><c>getting_linked</c></seealso>, and + <seealso marker="#trace_3_trace_messages_getting_unlinked"><c>getting_unlinked</c></seealso>.</p> </item> <tag><c>running</c></tag> <item> <p>Traces scheduling of processes.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_proc">in</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_out_proc">out</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_in_proc"><c>in</c></seealso> and + <seealso marker="#trace_3_trace_messages_out_proc"><c>out</c></seealso>.</p> </item> <tag><c>exiting</c></tag> <item> <p>Traces scheduling of exiting processes.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_exiting_proc">in_exiting</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_out_exiting_proc">out_exiting</seealso></c>, and - <c><seealso marker="#trace_3_trace_messages_out_exited_proc">out_exited</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_in_exiting_proc"><c>in_exiting</c></seealso>, + <seealso marker="#trace_3_trace_messages_out_exiting_proc"><c>out_exiting</c></seealso>, and + <seealso marker="#trace_3_trace_messages_out_exited_proc"><c>out_exited</c></seealso>.</p> </item> <tag><c>running_procs</c></tag> <item> @@ -8716,21 +8720,21 @@ timestamp() -> However this option also includes schedule events when the process executes within the context of a port without being scheduled out itself.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_proc">in</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_out_proc">out</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_in_proc"><c>in</c></seealso> and + <seealso marker="#trace_3_trace_messages_out_proc"><c>out</c></seealso>.</p> </item> <tag><c>running_ports</c></tag> <item> <p>Traces scheduling of ports.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_in_port">in</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_out_port">out</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_in_port"><c>in</c></seealso> and + <seealso marker="#trace_3_trace_messages_out_port"><c>out</c></seealso>.</p> </item> <tag><c>garbage_collection</c></tag> <item> <p>Traces garbage collections of processes.</p> - <p>Message tags: <c><seealso marker="#trace_3_trace_messages_gc_minor_start">gc_minor_start</seealso></c>, - <c><seealso marker="#trace_3_trace_messages_gc_max_heap_size">gc_max_heap_size</seealso></c> and - <c><seealso marker="#trace_3_trace_messages_gc_minor_end">gc_minor_end</seealso></c>.</p> + <p>Message tags: <seealso marker="#trace_3_trace_messages_gc_minor_start"><c>gc_minor_start</c></seealso>, + <seealso marker="#trace_3_trace_messages_gc_max_heap_size"><c>gc_max_heap_size</c></seealso> and + <seealso marker="#trace_3_trace_messages_gc_minor_end"><c>gc_minor_end</c></seealso>.</p> </item> <tag><c>timestamp</c></tag> <item> @@ -8758,7 +8762,7 @@ timestamp() -> <seealso marker="time_correction#Erlang_Monotonic_Time">Erlang monotonic time</seealso> time-stamp in all trace messages. The time-stamp (Ts) has the same format and value as produced by - <c><seealso marker="#monotonic_time-1">erlang:monotonic_time(nano_seconds)</seealso></c>. + <seealso marker="#monotonic_time-1"><c>erlang:monotonic_time(nano_seconds)</c></seealso>. This flag overrides the <c>cpu_timestamp</c> flag.</p> </item> <tag><c>strict_monotonic_timestamp</c></tag> @@ -8768,8 +8772,8 @@ timestamp() -> monotonic time</seealso> and a monotonically increasing integer in all trace messages. The time-stamp (Ts) has the same format and value as produced by - <c>{<seealso marker="#monotonic_time-1">erlang:monotonic_time(nano_seconds)</seealso>, - <seealso marker="#unique_integer-1">erlang:unique_integer([monotonic])</seealso>}</c>. + <c>{</c><seealso marker="#monotonic_time-1"><c>erlang:monotonic_time(nano_seconds)</c></seealso><c>,</c> + <seealso marker="#unique_integer-1"><c>erlang:unique_integer([monotonic])</c></seealso><c>}</c>. This flag overrides the <c>cpu_timestamp</c> flag.</p> </item> <tag><c>arity</c></tag> diff --git a/erts/emulator/beam/erl_db_hash.c b/erts/emulator/beam/erl_db_hash.c index 074ac6d64e..74979f984a 100644 --- a/erts/emulator/beam/erl_db_hash.c +++ b/erts/emulator/beam/erl_db_hash.c @@ -95,8 +95,7 @@ /* * The following symbols can be manipulated to "tune" the linear hash array */ -#define GROW_LIMIT(NACTIVE) ((NACTIVE)*2) -#define SHRINK_LIMIT(NACTIVE) ((NACTIVE) / 2) +#define CHAIN_LEN 6 /* Medium bucket chain len */ /* Number of slots per segment */ #define SEGSZ_EXP 8 @@ -464,7 +463,7 @@ db_finalize_dbterm_hash(int cret, DbUpdateHandle* handle); static ERTS_INLINE void try_shrink(DbTableHash* tb) { int nactive = NACTIVE(tb); - if (nactive > SEGSZ && NITEMS(tb) < SHRINK_LIMIT(nactive) + if (nactive > SEGSZ && NITEMS(tb) < (nactive * CHAIN_LEN) && !IS_FIXED(tb)) { shrink(tb, nactive); } @@ -671,8 +670,8 @@ int db_create_hash(Process *p, DbTable *tbl) tb->nsegs = NSEG_1; tb->nslots = SEGSZ; -#ifdef ERTS_SMP erts_smp_atomic_init_nob(&tb->is_resizing, 0); +#ifdef ERTS_SMP if (tb->common.type & DB_FINE_LOCKED) { erts_smp_rwmtx_opt_t rwmtx_opt = ERTS_SMP_RWMTX_OPT_DEFAULT_INITER; int i; @@ -863,7 +862,7 @@ Lnew: WUNLOCK_HASH(lck); { int nactive = NACTIVE(tb); - if (nitems > GROW_LIMIT(nactive) && !IS_FIXED(tb)) { + if (nitems > nactive * (CHAIN_LEN+1) && !IS_FIXED(tb)) { grow(tb, nactive); } } @@ -2251,12 +2250,12 @@ static int db_free_table_continue_hash(DbTable *tbl) done /= 2; while(tb->nslots != 0) { - done += 1 + SEGSZ/64 + free_seg(tb, 1); + free_seg(tb, 1); /* * If we have done enough work, get out here. */ - if (done >= DELETE_RECORD_LIMIT) { + if (++done >= (DELETE_RECORD_LIMIT / CHAIN_LEN / SEGSZ)) { return 0; /* Not done */ } } @@ -2605,22 +2604,23 @@ static Eterm build_term_list(Process* p, HashDbTerm* ptr1, HashDbTerm* ptr2, static ERTS_INLINE int begin_resizing(DbTableHash* tb) { -#ifdef ERTS_SMP if (DB_USING_FINE_LOCKING(tb)) - return !erts_atomic_xchg_acqb(&tb->is_resizing, 1); - else - ERTS_LC_ASSERT(erts_lc_rwmtx_is_rwlocked(&tb->common.rwlock)); -#endif - return 1; + return !erts_smp_atomic_xchg_acqb(&tb->is_resizing, 1); + else { + if (erts_smp_atomic_read_nob(&tb->is_resizing)) + return 0; + erts_smp_atomic_set_nob(&tb->is_resizing, 1); + return 1; + } } static ERTS_INLINE void done_resizing(DbTableHash* tb) { -#ifdef ERTS_SMP if (DB_USING_FINE_LOCKING(tb)) - erts_atomic_set_relb(&tb->is_resizing, 0); -#endif + erts_smp_atomic_set_relb(&tb->is_resizing, 0); + else + erts_smp_atomic_set_nob(&tb->is_resizing, 0); } /* Grow table with one new bucket. @@ -2871,7 +2871,7 @@ db_lookup_dbterm_hash(Process *p, DbTable *tbl, Eterm key, Eterm obj, int nitems = erts_smp_atomic_inc_read_nob(&tb->common.nitems); int nactive = NACTIVE(tb); - if (nitems > GROW_LIMIT(nactive) && !IS_FIXED(tb)) { + if (nitems > nactive * (CHAIN_LEN + 1) && !IS_FIXED(tb)) { grow(tb, nactive); } } diff --git a/erts/emulator/beam/erl_db_hash.h b/erts/emulator/beam/erl_db_hash.h index 081ff8fafc..e654363cd5 100644 --- a/erts/emulator/beam/erl_db_hash.h +++ b/erts/emulator/beam/erl_db_hash.h @@ -60,8 +60,8 @@ typedef struct db_table_hash { /* List of slots where elements have been deleted while table was fixed */ erts_smp_atomic_t fixdel; /* (FixedDeletion*) */ erts_smp_atomic_t nactive; /* Number of "active" slots */ -#ifdef ERTS_SMP erts_smp_atomic_t is_resizing; /* grow/shrink in progress */ +#ifdef ERTS_SMP DbTableHashFineLocks* locks; #endif #ifdef VALGRIND diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 48f89d2bd7..66f22979ad 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -3509,7 +3509,7 @@ wake_dirty_schedulers(ErtsRunQueue *rq, int one) #endif #define ERTS_NO_USED_RUNQS_SHIFT 16 -#define ERTS_NO_RUNQS_MASK 0xffff +#define ERTS_NO_RUNQS_MASK 0xffffU #if ERTS_MAX_NO_OF_SCHEDULERS > ERTS_NO_RUNQS_MASK # error "Too large amount of schedulers allowed" diff --git a/erts/emulator/beam/erl_ptab.h b/erts/emulator/beam/erl_ptab.h index a5931ffc25..fecfd96ab0 100644 --- a/erts/emulator/beam/erl_ptab.h +++ b/erts/emulator/beam/erl_ptab.h @@ -168,7 +168,7 @@ typedef struct { #define ERTS_PTAB_INVALID_ID(TAG) \ ((Eterm) \ - ((((1 << ERTS_PTAB_ID_DATA_SIZE) - 1) << ERTS_PTAB_ID_DATA_SHIFT) \ + ((((1U << ERTS_PTAB_ID_DATA_SIZE) - 1) << ERTS_PTAB_ID_DATA_SHIFT) \ | (TAG))) #define erts_ptab_is_valid_id(ID) \ diff --git a/erts/emulator/beam/erl_thr_progress.c b/erts/emulator/beam/erl_thr_progress.c index 542541165b..21938e7684 100644 --- a/erts/emulator/beam/erl_thr_progress.c +++ b/erts/emulator/beam/erl_thr_progress.c @@ -95,9 +95,9 @@ #define ERTS_THR_PRGR_FTL_ERR_BLCK_POLL_INTERVAL 100 -#define ERTS_THR_PRGR_LFLG_BLOCK (((erts_aint32_t) 1) << 31) -#define ERTS_THR_PRGR_LFLG_NO_LEADER (((erts_aint32_t) 1) << 30) -#define ERTS_THR_PRGR_LFLG_WAITING_UM (((erts_aint32_t) 1) << 29) +#define ERTS_THR_PRGR_LFLG_BLOCK ((erts_aint32_t) (1U << 31)) +#define ERTS_THR_PRGR_LFLG_NO_LEADER ((erts_aint32_t) (1U << 30)) +#define ERTS_THR_PRGR_LFLG_WAITING_UM ((erts_aint32_t) (1U << 29)) #define ERTS_THR_PRGR_LFLG_ACTIVE_MASK (~(ERTS_THR_PRGR_LFLG_NO_LEADER \ | ERTS_THR_PRGR_LFLG_BLOCK \ | ERTS_THR_PRGR_LFLG_WAITING_UM)) @@ -142,8 +142,8 @@ init_nob(ERTS_THR_PRGR_ATOMIC *atmc, ErtsThrPrgrVal val) #warning "Thread progress state debug is on" #endif -#define ERTS_THR_PROGRESS_STATE_DEBUG_LEADER (((erts_aint32_t) 1) << 0) -#define ERTS_THR_PROGRESS_STATE_DEBUG_ACTIVE (((erts_aint32_t) 1) << 1) +#define ERTS_THR_PROGRESS_STATE_DEBUG_LEADER ((erts_aint32_t) (1U << 0)) +#define ERTS_THR_PROGRESS_STATE_DEBUG_ACTIVE ((erts_aint32_t) (1U << 1)) #define ERTS_THR_PROGRESS_STATE_DEBUG_INIT(ID) \ erts_atomic32_init_nob(&intrnl->thr[(ID)].data.state_debug, \ @@ -179,10 +179,10 @@ do { \ #endif /* ERTS_THR_PROGRESS_STATE_DEBUG */ -#define ERTS_THR_PRGR_BLCKR_INVALID (~((erts_aint32_t) 0)) -#define ERTS_THR_PRGR_BLCKR_UNMANAGED (((erts_aint32_t) 1) << 31) +#define ERTS_THR_PRGR_BLCKR_INVALID ((erts_aint32_t) (~0U)) +#define ERTS_THR_PRGR_BLCKR_UNMANAGED ((erts_aint32_t) (1U << 31)) -#define ERTS_THR_PRGR_BC_FLG_NOT_BLOCKING (((erts_aint32_t) 1) << 31) +#define ERTS_THR_PRGR_BC_FLG_NOT_BLOCKING ((erts_aint32_t) (1U << 31)) #define ERTS_THR_PRGR_BM_BITS 32 #define ERTS_THR_PRGR_BM_SHIFT 5 @@ -1186,7 +1186,7 @@ wakeup_unmanaged_threads(ErtsThrPrgrUnmanagedWakeupData *umwd) int hbase = hix << ERTS_THR_PRGR_BM_SHIFT; int hbit; for (hbit = 0; hbit < ERTS_THR_PRGR_BM_BITS; hbit++) { - if (hmask & (1 << hbit)) { + if (hmask & (1U << hbit)) { erts_aint_t lmask; int lix = hbase + hbit; ASSERT(0 <= lix && lix < umwd->low_sz); @@ -1195,7 +1195,7 @@ wakeup_unmanaged_threads(ErtsThrPrgrUnmanagedWakeupData *umwd) int lbase = lix << ERTS_THR_PRGR_BM_SHIFT; int lbit; for (lbit = 0; lbit < ERTS_THR_PRGR_BM_BITS; lbit++) { - if (lmask & (1 << lbit)) { + if (lmask & (1U << lbit)) { int id = lbase + lbit; wakeup_unmanaged(id); } diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index 3dca58d60b..4cf38bf894 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -2115,32 +2115,36 @@ profile_runnable_proc(Process *p, Eterm status){ Eterm *hp, msg; Eterm where = am_undefined; ErlHeapFragment *bp = NULL; - int use_current = 1; + BeamInstr *current = NULL; #ifndef ERTS_SMP #define LOCAL_HEAP_SIZE (4 + 6 + ERTS_TRACE_PATCH_TS_MAX_SIZE) - DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE); UseTmpHeapNoproc(LOCAL_HEAP_SIZE); hp = local_heap; #else + ErtsThrPrgrDelayHandle dhndl; Uint hsz = 4 + 6 + patch_ts_size(erts_system_profile_ts_type)-1; #endif - - if (ERTS_PROC_IS_EXITING(p)) { - use_current = 0; - /* could probably set 'where' to 'exiting' here, - * though it's not documented as such */ - } else { - if (!p->current) { - p->current = find_function_from_pc(p->i); + /* Assumptions: + * We possibly don't have the MAIN_LOCK for the process p here. + * We assume that we can read from p->current and p->i atomically + */ +#ifdef ERTS_SMP + dhndl = erts_thr_progress_unmanaged_delay(); /* suspend purge operations */ +#endif + + if (!ERTS_PROC_IS_EXITING(p)) { + if (p->current) { + current = p->current; + } else { + current = find_function_from_pc(p->i); } - use_current = p->current != NULL; } #ifdef ERTS_SMP - if (!use_current) { + if (!current) { hsz -= 4; } @@ -2148,11 +2152,15 @@ profile_runnable_proc(Process *p, Eterm status){ hp = bp->mem; #endif - if (use_current) { - where = TUPLE3(hp, p->current[0], p->current[1], make_small(p->current[2])); hp += 4; + if (current) { + where = TUPLE3(hp, current[0], current[1], make_small(current[2])); hp += 4; } else { where = make_small(0); } + +#ifdef ERTS_SMP + erts_thr_progress_unmanaged_continue(dhndl); +#endif erts_smp_mtx_lock(&smq_mtx); diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c index 3c002d43a7..beed847578 100644 --- a/erts/emulator/beam/external.c +++ b/erts/emulator/beam/external.c @@ -2159,12 +2159,23 @@ enc_atom(ErtsAtomCacheMap *acmp, Eterm atom, byte *ep, Uint32 dflags) return ep; } +/* + * We use this atom as sysname in local pid/port/refs + * for the ETS compressed format (DFLAG_INTERNAL_TAGS). + * + * We used atom '' earlier but that turned out to cause problems + * for buggy erl_interface/ic usage of c-nodes with empty node names. + * A long atom reduces risk of nodes actually called this and the length + * does not matter anyway as it's encoded with atom index (ATOM_INTERNAL_REF2). + */ +#define INTERNAL_LOCAL_SYSNAME am_await_microstate_accounting_modifications + static byte* enc_pid(ErtsAtomCacheMap *acmp, Eterm pid, byte* ep, Uint32 dflags) { Uint on, os; Eterm sysname = ((is_internal_pid(pid) && (dflags & DFLAG_INTERNAL_TAGS)) - ? am_Empty : pid_node_name(pid)); + ? INTERNAL_LOCAL_SYSNAME : pid_node_name(pid)); Uint32 creation = pid_creation(pid); byte* tagp = ep++; @@ -2268,7 +2279,7 @@ dec_atom(ErtsDistExternal *edep, byte* ep, Eterm* objp) static ERTS_INLINE ErlNode* dec_get_node(Eterm sysname, Uint32 creation) { - if (sysname == am_Empty) /* && DFLAG_INTERNAL_TAGS */ + if (sysname == INTERNAL_LOCAL_SYSNAME) /* && DFLAG_INTERNAL_TAGS */ return erts_this_node; if (sysname == erts_this_node->sysname @@ -2555,7 +2566,7 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, case EXTERNAL_REF_DEF: { Uint32 *ref_num; Eterm sysname = (((dflags & DFLAG_INTERNAL_TAGS) && is_internal_ref(obj)) - ? am_Empty : ref_node_name(obj)); + ? INTERNAL_LOCAL_SYSNAME : ref_node_name(obj)); Uint32 creation = ref_creation(obj); byte* tagp = ep++; @@ -2584,7 +2595,7 @@ enc_term_int(TTBEncodeContext* ctx, ErtsAtomCacheMap *acmp, Eterm obj, byte* ep, case PORT_DEF: case EXTERNAL_PORT_DEF: { Eterm sysname = (((dflags & DFLAG_INTERNAL_TAGS) && is_internal_port(obj)) - ? am_Empty : port_node_name(obj)); + ? INTERNAL_LOCAL_SYSNAME : port_node_name(obj)); Uint32 creation = port_creation(obj); byte* tagp = ep++; diff --git a/erts/emulator/sys/common/erl_mmap.c b/erts/emulator/sys/common/erl_mmap.c index 53009a1481..7bbb406f29 100644 --- a/erts/emulator/sys/common/erl_mmap.c +++ b/erts/emulator/sys/common/erl_mmap.c @@ -1334,9 +1334,17 @@ os_mremap(void *ptr, UWord old_size, UWord new_size, int try_superalign) #define ERTS_MMAP_RESERVE_PROT_EXEC (ERTS_MMAP_PROT_EXEC) #define ERTS_MMAP_RESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_FIXED) #define ERTS_MMAP_UNRESERVE_PROT (PROT_NONE) +#if defined(__FreeBSD__) +#define ERTS_MMAP_UNRESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_FIXED) +#else #define ERTS_MMAP_UNRESERVE_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE|MAP_FIXED) +#endif /* __FreeBSD__ */ #define ERTS_MMAP_VIRTUAL_PROT (PROT_NONE) +#if defined(__FreeBSD__) +#define ERTS_MMAP_VIRTUAL_FLAGS (ERTS_MMAP_FLAGS) +#else #define ERTS_MMAP_VIRTUAL_FLAGS (ERTS_MMAP_FLAGS|MAP_NORESERVE) +#endif /* __FreeBSD__ */ static int os_reserve_physical(char *ptr, UWord size, int exec) diff --git a/erts/emulator/sys/common/erl_mmap.h b/erts/emulator/sys/common/erl_mmap.h index 7ac61a82c1..fa51b663fa 100644 --- a/erts/emulator/sys/common/erl_mmap.h +++ b/erts/emulator/sys/common/erl_mmap.h @@ -38,7 +38,17 @@ # if HAVE_MREMAP # define ERTS_HAVE_OS_MREMAP 1 # endif -# if defined(MAP_FIXED) && defined(MAP_NORESERVE) +/* + * MAP_NORESERVE is undefined in FreeBSD 10.x and later. + * This is to enable 64bit HiPE experimentally on FreeBSD. + * Note that on FreeBSD MAP_NORESERVE was "never implemented" + * even before 11.x (and the flag does not exist in /usr/src/sys/vm/mmap.c + * of 10.3-STABLE r301478 either), and HiPE was working on OTP 18.3.3, + * so mandating MAP_NORESERVE on FreeBSD might not be needed. + * See the following message on how MAP_NORESERVE was treated on FreeBSD: + * <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150202/122958.html> + */ +# if defined(MAP_FIXED) && (defined(MAP_NORESERVE) || defined(__FreeBSD__)) # define ERTS_HAVE_OS_PHYSICAL_MEMORY_RESERVATION 1 # endif #endif diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h index 241540b894..3a0d23cd36 100644 --- a/erts/emulator/sys/unix/erl_unix_sys.h +++ b/erts/emulator/sys/unix/erl_unix_sys.h @@ -163,7 +163,7 @@ typedef long long ErtsSysHrTime; typedef ErtsMonotonicTime ErtsSystemTime; typedef ErtsSysHrTime ErtsSysPerfCounter; -#define ERTS_MONOTONIC_TIME_MIN (((ErtsMonotonicTime) 1) << 63) +#define ERTS_MONOTONIC_TIME_MIN ((ErtsMonotonicTime) (1ULL << 63)) #define ERTS_MONOTONIC_TIME_MAX (~ERTS_MONOTONIC_TIME_MIN) /* diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h index 7bdfac168b..04fbf23109 100644 --- a/erts/emulator/sys/win32/erl_win_sys.h +++ b/erts/emulator/sys/win32/erl_win_sys.h @@ -187,7 +187,7 @@ typedef ErtsMonotonicTime ErtsSysPerfCounter; ErtsSystemTime erts_os_system_time(void); -#define ERTS_MONOTONIC_TIME_MIN (((ErtsMonotonicTime) 1) << 63) +#define ERTS_MONOTONIC_TIME_MIN ((ErtsMonotonicTime) (1ULL << 63)) #define ERTS_MONOTONIC_TIME_MAX (~ERTS_MONOTONIC_TIME_MIN) #define ERTS_HAVE_OS_MONOTONIC_TIME_SUPPORT 1 diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl index 22a1c0b765..95042ac802 100644 --- a/erts/emulator/test/bs_construct_SUITE.erl +++ b/erts/emulator/test/bs_construct_SUITE.erl @@ -23,6 +23,7 @@ -module(bs_construct_SUITE). -export([all/0, suite/0, + init_per_suite/1, end_per_suite/1, test1/1, test2/1, test3/1, test4/1, test5/1, testf/1, not_used/1, in_guard/1, mem_leak/1, coerce_to_float/1, bjorn/1, @@ -43,6 +44,12 @@ all() -> copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width, bad_append, bs_add_overflow]. +init_per_suite(Config) -> + Config. + +end_per_suite(_Config) -> + application:stop(os_mon). + big(1) -> 57285702734876389752897683. @@ -882,10 +889,14 @@ append_unit_16(Bin) -> %% Produce a large result of bs_add that, if cast to signed int, would overflow %% into a negative number that fits a smallnum. -bs_add_overflow(Config) -> +bs_add_overflow(_Config) -> + Memsize = memsize(), + io:format("Memsize = ~w Bytes~n", [Memsize]), case erlang:system_info(wordsize) of 8 -> {skip, "64-bit architecture"}; + _ when Memsize < (2 bsl 30) -> + {skip, "Less then 2 GB of memory"}; 4 -> Large = <<0:((1 bsl 30)-1)>>, {'EXIT',{system_limit,_}} = @@ -894,5 +905,10 @@ bs_add_overflow(Config) -> Large/bits>>), ok end. - + id(I) -> I. + +memsize() -> + application:ensure_all_started(os_mon), + {Tot,_Used,_} = memsup:get_memory_data(), + Tot. diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl index 26780f6017..c6939a695d 100644 --- a/erts/emulator/test/distribution_SUITE.erl +++ b/erts/emulator/test/distribution_SUITE.erl @@ -187,8 +187,13 @@ bulk_sendsend2(Terms, BinSize, BusyBufSize) -> {ok, NodeSend} = start_node(bulk_sender, "+zdbbl " ++ integer_to_list(BusyBufSize)), _Send = spawn(NodeSend, erlang, apply, [fun sendersender/4, [self(), Recv, Bin, Terms]]), {Elapsed, {_TermsN, SizeN}, MonitorCount} = - receive {sendersender, BigRes} -> - BigRes + receive + %% On some platforms (windows), the time taken is 0 so we + %% simulate that some little time has passed. + {sendersender, {0.0,T,MC}} -> + {0.0015, T, MC}; + {sendersender, BigRes} -> + BigRes end, stop_node(NodeRecv), stop_node(NodeSend), @@ -1042,10 +1047,13 @@ atom_roundtrip_r15b(Config) when is_list(Config) -> ct:timetrap({minutes, 6}), AtomData = atom_data(), verify_atom_data(AtomData), - {ok, Node} = start_node(Config, [], "r15b"), - do_atom_roundtrip(Node, AtomData), - stop_node(Node), - ok; + case start_node(Config, [], "r15b") of + {ok, Node} -> + do_atom_roundtrip(Node, AtomData), + stop_node(Node); + {error, timeout} -> + {skip,"Unable to start OTP R15B release"} + end; false -> {skip,"No OTP R15B available"} end. diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index 4ebc1f5782..dae8990f56 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -2581,7 +2581,10 @@ enable_internal_state() -> _ -> erts_debug:set_internal_state(available_internal_state, true) end. -sys_mem_cond_run(ReqSizeMB, TestFun) when is_integer(ReqSizeMB) -> +sys_mem_cond_run(OrigReqSizeMB, TestFun) when is_integer(OrigReqSizeMB) -> + %% Debug normally needs more memory, so double the requirement + Debug = erlang:system_info(debug_compiled), + ReqSizeMB = if Debug -> OrigReqSizeMB * 2; true -> OrigReqSizeMB end, case total_memory() of TotMem when is_integer(TotMem), TotMem >= ReqSizeMB -> TestFun(); diff --git a/erts/emulator/test/trace_call_time_SUITE.erl b/erts/emulator/test/trace_call_time_SUITE.erl index 40c8bc4340..6582ad134b 100644 --- a/erts/emulator/test/trace_call_time_SUITE.erl +++ b/erts/emulator/test/trace_call_time_SUITE.erl @@ -351,7 +351,7 @@ combo(Config) when is_list(Config) -> %% Tests tracing of bifs bif(Config) when is_list(Config) -> P = erlang:trace_pattern({'_','_','_'}, false, [call_time]), - M = 1000000, + M = 5000000, %% 2 = erlang:trace_pattern({erlang, binary_to_term, '_'}, true, [call_time]), 2 = erlang:trace_pattern({erlang, term_to_binary, '_'}, true, [call_time]), @@ -381,7 +381,7 @@ bif(Config) when is_list(Config) -> nif(Config) when is_list(Config) -> load_nif(Config), P = erlang:trace_pattern({'_','_','_'}, false, [call_time]), - M = 1000000, + M = 5000000, %% 1 = erlang:trace_pattern({?MODULE, nif_dec, '_'}, true, [call_time]), 1 = erlang:trace_pattern({?MODULE, with_nif, '_'}, true, [call_time]), diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c index a4008186c4..d67b997d6d 100644 --- a/erts/etc/common/heart.c +++ b/erts/etc/common/heart.c @@ -529,7 +529,7 @@ kill_old_erlang(void){ char* envvar = NULL; envvar = get_env(HEART_NO_KILL); - if (!envvar || strcmp(envvar, "TRUE") == 0) + if (envvar && strcmp(envvar, "TRUE") == 0) return; if(heart_beat_kill_pid != 0){ @@ -566,7 +566,7 @@ kill_old_erlang(void){ char *envvar = NULL; envvar = get_env(HEART_NO_KILL); - if (!envvar || strcmp(envvar, "TRUE") == 0) + if (envvar && strcmp(envvar, "TRUE") == 0) return; envvar = get_env(HEART_KILL_SIGNAL); diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in index 8f9945c4b4..15fb718c47 100644 --- a/erts/etc/unix/etp-commands.in +++ b/erts/etc/unix/etp-commands.in @@ -1807,52 +1807,53 @@ define etp-process-info # Args: Process* # printf " Pid: " - etp-1 ($arg0)->common.id + set $etp_proc = ((Process*)$arg0) + etp-1 $etp_proc->common.id printf "\n State: " - etp-proc-state $arg0 + etp-proc-state $etp_proc if $proxy_process != 0 - printf " Pointer: (Process *) %p\n", $arg0 + printf " Pointer: (Process *) %p\n", $etp_proc printf " *** PROXY process struct *** refer to: \n" - etp-pid2proc-1 $arg0->common.id + etp-pid2proc-1 $etp_proc->common.id etp-process-info $proc else - if (*(((Uint32 *) &(((Process *) $arg0)->state))) & 0x4) == 0 - if ($arg0->common.u.alive.reg) + if (*(((Uint32 *) &($etp_proc->state))) & 0x4) == 0 + if ($etp_proc->common.u.alive.reg) printf " Registered name: " - etp-1 $arg0->common.u.alive.reg->name + etp-1 $etp_proc->common.u.alive.reg->name printf "\n" end end - if ($arg0->current) + if ($etp_proc->current) printf " Current function: " - etp-1 $arg0->current[0] + etp-1 $etp_proc->current[0] printf ":" - etp-1 $arg0->current[1] - printf "/%d\n", $arg0->current[2] + etp-1 $etp_proc->current[1] + printf "/%d\n", $etp_proc->current[2] end - if ($arg0->cp) + if ($etp_proc->cp) printf " CP: " - etp-cp-1 $arg0->cp + etp-cp-1 $etp_proc->cp printf "\n" end - if ($arg0->i) + if ($etp_proc->i) printf " I: " - etp-cp-1 $arg0->i + etp-cp-1 $etp_proc->i printf "\n" end - printf " Heap size: %ld\n", $arg0->heap_sz - if ($arg0->old_heap) - printf " Old-heap size: %ld\n", $arg0->old_hend - $arg0->old_heap + printf " Heap size: %ld\n", $etp_proc->heap_sz + if ($etp_proc->old_heap) + printf " Old-heap size: %ld\n", $etp_proc->old_hend - $etp_proc->old_heap end - printf " Mbuf size: %ld\n", $arg0->mbuf_sz + printf " Mbuf size: %ld\n", $etp_proc->mbuf_sz if (etp_smp_compiled) - printf " Msgq len: %ld (inner=%ld, outer=%ld)\n", ($arg0->msg.len + $arg0->msg_inq.len), $arg0->msg.len, $arg0->msg_inq.len + printf " Msgq len: %ld (inner=%ld, outer=%ld)\n", ($etp_proc->msg.len + $etp_proc->msg_inq.len), $etp_proc->msg.len, $etp_proc->msg_inq.len else - printf " Msgq len: %d\n", $arg0->msg.len + printf " Msgq len: %d\n", $etp_proc->msg.len end printf " Parent: " - etp-1 $arg0->parent - printf "\n Pointer: (Process *) %p\n", $arg0 + etp-1 $etp_proc->parent + printf "\n Pointer: (Process *) %p\n", $etp_proc end end @@ -1918,57 +1919,58 @@ end define etp-process-memory-info # Args: Process* # - if ((*(((Uint32 *) &(((Process *) $arg0)->state)))) & 0x400000) + set $etp_pmem_proc = ((Process *) $arg0) + if ((*(((Uint32 *) &($etp_pmem_proc->state)))) & 0x400000) set $proxy_process = 1 else set $proxy_process = 0 end printf " " - etp-1 $arg0->common.id - printf ": (Process *) %p ", $arg0 + etp-1 $etp_pmem_proc->common.id + printf ": (Process *) %p ", $etp_pmem_proc if $proxy_process != 0 - printf "(Process *) %p ", $arg0 + printf "(Process *) %p ", $etp_pmem_proc printf " *** PROXY process struct *** refer to next: \n" - etp-pid2proc-1 $arg0->common.id + etp-pid2proc-1 $etp_pmem_proc->common.id printf " -" etp-process-memory-info $proc else - printf " [Heap: %5ld", $arg0->heap_sz - if ($arg0->old_heap) - printf " | %5ld", $arg0->old_hend - $arg0->old_heap + printf " [Heap: %5ld", $etp_pmem_proc->heap_sz + if ($etp_pmem_proc->old_heap) + printf " | %5ld", $etp_pmem_proc->old_hend - $etp_pmem_proc->old_heap else printf " | none " end - printf "] [Mbuf: %5ld", $arg0->mbuf_sz + printf "] [Mbuf: %5ld", $etp_pmem_proc->mbuf_sz if (etp_smp_compiled) - printf " | %3ld (%3ld | %3ld)", ($arg0->msg.len + $arg0->msg_inq.len), $arg0->msg.len, $arg0->msg_inq.len + printf " | %3ld (%3ld | %3ld)", ($etp_pmem_proc->msg.len + $etp_pmem_proc->msg_inq.len), $etp_pmem_proc->msg.len, $etp_pmem_proc->msg_inq.len else - printf " | %3ld", $arg0->msg.len + printf " | %3ld", $etp_pmem_proc->msg.len end printf "] " - if ($arg0->i) + if ($etp_pmem_proc->i) printf " I: " - etp-cp-1 $arg0->i + etp-cp-1 $etp_pmem_proc->i printf " " end - if ($arg0->current) - etp-1 $arg0->current[0] + if ($etp_pmem_proc->current) + etp-1 $etp_pmem_proc->current[0] printf ":" - etp-1 $arg0->current[1] - printf "/%d ", $arg0->current[2] + etp-1 $etp_pmem_proc->current[1] + printf "/%d ", $etp_pmem_proc->current[2] end - if (*(((Uint32 *) &(((Process *) $arg0)->state))) & 0x4) == 0 - if ($arg0->common.u.alive.reg) - etp-1 $arg0->common.u.alive.reg->name + if (*(((Uint32 *) &(((Process *) $etp_pmem_proc)->state))) & 0x4) == 0 + if ($etp_pmem_proc->common.u.alive.reg) + etp-1 $etp_pmem_proc->common.u.alive.reg->name printf " " end end - if ($arg0->cp) + if ($etp_pmem_proc->cp) printf " CP: " - etp-cp-1 $arg0->cp + etp-cp-1 $etp_pmem_proc->cp printf " " end printf "\n" @@ -2166,23 +2168,24 @@ define etp-port-info # Args: Port* # printf " Port: " - etp-1 $arg0->common.id - printf "\n Name: %s\n", $arg0->name + set $etp_pinfo_port = ((Port*)$arg0) + etp-1 $etp_pinfo_port->common.id + printf "\n Name: %s\n", $etp_pinfo_port->name printf " State:" - etp-port-state $arg0 + etp-port-state $etp_pinfo_port printf " Scheduler flags:" - etp-port-sched-flags $arg0 - if (*(((Uint32 *) &(((Port *) $arg0)->state))) & 0x5C00) == 0 - if ($arg0->common.u.alive.reg) + etp-port-sched-flags $etp_pinfo_port + if (*(((Uint32 *) &($etp_pinfo_port->state))) & 0x5C00) == 0 + if ($etp_pinfo_port->common.u.alive.reg) printf " Registered name: " - etp-1 $arg0->common.u.alive.reg->name + etp-1 $etp_pinfo_port->common.u.alive.reg->name printf "\n" end end printf " Connected: " - set $connected = *(((Eterm *) &(((Port *) $arg0)->connected))) + set $connected = *(((Eterm *) &(((Port *) $etp_pinfo_port)->connected))) etp-1 $connected - printf "\n Pointer: (Port *) %p\n", $arg0 + printf "\n Pointer: (Port *) %p\n", $etp_pinfo_port end document etp-port-info @@ -3694,6 +3697,26 @@ document etp-address-to-beam-opcode %--------------------------------------------------------------------------- end +define etp-compile-debug + shell (cd $ERL_TOP && make emulator FLAVOR=smp TYPE=debug) +end + +document etp-compile-debug +%--------------------------------------------------------------------------- +% Re-compile the debug erlang emulator +%--------------------------------------------------------------------------- +end + +define etp-compile + shell (cd $ERL_TOP && make emulator) +end + +document etp-compile +%--------------------------------------------------------------------------- +% Re-compile the erlang emulator +%--------------------------------------------------------------------------- +end + ############################################################################ # Toolbox parameter handling diff --git a/erts/include/internal/ethr_mutex.h b/erts/include/internal/ethr_mutex.h index a510a2c97f..8ef3b1e40b 100644 --- a/erts/include/internal/ethr_mutex.h +++ b/erts/include/internal/ethr_mutex.h @@ -108,13 +108,13 @@ void LeaveCriticalSection(CRITICAL_SECTION *); # error Need a qlock implementation #endif -#define ETHR_RWMTX_W_FLG__ (((ethr_sint32_t) 1) << 31) -#define ETHR_RWMTX_W_WAIT_FLG__ (((ethr_sint32_t) 1) << 30) -#define ETHR_RWMTX_R_WAIT_FLG__ (((ethr_sint32_t) 1) << 29) +#define ETHR_RWMTX_W_FLG__ ((ethr_sint32_t) (1U << 31)) +#define ETHR_RWMTX_W_WAIT_FLG__ ((ethr_sint32_t) (1U << 30)) +#define ETHR_RWMTX_R_WAIT_FLG__ ((ethr_sint32_t) (1U << 29)) /* frequent read kind */ -#define ETHR_RWMTX_R_FLG__ (((ethr_sint32_t) 1) << 28) -#define ETHR_RWMTX_R_ABRT_UNLCK_FLG__ (((ethr_sint32_t) 1) << 27) +#define ETHR_RWMTX_R_FLG__ ((ethr_sint32_t) (1U << 28)) +#define ETHR_RWMTX_R_ABRT_UNLCK_FLG__ ((ethr_sint32_t) (1U << 27)) #define ETHR_RWMTX_R_PEND_UNLCK_MASK__ (ETHR_RWMTX_R_ABRT_UNLCK_FLG__ - 1) /* normal kind */ |