diff options
-rw-r--r-- | erts/doc/src/crash_dump.xml | 3 | ||||
-rw-r--r-- | erts/doc/src/driver_entry.xml | 3 | ||||
-rw-r--r-- | erts/doc/src/erl_driver.xml | 63 | ||||
-rw-r--r-- | erts/doc/src/erl_nif.xml | 31 | ||||
-rw-r--r-- | erts/doc/src/erts_alloc.xml | 4 | ||||
-rw-r--r-- | lib/stdlib/doc/src/ets.xml | 4 | ||||
-rw-r--r-- | system/doc/efficiency_guide/commoncaveats.xml | 3 | ||||
-rw-r--r-- | system/doc/efficiency_guide/processes.xml | 20 |
8 files changed, 32 insertions, 99 deletions
diff --git a/erts/doc/src/crash_dump.xml b/erts/doc/src/crash_dump.xml index f5eab1273a..388b737ab9 100644 --- a/erts/doc/src/crash_dump.xml +++ b/erts/doc/src/crash_dump.xml @@ -233,8 +233,7 @@ Slogan: <reason></pre> <item> <p>If empty, the scheduler was doing some work. If not empty, the scheduler is either in some state of sleep, - or suspended. This entry is only present in an SMP-enabled - emulator.</p> + or suspended.</p> </item> <tag><em>Scheduler Sleep Info Aux Work</em></tag> <item> diff --git a/erts/doc/src/driver_entry.xml b/erts/doc/src/driver_entry.xml index cb6548d3f0..b3855a179f 100644 --- a/erts/doc/src/driver_entry.xml +++ b/erts/doc/src/driver_entry.xml @@ -465,8 +465,7 @@ typedef struct erl_drv_entry { <item> <p>The runtime system uses port-level locking on all ports executing this driver instead of driver-level - locking when the driver is run in a runtime - system with SMP support. For more information, see + locking. For more information, see <seecref marker="erl_driver#smp_support"> <c>erl_driver</c></seecref>.</p> </item> diff --git a/erts/doc/src/erl_driver.xml b/erts/doc/src/erl_driver.xml index febfc27c99..ee571eb749 100644 --- a/erts/doc/src/erl_driver.xml +++ b/erts/doc/src/erl_driver.xml @@ -112,9 +112,8 @@ the port. (Although in the latest Erlang versions there is the binary syntax, which enables you to match on the beginning of a binary.)</p> - <p><marker id="smp_support"></marker>In the runtime system with - SMP support, drivers are locked either on driver level - or port level (driver instance level). By default + <p><marker id="smp_support"></marker>Drivers are locked either on + driver level or port level (driver instance level). By default driver level locking will be used, that is, only one emulator thread will execute code in the driver at a time. If port level locking is used, multiple emulator threads can execute code in the driver @@ -139,18 +138,6 @@ communication" is strongly discouraged.</p> </note> - <p>Previously, in the runtime system without SMP support, - specific driver callbacks were always called from the same - thread. This is <em>not</em> the case in the runtime system - with SMP support. Regardless of locking scheme used, calls - to driver callbacks can be made from different threads. For example, - two consecutive calls to exactly the same callback for exactly - the same port can be made from two different threads. This - is for <em>most</em> drivers not a problem, but it can be. - Drivers that depend on all callbacks that are called in the - same thread, <em>must</em> be rewritten before they are used - in the runtime system with SMP support.</p> - <note> <p>Regardless of locking scheme used, calls to driver callbacks can be made from different threads.</p> @@ -167,9 +154,7 @@ <warning> <p>Functions not explicitly documented as thread-safe are - <em>not</em> thread safe. Also notice that some functions - are <em>only</em> thread-safe when used in a runtime - system with SMP support.</p> + <em>not</em> thread safe.</p> <p>A function not explicitly documented as thread-safe can, at some point in time, have a thread-safe implementation in the runtime system. Such an implementation can however change to @@ -287,19 +272,8 @@ omitted it from the Erlang driver thread API. In the Erlang driver case, time-outs can and are to be handled with the timer functionality of the Erlang driver API.</p> - <p>In order for the Erlang driver thread API to function, thread - support must be enabled in the runtime system. An Erlang driver - can check if thread support is enabled by use of - <seecref marker="#driver_system_info"> - <c>driver_system_info</c></seecref>. - Notice that some functions in the Erlang driver API are thread-safe - only when the runtime system has SMP support, also this - information can be retrieved through - <seecref marker="#driver_system_info"> - <c>driver_system_info</c></seecref>. - Also notice that many functions in the Erlang driver API are - <em>not</em> thread-safe, regardless of whether SMP support is - enabled or not. If a function is not documented as thread-safe, it + <p>Notice that many functions in the Erlang driver API are + <em>not</em> thread-safe. If a function is not documented as thread-safe, it is <em>not</em> thread-safe.</p> <note> <p>When executing in an emulator thread, it is @@ -1177,8 +1151,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <item>Called from <seemfa marker="erlang#port_call/3"> <c>erlang:port_call/3</c></seemfa>.</item> </taglist> - <p>Notice that this function is <em>not</em> thread-safe, not - even when the emulator with SMP support is used.</p> + <p>Notice that this function is <em>not</em> thread-safe.</p> </desc> </func> @@ -1217,8 +1190,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <desc> <marker id="driver_connected"></marker> <p>Returns the port owner process.</p> - <p>Notice that this function is <em>not</em> thread-safe, not - even when the emulator with SMP support is used.</p> + <p>Notice that this function is <em>not</em> thread-safe.</p> </desc> </func> @@ -1495,8 +1467,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <c>string</c>. The atom is created and does not change, so the return value can be saved and reused, which is faster than looking up the atom several times.</p> - <p>Notice that this function is <em>not</em> thread-safe, not - even when the emulator with SMP support is used.</p> + <p>Notice that this function is <em>not</em> thread-safe.</p> </desc> </func> @@ -1511,8 +1482,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <c>erl_drv_output_term</c></seecref> and <seecref marker="#erl_drv_send_term"> <c>erl_drv_send_term</c></seecref>.</p> - <p>Notice that this function is <em>not</em> thread-safe, not - even when the emulator with SMP support is used.</p> + <p>Notice that this function is <em>not</em> thread-safe.</p> </desc> </func> @@ -1602,8 +1572,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <p>Parameters <c>term</c> and <c>n</c> work as in <seecref marker="#erl_drv_output_term"> <c>erl_drv_output_term</c></seecref>.</p> - <p>Notice that this function is <em>not</em> thread-safe, not - even when the emulator with SMP support is used.</p> + <p>Notice that this function is <em>not</em> thread-safe.</p> </desc> </func> @@ -1905,8 +1874,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> value of <c>mode</c>.</p> </note> <p><c>ERL_DRV_USE</c> specifies if we are using the event object or - if we want to close it. - On an emulator with SMP support, it is not safe to clear all events + if we want to close it. It is not safe to clear all events and then close the event object after <c>driver_select</c> has returned. Another thread can still be using the event object internally. To safely close an event object, call @@ -1952,8 +1920,7 @@ r = driver_async(myPort, &myKey, myData, myFunc); ]]></code> <p>Parameters <c>term</c> and <c>n</c> work as in <seecref marker="#erl_drv_output_term"> <c>erl_drv_output_term</c></seecref>.</p> - <p>This function is only thread-safe when the emulator with SMP - support is used.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -2647,8 +2614,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] <p>The <c>ERL_DRV_UINT</c>, <c>ERL_DRV_BUF2BINARY</c>, and <c>ERL_DRV_EXT2TERM</c> term types were introduced in ERTS 5.6.</p> - <p>This function is only thread-safe when the emulator with SMP - support is used.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -2853,8 +2819,7 @@ erl_drv_output_term(driver_mk_port(drvport), spec, sizeof(spec) / sizeof(spec[0] <p>Parameters <c>port</c>, <c>term</c>, and <c>n</c> work as in <seecref marker="#erl_drv_output_term"> <c>erl_drv_output_term</c></seecref>.</p> - <p>This function is only thread-safe when the emulator with SMP - support is used.</p> + <p>This function is thread-safe.</p> </desc> </func> diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index faaebffbf4..0b88daf2b3 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -496,17 +496,6 @@ int writeiovec(ErlNifEnv *env, ERL_NIF_TERM term, ERL_NIF_TERM *tail, </item> <tag><marker id="dirty_nifs"/>Dirty NIF</tag> <item> - <note> - <p>Dirty NIF support is available only when the emulator is - configured with dirty scheduler support. As of ERTS version - 9.0, dirty scheduler support is enabled by default on the - runtime system with SMP support. The Erlang runtime without - SMP support does <em>not</em> support dirty schedulers even - when the dirty scheduler support is explicitly enabled. To - check at runtime for the presence of dirty scheduler threads, - code can use the <seecref marker="#enif_system_info"> - <c>enif_system_info()</c></seecref> API function.</p> - </note> <p>A NIF that cannot be split and cannot execute in a millisecond or less is called a "dirty NIF", as it performs work that the ordinary schedulers of the Erlang runtime system cannot handle cleanly. @@ -1301,9 +1290,7 @@ typedef struct { <item>already triggered</item> <item>just about to be triggered by a concurrent thread</item> </list> - <p>This function is only thread-safe when the emulator with SMP support - is used. It can only be used in a non-SMP emulator from a NIF-calling - thread.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -1991,9 +1978,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); <fsummary>Determine if a local port is alive.</fsummary> <desc> <p>Returns <c>true</c> if <c>port_id</c> is alive.</p> - <p>This function is only thread-safe when the emulator with SMP support - is used. It can only be used in a non-SMP emulator from a NIF-calling - thread.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -2003,9 +1988,7 @@ enif_inspect_iovec(env, max_elements, term, &tail, &iovec); <fsummary>Determine if a local process is alive.</fsummary> <desc> <p>Returns <c>true</c> if <c>pid</c> is alive.</p> - <p>This function is only thread-safe when the emulator with SMP support - is used. It can only be used in a non-SMP emulator from a NIF-calling - thread.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -2738,9 +2721,7 @@ enif_map_iterator_destroy(env, &iter);</code> provided, and > 0 if the process is no longer alive or if <c>target_pid</c> is <seecref marker="#enif_set_pid_undefined"> undefined</seecref>.</p> - <p>This function is only thread-safe when the emulator with SMP support - is used. It can only be used in a non-SMP emulator from a NIF-calling - thread.</p> + <p>This function is thread-safe.</p> </desc> </func> @@ -3424,9 +3405,7 @@ if (retval & ERL_NIF_SELECT_STOP_CALLED) { <p>If <c>msg_env</c> is set to <c>NULL</c>, the <c>msg</c> term is copied and the original term and its environment is still valid after the call.</p> - <p>This function is only thread-safe when the emulator with SMP support - is used. It can only be used in a non-SMP emulator from a NIF-calling - thread.</p> + <p>This function is thread-safe.</p> <note> <p>Passing <c>msg_env</c> as <c>NULL</c> is only supported as from ERTS 8.0 (Erlang/OTP 19).</p> diff --git a/erts/doc/src/erts_alloc.xml b/erts/doc/src/erts_alloc.xml index 7d8a3ebd5e..cd98123c5c 100644 --- a/erts/doc/src/erts_alloc.xml +++ b/erts/doc/src/erts_alloc.xml @@ -718,9 +718,7 @@ <tag><marker id="M_t"/><c><![CDATA[+M<S>t true|false]]></c></tag> <item> <p>Multiple, thread-specific instances of the allocator. - This option has only effect on the runtime system - with SMP support. Default behavior on the runtime system with - SMP support is <c>NoSchedulers+1</c> instances. Each scheduler + Default behavior is <c>NoSchedulers+1</c> instances. Each scheduler uses a lock-free instance of its own and other threads use a common instance.</p> <p>Before ERTS 5.9 it was possible to configure diff --git a/lib/stdlib/doc/src/ets.xml b/lib/stdlib/doc/src/ets.xml index f66257337b..8f3c5131af 100644 --- a/lib/stdlib/doc/src/ets.xml +++ b/lib/stdlib/doc/src/ets.xml @@ -1308,8 +1308,8 @@ ets:select(Table, MatchSpec),</code> <item> <p>Performance tuning. Defaults to <c>false</c>. When set to <c>true</c>, the table is optimized for concurrent read - operations. When this option is enabled on a runtime system with - SMP support, read operations become much cheaper; especially on + operations. When this option is enabled read operations + become much cheaper; especially on systems with multiple physical processors. However, switching between read and write operations becomes more expensive.</p> <p>You typically want to enable this option when concurrent read diff --git a/system/doc/efficiency_guide/commoncaveats.xml b/system/doc/efficiency_guide/commoncaveats.xml index 35dd23aa9b..a0ed5f5b0d 100644 --- a/system/doc/efficiency_guide/commoncaveats.xml +++ b/system/doc/efficiency_guide/commoncaveats.xml @@ -43,8 +43,7 @@ <seeerl marker="stdlib:timer">timer</seeerl> module in STDLIB. The <c>timer</c> module uses a separate process to manage the timers. That process can easily become overloaded if many processes - create and cancel timers frequently (especially when using the - SMP emulator).</p> + create and cancel timers frequently.</p> <p>The functions in the <c>timer</c> module that do not manage timers (such as <c>timer:tc/3</c> or <c>timer:sleep/1</c>), do not call the diff --git a/system/doc/efficiency_guide/processes.xml b/system/doc/efficiency_guide/processes.xml index 033e7f109e..cef50c19ea 100644 --- a/system/doc/efficiency_guide/processes.xml +++ b/system/doc/efficiency_guide/processes.xml @@ -36,13 +36,11 @@ <p>An Erlang process is lightweight compared to threads and processes in operating systems.</p> - <p>A newly spawned Erlang process uses 309 words of memory - in the non-SMP emulator without HiPE support. (SMP support - and HiPE support both add to this size.) The size can + <p>A newly spawned Erlang process uses 326 words of memory. The size can be found as follows:</p> <pre> -Erlang (BEAM) emulator version 5.6 [async-threads:0] [kernel-poll:false] +Erlang/OTP 24 [erts-12.0] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit] Eshell V5.6 (abort with ^G) 1> <input>Fun = fun() -> receive after infinity -> ok end end.</input> @@ -372,18 +370,14 @@ true <section> <title>SMP Emulator</title> - <p>The SMP emulator (introduced in R11B) takes advantage of a - multi-core or multi-CPU computer by running several Erlang scheduler - threads (typically, the same as the number of cores). Each scheduler - thread schedules Erlang processes in the same way as the Erlang scheduler - in the non-SMP emulator.</p> + <p>The emulator takes advantage of a multi-core or multi-CPU + computer by running several Erlang scheduler + threads (typically, the same as the number of cores).</p> - <p>To gain performance by using the SMP emulator, your application + <p>To gain performance from a multi-core computer, your application <em>must have more than one runnable Erlang process</em> most of the time. Otherwise, the Erlang emulator can still only run one Erlang process - at the time, but you must still pay the overhead for locking. Although - Erlang/OTP tries to reduce the locking overhead as much as possible, - it will never become exactly zero.</p> + at the time.</p> <p>Benchmarks that appear to be concurrent are often sequential. The estone benchmark, for example, is entirely sequential. So is |