diff options
Diffstat (limited to 'erts/emulator/beam/erl_process.c')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 138acfeb2c..6c136571d5 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -366,6 +366,9 @@ dbg_chk_aux_work_val(erts_aint32_t value) #ifdef ERTS_SMP_SCHEDULERS_NEED_TO_CHECK_CHILDREN valid |= ERTS_SSI_AUX_WORK_CHECK_CHILDREN; #endif +#ifdef ERTS_SMP + valid |= ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION; +#endif if (~valid & value) erl_exit(ERTS_ABORT_EXIT, @@ -861,7 +864,7 @@ set_aux_work_flags_wakeup_nob(ErtsSchedulerSleepInfo *ssi, } } -#if 0 /* Currently not used */ +#ifdef ERTS_SMP static ERTS_INLINE void set_aux_work_flags_wakeup_relb(ErtsSchedulerSleepInfo *ssi, @@ -882,7 +885,7 @@ set_aux_work_flags_wakeup_relb(ErtsSchedulerSleepInfo *ssi, } } -#endif +#endif /* ERTS_SMP */ static ERTS_INLINE erts_aint32_t set_aux_work_flags(ErtsSchedulerSleepInfo *ssi, erts_aint32_t flgs) @@ -1145,7 +1148,45 @@ handle_async_ready_clean(ErtsAuxWorkData *awdp, } } +#endif /* ERTS_USE_ASYNC_READY_Q */ + +#ifdef ERTS_SMP +void +erts_notify_code_ix_activation(Process* p, ErtsThrPrgrVal later) +{ + ErtsAuxWorkData* awdp = &p->scheduler_data->aux_work_data; + ASSERT(awdp->code_ix_activation.code_stager == NULL); + awdp->code_ix_activation.code_stager = p; + awdp->code_ix_activation.thr_prgr = later; + erts_smp_proc_inc_refc(p); + set_aux_work_flags_wakeup_relb(p->scheduler_data->ssi, + ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION); +} + +static erts_aint32_t +handle_code_ix_activation(ErtsAuxWorkData *awdp, erts_aint32_t aux_work) +{ + Process* p; + if (!erts_thr_progress_has_reached(awdp->code_ix_activation.thr_prgr)) { + return aux_work & ~ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION; + } + unset_aux_work_flags(awdp->ssi, ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION); + p = awdp->code_ix_activation.code_stager; + ASSERT(p); +#ifdef DEBUG + awdp->code_ix_activation.code_stager = NULL; #endif + erts_commit_staging_code_ix(); + erts_release_code_write_permission(); + erts_smp_proc_lock(p, ERTS_PROC_LOCK_STATUS); + if (!ERTS_PROC_IS_EXITING(p)) { + erts_resume(p, ERTS_PROC_LOCK_STATUS); + } + erts_smp_proc_unlock(p, ERTS_PROC_LOCK_STATUS); + erts_smp_proc_dec_refc(p); + return aux_work & ~ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION; +} +#endif /* ERTS_SMP */ static ERTS_INLINE erts_aint32_t handle_fix_alloc(ErtsAuxWorkData *awdp, erts_aint32_t aux_work) @@ -1451,6 +1492,10 @@ handle_aux_work(ErtsAuxWorkData *awdp, erts_aint32_t orig_aux_work) handle_mseg_cache_check); #endif +#ifdef ERTS_SMP + HANDLE_AUX_WORK(ERTS_SSI_AUX_WORK_CODE_IX_ACTIVATION, + handle_code_ix_activation); +#endif ERTS_DBG_CHK_AUX_WORK_VAL(aux_work); return aux_work; @@ -9599,13 +9644,8 @@ init_processes_bif(void) + 1); /* processes_trap/2 is a hidden BIF that the processes/0 BIF traps to. */ - sys_memset((void *) &processes_trap_export, 0, sizeof(Export)); - processes_trap_export.address = &processes_trap_export.code[3]; - processes_trap_export.code[0] = am_erlang; - processes_trap_export.code[1] = am_processes_trap; - processes_trap_export.code[2] = 2; - processes_trap_export.code[3] = (BeamInstr) em_apply_bif; - processes_trap_export.code[4] = (BeamInstr) &processes_trap; + erts_init_trap_export(&processes_trap_export, am_erlang, am_processes_trap, 2, + &processes_trap); #if ERTS_PROCESSES_BIF_DEBUGLEVEL >= ERTS_PROCS_DBGLVL_CHK_TERM_PROC_LIST erts_get_emu_time(&debug_tv_start); |