aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator')
-rw-r--r--erts/emulator/test/alloc_SUITE.erl59
-rw-r--r--erts/emulator/test/alloc_SUITE_data/bucket_mask.c2
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.c30
-rw-r--r--erts/emulator/test/alloc_SUITE_data/testcase_driver.h3
4 files changed, 75 insertions, 19 deletions
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 0dd68b778b..866008e3e0 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -202,13 +202,14 @@ drv_case(Config, Mode, NodeOpts) when is_list(Config) ->
end.
run_drv_case(Config, Mode) ->
- ?line DataDir = ?config(data_dir,Config),
- ?line CaseName = ?config(testcase,Config),
+ DataDir = ?config(data_dir,Config),
+ CaseName = ?config(testcase,Config),
File = filename:join(DataDir, CaseName),
{ok,CaseName,Bin} = compile:file(File, [binary,return_errors]),
- ?line {module,CaseName} = erlang:load_module(CaseName,Bin),
+ {module,CaseName} = erlang:load_module(CaseName,Bin),
ok = CaseName:init(File),
+ SlaveState = slave_init(CaseName),
case Mode of
one_shot ->
Result = one_shot(CaseName);
@@ -217,11 +218,26 @@ run_drv_case(Config, Mode) ->
Result = concurrent(CaseName)
end,
- ?line true = erlang:delete_module(CaseName),
- ?line Result.
+ true = erlang:delete_module(CaseName),
+ slave_end(SlaveState),
+ Result.
+
+slave_init(migration) ->
+ A0 = case application:start(sasl) of
+ ok -> [sasl];
+ _ -> []
+ end,
+ case application:start(os_mon) of
+ ok -> [os_mon|A0];
+ _ -> A0
+ end;
+slave_init(_) -> [].
+
+slave_end(Apps) ->
+ lists:foreach(fun (A) -> application:stop(A) end, Apps).
one_shot(CaseName) ->
- State = CaseName:start(1),
+ State = CaseName:start({1, 0, erlang:system_info(build_type)}),
Result0 = CaseName:run(State),
false = (Result0 =:= continue),
Result1 = handle_result(State, Result0),
@@ -229,8 +245,8 @@ one_shot(CaseName) ->
Result1.
-many_shot(CaseName, I) ->
- State = CaseName:start(I),
+many_shot(CaseName, I, Mem) ->
+ State = CaseName:start({I, Mem, erlang:system_info(build_type)}),
Result1 = repeat_while(fun() ->
Result0 = CaseName:run(State),
handle_result(State, Result0)
@@ -239,12 +255,15 @@ many_shot(CaseName, I) ->
Result1.
concurrent(CaseName) ->
+ NSched = erlang:system_info(schedulers),
+ Mem = (free_memory() * 3) div 4,
PRs = lists:map(fun(I) -> spawn_opt(fun() ->
- many_shot(CaseName, I)
+ many_shot(CaseName, I,
+ Mem div NSched)
end,
[monitor, {scheduler,I}])
end,
- lists:seq(1, erlang:system_info(schedulers))),
+ lists:seq(1, NSched)),
lists:foreach(fun({Pid,Ref}) ->
receive {'DOWN', Ref, process, Pid, Reason} ->
Reason
@@ -308,3 +327,23 @@ is_halfword_vm() ->
{4, 8} -> true;
{WS, WS} -> false
end.
+
+free_memory() ->
+ %% Free memory in MB.
+ try
+ SMD = memsup:get_system_memory_data(),
+ {value, {free_memory, Free}} = lists:keysearch(free_memory, 1, SMD),
+ TotFree = (Free +
+ case lists:keysearch(cached_memory, 1, SMD) of
+ {value, {cached_memory, Cached}} -> Cached;
+ false -> 0
+ end +
+ case lists:keysearch(buffered_memory, 1, SMD) of
+ {value, {buffered_memory, Buffed}} -> Buffed;
+ false -> 0
+ end),
+ TotFree div (1024*1024)
+ catch
+ error : undef ->
+ ?t:fail({"os_mon not built"})
+ end.
diff --git a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
index d474c80343..c94c265f4e 100644
--- a/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
+++ b/erts/emulator/test/alloc_SUITE_data/bucket_mask.c
@@ -52,7 +52,7 @@ testcase_run(TestCaseState_t *tcs)
typedef struct linked_block {
struct linked_block* next;
}Linked;
- Linked* link;
+ Linked* link = NULL;
Linked* fence_list;
Linked* pad_list;
void* tmp;
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
index 1503fea4cb..7dcca544e5 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.c
@@ -23,6 +23,7 @@
#include <stdarg.h>
#include <setjmp.h>
#include <string.h>
+#include <limits.h>
#ifdef __WIN32__
static void my_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
@@ -54,7 +55,6 @@ static void my_snprintf(char *outBuf, size_t size, const char *format, ...)
typedef struct {
TestCaseState_t visible;
- ErlNifEnv* curr_env;
int result;
jmp_buf* done_jmp_buf;
char *comment;
@@ -86,17 +86,26 @@ int testcase_nif_init(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
ERL_NIF_TERM
testcase_nif_start(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
-{
+{ /* (ThrNr, FreeMeg, BuildType) */
ERL_NIF_TERM ret;
InternalTestCaseState_t *itcs = (InternalTestCaseState_t *)
enif_alloc_resource(testcase_rt, sizeof(InternalTestCaseState_t));
-
- if (!itcs || !enif_get_int(env, argv[0], &itcs->visible.thr_nr)) {
+ int free_megabyte;
+ const int max_megabyte = INT_MAX / (1024*1024);
+ const ERL_NIF_TERM* tpl;
+ int tpl_arity;
+
+ if (!itcs
+ || !enif_get_tuple(env, argv[0], &tpl_arity, &tpl)
+ || tpl_arity != 3
+ || !enif_get_int(env, tpl[0], &itcs->visible.thr_nr)
+ || !enif_get_int(env, tpl[1], &free_megabyte)) {
enif_make_badarg(env);
}
-
+ itcs->visible.free_mem = (free_megabyte < max_megabyte ?
+ free_megabyte : max_megabyte) * (1024*1024);
itcs->visible.testcase_name = testcase_name();
-
+ itcs->visible.build_type = tpl[2];
itcs->visible.extra = NULL;
itcs->result = TESTCASE_FAILED;
itcs->comment = "";
@@ -126,7 +135,7 @@ testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
if (!enif_get_resource(env, argv[0], testcase_rt, (void**)&itcs))
return enif_make_badarg(env);
- itcs->curr_env = env;
+ itcs->visible.curr_env = env;
/* For some unknown reason, first call to setjmp crashes on win64
* when jmp_buf is allocated as part of the resource. But it works when
@@ -146,6 +155,11 @@ testcase_nif_run(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
case TESTCASE_SUCCEEDED: result_atom = "succeeded"; break;
case TESTCASE_SKIPPED: result_atom = "skipped"; break;
case TESTCASE_FAILED: result_atom = "failed"; break;
+ default:
+ result_atom = "failed";
+ my_snprintf(itcs->comment_buf, sizeof(itcs->comment_buf),
+ "Unexpected test result code %d.", itcs->result);
+ itcs->comment = itcs->comment_buf;
}
return enif_make_tuple2(env, enif_make_atom(env, result_atom),
@@ -176,7 +190,7 @@ testcase_printf(TestCaseState_t *tcs, char *frmt, ...)
msg = enif_make_tuple2(msg_env, print_atom,
enif_make_string(msg_env, itcs->comment_buf, ERL_NIF_LATIN1));
- enif_send(itcs->curr_env, enif_self(itcs->curr_env, &pid),
+ enif_send(itcs->visible.curr_env, enif_self(itcs->visible.curr_env, &pid),
msg_env, msg);
enif_free_env(msg_env);
diff --git a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
index 698ae66fac..f0ca91bd06 100644
--- a/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
+++ b/erts/emulator/test/alloc_SUITE_data/testcase_driver.h
@@ -24,8 +24,11 @@
#include <stdlib.h>
typedef struct {
+ ErlNifEnv* curr_env;
char *testcase_name;
int thr_nr;
+ int free_mem; /* in bytes */
+ ERL_NIF_TERM build_type; /* opt, debug, valgrind, ... */
void *extra;
} TestCaseState_t;