aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_nif.c
diff options
context:
space:
mode:
authorSteve Vinoski <[email protected]>2015-12-23 21:09:19 -0500
committerRickard Green <[email protected]>2016-05-31 15:13:50 +0200
commit60557173f8a7bd0d4deafdb2b3e066899c586f56 (patch)
tree280984f50391176714f4ed1b9eb19cdabd3369b3 /erts/emulator/beam/erl_nif.c
parentf0510a55fdc2591ea71107f77e36d6fc7b001874 (diff)
downloadotp-60557173f8a7bd0d4deafdb2b3e066899c586f56.tar.gz
otp-60557173f8a7bd0d4deafdb2b3e066899c586f56.tar.bz2
otp-60557173f8a7bd0d4deafdb2b3e066899c586f56.zip
Add dirty_process_main function
Dirty schedulers only execute NIFs, so having them execute the full process_main function isn't necessary. Add dirty_process_main for dirty schedulers to execute instead. Add erts_pre_dirty_nif(), called when preparing to execute a dirty nif. Add more dirty NIF tests to verify that activities requiring the process main lock can succeed when the process is executing a dirty NIF.
Diffstat (limited to 'erts/emulator/beam/erl_nif.c')
-rw-r--r--erts/emulator/beam/erl_nif.c81
1 files changed, 48 insertions, 33 deletions
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 2bbb8e3c91..4437adb57b 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -178,9 +178,11 @@ static ERTS_INLINE void ensure_heap(ErlNifEnv* env, size_t may_need)
void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif,
Process* tracee)
{
+#ifdef DEBUG
#ifdef ERTS_DIRTY_SCHEDULERS
ErtsSchedulerData *esdp;
#endif
+#endif
env->mod_nif = mod_nif;
env->proc = p;
env->hp = HEAP_TOP(p);
@@ -193,12 +195,12 @@ void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif,
ASSERT(p->common.id != ERTS_INVALID_PID);
+#ifdef DEBUG
#ifdef ERTS_DIRTY_SCHEDULERS
esdp = erts_get_scheduler_data();
ASSERT(esdp);
if (!ERTS_SCHEDULER_IS_DIRTY(esdp)) {
-#ifdef DEBUG
erts_aint32_t state = erts_smp_atomic32_read_nob(&p->state);
ASSERT(p->scheduler_data == esdp);
@@ -206,44 +208,57 @@ void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif,
| ERTS_PSFLG_RUNNING_SYS))
&& !(state & (ERTS_PSFLG_DIRTY_RUNNING
| ERTS_PSFLG_DIRTY_RUNNING_SYS)));
+ }
#endif
+#endif
+}
- }
- else {
- Process *sproc;
+void erts_pre_dirty_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif,
+ Process* tracee)
+{
+#ifdef ERTS_DIRTY_SCHEDULERS
#ifdef DEBUG
- erts_aint32_t state = erts_smp_atomic32_read_nob(&p->state);
+ erts_aint32_t state;
+#endif
+ Process *sproc;
+ ErtsSchedulerData *esdp;
+ esdp = erts_get_scheduler_data();
+ ASSERT(esdp);
+
+ erts_pre_nif(env, p, mod_nif, tracee);
- ASSERT(!p->scheduler_data);
- ASSERT((state & ERTS_PSFLG_DIRTY_RUNNING)
- && !(state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS)));
+#ifdef DEBUG
+ state = erts_smp_atomic32_read_nob(&p->state);
+
+ ASSERT(!p->scheduler_data);
+ ASSERT((state & ERTS_PSFLG_DIRTY_RUNNING)
+ && !(state & (ERTS_PSFLG_RUNNING|ERTS_PSFLG_RUNNING_SYS)));
#endif
- sproc = esdp->dirty_shadow_process;
- ASSERT(sproc);
- ASSERT(sproc->static_flags & ERTS_STC_FLG_SHADOW_PROC);
- ASSERT(erts_smp_atomic32_read_nob(&sproc->state)
- == (ERTS_PSFLG_ACTIVE
- | ERTS_PSFLG_DIRTY_RUNNING
- | ERTS_PSFLG_PROXY));
-
- sproc->next = p;
- sproc->common.id = p->common.id;
- sproc->htop = p->htop;
- sproc->stop = p->stop;
- sproc->hend = p->hend;
- sproc->heap = p->heap;
- sproc->abandoned_heap = p->abandoned_heap;
- sproc->heap_sz = p->heap_sz;
- sproc->high_water = p->high_water;
- sproc->old_hend = p->old_hend;
- sproc->old_htop = p->old_htop;
- sproc->old_heap = p->old_heap;
- sproc->mbuf = NULL;
- sproc->mbuf_sz = 0;
- ERTS_INIT_OFF_HEAP(&sproc->off_heap);
- env->proc = sproc;
- }
+ sproc = esdp->dirty_shadow_process;
+ ASSERT(sproc);
+ ASSERT(sproc->static_flags & ERTS_STC_FLG_SHADOW_PROC);
+ ASSERT(erts_smp_atomic32_read_nob(&sproc->state)
+ == (ERTS_PSFLG_ACTIVE
+ | ERTS_PSFLG_DIRTY_RUNNING
+ | ERTS_PSFLG_PROXY));
+
+ sproc->next = p;
+ sproc->common.id = p->common.id;
+ sproc->htop = p->htop;
+ sproc->stop = p->stop;
+ sproc->hend = p->hend;
+ sproc->heap = p->heap;
+ sproc->abandoned_heap = p->abandoned_heap;
+ sproc->heap_sz = p->heap_sz;
+ sproc->high_water = p->high_water;
+ sproc->old_hend = p->old_hend;
+ sproc->old_htop = p->old_htop;
+ sproc->old_heap = p->old_heap;
+ sproc->mbuf = NULL;
+ sproc->mbuf_sz = 0;
+ ERTS_INIT_OFF_HEAP(&sproc->off_heap);
+ env->proc = sproc;
#endif
}