diff options
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/test/nif_SUITE.erl | 7 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 39 |
2 files changed, 42 insertions, 4 deletions
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl index d29537e3ef..8439b28010 100644 --- a/erts/emulator/test/nif_SUITE.erl +++ b/erts/emulator/test/nif_SUITE.erl @@ -742,7 +742,12 @@ monitor_frenzy(Config) -> Pids = monitor_frenzy_nif(stop, 0, 0, 0), io:format("stats = ~p\n", [monitor_frenzy_nif(stats, 0, 0, 0)]), - lists:foreach(fun(P) -> exit(P, stop) end, Pids), + lists:foreach(fun(P) -> + MRef = monitor(process, P), + exit(P, stop), + {'DOWN', MRef, process, P, _} = receive_any() + end, + Pids), io:format("stats = ~p\n", [monitor_frenzy_nif(stats, 0, 0, 0)]), diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 97cb7e55d6..4f003d11f5 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -2484,9 +2484,11 @@ struct frenzy_resource { }; struct frenzy_reslot { ErlNifMutex* lock; + int stopped; struct frenzy_resource* obj; unsigned long alloc_cnt; unsigned long release_cnt; + unsigned long dtor_cnt; }; static struct frenzy_reslot resv[FRENZY_RESOURCES_MAX]; @@ -2536,8 +2538,10 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T for (rix = 0; rix < FRENZY_RESOURCES_MAX; rix++) { resv[rix].lock = enif_mutex_create("nif_SUITE:monitor_frenzy.resv.lock"); resv[rix].obj = NULL; + resv[rix].stopped = 0; resv[rix].alloc_cnt = 0; resv[rix].release_cnt = 0; + resv[rix].dtor_cnt = 0; } /* Add self as first process */ @@ -2553,12 +2557,14 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T ERL_NIF_TERM hist[FRENZY_PROCS_MAX]; unsigned long res_alloc_cnt = 0; unsigned long res_release_cnt = 0; + unsigned long res_dtor_cnt = 0; for (ref_ix = 0; ref_ix < FRENZY_PROCS_MAX; ref_ix++) { hist[ref_ix] = enif_make_ulong(env, proc_histogram[ref_ix]); } for (rix = 0; rix < FRENZY_RESOURCES_MAX; rix++) { res_alloc_cnt += resv[rix].alloc_cnt; res_release_cnt += resv[rix].release_cnt; + res_dtor_cnt += resv[rix].dtor_cnt; } return @@ -2569,12 +2575,29 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T enif_make_ulong(env, spawn_cnt)), enif_make_tuple2(env, enif_make_string(env, "kill_cnt", ERL_NIF_LATIN1), enif_make_ulong(env, kill_cnt)), - enif_make_tuple3(env, enif_make_string(env, "resource_alloc", ERL_NIF_LATIN1), + enif_make_tuple4(env, enif_make_string(env, "resource_alloc", ERL_NIF_LATIN1), enif_make_ulong(env, res_alloc_cnt), - enif_make_ulong(env, res_release_cnt))); + enif_make_ulong(env, res_release_cnt), + enif_make_ulong(env, res_dtor_cnt))); } else if (Op == atom_stop && procs_lock) { /* stop all */ + + /* Release all resources */ + for (rix = 0; rix < FRENZY_RESOURCES_MAX; rix++) { + enif_mutex_lock(resv[rix].lock); + r = resv[rix].obj; + if (r) { + resv[rix].obj = NULL; + resv[rix].release_cnt++; + } + resv[rix].stopped = 1; + enif_mutex_unlock(resv[rix].lock); + if (r) + enif_release_resource(r); + } + + /* Remove and return all pids */ retval = enif_make_list(env, 0); enif_mutex_lock(procs_lock); for (ref_ix = 0; ref_ix < nprocs; ref_ix++) { @@ -2587,6 +2610,7 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T nprocs = 0; old_nprocs = 0; enif_mutex_unlock(procs_lock); + return retval; } return enif_make_badarg(env); @@ -2655,7 +2679,12 @@ static ERL_NIF_TERM monitor_frenzy_nif(ErlNifEnv* env, int argc, const ERL_NIF_T while (enif_mutex_trylock(resv[rix].lock) == EBUSY) { rix = (rix + inc) % FRENZY_RESOURCES_MAX; } - if (resv[rix].obj == NULL) { + if (resv[rix].stopped) { + retval = atom_done; + enif_mutex_unlock(resv[rix].lock); + break; + } + else if (resv[rix].obj == NULL) { r = enif_alloc_resource(frenzy_resource_type, sizeof(struct frenzy_resource)); resv[rix].obj = r; @@ -2779,6 +2808,10 @@ static void frenzy_resource_dtor(ErlNifEnv* env, void* obj) DBG_TRACE2("DTOR r=%p rix=%u\n", r, r->rix); + enif_mutex_lock(resv[r->rix].lock); + resv[r->rix].dtor_cnt++; + enif_mutex_unlock(resv[r->rix].lock); + for (mix = 0; mix < FRENZY_MONITORS_MAX; mix++) { assert(r->monv[mix].state != MON_PENDING); enif_mutex_destroy(r->monv[mix].lock); |