From 6e01408aba71e26884c5db81b8e4fa89bd803576 Mon Sep 17 00:00:00 2001
From: Rickard Green
Date: Fri, 21 Sep 2012 15:12:07 +0200
Subject: Implement true asynchronous signaling between processes and ports
---
erts/doc/src/erl.xml | 60 +++++++++++++++----
erts/doc/src/erlang.xml | 152 +++++++++++++++++++++++++++++++++++-------------
2 files changed, 158 insertions(+), 54 deletions(-)
(limited to 'erts/doc')
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index f7d8d37fd3..85c6140b01 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -586,18 +586,38 @@
erts_alloc(3) for
further information.
- -
-
Enable synchronous message passing to ports.
- As of OTP-R16 message passing to ports are truly asynchronously
- implemented. Correctly written Erlang programs should be able
- to handle this without any issues. Bugs in existing Erlang
- programs that make false assumptions about message passing to
- ports may, however, be tricky to find. This switch has been
- introduced in order to at least make it easier to compare
- behaviors during a transition period. Note that this flag is
- deprecated as of its introduction, and is scheduled for removal
- in OTP-R17.
+
+ -
+
Control behavior of signals to ports.
+ As of OTP-R16 signals to ports are truly asynchronously
+ delivered. Note that signals always have been documented as
+ asynchronous. The underlying implementation has, however,
+ previously delivered these signals synchronously. Correctly
+ written Erlang programs should be able to handle this without
+ any issues. Bugs in existing Erlang programs that make false
+ assumptions about signals to ports may, however, be tricky to
+ find. This switch has been introduced in order to at least
+ make it easier to compare behaviors during a transition period.
+ Note that this flag is deprecated as of its
+ introduction, and is scheduled for removal in OTP-R17.
+ Behavior should be one of the following characters:
+
+ d
+ - The default. Asynchronous signals. A process that sends
+ a signal to a port may continue execution before the signal
+ has been delivered to the port.
+ s
+ - Synchronous signals. A processes that sends a signal
+ to a port will not continue execution until the signal has
+ been delivered. Should only be used for testing and
+ debugging.
+ a
+ - Asynchronous signals. As the default, but a processes
+ that sends a signal will even more frequently continue
+ execution before the signal has been delivered to the
+ port. Should only be used for testing and
+ debugging.
+
-
@@ -948,6 +968,22 @@
without prior notice.
+ +spp Bool
+ -
+
Set default scheduler hint for port parallelism. If set to
+ true, the VM will schedule port tasks when it by this can
+ improve the parallelism in the system. If set to false,
+ the VM will try to perform port tasks immediately and by this
+ improve latency at the expense of parallelism. If this
+ flag has not been passed, the default scheduler hint for port
+ parallelism is currently false. The default used can be
+ inspected in runtime by calling
+ erlang:system_info(port_parallelism).
+ The default can be overriden on port creation by passing the
+ parallelism
+ option to
+ open_port/2
.
+
-
Suggested stack size, in kilowords, for scheduler threads.
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index 2da456d49f..57346d3935 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -1000,14 +1000,14 @@ b
exit(Pid, Reason) -> true
- Send an exit signal to a process
+ Send an exit signal to a process or port
- Pid = pid()
+ Pid = pid() | port()
Reason = term()
Sends an exit signal with exit reason Reason to
- the process Pid.
+ the process or port identified by Pid.
The following behavior apply if Reason is any term
except normal or kill:
If Pid is not trapping exits, Pid itself will
@@ -2875,7 +2875,7 @@ os_prompt%
FileNameChar = integer() (1..255 or any Unicode codepoint, see description)
In = Out = integer()
PortSettings = [Opt]
- Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof
+ Opt = {packet, N} | stream | {line, L} | {cd, Dir} | {env, Env} | {args, [ ArgString ]} | {arg0, ArgString} | exit_status | use_stdio | nouse_stdio | stderr_to_stdout | in | out | binary | eof | {parallelism, true|false}
N = 1 | 2 | 4
L = integer()
Dir = string()
@@ -3173,6 +3173,18 @@ os_prompt%
console window when spawning the port program.
(This option has no effect on other platforms.)
+ {parallelism, Boolean}
+ -
+
Set scheduler hint for port parallelism. If set to true,
+ the VM will schedule port tasks when it by this can improve the
+ parallelism in the system. If set to false, the VM will
+ try to perform port tasks immediately and by this improving the
+ latency at the expense of parallelism. The default can be set on
+ system startup by passing the
+ +spp command line argument
+ to erl(1).
+
+
The default is stream for all types of port and
use_stdio for spawned ports.
@@ -3299,10 +3311,10 @@ os_prompt%
Closes an open port. Roughly the same as
Port ! {self(), close} except for the error behaviour
- (see below), and that the port does not reply with
- {Port, closed}. Any process may close a port with
- port_close/1, not only the port owner (the connected
- process).
+ (see below), being synchronous, and that the port does
+ not reply with {Port, closed}. Any process may
+ close a port with port_close/1, not only the port owner
+ (the connected process).
For comparison: Port ! {self(), close} fails with
badarg if Port cannot be sent to (i.e.,
Port refers neither to a port nor to a process). If
@@ -3314,8 +3326,12 @@ os_prompt%
Note that any process can close a port using
Port ! {PortOwner, close} just as if it itself was
the port owner, but the reply always goes to the port owner.
- In short: port_close(Port) has a cleaner and more
- logical behaviour than Port ! {self(), close}.
+ As of OTP-R16 Port ! {PortOwner, close} is truly
+ asynchronous. Note that this operation has always been
+ documented as an asynchronous operation, while the underlying
+ implementation has been synchronous. port_close/1 is
+ however still fully synchronous. This due to its error
+ behavior.
Failure: badarg if Port is not an open port or
the registered name of an open port.
@@ -3329,11 +3345,11 @@ os_prompt%
Sends data to a port. Same as
- Port ! {self(), {command, Data}} except for the error
- behaviour (see below). Any process may send data to a port
- with port_command/2, not only the port owner
- (the connected process).
- For comparison: Port ! {self(), {command, Data}}
+ Port ! {PortOwner, {command, Data}} except for the error
+ behaviour and being synchronous (see below). Any process may
+ send data to a port with port_command/2, not only the
+ port owner (the connected process).
+ For comparison: Port ! {PortOwner, {command, Data}}
fails with badarg if Port cannot be sent to
(i.e., Port refers neither to a port nor to a process).
If Port is a closed port the data message disappears
@@ -3344,11 +3360,14 @@ os_prompt%
Note that any process can send to a port using
Port ! {PortOwner, {command, Data}} just as if it
itself was the port owner.
- In short: port_command(Port, Data) has a cleaner and
- more logical behaviour than
- Port ! {self(), {command, Data}}.
If the port is busy, the calling process will be suspended
until the port is not busy anymore.
+ As of OTP-R16 Port ! {PortOwner, {command, Data}} is
+ truly asynchronous. Note that this operation has always been
+ documented as an asynchronous operation, while the underlying
+ implementation has been synchronous. port_command/2 is
+ however still fully synchronous. This due to its error
+ behavior.
Failures:
badarg
@@ -3433,7 +3452,7 @@ os_prompt%
Sets the port owner (the connected port) to Pid.
- Roughly the same as Port ! {self(), {connect, Pid}}
+ Roughly the same as Port ! {Owner, {connect, Pid}}
except for the following:
-
@@ -3443,6 +3462,9 @@ os_prompt%
The port does not reply with
{Port,connected}.
+ -
+
port_connect/1 is synchronous, see below.
+
-
The new port owner gets linked to the port.
@@ -3467,9 +3489,12 @@ os_prompt%
Port ! {PortOwner, {connect, Pid}} just as if it
itself was the port owner, but the reply always goes to
the port owner.
- In short: port_connect(Port, Pid) has a cleaner and
- more logical behaviour than
- Port ! {self(),{connect,Pid}}.
+ As of OTP-R16 Port ! {PortOwner, {connect, Pid}} is
+ truly asynchronous. Note that this operation has always been
+ documented as an asynchronous operation, while the underlying
+ implementation has been synchronous. port_connect/2 is
+ however still fully synchronous. This due to its error
+ behavior.
Failure: badarg if Port is not an open port
or the registered name of an open port, or if Pid is
not an existing local pid.
@@ -3538,12 +3563,35 @@ os_prompt%
the Port, or undefined if the port is not open.
The order of the tuples is not defined, nor are all the
tuples mandatory.
+ Currently the result will containt information about the
+ following Items: registered_name (if the port has
+ a registed name), id, connected, links,
+ name, input, and output. For more information
+ about the different Items, see
+ port_info/2.
+ Failure: badarg if Port is not a local port.
+
+
+
+ erlang:port_info(Port, Item) -> {Item, Info} | undefined | []
+ Information about a port
+
+ Port = port() | atom()
+ Item, Info -- see below
+
+
+ Returns information about Port as specified
+ by Item, or undefined if the port is not open.
+ Also, if Item == registered_name and the port has no
+ registered name, [] is returned.
+ Valid values of Item, and corresponding {Item, Info}
+ tuples:
{registered_name, RegName}
-
RegName (an atom) is the registered name of
- the port. If the port has no registered name, this tuple
- is not present in the list.
+ the port. If the port has no registered name, []
+ is returned.
{id, Index}
-
@@ -3574,28 +3622,43 @@ os_prompt%
Bytes is the total number of bytes written to
the port.
+ {monitors, Monitors}
+ -
+
Monitors represent processes that this port
+ is monitoring. Note that the type of Monitors is
+ likey to change in the future.
+
+ {parallelism, Boolean}
+ -
+
Boolean corresponds to the port parallelism
+ hint being used by this port. For more information see
+ the parallelism
+ option of open_port/2.
+
+ {memory, MemSz}
+ -
+
MemSz is the total amount of memory, in bytes,
+ allocated for this port by the runtime system. Note that
+ the port itself might have allocated memory which is not
+ included in MemSz.
+
+ {queue_size, QSz}
+ -
+
QSz is the total amount of data, in bytes, queued
+ by the port using the ERTS driver queue implementation.
+
+ {locking, Locking}
+ -
+
Locking is currently either false (emulator
+ without SMP support), port_level (port specific locking),
+ or driver_level (driver specific locking). Note that
+ these results are highly implementation specific and might
+ change in the future.
+
Failure: badarg if Port is not a local port.
-
- erlang:port_info(Port, Item) -> {Item, Info} | undefined | []
- Information about a port
-
- Port = port() | atom()
- Item, Info -- see below
-
-
- Returns information about Port as specified
- by Item, or undefined if the port is not open.
- Also, if Item == registered_name and the port has no
- registered name, [] is returned.
- For valid values of Item, and corresponding
- values of Info, see
- erlang:port_info/1.
- Failure: badarg if Port is not a local port.
-
-
erlang:port_to_list(Port) -> string()
Text representation of a port identifier
@@ -5954,6 +6017,11 @@ ok
-
Returns a string containing the OTP release number.
+ port_parallelism
+ Returns the default port parallelism scheduling hint used.
+ For more information see the
+ +spp command line argument
+ of erl(1).
process_count
-
Returns the number of ports currently existing at
--
cgit v1.2.3