summaryrefslogtreecommitdiff
path: root/erts/emulator/beam/erl_process_lock.h
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_process_lock.h')
-rw-r--r--erts/emulator/beam/erl_process_lock.h52
1 files changed, 51 insertions, 1 deletions
diff --git a/erts/emulator/beam/erl_process_lock.h b/erts/emulator/beam/erl_process_lock.h
index 70ff3baf49..3c8428c5b9 100644
--- a/erts/emulator/beam/erl_process_lock.h
+++ b/erts/emulator/beam/erl_process_lock.h
@@ -229,7 +229,7 @@ typedef struct erts_proc_lock_t_ {
#ifndef ERTS_PROC_LOCK_LOCK_CHECK__
#define ERTS_PROC_LOCK_LOCK_CHECK__
-/* Lock counter implemetation */
+/* Lock counter implementation */
#ifdef ERTS_ENABLE_LOCK_POSITION
#define erts_proc_lock__(P,I,L) erts_proc_lock_x__(P,I,L,__FILE__,__LINE__)
@@ -462,6 +462,9 @@ typedef struct {
#define ERTS_PROC_LOCK_FLGS_READ_(L) \
((ErtsProcLocks) erts_atomic32_read_nob(&(L)->flags))
+#define ERTS_PROC_LOCK_FLGS_READ_ACQB_(L) \
+ ((ErtsProcLocks) erts_atomic32_read_acqb(&(L)->flags))
+
#else /* no opt atomic ops */
ERTS_GLB_INLINE ErtsProcLocks erts_proc_lock_flags_band(erts_proc_lock_t *,
@@ -509,6 +512,7 @@ erts_proc_lock_flags_cmpxchg(erts_proc_lock_t *lck, ErtsProcLocks new,
#define ERTS_PROC_LOCK_FLGS_CMPXCHG_RELB_(L, NEW, EXPECTED) \
erts_proc_lock_flags_cmpxchg((L), (NEW), (EXPECTED))
#define ERTS_PROC_LOCK_FLGS_READ_(L) ((L)->flags)
+#define ERTS_PROC_LOCK_FLGS_READ_ACQB_(L) ((L)->flags)
#endif /* end no opt atomic ops */
#endif /* ERTS_PROC_LOCK_OWN_IMPL */
@@ -918,6 +922,8 @@ ERTS_GLB_INLINE void erts_proc_lock(Process *, ErtsProcLocks);
#endif
ERTS_GLB_INLINE void erts_proc_unlock(Process *, ErtsProcLocks);
ERTS_GLB_INLINE int erts_proc_trylock(Process *, ErtsProcLocks);
+ERTS_GLB_INLINE void
+erts_proc_lock_wait_until_released(Process *p, ErtsProcLocks locks);
ERTS_GLB_INLINE void erts_proc_inc_refc(Process *);
ERTS_GLB_INLINE void erts_proc_dec_refc(Process *);
@@ -979,6 +985,50 @@ erts_proc_trylock(Process *p, ErtsProcLocks locks)
locks);
}
+ERTS_GLB_INLINE void
+erts_proc_lock_wait_until_released(Process *p, ErtsProcLocks locks)
+{
+#if ERTS_PROC_LOCK_OWN_IMPL
+#if !ERTS_PROC_LOCK_ATOMIC_IMPL
+ Uint32 was_locked;
+ erts_pix_lock(pix_lck);
+ was_locked = (ERTS_PROC_LOCK_FLGS_READ_(&p->lock) & locks);
+ erts_pix_unlock(pix_lck);
+ if (was_locked) {
+ erts_proc_lock(p, locks);
+ erts_proc_unlock(p, locks);
+ }
+#else
+ ETHR_MEMBAR(ETHR_StoreLoad | ETHR_LoadLoad);
+ if (ERTS_PROC_LOCK_FLGS_READ_ACQB_(&p->lock) & locks) {
+ erts_proc_lock(p, locks);
+ erts_proc_unlock(p, locks);
+ }
+#endif
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ if (locks & ERTS_PROC_LOCK_MAIN) {
+ erts_mtx_lock(&p->lock.main);
+ erts_mtx_unlock(&p->lock.main);
+ }
+ if (locks & ERTS_PROC_LOCK_MSGQ) {
+ erts_mtx_lock(&p->lock.msgq);
+ erts_mtx_unlock(&p->lock.msgq);
+ }
+ if (locks & ERTS_PROC_LOCK_BTM) {
+ erts_mtx_lock(&p->lock.btm);
+ erts_mtx_unlock(&p->lock.btm);
+ }
+ if (locks & ERTS_PROC_LOCK_STATUS) {
+ erts_mtx_lock(&p->lock.status);
+ erts_mtx_unlock(&p->lock.status);
+ }
+ if (locks & ERTS_PROC_LOCK_TRACE) {
+ erts_mtx_lock(&p->lock.trace);
+ erts_mtx_unlock(&p->lock.trace);
+ }
+#endif
+}
+
ERTS_GLB_INLINE void erts_proc_inc_refc(Process *p)
{
ASSERT(!(erts_atomic32_read_nob(&p->state) & ERTS_PSFLG_PROXY));