From ef302baca81ceaedbfb128fae60a42e53910f061 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Wed, 24 Oct 2012 11:30:42 +0200 Subject: Remove R9 compatibility features --- lib/kernel/test/global_SUITE.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/kernel/test/global_SUITE.erl b/lib/kernel/test/global_SUITE.erl index 60035b50a0..631a544a21 100644 --- a/lib/kernel/test/global_SUITE.erl +++ b/lib/kernel/test/global_SUITE.erl @@ -3855,7 +3855,7 @@ start_node_rel(Name0, Rel, Config) -> Name = node_name(Name0, Config), {Release, Compat} = case Rel of this -> - {[this], "+R8"}; + {[this], ""}; Rel when is_atom(Rel) -> {[{release, atom_to_list(Rel)}], ""}; RelList -> -- cgit v1.2.3 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 --- lib/hipe/cerl/erl_bif_types.erl | 105 ++++++++++++++++++++++------------------ lib/sasl/src/systools_make.erl | 3 +- 2 files changed, 60 insertions(+), 48 deletions(-) (limited to 'lib') diff --git a/lib/hipe/cerl/erl_bif_types.erl b/lib/hipe/cerl/erl_bif_types.erl index 0c2e846010..645ec71c3c 100644 --- a/lib/hipe/cerl/erl_bif_types.erl +++ b/lib/hipe/cerl/erl_bif_types.erl @@ -1153,59 +1153,66 @@ type(erlang, phash2, 2, Xs) -> strict(arg_types(erlang, phash2, 2), Xs, fun (_) -> t_non_neg_integer() end); type(erlang, pid_to_list, 1, Xs) -> strict(arg_types(erlang, pid_to_list, 1), Xs, fun (_) -> t_string() end); -type(erlang, port_call, Arity, Xs) when Arity =:= 2; Arity =:= 3 -> - strict(arg_types(erlang, port_call, Arity), Xs, fun (_) -> t_any() end); -type(erlang, port_close, 1, Xs) -> - strict(arg_types(erlang, port_close, 1), Xs, - fun (_) -> t_atom('true') end); -type(erlang, port_command, 2, Xs) -> - strict(arg_types(erlang, port_command, 2), Xs, - fun (_) -> t_atom('true') end); -type(erlang, port_command, 3, Xs) -> - strict(arg_types(erlang, port_command, 3), Xs, - fun (_) -> t_boolean() end); -type(erlang, port_connect, 2, Xs) -> - strict(arg_types(erlang, port_connect, 2), Xs, - fun (_) -> t_atom('true') end); -type(erlang, port_control, 3, Xs) -> - strict(arg_types(erlang, port_control, 3), Xs, - fun (_) -> t_sup(t_string(), t_binary()) end); -type(erlang, port_get_data, 1, Xs) -> - strict(arg_types(erlang, port_get_data, 1), Xs, fun (_) -> t_any() end); -type(erlang, port_info, 1, Xs) -> - strict(arg_types(erlang, port_info, 1), Xs, - fun (_) -> t_sup(t_atom('undefined'), t_list()) end); -type(erlang, port_info, 2, Xs) -> - strict(arg_types(erlang, port_info, 2), Xs, +type(erts_internal, port_call, 3, Xs) -> + strict(arg_types(erts_internal, port_call, 3), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_reference(), t_tuple(['ok', t_any()])]) end); +type(erts_internal, port_close, 1, Xs) -> + strict(arg_types(erts_internal, port_close, 1), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_atom('true'), t_reference()]) end); +type(erts_internal, port_command, 3, Xs) -> + strict(arg_types(erts_internal, port_command, 3), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_boolean(), t_reference()]) end); +type(erts_internal, port_connect, 2, Xs) -> + strict(arg_types(erts_internal, port_connect, 2), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_atom('true'), t_reference()]) end); +type(erts_internal, port_control, 3, Xs) -> + strict(arg_types(erts_internal, port_control, 3), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_reference(), t_string(), t_binary()]) end); +type(erts_internal, port_get_data, 1, Xs) -> + strict(arg_types(erts_internal, port_get_data, 1), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_reference(), t_tuple(['ok', t_any()])]) end); +type(erts_internal, port_info, 1, Xs) -> + [_, PossibleItems] =arg_types(erts_internal, port_info, 2), + strict(arg_types(erts_internal, port_info, 1), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_atom('undefined'), t_reference(), t_list(t_tuple([PossibleItems, t_any()]))]) end); +type(erts_internal, port_info, 2, Xs) -> + strict(arg_types(erts_internal, port_info, 2), Xs, fun ([_Port, Item]) -> - t_sup(t_atom('undefined'), - case t_atom_vals(Item) of + t_sup([t_atom('undefined'), + t_atom('badarg'), + t_reference(), + case t_atom_vals(Item) of ['connected'] -> t_tuple([Item, t_pid()]); ['id'] -> t_tuple([Item, t_integer()]); ['input'] -> t_tuple([Item, t_integer()]); ['links'] -> t_tuple([Item, t_list(t_pid())]); ['name'] -> t_tuple([Item, t_string()]); ['output'] -> t_tuple([Item, t_integer()]); - ['registered_name'] -> t_tuple([Item, t_atom()]); + ['registered_name'] -> t_sup(t_tuple([Item, t_atom()]), t_nil()); + ['monitors'] -> t_tuple([Item, t_list(t_tuple([t_atom('process'), t_pid()]))]); + ['memory'] -> t_tuple([Item, t_integer()]); + ['queue_size'] -> t_tuple([Item, t_integer()]); + ['locking'] -> t_tuple([Item, t_sup([t_atom('false'), t_atom('port_level'), t_atom('driver_level')])]); + ['parallelism'] -> t_tuple([Item, t_boolean()]); List when is_list(List) -> t_tuple([t_sup([t_atom(A) || A <- List]), t_sup([t_atom(), t_integer(), t_pid(), t_list(t_pid()), t_string()])]); unknown -> - [_, PosItem] = arg_types(erlang, port_info, 2), + [_, PosItem] = arg_types(erts_internal, port_info, 2), t_tuple([PosItem, t_sup([t_atom(), t_integer(), t_pid(), t_list(t_pid()), t_string()])]) - end) + end]) end); type(erlang, port_to_list, 1, Xs) -> strict(arg_types(erlang, port_to_list, 1), Xs, fun (_) -> t_string() end); type(erlang, ports, 0, _) -> t_list(t_port()); -type(erlang, port_set_data, 2, Xs) -> - strict(arg_types(erlang, port_set_data, 2), Xs, - fun (_) -> t_atom('true') end); +type(erts_internal, port_set_data, 2, Xs) -> + strict(arg_types(erts_internal, port_set_data, 2), Xs, + fun (_) -> t_sup([t_atom('badarg'), t_atom('true'), t_reference()]) end); type(erlang, pre_loaded, 0, _) -> t_list(t_atom()); type(erlang, process_display, 2, _) -> t_atom('true'); type(erlang, process_flag, 2, Xs) -> @@ -1638,6 +1645,12 @@ type(erlang, system_info, 1, Xs) -> t_string()); ['otp_release'] -> t_string(); + ['port_parallelism'] -> + t_boolean(); + ['port_count'] -> + t_non_neg_fixnum(); + ['port_limit'] -> + t_non_neg_fixnum(); ['process_count'] -> t_non_neg_fixnum(); ['process_limit'] -> @@ -3757,7 +3770,8 @@ arg_types(erlang, open_port, 2) -> t_tuple([t_atom('cd'), t_string()]), t_tuple([t_atom('env'), t_list(t_tuple(2))]), % XXX: More t_tuple([t_atom('args'), t_list(ArgT)]), - t_tuple([t_atom('arg0'), ArgT])])))]; + t_tuple([t_atom('arg0'), ArgT]), + t_tuple([t_atom('parallelism'), t_boolean()])])))]; arg_types(erlang, phash, 2) -> [t_any(), t_pos_integer()]; arg_types(erlang, phash2, 1) -> @@ -3766,35 +3780,32 @@ arg_types(erlang, phash2, 2) -> [t_any(), t_pos_integer()]; arg_types(erlang, pid_to_list, 1) -> [t_pid()]; -arg_types(erlang, port_call, 2) -> - [t_sup(t_port(), t_atom()), t_any()]; -arg_types(erlang, port_call, 3) -> +arg_types(erts_internal, port_call, 3) -> [t_sup(t_port(), t_atom()), t_integer(), t_any()]; -arg_types(erlang, port_close, 1) -> +arg_types(erts_internal, port_close, 1) -> [t_sup(t_port(), t_atom())]; -arg_types(erlang, port_command, 2) -> - [t_sup(t_port(), t_atom()), t_sup(t_iolist(), t_binary())]; -arg_types(erlang, port_command, 3) -> +arg_types(erts_internal, port_command, 3) -> [t_sup(t_port(), t_atom()), t_sup(t_iolist(), t_binary()), t_list(t_atoms(['force', 'nosuspend']))]; -arg_types(erlang, port_connect, 2) -> +arg_types(erts_internal, port_connect, 2) -> [t_sup(t_port(), t_atom()), t_pid()]; -arg_types(erlang, port_control, 3) -> +arg_types(erts_internal, port_control, 3) -> [t_sup(t_port(), t_atom()), t_integer(), t_sup(t_iolist(), t_binary())]; -arg_types(erlang, port_get_data, 1) -> +arg_types(erts_internal, port_get_data, 1) -> [t_sup(t_port(), t_atom())]; -arg_types(erlang, port_info, 1) -> +arg_types(erts_internal, port_info, 1) -> [t_sup(t_port(), t_atom())]; -arg_types(erlang, port_info, 2) -> +arg_types(erts_internal, port_info, 2) -> [t_sup(t_port(), t_atom()), t_atoms(['registered_name', 'id', 'connected', - 'links', 'name', 'input', 'output'])]; + 'links', 'name', 'input', 'output', + 'monitors', 'memory', 'queue_size', 'locking', 'parallelism'])]; arg_types(erlang, port_to_list, 1) -> [t_port()]; arg_types(erlang, ports, 0) -> []; -arg_types(erlang, port_set_data, 2) -> +arg_types(erts_internal, port_set_data, 2) -> [t_sup(t_port(), t_atom()), t_any()]; arg_types(erlang, pre_loaded, 0) -> []; diff --git a/lib/sasl/src/systools_make.erl b/lib/sasl/src/systools_make.erl index 61e660e918..806f597675 100644 --- a/lib/sasl/src/systools_make.erl +++ b/lib/sasl/src/systools_make.erl @@ -1497,7 +1497,8 @@ mandatory_modules() -> preloaded() -> %% Sorted - [erl_prim_loader,erlang,init,otp_ring0,prim_file,prim_inet, prim_zip,zlib]. + [erl_prim_loader,erlang,erts_internal,init,otp_ring0,prim_file,prim_inet, + prim_zip,zlib]. %%______________________________________________________________________ %% Kernel processes; processes that are specially treated by the init -- cgit v1.2.3 From 9e4895da833b7777e69efc173f5dc777aaea3201 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Thu, 29 Nov 2012 01:24:43 +0100 Subject: Add support for busy port message queue --- lib/kernel/doc/src/inet.xml | 64 +++++++++++++++++++++++++++++++++++++++++++++ lib/kernel/src/gen_tcp.erl | 4 +++ lib/kernel/src/inet.erl | 11 +++++--- lib/kernel/src/inet_int.hrl | 2 ++ 4 files changed, 77 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/kernel/doc/src/inet.xml b/lib/kernel/doc/src/inet.xml index bf6c4cfb1a..bfdb163e17 100644 --- a/lib/kernel/doc/src/inet.xml +++ b/lib/kernel/doc/src/inet.xml @@ -487,6 +487,36 @@ fe80::204:acff:fe17:bf38 example Size == 2, the data received will match [Byte1,Byte2|Binary].

+ {high_msgq_watermark, Size} (TCP/IP sockets) + +

The socket message queue will be set into a busy + state when the amount of data queued on the message + queue reaches this limit. Note that this limit only + concerns data that have not yet reached the ERTS internal + socket implementation. Default value used is 8 kB.

+

Senders of data to the socket will be suspended if + either the socket message queue is busy, or the socket + itself is busy.

+

For more information see the low_msgq_watermark, + high_watermark, and low_watermark options.

+

Note that distribution sockets will disable the use of + high_msgq_watermark and low_msgq_watermark, + and will instead use the + distribution + buffer busy limit which is a similar feature.

+
+ {high_watermark, Size} (TCP/IP sockets) + +

The socket will be set into a busy state when the amount + of data queued internally by the ERTS socket implementation + reaches this limit. Default value used is 8 kB.

+

Senders of data to the socket will be suspended if + either the socket message queue is busy, or the socket + itself is busy.

+

For more information see the low_watermark, + high_msgq_watermark, and low_msqg_watermark + options.

+
{keepalive, Boolean}(TCP/IP sockets)

Enables/disables periodic transmission on a connected @@ -495,6 +525,40 @@ fe80::204:acff:fe17:bf38 considered broken and an error message will be sent to the controlling process. Default disabled.

+ {low_msgq_watermark, Size} (TCP/IP sockets) + +

If the socket message queue is in a busy state, the + socket message queue will be set in a not busy state when + the amount of data queued in the message queue falls + below this limit. Note that this limit only concerns data + that have not yet reached the ERTS internal socket + implementation. Default value used is 4 kB.

+

Senders that have been suspended due to either a + busy message queue or a busy socket, will be resumed + when neither the socket message queue, nor the socket + are busy.

+

For more information see the high_msgq_watermark, + high_watermark, and low_watermark options.

+

Note that distribution sockets will disable the use of + high_msgq_watermark and low_msgq_watermark, + and will instead use the + distribution + buffer busy limit which is a similar feature.

+
+ {low_watermark, Size} (TCP/IP sockets) + +

If the socket is in a busy state, the socket will + be set in a not busy state when the amount of data + queued internally by the ERTS socket implementation + falls below this limit. Default value used is 4 kB.

+

Senders that have been suspended due to either a + busy message queue or a busy socket, will be resumed + when neither the socket message queue, nor the socket + are busy.

+

For more information see the high_watermark, + high_msgq_watermark, and low_msgq_watermark + options.

+
{nodelay, Boolean}(TCP/IP sockets)

If Boolean == true, the TCP_NODELAY option diff --git a/lib/kernel/src/gen_tcp.erl b/lib/kernel/src/gen_tcp.erl index ef6bfdf7f4..519c1bb8b4 100644 --- a/lib/kernel/src/gen_tcp.erl +++ b/lib/kernel/src/gen_tcp.erl @@ -38,9 +38,11 @@ {dontroute, boolean()} | {exit_on_close, boolean()} | {header, non_neg_integer()} | + {high_msgq_watermark, pos_integer()} | {high_watermark, non_neg_integer()} | {keepalive, boolean()} | {linger, {boolean(), non_neg_integer()}} | + {low_msgq_watermark, pos_integer()} | {low_watermark, non_neg_integer()} | {mode, list | binary} | list | binary | {nodelay, boolean()} | @@ -68,9 +70,11 @@ dontroute | exit_on_close | header | + high_msgq_watermark | high_watermark | keepalive | linger | + low_msgq_watermark | low_watermark | mode | nodelay | diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl index abaf4486dc..e791bb135f 100644 --- a/lib/kernel/src/inet.erl +++ b/lib/kernel/src/inet.erl @@ -535,6 +535,7 @@ options() -> buffer, header, active, packet, deliver, mode, multicast_if, multicast_ttl, multicast_loop, exit_on_close, high_watermark, low_watermark, + high_msgq_watermark, low_msgq_watermark, bit8, send_timeout, send_timeout_close ]. @@ -552,8 +553,9 @@ stats() -> connect_options() -> [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay, header, active, packet, packet_size, buffer, mode, deliver, - exit_on_close, high_watermark, low_watermark, bit8, send_timeout, - send_timeout_close, delay_send,raw]. + exit_on_close, high_watermark, low_watermark, high_msgq_watermark, + low_msgq_watermark, bit8, send_timeout, send_timeout_close, + delay_send,raw]. connect_options(Opts, Family) -> BaseOpts = @@ -608,8 +610,9 @@ con_add(Name, Val, R, Opts, AllOpts) -> listen_options() -> [tos, priority, reuseaddr, keepalive, linger, sndbuf, recbuf, nodelay, header, active, packet, buffer, mode, deliver, backlog, - exit_on_close, high_watermark, low_watermark, bit8, send_timeout, - send_timeout_close, delay_send, packet_size,raw]. + exit_on_close, high_watermark, low_watermark, high_msgq_watermark, + low_msgq_watermark, bit8, send_timeout, send_timeout_close, + delay_send, packet_size,raw]. listen_options(Opts, Family) -> BaseOpts = diff --git a/lib/kernel/src/inet_int.hrl b/lib/kernel/src/inet_int.hrl index cf893c73eb..2dfbf75d25 100644 --- a/lib/kernel/src/inet_int.hrl +++ b/lib/kernel/src/inet_int.hrl @@ -141,6 +141,8 @@ -define(INET_LOPT_READ_PACKETS, 33). -define(INET_OPT_RAW, 34). -define(INET_LOPT_TCP_SEND_TIMEOUT_CLOSE, 35). +-define(INET_LOPT_TCP_MSGQ_HIWTRMRK, 36). +-define(INET_LOPT_TCP_MSGQ_LOWTRMRK, 37). % Specific SCTP options: separate range: -define(SCTP_OPT_RTOINFO, 100). -define(SCTP_OPT_ASSOCINFO, 101). -- cgit v1.2.3