From 3f0e95a08394e92a58f99f99a94f9349e35842dd Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Fri, 5 May 2017 19:47:07 +0200
Subject: erts: Unbreak --enable-lock-checking --enable-lock-counter

both together.

Broken in OTP-20.0-rc1 by 7d161f5b475575bd79bd90977b3a79334a8ec658.
---
 erts/emulator/beam/erl_lock_count.c | 8 ++++++--
 erts/emulator/beam/erl_lock_count.h | 2 ++
 erts/emulator/beam/erl_port_task.h  | 8 +++++---
 erts/emulator/beam/erl_smp.h        | 2 +-
 erts/emulator/beam/erl_threads.h    | 6 +++---
 erts/emulator/beam/io.c             | 8 +++++---
 6 files changed, 22 insertions(+), 12 deletions(-)

(limited to 'erts/emulator')

diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index 6354fc8663..49b1f08b44 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -358,8 +358,11 @@ void erts_lcnt_init_lock(erts_lcnt_lock_t *lock, char *name, Uint16 flag ) {
 
 void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eterm id) {
     int i;
-    if (name == NULL) { ERTS_LCNT_CLEAR_FLAG(lock); return; }
-    lcnt_lock();
+
+    if (flag & ERTS_LCNT_LT_DISABLE) {
+        ERTS_LCNT_CLEAR_FLAG(lock);
+        return;
+    }
 
     lock->next = NULL;
     lock->prev = NULL;
@@ -379,6 +382,7 @@ void erts_lcnt_init_lock_x(erts_lcnt_lock_t *lock, char *name, Uint16 flag, Eter
         lcnt_clear_stats(&lock->stats[i]);
     }
 
+    lcnt_lock();
     erts_lcnt_list_insert(erts_lcnt_data->current_locks, lock);
     lcnt_unlock();
 }
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index 3041474382..be601a26fc 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -95,6 +95,8 @@
 #define ERTS_LCNT_LO_READ       (((Uint16) 1) << 6)
 #define ERTS_LCNT_LO_WRITE      (((Uint16) 1) << 7)
 
+#define ERTS_LCNT_LT_DISABLE    (((Uint16) 1) << 8)
+
 #define ERTS_LCNT_LO_READ_WRITE ( ERTS_LCNT_LO_READ  \
                                 | ERTS_LCNT_LO_WRITE )
 
diff --git a/erts/emulator/beam/erl_port_task.h b/erts/emulator/beam/erl_port_task.h
index e3550e878e..858ddfe029 100644
--- a/erts/emulator/beam/erl_port_task.h
+++ b/erts/emulator/beam/erl_port_task.h
@@ -189,11 +189,13 @@ erts_port_task_init_sched(ErtsPortTaskSched *ptsp, Eterm instr_id)
     erts_smp_atomic32_init_nob(&ptsp->flags, 0);
 #ifdef ERTS_SMP
 #ifdef ERTS_ENABLE_LOCK_COUNT
-    if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PORTLOCK))
-        lock_str = NULL;
-#endif
+    erts_mtx_init_x_opt(&ptsp->mtx, lock_str, instr_id,
+			((erts_lcnt_rt_options & ERTS_LCNT_OPT_PORTLOCK)
+			 ? 0 : ERTS_LCNT_LT_DISABLE));
+#else
     erts_mtx_init_x(&ptsp->mtx, lock_str, instr_id);
 #endif
+#endif
 }
 
 ERTS_GLB_INLINE void
diff --git a/erts/emulator/beam/erl_smp.h b/erts/emulator/beam/erl_smp.h
index 14be511f86..55ba943bdd 100644
--- a/erts/emulator/beam/erl_smp.h
+++ b/erts/emulator/beam/erl_smp.h
@@ -1073,7 +1073,7 @@ ERTS_GLB_INLINE void
 erts_smp_mtx_init_locked_x(erts_smp_mtx_t *mtx, char *name, Eterm extra)
 {
 #ifdef ERTS_SMP
-    erts_mtx_init_locked_x(mtx, name, extra);
+    erts_mtx_init_locked_x_opt(mtx, name, extra, 0);
 #endif
 }
 
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h
index 9e75f6fee5..28ff5d3a42 100644
--- a/erts/emulator/beam/erl_threads.h
+++ b/erts/emulator/beam/erl_threads.h
@@ -481,7 +481,7 @@ ERTS_GLB_INLINE int erts_thr_getname(erts_tid_t tid, char *buf, size_t len);
 ERTS_GLB_INLINE int erts_equal_tids(erts_tid_t x, erts_tid_t y);
 ERTS_GLB_INLINE void erts_mtx_init_x(erts_mtx_t *mtx, char *name, Eterm extra);
 ERTS_GLB_INLINE void erts_mtx_init_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, Uint16 opt);
-ERTS_GLB_INLINE void erts_mtx_init_locked_x(erts_mtx_t *mtx, char *name, Eterm extra);
+ERTS_GLB_INLINE void erts_mtx_init_locked_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, Uint16 opt);
 ERTS_GLB_INLINE void erts_mtx_init(erts_mtx_t *mtx, char *name);
 ERTS_GLB_INLINE void erts_mtx_init_locked(erts_mtx_t *mtx, char *name);
 ERTS_GLB_INLINE void erts_mtx_destroy(erts_mtx_t *mtx);
@@ -2192,7 +2192,7 @@ erts_mtx_init_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, Uint16 opt)
 
 
 ERTS_GLB_INLINE void
-erts_mtx_init_locked_x(erts_mtx_t *mtx, char *name, Eterm extra)
+erts_mtx_init_locked_x_opt(erts_mtx_t *mtx, char *name, Eterm extra, Uint16 opt)
 {
 #ifdef USE_THREADS
     int res = ethr_mutex_init(&mtx->mtx);
@@ -2202,7 +2202,7 @@ erts_mtx_init_locked_x(erts_mtx_t *mtx, char *name, Eterm extra)
     erts_lc_init_lock_x(&mtx->lc, name, ERTS_LC_FLG_LT_MUTEX, extra);
 #endif
 #ifdef ERTS_ENABLE_LOCK_COUNT
-    erts_lcnt_init_lock_x(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX, extra);
+    erts_lcnt_init_lock_x(&mtx->lcnt, name, ERTS_LCNT_LT_MUTEX | opt, extra);
 #endif
     ethr_mutex_lock(&mtx->mtx);
 #ifdef ERTS_ENABLE_LOCK_CHECK
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index bf89740fda..93a5ed4397 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -260,10 +260,12 @@ static ERTS_INLINE void port_init_instr(Port *prt
     if (!prt->drv_ptr->lock) {
 	char *lock_str = "port_lock";
 #ifdef ERTS_ENABLE_LOCK_COUNT
-        if (!(erts_lcnt_rt_options & ERTS_LCNT_OPT_PORTLOCK))
-            lock_str = NULL;
+	Uint16 opt = ((erts_lcnt_rt_options & ERTS_LCNT_OPT_PORTLOCK)
+			    ? 0 : ERTS_LCNT_LT_DISABLE);
+#else
+	Uint16 opt = 0;
 #endif
-	erts_mtx_init_locked_x(prt->lock, lock_str, id);
+	erts_mtx_init_locked_x_opt(prt->lock, lock_str, id, opt);
     }
 #endif
     erts_port_task_init_sched(&prt->sched, id);
-- 
cgit v1.2.3


From eb9ffb378b9eb3b9f4a0f898e60ade01d3d48283 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Fri, 5 May 2017 20:29:58 +0200
Subject: erts: Add minor lock optimization for lcnt

---
 erts/emulator/beam/erl_lock_count.c | 21 ++++++++++-----------
 erts/emulator/beam/erl_lock_count.h |  1 -
 2 files changed, 10 insertions(+), 12 deletions(-)

(limited to 'erts/emulator')

diff --git a/erts/emulator/beam/erl_lock_count.c b/erts/emulator/beam/erl_lock_count.c
index 49b1f08b44..aee9796171 100644
--- a/erts/emulator/beam/erl_lock_count.c
+++ b/erts/emulator/beam/erl_lock_count.c
@@ -299,22 +299,16 @@ erts_lcnt_lock_list_t *erts_lcnt_list_init(void) {
     return list;
 }
 
-/* only do this on the list with the deleted locks! */
-void erts_lcnt_list_clear(erts_lcnt_lock_list_t *list) {
-    erts_lcnt_lock_t *lock = NULL,
-                     *next = NULL;
+static void lcnt_list_free(erts_lcnt_lock_t *head) {
+    erts_lcnt_lock_t *lock, *next;
 
-    lock = list->head;
+    lock = head;
 
     while(lock != NULL) {
         next = lock->next;
         free(lock);
         lock = next;
     }
-
-    list->head = NULL;
-    list->tail = NULL;
-    list->n    = 0;
 }
 
 void erts_lcnt_list_insert(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock) {
@@ -679,12 +673,17 @@ void erts_lcnt_clear_counters(void) {
         lock->n_stats = 1;
     }
 
-    /* empty deleted locks in lock list */
-    erts_lcnt_list_clear(erts_lcnt_data->deleted_locks);
+    lock = erts_lcnt_data->deleted_locks->head;
+    erts_lcnt_data->deleted_locks->head = NULL;
+    erts_lcnt_data->deleted_locks->tail = NULL;
+    erts_lcnt_data->deleted_locks->n = 0;
 
     lcnt_time(&timer_start);
 
     lcnt_unlock();
+
+    /* free deleted locks */
+    lcnt_list_free(lock);
 }
 
 erts_lcnt_data_t *erts_lcnt_get_data(void) {
diff --git a/erts/emulator/beam/erl_lock_count.h b/erts/emulator/beam/erl_lock_count.h
index be601a26fc..6caffbfe86 100644
--- a/erts/emulator/beam/erl_lock_count.h
+++ b/erts/emulator/beam/erl_lock_count.h
@@ -206,7 +206,6 @@ void erts_lcnt_thread_exit_handler(void);
 /* list operations (local)  */
 erts_lcnt_lock_list_t *erts_lcnt_list_init(void);
 
-void erts_lcnt_list_clear( erts_lcnt_lock_list_t *list);
 void erts_lcnt_list_insert(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock);
 void erts_lcnt_list_delete(erts_lcnt_lock_list_t *list, erts_lcnt_lock_t *lock);
 
-- 
cgit v1.2.3