aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_fun.h
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2016-08-02 15:58:06 +0200
committerRickard Green <[email protected]>2016-08-29 16:26:24 +0200
commit9d0638216d35ca0f21c1eea20f8daa3992ac4f71 (patch)
treeb270d8f0226e88c376826584c4ea88ae377dff6f /erts/emulator/beam/erl_fun.h
parent2fe03e832adb11c50bcfc62679cf17779b284124 (diff)
downloadotp-9d0638216d35ca0f21c1eea20f8daa3992ac4f71.tar.gz
otp-9d0638216d35ca0f21c1eea20f8daa3992ac4f71.tar.bz2
otp-9d0638216d35ca0f21c1eea20f8daa3992ac4f71.zip
Fix purge of code
Ensure that we cannot get any dangling pointers into code that has been purged. This is done by a two phase purge. At first phase all fun entries pointing into the code to purge are marked for purge. All processes trying to call these funs will be suspended and by this we avoid getting new direct references into the code. When all processes has been checked, these processes are resumed. The new purge strategy now also completely ignore the existence of indirect references to the code (funs). If such exist, they will cause bad fun exceptions to the caller, but will not prevent a soft purge or cause a kill of a process having such live references during a hard purge. This since it is impossible to give any guarantees that no processes in the system have such indirect references. Even when the system is completely clean from such references, new ones can appear via distribution and/or disk.
Diffstat (limited to 'erts/emulator/beam/erl_fun.h')
-rw-r--r--erts/emulator/beam/erl_fun.h6
1 files changed, 5 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_fun.h b/erts/emulator/beam/erl_fun.h
index 8c4deea7a0..73c3e19c1c 100644
--- a/erts/emulator/beam/erl_fun.h
+++ b/erts/emulator/beam/erl_fun.h
@@ -44,6 +44,7 @@ typedef struct erl_fun_entry {
Eterm module; /* Tagged atom for module. */
erts_refc_t refc; /* Reference count: One for code + one for each
fun object in each process. */
+ BeamInstr *pend_purge_address; /* address stored during a pending purge */
} ErlFunEntry;
/*
@@ -81,7 +82,10 @@ ErlFunEntry* erts_put_fun_entry2(Eterm mod, int old_uniq, int old_index,
void erts_erase_fun_entry(ErlFunEntry* fe);
void erts_cleanup_funs(ErlFunThing* funp);
-void erts_cleanup_funs_on_purge(BeamInstr* start, BeamInstr* end);
+void erts_fun_purge_prepare(BeamInstr* start, BeamInstr* end);
+void erts_fun_purge_abort_prepare(ErlFunEntry **funs, Uint no);
+void erts_fun_purge_abort_finalize(ErlFunEntry **funs, Uint no);
+void erts_fun_purge_complete(ErlFunEntry **funs, Uint no);
void erts_dump_fun_entries(int, void *);
#endif