diff options
author | Rikard Green <[email protected]> | 2018-05-18 11:22:33 +0200 |
---|---|---|
committer | Rikard Green <[email protected]> | 2018-05-18 11:22:33 +0200 |
commit | 2bc6ef5bb99ff1a7a4ac2a1370f0628acc730869 (patch) | |
tree | bc7816ec946c91d775666db0ce82addc67642344 /erts | |
parent | f8de655b70b91d72d90e39afae3d5cbe2678c75a (diff) | |
parent | 0985a72500ecd46579f6f7462ff121cc2c015f1f (diff) | |
download | otp-2bc6ef5bb99ff1a7a4ac2a1370f0628acc730869.tar.gz otp-2bc6ef5bb99ff1a7a4ac2a1370f0628acc730869.tar.bz2 otp-2bc6ef5bb99ff1a7a4ac2a1370f0628acc730869.zip |
Merge branch 'rickard/delete_process_schedule/OTP-15081'
* rickard/delete_process_schedule/OTP-15081:
Do not hold runq lock while deleting a process
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 15 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process_lock.h | 18 |
2 files changed, 32 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index b373d08a6b..58a5369515 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9085,6 +9085,17 @@ scheduler_gc_proc(Process *c_p, int reds_left) return reds; } +static void +unlock_lock_rq(int pre_free, void *vrq) +{ + ErtsRunQueue *rq = vrq; + if (pre_free) + erts_runq_unlock(rq); + else + erts_runq_lock(rq); +} + + /* * schedule() is called from BEAM (process_main()) or HiPE * (hipe_mode_switch()) when the current process is to be @@ -9253,7 +9264,9 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) } if (dec_refc) - erts_proc_dec_refc(p); + erts_proc_dec_refc_free_func(p, + unlock_lock_rq, + (void *) rq); } ASSERT(!esdp->free_process); diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h index 43f396c547..bd38eca4dc 100644 --- a/erts/emulator/beam/erl_process_lock.h +++ b/erts/emulator/beam/erl_process_lock.h @@ -921,6 +921,9 @@ ERTS_GLB_INLINE int erts_proc_trylock(Process *, ErtsProcLocks); ERTS_GLB_INLINE void erts_proc_inc_refc(Process *); ERTS_GLB_INLINE void erts_proc_dec_refc(Process *); +ERTS_GLB_INLINE void erts_proc_dec_refc_free_func(Process *p, + void (*func)(int, void *), + void *arg); ERTS_GLB_INLINE void erts_proc_add_refc(Process *, Sint); ERTS_GLB_INLINE Sint erts_proc_read_refc(Process *); @@ -993,6 +996,21 @@ ERTS_GLB_INLINE void erts_proc_dec_refc(Process *p) } } +ERTS_GLB_INLINE void erts_proc_dec_refc_free_func(Process *p, + void (*func)(int, void *), + void *arg) +{ + Sint referred; + ASSERT(!(erts_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY)); + referred = erts_ptab_atmc_dec_test_refc(&p->common); + if (!referred) { + ASSERT(ERTS_PROC_IS_EXITING(p)); + (*func)(!0, arg); + erts_free_proc(p); + (*func)(0, arg); + } +} + ERTS_GLB_INLINE void erts_proc_add_refc(Process *p, Sint add_refc) { Sint referred; |