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