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/src') 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