aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_process_lock.c
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2012-04-27 13:06:27 +0200
committerRickard Green <[email protected]>2012-04-27 13:06:27 +0200
commit398bb9a9a5b2a56f0333ce81efe00380692ec93a (patch)
treeadb7239744ae6f3d45f672e29d9c2bd97e0e67d9 /erts/emulator/beam/erl_process_lock.c
parent52312a8b93e8b250099e2f1b1b802e63e37971cc (diff)
parent3730e28ad736f0538141d4474e0038a9cc48df71 (diff)
downloadotp-398bb9a9a5b2a56f0333ce81efe00380692ec93a.tar.gz
otp-398bb9a9a5b2a56f0333ce81efe00380692ec93a.tar.bz2
otp-398bb9a9a5b2a56f0333ce81efe00380692ec93a.zip
Merge branch 'rickard/proc-sched/OTP-9892'
* rickard/proc-sched/OTP-9892: Teach etp-commands to understand new emulator internal data structures Optimize process state changes Optimize process table access Implement possibility to use ordinary mutexes as process locks Conflicts: erts/emulator/beam/erl_alloc.types
Diffstat (limited to 'erts/emulator/beam/erl_process_lock.c')
-rw-r--r--erts/emulator/beam/erl_process_lock.c452
1 files changed, 345 insertions, 107 deletions
diff --git a/erts/emulator/beam/erl_process_lock.c b/erts/emulator/beam/erl_process_lock.c
index b3b4601a31..bae2b383a4 100644
--- a/erts/emulator/beam/erl_process_lock.c
+++ b/erts/emulator/beam/erl_process_lock.c
@@ -67,10 +67,12 @@
#include "erl_process.h"
-const Process erts_proc_lock_busy;
+const Process erts_proc_lock_busy = {ERTS_INVALID_PID};
#ifdef ERTS_SMP
+#if ERTS_PROC_LOCK_OWN_IMPL
+
#define ERTS_PROC_LOCK_SPIN_COUNT_MAX 2000
#define ERTS_PROC_LOCK_SPIN_COUNT_SCHED_INC 32
#define ERTS_PROC_LOCK_SPIN_COUNT_BASE 1000
@@ -100,6 +102,13 @@ static erts_proc_lock_queues_t zeroqs = {0};
static erts_smp_spinlock_t qs_lock;
static erts_proc_lock_queues_t *queue_free_list;
+static int proc_lock_spin_count;
+static int aux_thr_proc_lock_spin_count;
+
+static void cleanup_tse(void);
+
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
+
#ifdef ERTS_ENABLE_LOCK_CHECK
static struct {
Sint16 proc_lock_main;
@@ -111,16 +120,11 @@ static struct {
erts_pix_lock_t erts_pix_locks[ERTS_NO_OF_PIX_LOCKS];
-static int proc_lock_spin_count;
-static int aux_thr_proc_lock_spin_count;
-
-static void cleanup_tse(void);
void
erts_init_proc_lock(int cpus)
{
int i;
- erts_smp_spinlock_init(&qs_lock, "proc_lck_qs_alloc");
for (i = 0; i < ERTS_NO_OF_PIX_LOCKS; i++) {
#ifdef ERTS_ENABLE_LOCK_COUNT
erts_mtx_init_x(&erts_pix_locks[i].u.mtx,
@@ -129,14 +133,10 @@ erts_init_proc_lock(int cpus)
erts_mtx_init(&erts_pix_locks[i].u.mtx, "pix_lock");
#endif
}
+#if ERTS_PROC_LOCK_OWN_IMPL
+ erts_smp_spinlock_init(&qs_lock, "proc_lck_qs_alloc");
queue_free_list = NULL;
erts_thr_install_exit_handler(cleanup_tse);
-#ifdef ERTS_ENABLE_LOCK_CHECK
- lc_id.proc_lock_main = erts_lc_get_lock_order_id("proc_main");
- lc_id.proc_lock_link = erts_lc_get_lock_order_id("proc_link");
- lc_id.proc_lock_msgq = erts_lc_get_lock_order_id("proc_msgq");
- lc_id.proc_lock_status = erts_lc_get_lock_order_id("proc_status");
-#endif
if (cpus > 1) {
proc_lock_spin_count = ERTS_PROC_LOCK_SPIN_COUNT_BASE;
proc_lock_spin_count += (ERTS_PROC_LOCK_SPIN_COUNT_SCHED_INC
@@ -153,8 +153,17 @@ erts_init_proc_lock(int cpus)
}
if (proc_lock_spin_count > ERTS_PROC_LOCK_SPIN_COUNT_MAX)
proc_lock_spin_count = ERTS_PROC_LOCK_SPIN_COUNT_MAX;
+#endif
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ lc_id.proc_lock_main = erts_lc_get_lock_order_id("proc_main");
+ lc_id.proc_lock_link = erts_lc_get_lock_order_id("proc_link");
+ lc_id.proc_lock_msgq = erts_lc_get_lock_order_id("proc_msgq");
+ lc_id.proc_lock_status = erts_lc_get_lock_order_id("proc_status");
+#endif
}
+#if ERTS_PROC_LOCK_OWN_IMPL
+
#ifdef ERTS_ENABLE_LOCK_CHECK
static void
check_unused_tse(erts_tse_t *wtr)
@@ -220,13 +229,6 @@ tse_return(erts_tse_t *tse, int force_free_q)
erts_tse_return(tse);
}
-void
-erts_proc_lock_prepare_proc_lock_waiter(void)
-{
- tse_return(tse_fetch(NULL), 0);
-}
-
-
static void
cleanup_tse(void)
{
@@ -651,6 +653,16 @@ erts_proc_unlock_failed(Process *p,
transfer_locks(p, wait_locks, pix_lock, 1); /* unlocks pix_lock */
}
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
+
+void
+erts_proc_lock_prepare_proc_lock_waiter(void)
+{
+#if ERTS_PROC_LOCK_OWN_IMPL
+ tse_return(tse_fetch(NULL), 0);
+#endif
+}
+
/*
* proc_safelock() locks process locks on two processes. In order
* to avoid a deadlock, proc_safelock() unlocks those locks that
@@ -659,12 +671,11 @@ erts_proc_unlock_failed(Process *p,
*/
static void
-proc_safelock(Process *a_proc,
- erts_pix_lock_t *a_pix_lck,
+proc_safelock(int is_sched,
+ Process *a_proc,
ErtsProcLocks a_have_locks,
ErtsProcLocks a_need_locks,
Process *b_proc,
- erts_pix_lock_t *b_pix_lck,
ErtsProcLocks b_have_locks,
ErtsProcLocks b_need_locks)
{
@@ -672,7 +683,6 @@ proc_safelock(Process *a_proc,
#ifdef ERTS_ENABLE_LOCK_CHECK
Eterm pid1, pid2;
#endif
- erts_pix_lock_t *pix_lck1, *pix_lck2;
ErtsProcLocks need_locks1, have_locks1, need_locks2, have_locks2;
ErtsProcLocks unlock_mask;
int lock_no, refc1 = 0, refc2 = 0;
@@ -689,14 +699,12 @@ proc_safelock(Process *a_proc,
#ifdef ERTS_ENABLE_LOCK_CHECK
pid1 = a_proc->id;
#endif
- pix_lck1 = a_pix_lck;
need_locks1 = a_need_locks;
have_locks1 = a_have_locks;
p2 = b_proc;
#ifdef ERTS_ENABLE_LOCK_CHECK
pid2 = b_proc->id;
#endif
- pix_lck2 = b_pix_lck;
need_locks2 = b_need_locks;
have_locks2 = b_have_locks;
}
@@ -705,14 +713,12 @@ proc_safelock(Process *a_proc,
#ifdef ERTS_ENABLE_LOCK_CHECK
pid1 = b_proc->id;
#endif
- pix_lck1 = b_pix_lck;
need_locks1 = b_need_locks;
have_locks1 = b_have_locks;
p2 = a_proc;
#ifdef ERTS_ENABLE_LOCK_CHECK
pid2 = a_proc->id;
#endif
- pix_lck2 = a_pix_lck;
need_locks2 = a_need_locks;
have_locks2 = a_have_locks;
}
@@ -723,14 +729,12 @@ proc_safelock(Process *a_proc,
#ifdef ERTS_ENABLE_LOCK_CHECK
pid1 = a_proc->id;
#endif
- pix_lck1 = a_pix_lck;
need_locks1 = a_need_locks | b_need_locks;
have_locks1 = a_have_locks | b_have_locks;
p2 = NULL;
#ifdef ERTS_ENABLE_LOCK_CHECK
pid2 = 0;
#endif
- pix_lck2 = NULL;
need_locks2 = 0;
have_locks2 = 0;
}
@@ -740,14 +744,12 @@ proc_safelock(Process *a_proc,
#ifdef ERTS_ENABLE_LOCK_CHECK
pid1 = b_proc->id;
#endif
- pix_lck1 = b_pix_lck;
need_locks1 = b_need_locks;
have_locks1 = b_have_locks;
p2 = NULL;
#ifdef ERTS_ENABLE_LOCK_CHECK
pid2 = 0;
#endif
- pix_lck2 = NULL;
need_locks2 = 0;
have_locks2 = 0;
#ifdef ERTS_ENABLE_LOCK_CHECK
@@ -795,21 +797,21 @@ proc_safelock(Process *a_proc,
if (unlock_locks) {
have_locks1 &= ~unlock_locks;
need_locks1 |= unlock_locks;
- if (!have_locks1) {
+ if (!is_sched && !have_locks1) {
refc1 = 1;
erts_smp_proc_inc_refc(p1);
}
- erts_smp_proc_unlock__(p1, pix_lck1, unlock_locks);
+ erts_smp_proc_unlock(p1, unlock_locks);
}
unlock_locks = unlock_mask & have_locks2;
if (unlock_locks) {
have_locks2 &= ~unlock_locks;
need_locks2 |= unlock_locks;
- if (!have_locks2) {
+ if (!is_sched && !have_locks2) {
refc2 = 1;
erts_smp_proc_inc_refc(p2);
}
- erts_smp_proc_unlock__(p2, pix_lck2, unlock_locks);
+ erts_smp_proc_unlock(p2, unlock_locks);
}
}
@@ -840,7 +842,7 @@ proc_safelock(Process *a_proc,
if (need_locks2 & lock)
lock_no--;
locks = need_locks1 & lock_mask;
- erts_smp_proc_lock__(p1, pix_lck1, locks);
+ erts_smp_proc_lock(p1, locks);
have_locks1 |= locks;
need_locks1 &= ~locks;
}
@@ -851,7 +853,7 @@ proc_safelock(Process *a_proc,
lock = (1 << ++lock_no);
}
locks = need_locks2 & lock_mask;
- erts_smp_proc_lock__(p2, pix_lck2, locks);
+ erts_smp_proc_lock(p2, locks);
have_locks2 |= locks;
need_locks2 &= ~locks;
}
@@ -886,10 +888,12 @@ proc_safelock(Process *a_proc,
}
#endif
- if (refc1)
- erts_smp_proc_dec_refc(p1);
- if (refc2)
- erts_smp_proc_dec_refc(p2);
+ if (!is_sched) {
+ if (refc1)
+ erts_smp_proc_dec_refc(p1);
+ if (refc2)
+ erts_smp_proc_dec_refc(p2);
+ }
}
void
@@ -900,77 +904,191 @@ erts_proc_safelock(Process *a_proc,
ErtsProcLocks b_have_locks,
ErtsProcLocks b_need_locks)
{
- proc_safelock(a_proc,
- a_proc ? ERTS_PID2PIXLOCK(a_proc->id) : NULL,
+ proc_safelock(erts_get_scheduler_id() != 0,
+ a_proc,
a_have_locks,
a_need_locks,
b_proc,
- b_proc ? ERTS_PID2PIXLOCK(b_proc->id) : NULL,
b_have_locks,
b_need_locks);
}
-/*
- * erts_pid2proc_safelock() is called from erts_pid2proc_opt() when
- * it wasn't possible to trylock all locks needed.
- * c_p - current process
- * c_p_have_locks - locks held on c_p
- * pid - process id of process we are looking up
- * proc - process struct of process we are looking
- * up (both in and out argument)
- * need_locks - all locks we need (including have_locks)
- * pix_lock - pix lock for process we are looking up
- * flags - option flags
- */
-void
-erts_pid2proc_safelock(Process *c_p,
- ErtsProcLocks c_p_have_locks,
- Process **proc,
- ErtsProcLocks need_locks,
- erts_pix_lock_t *pix_lock,
- int flags)
+Process *
+erts_pid2proc_opt(Process *c_p,
+ ErtsProcLocks c_p_have_locks,
+ Eterm pid,
+ ErtsProcLocks pid_need_locks,
+ int flags)
{
- Process *p = *proc;
- ERTS_LC_ASSERT(p->lock.refc > 0);
- ERTS_LC_ASSERT(process_tab[internal_pid_index(p->id)] == p);
- p->lock.refc++;
- erts_pix_unlock(pix_lock);
-
- proc_safelock(c_p,
- c_p ? ERTS_PID2PIXLOCK(c_p->id) : NULL,
- c_p_have_locks,
- c_p_have_locks,
- p,
- pix_lock,
- 0,
- need_locks);
+ Process *dec_refc_proc = NULL;
+ int need_ptl;
+ ErtsProcLocks need_locks;
+ Uint pix;
+ Process *proc;
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
+ ErtsProcLocks lcnt_locks;
+#endif
- erts_pix_lock(pix_lock);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ if (c_p) {
+ ErtsProcLocks might_unlock = c_p_have_locks & pid_need_locks;
+ if (might_unlock)
+ erts_proc_lc_might_unlock(c_p, might_unlock);
+ }
+#endif
- if (!p->is_exiting
- || ((flags & ERTS_P2P_FLG_ALLOW_OTHER_X)
- && process_tab[internal_pid_index(p->id)] == p)) {
- ERTS_LC_ASSERT(p->lock.refc > 1);
- p->lock.refc--;
+ if (is_not_internal_pid(pid))
+ return NULL;
+ pix = internal_pid_index(pid);
+
+ ERTS_LC_ASSERT((pid_need_locks & ERTS_PROC_LOCKS_ALL) == pid_need_locks);
+ need_locks = pid_need_locks;
+
+ if (c_p && c_p->id == pid) {
+ ASSERT(c_p->id != ERTS_INVALID_PID);
+ ASSERT(c_p == erts_pix2proc(pix));
+
+ if (!(flags & ERTS_P2P_FLG_ALLOW_OTHER_X)
+ && ERTS_PROC_IS_EXITING(c_p))
+ return NULL;
+ need_locks &= ~c_p_have_locks;
+ if (!need_locks) {
+ if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ erts_smp_proc_inc_refc(c_p);
+ return c_p;
+ }
}
- else {
- /* No proc. Note, we need to keep refc until after process unlock */
- erts_pix_unlock(pix_lock);
- erts_smp_proc_unlock__(p, pix_lock, need_locks);
- *proc = NULL;
- erts_pix_lock(pix_lock);
- ERTS_LC_ASSERT(p->lock.refc > 0);
- if (--p->lock.refc == 0) {
- erts_pix_unlock(pix_lock);
- erts_free_proc(p);
- erts_pix_lock(pix_lock);
+
+ need_ptl = !erts_get_scheduler_id();
+
+ if (need_ptl)
+ erts_smp_rwmtx_rwlock(&erts_proc_tab_rwmtx);
+
+ proc = (Process *) erts_smp_atomic_read_ddrb(&erts_proc.tab[pix]);
+
+ if (proc) {
+ if (proc->id != pid)
+ proc = NULL;
+ else if (!need_locks) {
+ if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ erts_smp_proc_inc_refc(proc);
}
+ else {
+ int busy;
+
+#if ERTS_PROC_LOCK_OWN_IMPL
+#ifdef ERTS_ENABLE_LOCK_COUNT
+ lcnt_locks = need_locks;
+ if (!(flags & ERTS_P2P_FLG_TRY_LOCK)) {
+ erts_lcnt_proc_lock(&proc->lock, need_locks);
+ }
+#endif
+
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ /* Make sure erts_pid2proc_safelock() is enough to handle
+ a potential lock order violation situation... */
+ busy = erts_proc_lc_trylock_force_busy(proc, need_locks);
+ if (!busy)
+#endif
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
+ {
+ /* Try a quick trylock to grab all the locks we need. */
+ busy = (int) erts_smp_proc_raw_trylock__(proc, need_locks);
+
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_CHECK)
+ erts_proc_lc_trylock(proc, need_locks, !busy);
+#endif
+#ifdef ERTS_PROC_LOCK_DEBUG
+ if (!busy)
+ erts_proc_lock_op_debug(proc, need_locks, 1);
+#endif
+ }
+
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
+ if (flags & ERTS_P2P_FLG_TRY_LOCK)
+ erts_lcnt_proc_trylock(&proc->lock, need_locks,
+ busy ? EBUSY : 0);
+#endif
+
+ if (!busy) {
+ if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ erts_smp_proc_inc_refc(proc);
+
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
+ /* all is great */
+ if (!(flags & ERTS_P2P_FLG_TRY_LOCK))
+ erts_lcnt_proc_lock_post_x(&proc->lock, lcnt_locks,
+ __FILE__, __LINE__);
+#endif
+
+ }
+ else {
+ if (flags & ERTS_P2P_FLG_TRY_LOCK)
+ proc = ERTS_PROC_LOCK_BUSY;
+ else {
+ if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ erts_smp_proc_inc_refc(proc);
+
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
+ erts_lcnt_proc_lock_unaquire(&proc->lock, lcnt_locks);
+#endif
+
+ if (need_ptl) {
+ erts_smp_proc_inc_refc(proc);
+ dec_refc_proc = proc;
+ erts_smp_rwmtx_rwunlock(&erts_proc_tab_rwmtx);
+ need_ptl = 0;
+ }
+
+ proc_safelock(!need_ptl,
+ c_p,
+ c_p_have_locks,
+ c_p_have_locks,
+ proc,
+ 0,
+ need_locks);
+ }
+ }
+ }
}
+
+ if (need_ptl)
+ erts_smp_rwmtx_rwunlock(&erts_proc_tab_rwmtx);
+
+ if (need_locks
+ && proc
+ && proc != ERTS_PROC_LOCK_BUSY
+ && (!(flags & ERTS_P2P_FLG_ALLOW_OTHER_X)
+ ? ERTS_PROC_IS_EXITING(proc)
+ : (proc
+ != (Process *) erts_smp_atomic_read_nob(&erts_proc.tab[pix])))) {
+
+ erts_smp_proc_unlock(proc, need_locks);
+
+ if (flags & ERTS_P2P_FLG_SMP_INC_REFC)
+ dec_refc_proc = proc;
+ proc = NULL;
+
+ }
+
+ if (dec_refc_proc)
+ erts_smp_proc_dec_refc(dec_refc_proc);
+
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_PROC_LOCK_DEBUG)
+ ERTS_LC_ASSERT(!proc
+ || proc == ERTS_PROC_LOCK_BUSY
+ || (pid_need_locks ==
+ (ERTS_PROC_LOCK_FLGS_READ_(&proc->lock)
+ & pid_need_locks)));
+#endif
+
+ return proc;
}
void
erts_proc_lock_init(Process *p)
{
+#if ERTS_PROC_LOCK_OWN_IMPL
/* We always start with all locks locked */
#if ERTS_PROC_LOCK_ATOMIC_IMPL
erts_smp_atomic32_init_nob(&p->lock.flags,
@@ -979,16 +1097,32 @@ erts_proc_lock_init(Process *p)
p->lock.flags = ERTS_PROC_LOCKS_ALL;
#endif
p->lock.queues = NULL;
- p->lock.refc = 1;
-#ifdef ERTS_ENABLE_LOCK_COUNT
- erts_lcnt_proc_lock_init(p);
- erts_lcnt_proc_lock(&(p->lock), ERTS_PROC_LOCKS_ALL);
- erts_lcnt_proc_lock_post_x(&(p->lock), ERTS_PROC_LOCKS_ALL, __FILE__, __LINE__);
-#endif
-
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_proc_lc_trylock(p, ERTS_PROC_LOCKS_ALL, 1);
#endif
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_mtx_init_x(&p->lock.main, "proc_main", p->id);
+ ethr_mutex_lock(&p->lock.main.mtx);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_trylock(1, &p->lock.main.lc);
+#endif
+ erts_mtx_init_x(&p->lock.link, "proc_link", p->id);
+ ethr_mutex_lock(&p->lock.link.mtx);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_trylock(1, &p->lock.link.lc);
+#endif
+ erts_mtx_init_x(&p->lock.msgq, "proc_msgq", p->id);
+ ethr_mutex_lock(&p->lock.msgq.mtx);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_trylock(1, &p->lock.msgq.lc);
+#endif
+ erts_mtx_init_x(&p->lock.status, "proc_status", p->id);
+ ethr_mutex_lock(&p->lock.status.mtx);
+#ifdef ERTS_ENABLE_LOCK_CHECK
+ erts_lc_trylock(1, &p->lock.status.lc);
+#endif
+#endif
+ erts_atomic32_init_nob(&p->lock.refc, 1);
#ifdef ERTS_PROC_LOCK_DEBUG
{
int i;
@@ -996,11 +1130,30 @@ erts_proc_lock_init(Process *p)
erts_smp_atomic32_init_nob(&p->lock.locked[i], (erts_aint32_t) 1);
}
#endif
+#ifdef ERTS_ENABLE_LOCK_COUNT
+ erts_lcnt_proc_lock_init(p);
+ erts_lcnt_proc_lock(&(p->lock), ERTS_PROC_LOCKS_ALL);
+ erts_lcnt_proc_lock_post_x(&(p->lock), ERTS_PROC_LOCKS_ALL, __FILE__, __LINE__);
+#endif
+}
+
+void
+erts_proc_lock_fin(Process *p)
+{
+#if ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_mtx_destroy(&p->lock.main);
+ erts_mtx_destroy(&p->lock.link);
+ erts_mtx_destroy(&p->lock.msgq);
+ erts_mtx_destroy(&p->lock.status);
+#endif
+#if defined(ERTS_ENABLE_LOCK_COUNT) && defined(ERTS_SMP)
+ erts_lcnt_proc_lock_destroy(p);
+#endif
}
/* --- Process lock counting ----------------------------------------------- */
-#ifdef ERTS_ENABLE_LOCK_COUNT
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_ENABLE_LOCK_COUNT)
void erts_lcnt_proc_lock_init(Process *p) {
if (erts_lcnt_rt_options & ERTS_LCNT_OPT_PROCLOCK) {
if (p->id != ERTS_INVALID_PID) {
@@ -1141,6 +1294,8 @@ void erts_lcnt_enable_proc_lock_count(int enable) {
#ifdef ERTS_ENABLE_LOCK_CHECK
+#if ERTS_PROC_LOCK_OWN_IMPL
+
void
erts_proc_lc_lock(Process *p, ErtsProcLocks locks)
{
@@ -1213,9 +1368,12 @@ erts_proc_lc_unlock(Process *p, ErtsProcLocks locks)
}
}
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
+
void
erts_proc_lc_might_unlock(Process *p, ErtsProcLocks locks)
{
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t lck = ERTS_LC_LOCK_INIT(-1,
p->id,
ERTS_LC_FLG_LT_PROCLOCK);
@@ -1235,11 +1393,22 @@ erts_proc_lc_might_unlock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_main;
erts_lc_might_unlock(&lck);
}
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ if (locks & ERTS_PROC_LOCK_MAIN)
+ erts_lc_might_unlock(&p->lock.main.lc);
+ if (locks & ERTS_PROC_LOCK_LINK)
+ erts_lc_might_unlock(&p->lock.link.lc);
+ if (locks & ERTS_PROC_LOCK_MSGQ)
+ erts_lc_might_unlock(&p->lock.msgq.lc);
+ if (locks & ERTS_PROC_LOCK_STATUS)
+ erts_lc_might_unlock(&p->lock.status.lc);
+#endif
}
void
erts_proc_lc_require_lock(Process *p, ErtsProcLocks locks)
{
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t lck = ERTS_LC_LOCK_INIT(-1,
p->id,
ERTS_LC_FLG_LT_PROCLOCK);
@@ -1259,11 +1428,22 @@ erts_proc_lc_require_lock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_status;
erts_lc_require_lock(&lck);
}
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ if (locks & ERTS_PROC_LOCK_MAIN)
+ erts_lc_require_lock(&p->lock.main.lc);
+ if (locks & ERTS_PROC_LOCK_LINK)
+ erts_lc_require_lock(&p->lock.link.lc);
+ if (locks & ERTS_PROC_LOCK_MSGQ)
+ erts_lc_require_lock(&p->lock.msgq.lc);
+ if (locks & ERTS_PROC_LOCK_STATUS)
+ erts_lc_require_lock(&p->lock.status.lc);
+#endif
}
void
erts_proc_lc_unrequire_lock(Process *p, ErtsProcLocks locks)
{
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t lck = ERTS_LC_LOCK_INIT(-1,
p->id,
ERTS_LC_FLG_LT_PROCLOCK);
@@ -1283,8 +1463,19 @@ erts_proc_lc_unrequire_lock(Process *p, ErtsProcLocks locks)
lck.id = lc_id.proc_lock_main;
erts_lc_unrequire_lock(&lck);
}
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ if (locks & ERTS_PROC_LOCK_MAIN)
+ erts_lc_unrequire_lock(&p->lock.main.lc);
+ if (locks & ERTS_PROC_LOCK_LINK)
+ erts_lc_unrequire_lock(&p->lock.link.lc);
+ if (locks & ERTS_PROC_LOCK_MSGQ)
+ erts_lc_unrequire_lock(&p->lock.msgq.lc);
+ if (locks & ERTS_PROC_LOCK_STATUS)
+ erts_lc_unrequire_lock(&p->lock.status.lc);
+#endif
}
+#if ERTS_PROC_LOCK_OWN_IMPL
int
erts_proc_lc_trylock_force_busy(Process *p, ErtsProcLocks locks)
@@ -1310,21 +1501,30 @@ erts_proc_lc_trylock_force_busy(Process *p, ErtsProcLocks locks)
return 0;
}
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
+
void erts_proc_lc_chk_only_proc_main(Process *p)
{
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t proc_main = ERTS_LC_LOCK_INIT(lc_id.proc_lock_main,
p->id,
ERTS_LC_FLG_LT_PROCLOCK);
erts_lc_check_exact(&proc_main, 1);
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_lc_check_exact(&p->lock.main.lc, 1);
+#endif
}
+#if ERTS_PROC_LOCK_OWN_IMPL
#define ERTS_PROC_LC_EMPTY_LOCK_INIT \
ERTS_LC_LOCK_INIT(-1, THE_NON_VALUE, ERTS_LC_FLG_LT_PROCLOCK)
+#endif /* ERTS_PROC_LOCK_OWN_IMPL */
void
erts_proc_lc_chk_have_proc_locks(Process *p, ErtsProcLocks locks)
{
int have_locks_len = 0;
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t have_locks[4] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
@@ -1345,7 +1545,17 @@ erts_proc_lc_chk_have_proc_locks(Process *p, ErtsProcLocks locks)
have_locks[have_locks_len].id = lc_id.proc_lock_status;
have_locks[have_locks_len++].extra = p->id;
}
-
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_lc_lock_t have_locks[4];
+ if (locks & ERTS_PROC_LOCK_MAIN)
+ have_locks[have_locks_len++] = p->lock.main.lc;
+ if (locks & ERTS_PROC_LOCK_LINK)
+ have_locks[have_locks_len++] = p->lock.link.lc;
+ if (locks & ERTS_PROC_LOCK_MSGQ)
+ have_locks[have_locks_len++] = p->lock.msgq.lc;
+ if (locks & ERTS_PROC_LOCK_STATUS)
+ have_locks[have_locks_len++] = p->lock.status.lc;
+#endif
erts_lc_check(have_locks, have_locks_len, NULL, 0);
}
@@ -1354,6 +1564,7 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
{
int have_locks_len = 0;
int have_not_locks_len = 0;
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t have_locks[4] = {ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
ERTS_PROC_LC_EMPTY_LOCK_INIT,
@@ -1395,6 +1606,27 @@ erts_proc_lc_chk_proc_locks(Process *p, ErtsProcLocks locks)
have_not_locks[have_not_locks_len].id = lc_id.proc_lock_status;
have_not_locks[have_not_locks_len++].extra = p->id;
}
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_lc_lock_t have_locks[4];
+ erts_lc_lock_t have_not_locks[4];
+
+ if (locks & ERTS_PROC_LOCK_MAIN)
+ have_locks[have_locks_len++] = p->lock.main.lc;
+ else
+ have_not_locks[have_not_locks_len++] = p->lock.main.lc;
+ if (locks & ERTS_PROC_LOCK_LINK)
+ have_locks[have_locks_len++] = p->lock.link.lc;
+ else
+ have_not_locks[have_not_locks_len++] = p->lock.link.lc;
+ if (locks & ERTS_PROC_LOCK_MSGQ)
+ have_locks[have_locks_len++] = p->lock.msgq.lc;
+ else
+ have_not_locks[have_not_locks_len++] = p->lock.msgq.lc;
+ if (locks & ERTS_PROC_LOCK_STATUS)
+ have_locks[have_locks_len++] = p->lock.status.lc;
+ else
+ have_not_locks[have_not_locks_len++] = p->lock.status.lc;
+#endif
erts_lc_check(have_locks, have_locks_len,
have_not_locks, have_not_locks_len);
@@ -1404,6 +1636,8 @@ ErtsProcLocks
erts_proc_lc_my_proc_locks(Process *p)
{
int resv[4];
+ ErtsProcLocks res = 0;
+#if ERTS_PROC_LOCK_OWN_IMPL
erts_lc_lock_t locks[4] = {ERTS_LC_LOCK_INIT(lc_id.proc_lock_main,
p->id,
ERTS_LC_FLG_LT_PROCLOCK),
@@ -1416,8 +1650,12 @@ erts_proc_lc_my_proc_locks(Process *p)
ERTS_LC_LOCK_INIT(lc_id.proc_lock_status,
p->id,
ERTS_LC_FLG_LT_PROCLOCK)};
-
- ErtsProcLocks res = 0;
+#elif ERTS_PROC_LOCK_RAW_MUTEX_IMPL
+ erts_lc_lock_t locks[4] = {p->lock.main.lc,
+ p->lock.link.lc,
+ p->lock.msgq.lc,
+ p->lock.status.lc};
+#endif
erts_lc_have_locks(resv, locks, 4);
if (resv[0])
@@ -1450,7 +1688,7 @@ erts_proc_lc_chk_no_proc_locks(char *file, int line)
#endif /* #ifdef ERTS_ENABLE_LOCK_CHECK */
-#ifdef ERTS_PROC_LOCK_HARD_DEBUG
+#if ERTS_PROC_LOCK_OWN_IMPL && defined(ERTS_PROC_LOCK_HARD_DEBUG)
void
check_queue(erts_proc_lock_t *lck)
{
@@ -1483,4 +1721,4 @@ check_queue(erts_proc_lock_t *lck)
}
#endif
-#endif /* ERTS_SMP (the whole file) */
+#endif /* ERTS_SMP */