diff options
-rw-r--r-- | erts/emulator/test/alloc_SUITE.erl | 59 | ||||
-rw-r--r-- | erts/emulator/test/alloc_SUITE_data/bucket_mask.c | 2 | ||||
-rw-r--r-- | erts/emulator/test/alloc_SUITE_data/testcase_driver.c | 30 | ||||
-rw-r--r-- | erts/emulator/test/alloc_SUITE_data/testcase_driver.h | 3 |
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; |