diff options
31 files changed, 564 insertions, 256 deletions
diff --git a/Makefile.in b/Makefile.in index 107bf80bb5..7596a82720 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 1998-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 1998-2010. All Rights Reserved. +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # Toplevel makefile for building the Erlang system @@ -441,6 +441,8 @@ fourth_bootstrap_copy: if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx ; fi if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/ebin ; fi if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/wx/include ; fi + if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server ; fi + if test ! -d $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; then mkdir $(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include ; fi for x in lib/ic/ebin/*.beam; do \ BN=`basename $$x`; \ TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/ic/ebin/$$BN; \ @@ -506,6 +508,16 @@ fourth_bootstrap_copy: cp $$x $$TF; \ true; \ done + for x in lib/test_server/include/*.hrl; do \ + BN=`basename $$x`; \ + TF=$(BOOTSTRAP_ROOT)/bootstrap/lib/test_server/include/$$BN; \ + test -f $$TF && \ + test '!' -z "`find $$x -newer $$TF -print`" && \ + cp $$x $$TF; \ + test '!' -f $$TF && \ + cp $$x $$TF; \ + true; \ + done # cp lib/syntax_tools/ebin/*.beam $(BOOTSTRAP_ROOT)/bootstrap/lib/syntax_tools/ebin diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index 90a3c53a37..6f5dd248ce 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -4,7 +4,7 @@ <comref> <header> <copyright> - <year>1996</year><year>2009</year> + <year>1996</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + </legalnotice> <title>erl</title> @@ -527,11 +527,16 @@ <p>Calling <c>erlang:halt/1</c> with a string argument will still produce a crash dump.</p> </item> - <tag><c><![CDATA[+h Size]]></c></tag> + <tag><c><![CDATA[+hms Size]]></c></tag> <item> <p>Sets the default heap size of processes to the size <c><![CDATA[Size]]></c>.</p> </item> + <tag><c><![CDATA[+hmbs Size]]></c></tag> + <item> + <p>Sets the default binary virtual heap size of processes to the size + <c><![CDATA[Size]]></c>.</p> + </item> <tag><c><![CDATA[+K true | false]]></c></tag> <item> <p>Enables or disables the kernel poll functionality if diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml index 4a401156d1..28b040a441 100644 --- a/erts/doc/src/erlang.xml +++ b/erts/doc/src/erlang.xml @@ -3469,6 +3469,11 @@ os_prompt%</pre> <p>This changes the minimum heap size for the calling process.</p> </item> + <tag><c>process_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag> + <item> + <p>This changes the minimum binary virtual heap size for the calling + process.</p> + </item> <tag><c>process_flag(priority, Level)</c></tag> <item> <marker id="process_flag_priority"></marker> @@ -3800,6 +3805,14 @@ os_prompt%</pre> <p><c>MessageQueue</c> is a list of the messages to the process, which have not yet been processed.</p> </item> + <tag><c>{min_heap_size, MinHeapSize}</c></tag> + <item> + <p><c>MinHeapSize</c> is the minimum heap size for the process.</p> + </item> + <tag><c>{min_bin_vheap_size, MinBinVHeapSize}</c></tag> + <item> + <p><c>MinBinVHeapSize</c> is the minimum binary virtual heap size for the process.</p> + </item> <tag><c>{monitored_by, Pids}</c></tag> <item> <p>A list of pids that are monitoring the process (with @@ -4533,10 +4546,11 @@ true</pre> <fsummary>Create a new process with a fun as entry point</fsummary> <type> <v>Fun = fun()</v> - <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v> + <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v> <v> Level = low | normal | high</v> <v> Number = int()</v> <v> Size = int()</v> + <v> VSize = int()</v> </type> <desc> <p>Returns the pid of a new process started by the application @@ -4554,10 +4568,11 @@ true</pre> <type> <v>Node = node()</v> <v>Fun = fun()</v> - <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v> + <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v> <v> Level = low | normal | high</v> <v> Number = int()</v> <v> Size = int()</v> + <v> VSize = int()</v> </type> <desc> <p>Returns the pid of a new process started by the application @@ -4573,10 +4588,11 @@ true</pre> <type> <v>Module = Function = atom()</v> <v>Args = [term()]</v> - <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v> + <v>Option = link | monitor | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v> <v> Level = low | normal | high</v> <v> Number = int()</v> <v> Size = int()</v> + <v> VSize = int()</v> </type> <desc> <p>Works exactly like @@ -4656,6 +4672,23 @@ true</pre> fine-tuning an application and to measure the execution time with various <c>Size</c> values.</p> </item> + <tag><c>{min_bin_vheap_size, VSize}</c></tag> + <item> + <p>This option is only useful for performance tuning. + In general, you should not use this option unless you + know that there is problem with execution times and/or + memory consumption, and you should measure to make sure + that the option improved matters. + </p> + <p>Gives a minimum binary virtual heap size in words. Setting this value + higher than the system default might speed up some + processes because less garbage collection is done. + Setting too high value, however, might waste memory. + Therefore, it is recommended to use this option only for + fine-tuning an application and to measure the execution + time with various <c>VSize</c> values.</p> + </item> + </taglist> </desc> </func> @@ -4666,10 +4699,11 @@ true</pre> <v>Node = node()</v> <v>Module = Function = atom()</v> <v>Args = [term()]</v> - <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size}</v> + <v>Option = link | {priority, Level} | {fullsweep_after, Number} | {min_heap_size, Size} | {min_bin_vheap_size, VSize}</v> <v> Level = low | normal | high</v> <v> Number = int()</v> <v> Size = int()</v> + <v> VSize = int()</v> </type> <desc> <p>Returns the pid of a new process started by the application @@ -5002,6 +5036,17 @@ true</pre> <seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or <seealso marker="#process_flag/2">process_flag/2</seealso>. </p> </item> + <tag><c>erlang:system_flag(min_bin_vheap_size, MinBinVHeapSize)</c></tag> + <item> + <p>Sets the default minimum binary virtual heap size for processes. The + size is given in words. The new <c>min_bin_vhheap_size</c> only + effects processes spawned after the change of + <c>min_bin_vhheap_size</c> has been made. + The <c>min_bin_vheap_size</c> can be set for individual + processes by use of + <seealso marker="#spawn_opt/4">spawn_opt/N</seealso> or + <seealso marker="#process_flag/2">process_flag/2</seealso>. </p> + </item> <tag><c>erlang:system_flag(multi_scheduling, BlockState)</c></tag> <item> <marker id="system_flag_multi_scheduling"></marker> @@ -5613,6 +5658,16 @@ true</pre> <item> <p>Returns a string containing the Erlang machine name.</p> </item> + <tag><c>min_heap_size</c></tag> + <item> + <p>Returns <c>{min_heap_size, MinHeapSize}</c> where <c>MinHeapSize</c> is the current system wide + minimum heap size for spawned processes.</p> + </item> + <tag><c>min_bin_vheap_size</c></tag> + <item> + <p>Returns <c>{min_bin_vheap_size, MinBinVHeapSize}</c> where <c>MinBinVHeapSize</c> is the current system wide + minimum binary virtual heap size for spawned processes.</p> + </item> <tag><c>modified_timing_level</c></tag> <item> <p>Returns the modified timing level (an integer) if @@ -6449,6 +6504,19 @@ true</pre> <tag><c>mbuf_size</c></tag> <item>The combined size of message buffers associated with the process.</item> + + <tag><c>bin_vheap_size</c></tag> + <item>The total size of unique off-heap binaries referenced from the process heap.</item> + <tag><c>bin_vheap_block_size</c></tag> + <item>The total size of binaries, in words, allowed in the virtual + heap in the process before doing a garbage collection. </item> + <tag><c>bin_old_vheap_size</c></tag> + <item>The total size of unique off-heap binaries referenced from the process old heap.</item> + <tag><c>bin_vheap_block_size</c></tag> + <item>The total size of binaries, in words, allowed in the virtual + old heap in the process before doing a garbage collection. </item> + + </taglist> <p>All sizes are in words.</p> </item> diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names index 3ce26c4a7a..57c8b08223 100644 --- a/erts/emulator/beam/atom.names +++ b/erts/emulator/beam/atom.names @@ -303,6 +303,7 @@ atom messages atom meta atom meta_match_spec atom min_heap_size +atom min_bin_vheap_size atom minor_version atom Minus='-' atom module diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c index 74b231d56d..9c8c0df9f0 100644 --- a/erts/emulator/beam/bif.c +++ b/erts/emulator/beam/bif.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1996-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -807,11 +807,12 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1) /* * Store default values for options. */ - so.flags = SPO_USE_ARGS; - so.min_heap_size = H_MIN_SIZE; - so.priority = PRIORITY_NORMAL; - so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs); - so.scheduler = 0; + so.flags = SPO_USE_ARGS; + so.min_heap_size = H_MIN_SIZE; + so.min_vheap_size = BIN_VH_MIN_SIZE; + so.priority = PRIORITY_NORMAL; + so.max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs); + so.scheduler = 0; /* * Walk through the option list. @@ -850,6 +851,15 @@ BIF_RETTYPE spawn_opt_1(BIF_ALIST_1) } else { so.min_heap_size = erts_next_heap_size(min_heap_size, 0); } + } else if (arg == am_min_bin_vheap_size && is_small(val)) { + Sint min_vheap_size = signed_val(val); + if (min_vheap_size < 0) { + goto error; + } else if (min_vheap_size < BIN_VH_MIN_SIZE) { + so.min_vheap_size = BIN_VH_MIN_SIZE; + } else { + so.min_vheap_size = erts_next_heap_size(min_vheap_size, 0); + } } else if (arg == am_fullsweep_after && is_small(val)) { Sint max_gen_gcs = signed_val(val); if (max_gen_gcs < 0) { @@ -1485,6 +1495,23 @@ BIF_RETTYPE process_flag_2(BIF_ALIST_2) } BIF_RET(old_value); } + else if (BIF_ARG_1 == am_min_bin_vheap_size) { + Sint i; + if (!is_small(BIF_ARG_2)) { + goto error; + } + i = signed_val(BIF_ARG_2); + if (i < 0) { + goto error; + } + old_value = make_small(BIF_P->min_vheap_size); + if (i < BIN_VH_MIN_SIZE) { + BIF_P->min_vheap_size = BIN_VH_MIN_SIZE; + } else { + BIF_P->min_vheap_size = erts_next_heap_size(i, 0); + } + BIF_RET(old_value); + } else if (BIF_ARG_1 == am_sensitive) { Uint is_sensitive; if (BIF_ARG_2 == am_true) { @@ -3736,10 +3763,35 @@ BIF_RETTYPE system_flag_2(BIF_ALIST_2) BIF_RET(make_small(oval)); } else if (BIF_ARG_1 == am_min_heap_size) { int oval = H_MIN_SIZE; + if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) { goto error; } + + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_block_system(0); + H_MIN_SIZE = erts_next_heap_size(n, 0); + + erts_smp_release_system(); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + + BIF_RET(make_small(oval)); + } else if (BIF_ARG_1 == am_min_bin_vheap_size) { + int oval = BIN_VH_MIN_SIZE; + + if (!is_small(BIF_ARG_2) || (n = signed_val(BIF_ARG_2)) < 0) { + goto error; + } + + erts_smp_proc_unlock(BIF_P, ERTS_PROC_LOCK_MAIN); + erts_smp_block_system(0); + + BIN_VH_MIN_SIZE = erts_next_heap_size(n, 0); + + erts_smp_release_system(); + erts_smp_proc_lock(BIF_P, ERTS_PROC_LOCK_MAIN); + BIF_RET(make_small(oval)); } else if (BIF_ARG_1 == am_display_items) { int oval = display_items; diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c index 9e15f4e399..440b0b4f14 100644 --- a/erts/emulator/beam/erl_bif_guard.c +++ b/erts/emulator/beam/erl_bif_guard.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 2006-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 2006-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c index b2f81b6861..5ff1f794df 100644 --- a/erts/emulator/beam/erl_bif_info.c +++ b/erts/emulator/beam/erl_bif_info.c @@ -543,6 +543,8 @@ static Eterm pi_args[] = { am_last_calls, am_total_heap_size, am_suspending, + am_min_heap_size, + am_min_bin_vheap_size, #ifdef HYBRID am_message_binary #endif @@ -589,8 +591,10 @@ pi_arg2ix(Eterm arg) case am_last_calls: return 24; case am_total_heap_size: return 25; case am_suspending: return 26; + case am_min_heap_size: return 27; + case am_min_bin_vheap_size: return 28; #ifdef HYBRID - case am_message_binary: return 27; + case am_message_binary: return 29; #endif default: return -1; } @@ -1355,6 +1359,30 @@ process_info_aux(Process *BIF_P, break; } + case am_fullsweep_after: { + Uint hsz = 3; + (void) erts_bld_uint(NULL, &hsz, MAX_GEN_GCS(rp)); + hp = HAlloc(BIF_P, hsz); + res = erts_bld_uint(&hp, NULL, MAX_GEN_GCS(rp)); + break; + } + + case am_min_heap_size: { + Uint hsz = 3; + (void) erts_bld_uint(NULL, &hsz, MIN_HEAP_SIZE(rp)); + hp = HAlloc(BIF_P, hsz); + res = erts_bld_uint(&hp, NULL, MIN_HEAP_SIZE(rp)); + break; + } + + case am_min_bin_vheap_size: { + Uint hsz = 3; + (void) erts_bld_uint(NULL, &hsz, MIN_VHEAP_SIZE(rp)); + hp = HAlloc(BIF_P, hsz); + res = erts_bld_uint(&hp, NULL, MIN_VHEAP_SIZE(rp)); + break; + } + case am_total_heap_size: { ErlMessage *mp; Uint total_heap_size; @@ -1433,15 +1461,17 @@ process_info_aux(Process *BIF_P, DECL_AM(minor_gcs); Eterm t; - hp = HAlloc(BIF_P, 3+2+3+2+3); - t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp))); - hp += 3; - res = CONS(hp, t, NIL); - hp += 2; - t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp))); - hp += 3; - res = CONS(hp, t, res); - hp += 2; + hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2 + 3+2 + 3); /* last "3" is for outside tuple */ + + t = TUPLE2(hp, AM_minor_gcs, make_small(GEN_GCS(rp))); hp += 3; + res = CONS(hp, t, NIL); hp += 2; + t = TUPLE2(hp, am_fullsweep_after, make_small(MAX_GEN_GCS(rp))); hp += 3; + res = CONS(hp, t, res); hp += 2; + + t = TUPLE2(hp, am_min_heap_size, make_small(MIN_HEAP_SIZE(rp))); hp += 3; + res = CONS(hp, t, res); hp += 2; + t = TUPLE2(hp, am_min_bin_vheap_size, make_small(MIN_VHEAP_SIZE(rp))); hp += 3; + res = CONS(hp, t, res); hp += 2; break; } @@ -1897,16 +1927,32 @@ BIF_RETTYPE system_info_1(BIF_ALIST_1) BIF_RET(res); } else if (BIF_ARG_1 == am_garbage_collection){ Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs); - hp = HAlloc(BIF_P, 3+2); - res = TUPLE2(hp, am_fullsweep_after, make_small(val)); - hp += 3; - res = CONS(hp, res, NIL); + Eterm tup; + hp = HAlloc(BIF_P, 3+2 + 3+2 + 3+2); + + tup = TUPLE2(hp, am_fullsweep_after, make_small(val)); hp += 3; + res = CONS(hp, tup, NIL); hp += 2; + + tup = TUPLE2(hp, am_min_heap_size, make_small(H_MIN_SIZE)); hp += 3; + res = CONS(hp, tup, res); hp += 2; + + tup = TUPLE2(hp, am_min_bin_vheap_size, make_small(BIN_VH_MIN_SIZE)); hp += 3; + res = CONS(hp, tup, res); hp += 2; + BIF_RET(res); } else if (BIF_ARG_1 == am_fullsweep_after){ Uint val = (Uint) erts_smp_atomic_read(&erts_max_gen_gcs); hp = HAlloc(BIF_P, 3); res = TUPLE2(hp, am_fullsweep_after, make_small(val)); BIF_RET(res); + } else if (BIF_ARG_1 == am_min_heap_size) { + hp = HAlloc(BIF_P, 3); + res = TUPLE2(hp, am_min_heap_size,make_small(H_MIN_SIZE)); + BIF_RET(res); + } else if (BIF_ARG_1 == am_min_bin_vheap_size) { + hp = HAlloc(BIF_P, 3); + res = TUPLE2(hp, am_min_bin_vheap_size,make_small(BIN_VH_MIN_SIZE)); + BIF_RET(res); } else if (BIF_ARG_1 == am_process_count) { BIF_RET(make_small(erts_process_count())); } else if (BIF_ARG_1 == am_process_limit) { diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 363f956b58..e9bf37a173 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -2031,23 +2031,45 @@ shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj) } static Uint -next_vheap_size(Uint vheap, Uint vheap_sz) { - if (vheap < H_MIN_SIZE) { - return H_MIN_SIZE; - } +do_next_vheap_size(Uint vheap, Uint vheap_sz) { + + /* grow + * + * vheap_sz ====================== + * + * vheap 75% + grow + * ---------------------- + * + * vheap 25 - 75% same + * ---------------------- + * + * vheap ~ - 25% shrink + * + * ---------------------- + */ - /* grow */ - if (vheap > vheap_sz) { - return erts_next_heap_size(2*vheap, 0); + if (vheap > (Uint) (vheap_sz*3/4)) { + + while(vheap > (Uint) (vheap_sz*3/4)) { + vheap_sz = vheap_sz*2; + } + + return erts_next_heap_size(vheap_sz, 0); } - /* shrink */ - if ( vheap < vheap_sz/2) { - return (Uint)vheap_sz*3/4; + + if (vheap < (Uint) (vheap_sz/4)) { + return erts_next_heap_size((Uint) (vheap_sz / 2), 0); } return vheap_sz; + } +static Uint +next_vheap_size(Process* p, Uint vheap, Uint vheap_sz) { + vheap_sz = do_next_vheap_size(vheap, vheap_sz); + return vheap_sz < p->min_vheap_size ? p->min_vheap_size : vheap_sz; +} static void sweep_proc_externals(Process *p, int fullsweep) @@ -2250,8 +2272,8 @@ sweep_proc_bins(Process *p, int fullsweep) FLAGS(p) |= F_NEED_FULLSWEEP; } - BIN_VHEAP_SZ(p) = next_vheap_size(bin_vheap, BIN_VHEAP_SZ(p)); - BIN_OLD_VHEAP_SZ(p) = next_vheap_size(BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p)); + BIN_VHEAP_SZ(p) = next_vheap_size(p, bin_vheap, BIN_VHEAP_SZ(p)); + BIN_OLD_VHEAP_SZ(p) = next_vheap_size(p, BIN_OLD_VHEAP(p), BIN_OLD_VHEAP_SZ(p)); MSO(p).overhead = bin_vheap; /* diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 8afd349b85..bdf888eaff 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1997-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1997-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -84,9 +84,10 @@ int erts_use_sender_punish; * Configurable parameters. */ -Uint display_items; /* no of items to display in traces etc */ +Uint display_items; /* no of items to display in traces etc */ Uint display_loads; /* print info about loaded modules */ int H_MIN_SIZE; /* The minimum heap grain */ +int BIN_VH_MIN_SIZE; /* The minimum binary virtual*/ Uint32 erts_debug_flags; /* Debug flags. */ #ifdef ERTS_OPCODE_COUNTER_SUPPORT @@ -252,7 +253,8 @@ erl_init(void) no_schedulers, no_schedulers_online); - H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0); + H_MIN_SIZE = erts_next_heap_size(H_MIN_SIZE, 0); + BIN_VH_MIN_SIZE = erts_next_heap_size(BIN_VH_MIN_SIZE, 0); erts_init_trace(); erts_init_binary(); @@ -513,67 +515,69 @@ void erts_usage(void) /* erts_fprintf(stderr, "-# number set the number of items to be used in traces etc\n"); */ - erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n"); - erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n", + erts_fprintf(stderr, "-a size suggested stack size in kilo words for threads\n"); + erts_fprintf(stderr, " in the async-thread pool, valid range is [%d-%d]\n", ERTS_ASYNC_THREAD_MIN_STACK_SIZE, ERTS_ASYNC_THREAD_MAX_STACK_SIZE); - erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n"); - erts_fprintf(stderr, " valid range is [0-%d]\n", + erts_fprintf(stderr, "-A number set number of threads in async thread pool,\n"); + erts_fprintf(stderr, " valid range is [0-%d]\n", ERTS_MAX_NO_OF_ASYNC_THREADS); - erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n"); - erts_fprintf(stderr, " d (or no extra option) to disable the break\n"); - erts_fprintf(stderr, " handler, i to ignore break signals\n"); + erts_fprintf(stderr, "-B[c|d|i] c to have Ctrl-c interrupt the Erlang shell,\n"); + erts_fprintf(stderr, " d (or no extra option) to disable the break\n"); + erts_fprintf(stderr, " handler, i to ignore break signals\n"); /* erts_fprintf(stderr, "-b func set the boot function (default boot)\n"); */ - erts_fprintf(stderr, "-c disable continuous date/time correction with\n"); - erts_fprintf(stderr, " respect to uptime\n"); + erts_fprintf(stderr, "-c disable continuous date/time correction with\n"); + erts_fprintf(stderr, " respect to uptime\n"); - erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n"); - erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n"); + erts_fprintf(stderr, "-d don't write a crash dump for internally detected errors\n"); + erts_fprintf(stderr, " (halt(String) will still produce a crash dump)\n"); - erts_fprintf(stderr, "-h number set minimum heap size in words (default %d)\n", + erts_fprintf(stderr, "-hms size set minimum heap size in words (default %d)\n", H_DEFAULT_SIZE); + erts_fprintf(stderr, "-hmbs size set minimum binary virtual heap size in words (default %d)\n", + VH_DEFAULT_SIZE); /* erts_fprintf(stderr, "-i module set the boot module (default init)\n"); */ - erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n"); + erts_fprintf(stderr, "-K boolean enable or disable kernel poll\n"); - erts_fprintf(stderr, "-l turn on auto load tracing\n"); + erts_fprintf(stderr, "-l turn on auto load tracing\n"); - erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n"); - erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n"); + erts_fprintf(stderr, "-M<X> <Y> memory allocator switches,\n"); + erts_fprintf(stderr, " see the erts_alloc(3) documentation for more info.\n"); - erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n"); - erts_fprintf(stderr, " valid range is [%d-%d]\n", + erts_fprintf(stderr, "-P number set maximum number of processes on this node,\n"); + erts_fprintf(stderr, " valid range is [%d-%d]\n", ERTS_MIN_PROCESSES, ERTS_MAX_PROCESSES); - erts_fprintf(stderr, "-R number set compatibility release number,\n"); - erts_fprintf(stderr, " valid range [%d-%d]\n", + erts_fprintf(stderr, "-R number set compatibility release number,\n"); + erts_fprintf(stderr, " valid range [%d-%d]\n", ERTS_MIN_COMPAT_REL, this_rel_num()); - erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n"); - erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n"); - erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n"); - erts_fprintf(stderr, "-sct cput set cpu topology,\n"); - erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); - erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n"); - erts_fprintf(stderr, " valid range is [%d-%d]\n", + erts_fprintf(stderr, "-r force ets memory block to be moved on realloc\n"); + erts_fprintf(stderr, "-sbt type set scheduler bind type, valid types are:\n"); + erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n"); + erts_fprintf(stderr, "-sct cput set cpu topology,\n"); + erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); + erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n"); + erts_fprintf(stderr, " valid range is [%d-%d]\n", ERTS_SCHED_THREAD_MIN_STACK_SIZE, ERTS_SCHED_THREAD_MAX_STACK_SIZE); - erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n"); - erts_fprintf(stderr, " schedulers online (n2), valid range for both\n"); - erts_fprintf(stderr, " numbers are [1-%d]\n", + erts_fprintf(stderr, "-S n1:n2 set number of schedulers (n1), and number of\n"); + erts_fprintf(stderr, " schedulers online (n2), valid range for both\n"); + erts_fprintf(stderr, " numbers are [1-%d]\n", ERTS_MAX_NO_OF_SCHEDULERS); - erts_fprintf(stderr, "-T number set modified timing level,\n"); - erts_fprintf(stderr, " valid range is [0-%d]\n", + erts_fprintf(stderr, "-T number set modified timing level,\n"); + erts_fprintf(stderr, " valid range is [0-%d]\n", ERTS_MODIFIED_TIMING_LEVELS-1); - erts_fprintf(stderr, "-V print Erlang version\n"); + erts_fprintf(stderr, "-V print Erlang version\n"); - erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n"); + erts_fprintf(stderr, "-v turn on chatty mode (GCs will be reported etc)\n"); - erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n"); - erts_fprintf(stderr, " see error_logger documentation for details\n"); + erts_fprintf(stderr, "-W<i|w> set error logger warnings mapping,\n"); + erts_fprintf(stderr, " see error_logger documentation for details\n"); erts_fprintf(stderr, "\n"); erts_fprintf(stderr, "Note that if the emulator is started with erlexec (typically\n"); @@ -604,6 +608,7 @@ early_init(int *argc, char **argv) /* erts_async_max_threads = 0; erts_async_thread_suggested_stack_size = ERTS_ASYNC_THREAD_MIN_STACK_SIZE; H_MIN_SIZE = H_DEFAULT_SIZE; + BIN_VH_MIN_SIZE = VH_DEFAULT_SIZE; erts_initialized = 0; @@ -922,17 +927,40 @@ erl_start(int argc, char **argv) fprintf(stderr, "The undocumented +H option has been removed (R10B-6).\n\n"); break; - case 'h': - /* set default heap size */ - arg = get_arg(argv[i]+2, argv[i+1], &i); - if ((H_MIN_SIZE = atoi(arg)) <= 0) { - erts_fprintf(stderr, "bad heap size %s\n", arg); - erts_usage(); + case 'h': { + char *sub_param = argv[i]+2; + /* set default heap size + * + * h|ms - min_heap_size + * h|mbs - min_bin_vheap_size + * + */ + if (has_prefix("mbs", sub_param)) { + arg = get_arg(sub_param+3, argv[i+1], &i); + if ((BIN_VH_MIN_SIZE = atoi(arg)) <= 0) { + erts_fprintf(stderr, "bad heap size %s\n", arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, ("using minimum binary virtual heap size %d\n", BIN_VH_MIN_SIZE)); + + } else if (has_prefix("ms", sub_param)) { + arg = get_arg(sub_param+2, argv[i+1], &i); + if ((H_MIN_SIZE = atoi(arg)) <= 0) { + erts_fprintf(stderr, "bad heap size %s\n", arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE)); + } else { + /* backward compatibility */ + arg = get_arg(argv[i]+2, argv[i+1], &i); + if ((H_MIN_SIZE = atoi(arg)) <= 0) { + erts_fprintf(stderr, "bad heap size %s\n", arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, ("using minimum heap size %d\n", H_MIN_SIZE)); } - VERBOSE(DEBUG_SYSTEM, - ("using minimum heap size %d\n",H_MIN_SIZE)); break; - + } case 'd': /* * Never produce crash dumps for internally detected diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index a4afe0574f..5f512a9982 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1996-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -6272,7 +6272,7 @@ Process *schedule(Process *p, int calls) erts_check_my_tracer_proc(p); #endif - if ((FLAGS(p) & F_FORCE_GC) || (MSO(p).overhead >= BIN_VHEAP_SZ(p))) { + if ((FLAGS(p) & F_FORCE_GC) || (MSO(p).overhead > BIN_VHEAP_SZ(p))) { reds -= erts_garbage_collect(p, 0, p->arg_reg, p->arity); if (reds < 0) { reds = 1; @@ -6683,13 +6683,15 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). * noone except us has access to the process. */ if (so->flags & SPO_USE_ARGS) { - p->min_heap_size = so->min_heap_size; - p->prio = so->priority; - p->max_gen_gcs = so->max_gen_gcs; + p->min_heap_size = so->min_heap_size; + p->min_vheap_size = so->min_vheap_size; + p->prio = so->priority; + p->max_gen_gcs = so->max_gen_gcs; } else { - p->min_heap_size = H_MIN_SIZE; - p->prio = PRIORITY_NORMAL; - p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs); + p->min_heap_size = H_MIN_SIZE; + p->min_vheap_size = BIN_VH_MIN_SIZE; + p->prio = PRIORITY_NORMAL; + p->max_gen_gcs = (Uint16) erts_smp_atomic_read(&erts_max_gen_gcs); } p->skipped = 0; ASSERT(p->min_heap_size == erts_next_heap_size(p->min_heap_size, 0)); @@ -6736,9 +6738,9 @@ erl_create_process(Process* parent, /* Parent of process (default group leader). p->heap_sz = sz; p->catches = 0; - p->bin_vheap_sz = H_MIN_SIZE; - p->bin_old_vheap_sz = H_MIN_SIZE; - p->bin_old_vheap = 0; + p->bin_vheap_sz = p->min_vheap_size; + p->bin_old_vheap_sz = p->min_vheap_size; + p->bin_old_vheap = 0; /* No need to initialize p->fcalls. */ @@ -6969,6 +6971,7 @@ void erts_init_empty_process(Process *p) p->gen_gcs = 0; p->max_gen_gcs = 0; p->min_heap_size = 0; + p->min_vheap_size = 0; p->status = P_RUNABLE; p->gcstatus = P_RUNABLE; p->rstatus = P_RUNABLE; @@ -6985,8 +6988,8 @@ void erts_init_empty_process(Process *p) p->ftrace = NIL; p->fcalls = 0; - p->bin_vheap_sz=H_MIN_SIZE; - p->bin_old_vheap_sz=H_MIN_SIZE; + p->bin_vheap_sz = BIN_VH_MIN_SIZE; + p->bin_old_vheap_sz = BIN_VH_MIN_SIZE; p->bin_old_vheap = 0; #ifdef ERTS_SMP p->u.ptimer = NULL; diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index 1f841b2113..f58b6932b3 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -477,6 +477,7 @@ struct ErtsPendingSuspend_ { # define MSO(p) (p)->off_heap # define MIN_HEAP_SIZE(p) (p)->min_heap_size +# define MIN_VHEAP_SIZE(p) (p)->min_vheap_size # define BIN_VHEAP_SZ(p) (p)->bin_vheap_sz # define BIN_OLD_VHEAP_SZ(p) (p)->bin_old_vheap_sz # define BIN_OLD_VHEAP(p) (p)->bin_old_vheap @@ -495,6 +496,7 @@ struct process { Eterm* hend; /* Heap end */ Uint heap_sz; /* Size of heap in words */ Uint min_heap_size; /* Minimum size of heap (in words). */ + Uint min_vheap_size; /* Minimum size of virtual heap (in words). */ #if !defined(NO_FPE_SIGNALS) volatile unsigned long fp_exception; @@ -730,8 +732,8 @@ typedef struct { * The following items are only initialized if the SPO_USE_ARGS flag is set. */ Uint min_heap_size; /* Minimum heap size (must be a valued returned - * from next_heap_size()). - */ + * from next_heap_size()). */ + Uint min_vheap_size; /* Minimum virtual heap size */ int priority; /* Priority for process. */ Uint16 max_gen_gcs; /* Maximum number of gen GCs before fullsweep. */ int scheduler; diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c index 2afb16fc52..2842c2361a 100644 --- a/erts/emulator/beam/erl_trace.c +++ b/erts/emulator/beam/erl_trace.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1999-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1999-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -2171,6 +2171,11 @@ erts_bif_trace(int bif_index, Process* p, void trace_gc(Process *p, Eterm what) { + ERTS_DECL_AM(bin_vheap_size); + ERTS_DECL_AM(bin_vheap_block_size); + ERTS_DECL_AM(bin_old_vheap_size); + ERTS_DECL_AM(bin_old_vheap_block_size); + ErlHeapFragment *bp = NULL; ErlOffHeap *off_heap; ERTS_TRACER_REF_TYPE tracer_ref = ERTS_NULL_TRACER_REF; /* Initialized @@ -2180,6 +2185,7 @@ trace_gc(Process *p, Eterm what) Eterm* hp; Eterm msg = NIL; Uint size; + Eterm tags[] = { am_old_heap_block_size, am_heap_block_size, @@ -2187,8 +2193,13 @@ trace_gc(Process *p, Eterm what) am_recent_size, am_stack_size, am_old_heap_size, - am_heap_size + am_heap_size, + AM_bin_vheap_size, + AM_bin_vheap_block_size, + AM_bin_old_vheap_size, + AM_bin_old_vheap_block_size }; + Uint values[] = { OLD_HEAP(p) ? OLD_HEND(p) - OLD_HEAP(p) : 0, HEAP_SIZE(p), @@ -2196,7 +2207,11 @@ trace_gc(Process *p, Eterm what) HIGH_WATER(p) - HEAP_START(p), STACK_START(p) - p->stop, OLD_HEAP(p) ? OLD_HTOP(p) - OLD_HEAP(p) : 0, - HEAP_TOP(p) - HEAP_START(p) + HEAP_TOP(p) - HEAP_START(p), + MSO(p).overhead, + BIN_VHEAP_SZ(p), + BIN_OLD_VHEAP(p), + BIN_OLD_VHEAP_SZ(p) }; Eterm local_heap[(sizeof(values)/sizeof(Uint)) *(2/*cons*/ + 3/*2-tuple*/ + BIG_UINT_HEAP_SIZE) diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h index d8d6246cfd..5b0d3c2bfa 100644 --- a/erts/emulator/beam/erl_vm.h +++ b/erts/emulator/beam/erl_vm.h @@ -57,7 +57,8 @@ #define INPUT_REDUCTIONS (2 * CONTEXT_REDS) -#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */ +#define H_DEFAULT_SIZE 233 /* default (heap + stack) min size */ +#define VH_DEFAULT_SIZE 32768 /* default virtual (bin) heap min size (words) */ #ifdef HYBRID # define SH_DEFAULT_SIZE 2629425 /* default message area min size */ @@ -178,6 +179,7 @@ extern int num_instructions; /* Number of instruction in opc[]. */ #define MAX_PORT_LINK 8 /* Maximum number of links to a port */ extern int H_MIN_SIZE; /* minimum (heap + stack) */ +extern int BIN_VH_MIN_SIZE; /* minimum virtual (bin) heap */ #define ORIG_CREATION 0 diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index fdedf30e78..77f850d0fb 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -41,7 +41,8 @@ bump_reductions/1, low_prio/1, binary_owner/1, yield/1, yield2/1, process_status_exiting/1, otp_4725/1, bad_register/1, garbage_collect/1, otp_6237/1, - process_info_messages/1, process_flag_badarg/1, + process_info_messages/1, process_flag_badarg/1, process_flag_heap_size/1, + spawn_opt_heap_size/1, processes_large_tab/1, processes_default_tab/1, processes_small_tab/1, processes_this_tab/1, processes_apply_trap/1, processes_last_call_trap/1, processes_gc_trap/1, @@ -63,9 +64,8 @@ all(suite) -> process_info_lock_reschedule, process_info_lock_reschedule2, process_status_exiting, bump_reductions, low_prio, yield, yield2, otp_4725, bad_register, - garbage_collect, process_info_messages, process_flag_badarg, otp_6237, - processes_bif, - otp_7738]. + garbage_collect, process_info_messages, process_flag_badarg, process_flag_heap_size, + spawn_opt_heap_size, otp_6237, processes_bif, otp_7738]. init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) -> Dog=?t:timetrap(?t:minutes(10)), @@ -388,6 +388,8 @@ t_process_info(Config) when is_list(Config) -> ?line register(my_name, self()), ?line {registered_name, my_name} = process_info(self(), registered_name), ?line {status, running} = process_info(self(), status), + ?line {min_heap_size, 233} = process_info(self(), min_heap_size), + ?line {min_bin_vheap_size, 46368} = process_info(self(), min_bin_vheap_size), ?line {current_function, {?MODULE, t_process_info, 1}} = process_info(self(), current_function), ?line Gleader = group_leader(), @@ -437,6 +439,10 @@ process_info_other_msg(Config) when is_list(Config) -> empty -> ok end, ?line {messages,[]} = process_info(Pid, messages), + + ?line {min_heap_size, 233} = process_info(Pid, min_heap_size), + ?line {min_bin_vheap_size, 46368} = process_info(Pid, min_bin_vheap_size), + ?line Pid ! stop, ok. @@ -1148,6 +1154,8 @@ process_flag_badarg(Config) when is_list(Config) -> ?line chk_badarg(fun () -> process_flag(trap_exit, gurka) end), ?line chk_badarg(fun () -> process_flag(error_handler, 1) end), ?line chk_badarg(fun () -> process_flag(min_heap_size, gurka) end), + ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, gurka) end), + ?line chk_badarg(fun () -> process_flag(min_bin_vheap_size, -1) end), ?line chk_badarg(fun () -> process_flag(priority, 4711) end), ?line chk_badarg(fun () -> process_flag(save_calls, hmmm) end), ?line P= spawn_link(fun () -> receive die -> ok end end), @@ -1774,6 +1782,34 @@ processes_gc_trap(Config) when is_list(Config) -> ?line exit(Suspendee, bang), ?line ok. +process_flag_heap_size(doc) -> + []; +process_flag_heap_size(suite) -> + []; +process_flag_heap_size(Config) when is_list(Config) -> + HSize = 2584, % must be gc fib number + VHSize = 317811, % must be gc fib number + ?line OldHmin = erlang:process_flag(min_heap_size, HSize), + ?line {min_heap_size, HSize} = erlang:process_info(self(), min_heap_size), + ?line OldVHmin = erlang:process_flag(min_bin_vheap_size, VHSize), + ?line {min_bin_vheap_size, VHSize} = erlang:process_info(self(), min_bin_vheap_size), + ?line HSize = erlang:process_flag(min_heap_size, OldHmin), + ?line VHSize = erlang:process_flag(min_bin_vheap_size, OldVHmin), + ?line ok. + +spawn_opt_heap_size(doc) -> + []; +spawn_opt_heap_size(suite) -> + []; +spawn_opt_heap_size(Config) when is_list(Config) -> + HSize = 987, % must be gc fib number + VHSize = 46368, % must be gc fib number + ?line Pid = spawn_opt(fun () -> receive stop -> ok end end, + [{min_heap_size, HSize},{ min_bin_vheap_size, VHSize}]), + ?line {min_heap_size, HSize} = process_info(Pid, min_heap_size), + ?line {min_bin_vheap_size, VHSize} = process_info(Pid, min_bin_vheap_size), + ?line Pid ! stop, + ?line ok. processes_term_proc_list(doc) -> []; diff --git a/erts/emulator/test/statistics_SUITE.erl b/erts/emulator/test/statistics_SUITE.erl index 9e1732a445..898908c40f 100644 --- a/erts/emulator/test/statistics_SUITE.erl +++ b/erts/emulator/test/statistics_SUITE.erl @@ -25,7 +25,7 @@ init_per_testcase/2, fin_per_testcase/2, wall_clock/1, wall_clock_zero_diff/1, wall_clock_update/1, - runtime/1, runtime_zero_diff/1, runtime_zero_update/1, + runtime/1, runtime_zero_diff/1, runtime_update/1, runtime_diff/1, run_queue/1, run_queue_one/1, reductions/1, reductions_big/1, garbage_collection/1, io/1, @@ -99,8 +99,7 @@ wall_clock_update1(0) -> %%% Test statistics(runtime). -runtime(suite) -> [runtime_zero_diff, runtime_zero_update, runtime_update, - runtime_diff]. +runtime(suite) -> [runtime_zero_diff, runtime_update, runtime_diff]. runtime_zero_diff(doc) -> "Tests that the difference between the times returned from two consectuitive " @@ -117,55 +116,32 @@ runtime_zero_diff1(N) when N > 0 -> runtime_zero_diff1(0) -> ?line test_server:fail("statistics(runtime) never returned zero difference"). -runtime_zero_update(doc) -> - "Test that the time differences returned by two calls to " - "statistics(runtime) several seconds apart is zero."; -runtime_zero_update(Config) when is_list(Config) -> - case ?t:is_debug() of - false -> ?line runtime_zero_update1(6); - true -> {skip,"Unreliable in DEBUG build"} - end. - -runtime_zero_update1(N) when N > 0 -> - ?line {T1, _} = statistics(runtime), - ?line receive after 7000 -> ok end, - ?line case statistics(runtime) of - {T, Td} when Td =< 80 -> - test_server:format("ok, Runtime before: {~p, _} after: {~p, ~p}", - [T1, T, Td]), - ok; - {T, R} -> - test_server:format("nok, Runtime before: {~p, _} after: {~p, ~p}", - [T1, T, R]), - runtime_zero_update1(N-1) - end; -runtime_zero_update1(0) -> - ?line test_server:fail("statistics(runtime) never returned zero difference"). - runtime_update(doc) -> - "Test that the statistics(runtime) returns a substanstially updated difference " - "after running a process that takes all CPU power of the Erlang process " - "for a second."; + "Test that the statistics(runtime) returns a substanstially " + "updated difference after running a process that takes all CPU " + " power of the Erlang process for a second."; runtime_update(Config) when is_list(Config) -> case ?t:is_cover() of false -> ?line process_flag(priority, high), - ?line test_server:m_out_of_n(1, 10, fun runtime_update/0); + do_runtime_update(10); true -> {skip,"Cover-compiled"} end. -runtime_update() -> - ?line {T1,_} = statistics(runtime), +do_runtime_update(0) -> + {comment,"Never close enough"}; +do_runtime_update(N) -> + ?line {T1,Diff0} = statistics(runtime), ?line spawn_link(fun cpu_heavy/0), receive after 1000 -> ok end, ?line {T2,Diff} = statistics(runtime), - ?line Delta = abs(Diff-1000), - ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, abs(Diff-1000) = ~p", - [T1,T2,Diff,Delta]), + ?line true = is_integer(T1+T2+Diff0+Diff), + ?line test_server:format("T1 = ~p, T2 = ~p, Diff = ~p, T2-T1 = ~p", + [T1,T2,Diff,T2-T1]), ?line if - abs(Diff-1000) =:= Delta, Delta =< 100 -> - ok + T2 - T1 =:= Diff, 900 =< Diff, Diff =< 1500 -> ok; + true -> do_runtime_update(N-1) end. cpu_heavy() -> diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl index 2c7124839a..e782d2f293 100644 --- a/erts/emulator/test/system_info_SUITE.erl +++ b/erts/emulator/test/system_info_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2005-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2005-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% @@ -35,12 +35,12 @@ %-compile(export_all). -export([all/1, init_per_testcase/2, fin_per_testcase/2]). --export([process_count/1, system_version/1, misc_smoke_tests/1]). +-export([process_count/1, system_version/1, misc_smoke_tests/1, heap_size/1]). -define(DEFAULT_TIMEOUT, ?t:minutes(2)). all(doc) -> []; -all(suite) -> [process_count, system_version, misc_smoke_tests]. +all(suite) -> [process_count, system_version, misc_smoke_tests, heap_size]. init_per_testcase(_Case, Config) when is_list(Config) -> Dog = ?t:timetrap(?DEFAULT_TIMEOUT), @@ -135,8 +135,13 @@ misc_smoke_tests(Config) when is_list(Config) -> ?line ok. - - - - +heap_size(doc) -> []; +heap_size(suite) -> []; +heap_size(Config) when is_list(Config) -> + ?line {min_bin_vheap_size, VHmin} = erlang:system_info(min_bin_vheap_size), + ?line {min_heap_size, Hmin} = erlang:system_info(min_heap_size), + ?line GCinf = erlang:system_info(garbage_collection), + ?line VHmin = proplists:get_value(min_bin_vheap_size, GCinf), + ?line Hmin = proplists:get_value(min_heap_size, GCinf), + ok. diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 4325418e7c..0ad26aeea7 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -1,19 +1,19 @@ /* * %CopyrightBegin% - * - * Copyright Ericsson AB 1996-2009. All Rights Reserved. - * + * + * Copyright Ericsson AB 1996-2010. All Rights Reserved. + * * The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved online at http://www.erlang.org/. - * + * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. - * + * * %CopyrightEnd% */ @@ -123,6 +123,14 @@ static char *pluss_val_switches[] = { "ss", NULL }; +/* +h arguments with values */ +static char *plush_val_switches[] = { + "ms", + "mbs", + "", + NULL +}; + /* * Define sleep(seconds) in terms of Sleep() on Windows. @@ -783,7 +791,6 @@ int main(int argc, char **argv) case 'a': case 'A': case 'b': - case 'h': case 'i': case 'P': case 'S': @@ -850,6 +857,20 @@ int main(int argc, char **argv) goto the_default; break; } + case 'h': + if (!is_one_of_strings(&argv[i][2], plush_val_switches)) { + goto the_default; + } else { + if (i+1 >= argc + || argv[i+1][0] == '-' + || argv[i+1][0] == '+') + usage(argv[i]); + argv[i][0] = '-'; + add_Eargs(argv[i]); + add_Eargs(argv[i+1]); + i++; + } + break; case 's': if (!is_one_of_strings(&argv[i][2], pluss_val_switches)) @@ -1048,7 +1069,7 @@ usage_aux(void) #endif "[-make] [-man [manopts] MANPAGE] [-x] [-emu_args] " "[-args_file FILENAME] " - "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE] [+K BOOLEAN] " + "[+A THREADS] [+a SIZE] [+B[c|d|i]] [+c] [+h HEAP_SIZE_OPTION] [+K BOOLEAN] " "[+l] [+M<SUBSWITCH> <ARGUMENT>] [+P MAX_PROCS] [+R COMPAT_REL] " "[+r] [+s SCHEDULER_OPTION] [+S NO_SCHEDULERS:NO_SCHEDULERS_ONLINE] [+T LEVEL] [+V] [+v] [+W<i|w>] " "[args ...]\n"); diff --git a/lib/common_test/doc/src/example_chapter.xml b/lib/common_test/doc/src/example_chapter.xml index 028cbf7c8d..f269dba2cd 100644 --- a/lib/common_test/doc/src/example_chapter.xml +++ b/lib/common_test/doc/src/example_chapter.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2003</year><year>2009</year> + <year>2003</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + </legalnotice> <title>Examples and Templates</title> @@ -38,7 +38,7 @@ <code> -module(db_data_type_SUITE). --include("ct.hrl"). +-include_lib("common_test/include/ct.hrl"). %% Test server callbacks -export([suite/0, all/0, @@ -186,7 +186,7 @@ insert_and_lookup(Key, Value, Config) -> %% Note: This directive should only be used in test suites. -compile(export_all). --include("ct.hrl"). +-include_lib("common_test/include/ct.hrl"). %%-------------------------------------------------------------------- %% COMMON TEST CALLBACK FUNCTIONS @@ -394,7 +394,7 @@ my_test_case(_Config) -> -compile(export_all). --include("ct.hrl"). +-include_lib("common_test/include/ct.hrl"). %%-------------------------------------------------------------------- %% Function: suite() -> Info diff --git a/lib/common_test/include/ct.hrl b/lib/common_test/include/ct.hrl index ad3b3374c4..aa1cc832cf 100644 --- a/lib/common_test/include/ct.hrl +++ b/lib/common_test/include/ct.hrl @@ -1,22 +1,22 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% --include("test_server.hrl"). +-include_lib("test_server/include/test_server.hrl"). -compile({parse_transform,ct_line}). diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index 5ddc534abc..1fd61831e0 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% -module(beam_validator). diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl index 0659d5575e..74b5d7c7eb 100644 --- a/lib/compiler/test/beam_validator_SUITE.erl +++ b/lib/compiler/test/beam_validator_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2004-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% -module(beam_validator_SUITE). diff --git a/lib/cosFileTransfer/doc/src/notes.xml b/lib/cosFileTransfer/doc/src/notes.xml index 5bb2ea68c4..48d0c04236 100644 --- a/lib/cosFileTransfer/doc/src/notes.xml +++ b/lib/cosFileTransfer/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2000</year><year>2009</year> + <year>2000</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + </legalnotice> <title>cosFileTransfer Release Notes</title> @@ -34,6 +34,18 @@ <title>cosFileTransfer 1.1.10</title> <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Removed obsolete SSL dependency.</p> + <p> + Own Id: OTP-8374 Aux Id:</p> + </item> + </list> + </section> + + <section> <title>Fixed Bugs and Malfunctions</title> <list type="bulleted"> <item> diff --git a/lib/cosFileTransfer/vsn.mk b/lib/cosFileTransfer/vsn.mk index 88786178fb..2700ecb3e3 100644 --- a/lib/cosFileTransfer/vsn.mk +++ b/lib/cosFileTransfer/vsn.mk @@ -1,7 +1,8 @@ COSFILETRANSFER_VSN = 1.1.10 TICKETS = \ - OTP-8355 + OTP-8355 \ + OTP-8374 TICKETS_1.1.9 = OTP-8201 diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml index 10c91949b4..ed83708940 100644 --- a/lib/inets/doc/src/notes.xml +++ b/lib/inets/doc/src/notes.xml @@ -135,7 +135,7 @@ <list> <item> <p>[httpd] The server did not fully support the documented module - callback api. Spicifically, the load function should be able to + callback api. Specifically, the load function should be able to return the atom <c>ok</c>, but this was not accepted. </p> <p>Own Id: OTP-8359</p> </item> @@ -269,7 +269,7 @@ <p>Timeout out requests are retried. </p> </item> </list> - <p>Jean-S�bastien P�dron</p> + <p>Jean-Sébastien Pédron</p> <p>Own Id: OTP-8248</p> </item> diff --git a/lib/inets/test/Makefile b/lib/inets/test/Makefile index 1dd7a51717..668752da9e 100644 --- a/lib/inets/test/Makefile +++ b/lib/inets/test/Makefile @@ -235,9 +235,6 @@ RELTESTSYSDIR = $(RELEASE_PATH)/inets_test RELTESTSYSALLDATADIR = $(RELTESTSYSDIR)/all_SUITE_data RELTESTSYSBINDIR = $(RELTESTSYSALLDATADIR)/bin -MAKEFILE_SRC = Makefile.src -INETS_SSL_LIB_DIR = ../../ssl/usr/ssleay/ - # ---------------------------------------------------- # FLAGS @@ -253,8 +250,6 @@ ERL_COMPILE_FLAGS += -pa ../../../internal_tools/test_server/ebin \ # If you intend to run the test suite locally (private), then # there is some requirements: # 1) INETS_PRIV_DIR must be created -# 2) INETS_SSL_LIB_DIR must be created with the same content as -# content comparable to all_SUITE_data/bin (see test-server). # ---------------------------------------------------- tests debug opt: $(BUILDTARGET) @@ -306,13 +301,9 @@ release_tests_spec: opt chmod -f -R u+w $(RELTESTSYSDIR) tar chf - $(DATADIRS) | (cd $(RELTESTSYSDIR); tar xf -) $(INSTALL_DIR) $(RELTESTSYSALLDATADIR) - $(INSTALL_DATA) $(MAKEFILE_SRC) $(RELTESTSYSALLDATADIR)/Makefile.src $(INSTALL_DIR) $(RELTESTSYSBINDIR) chmod -f -R +x $(RELTESTSYSBINDIR) - tar cf - -C $(INETS_SSL_LIB_DIR) . | (cd $(RELTESTSYSALLDATADIR); tar xf -) $(INSTALL_DIR) $(RELTESTSYSALLDATADIR)/win32/lib - tar cf - -C $(INETS_SSL_LIB_DIR)/win32/out32dll . | \ - (cd $(RELTESTSYSALLDATADIR)/win32/lib; tar xf -) release_docs_spec: @@ -340,7 +331,6 @@ info: @echo "" @echo "INETS_DATA_DIR = $(INETS_DATA_DIR)" @echo "INETS_PRIV_DIR = $(INETS_PRIV_DIR)" - @echo "INETS_SSL_LIB_DIR = $(INETS_SSL_LIB_DIR)" @echo "INETS_ROOT = $(INETS_ROOT)" @echo "INETS_FLAGS = $(INETS_FLAGS)" @echo "FTP_FLAGS = $(FTP_FLAGS)" diff --git a/lib/inets/test/Makefile.src b/lib/inets/test/Makefile.src deleted file mode 120000 index f361bfce20..0000000000 --- a/lib/inets/test/Makefile.src +++ /dev/null @@ -1 +0,0 @@ -../../ssl/test/Makefile.src
\ No newline at end of file diff --git a/lib/inets/test/ftp_SUITE_data/TAR.exclude b/lib/inets/test/ftp_SUITE_data/TAR.exclude deleted file mode 100644 index 2078965740..0000000000 --- a/lib/inets/test/ftp_SUITE_data/TAR.exclude +++ /dev/null @@ -1,2 +0,0 @@ -ftp_SUITE_data/TAR.exclude -ftp_SUITE_data/ftpd_hosts diff --git a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel index a820f8d014..75096ce687 100644 --- a/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel +++ b/lib/inets/test/ftp_SUITE_data/ftpd_hosts.skel @@ -1,17 +1,18 @@ %% Add a host name in the appropriate list %% Each "platform" contains a list of hostnames (a string) that can %% be used for testing the ftp client. -[{solaris8_sparc, []}, - {solaris9_sparc, []}, - {solaris10_sparc, []}, - {solaris10_x86, []}, - {linux_x86, []}, - {linux_ppc, []}, - {macosx_ppc, []}, - {macosx_x86, []}, +%% The definition below are an example!! +[{solaris8_sparc, ["solaris8_sparc_dummy1", "solaris8_sparc_dummy2"]}, + {solaris9_sparc, ["solaris9_sparc_dummy1"]}, + {solaris10_sparc, ["solaris10_sparc_dummy1"]}, + {solaris10_x86, ["solaris10_x86_dummy1", "solaris10_x86_dummy2"]}, + {linux_x86, ["linux_x86_dummy1", "linux_x86_dummy2"]}, + {linux_ppc, ["linux_ppc_dummy1"]}, + {macosx_ppc, ["macosx_ppc_dummy1"]}, + {macosx_x86, ["macosx_x86_dummy1", "macosx_x86_dummy2"]}, {openbsd_x86, []}, - {freebsd_x86, []}, + {freebsd_x86, ["freebsd_x86_dummy1"]}, {netbsd_x86, []}, {windows_xp, []}, - {windows_2003_server, []}, - {ticket_test, []}]. + {windows_2003_server, ["win2003_dummy1"]}, + {ticket_test, ["solaris8_x86_dummy1", "linux_x86_dummy1"]}]. diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk index 34c18c4d13..433724f190 100644 --- a/lib/inets/vsn.mk +++ b/lib/inets/vsn.mk @@ -19,7 +19,7 @@ APPLICATION = inets INETS_VSN = 5.3 -PRE_VSN =-p10 +PRE_VSN =-p12 APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)" TICKETS = \ diff --git a/lib/orber/doc/src/notes.xml b/lib/orber/doc/src/notes.xml index 1185b7658f..816ec77d61 100644 --- a/lib/orber/doc/src/notes.xml +++ b/lib/orber/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2009</year> + <year>1997</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + </legalnotice> <title>Orber Release Notes</title> @@ -36,6 +36,18 @@ <title>Orber 3.6.15</title> <section> + <title>Improvements and New Features</title> + <list type="bulleted"> + <item> + <p> + Removed obsolete SSL dependency.</p> + <p> + Own Id: OTP-8374 Aux Id:</p> + </item> + </list> + </section> + + <section> <title>Fixed Bugs and Malfunctions</title> <list type="bulleted"> <item> diff --git a/lib/orber/vsn.mk b/lib/orber/vsn.mk index ccba631fb5..8bfa13eb03 100644 --- a/lib/orber/vsn.mk +++ b/lib/orber/vsn.mk @@ -2,7 +2,8 @@ ORBER_VSN = 3.6.15 TICKETS = OTP-8353 \ - OTP-8354 + OTP-8354 \ + OTP-8374 TICKETS_3.6.14 = OTP-8201 |