aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/beam/atom.names1
-rw-r--r--erts/emulator/beam/bif.c72
-rw-r--r--erts/emulator/beam/erl_bif_info.c74
-rw-r--r--erts/emulator/beam/erl_gc.c46
-rw-r--r--erts/emulator/beam/erl_init.c132
-rw-r--r--erts/emulator/beam/erl_process.c37
-rw-r--r--erts/emulator/beam/erl_process.h6
-rw-r--r--erts/emulator/beam/erl_trace.c29
-rw-r--r--erts/emulator/beam/erl_vm.h4
-rw-r--r--erts/emulator/test/process_SUITE.erl54
-rw-r--r--erts/emulator/test/system_info_SUITE.erl27
11 files changed, 347 insertions, 135 deletions
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_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/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.