File 0542-erts-Refactor-DB_READ_TBL_STRUCT-in-erl_db.c.patch of Package erlang

From 30be223d2a93b1b533bd011a311852321bad7c73 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Fri, 2 Sep 2022 14:25:29 +0200
Subject: [PATCH 2/5] erts: Refactor DB_READ_TBL_STRUCT in erl_db.c

---
 erts/emulator/beam/erl_db.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/erts/emulator/beam/erl_db.c b/erts/emulator/beam/erl_db.c
index 4a699427eb..456770041a 100644
--- a/erts/emulator/beam/erl_db.c
+++ b/erts/emulator/beam/erl_db.c
@@ -388,7 +388,7 @@ typedef enum {
     LCK_READ=1,     /* read only access */
     LCK_WRITE=2,    /* exclusive table write access */
     LCK_WRITE_REC=3, /* record write access */
-    NOLCK_ACCESS=4 /* Used to access the table structure
+    LCK_NOLOCK_ACCESS=4 /* Used to access the table structure
                       without acquiring the table lock */
 } db_lock_kind_t;
 
@@ -650,13 +650,15 @@ static ERTS_INLINE void db_init_lock(DbTable* tb, int use_frequent_read_lock)
 
 static ERTS_INLINE void db_lock(DbTable* tb, db_lock_kind_t kind)
 {
+    ASSERT(kind != LCK_NOLOCK_ACCESS);
     if (DB_LOCK_FREE(tb))
         return;
     if (tb->common.type & DB_FINE_LOCKED) {
         if (kind == LCK_WRITE) {
             erts_rwmtx_rwlock(&tb->common.rwlock);
             tb->common.is_thread_safe = 1;
-        } else if (kind != NOLCK_ACCESS) {
+        }
+        else {
             erts_rwmtx_rlock(&tb->common.rwlock);
             ASSERT(!tb->common.is_thread_safe);
         }
@@ -668,8 +670,6 @@ static ERTS_INLINE void db_lock(DbTable* tb, db_lock_kind_t kind)
         case LCK_WRITE_REC:
             erts_rwmtx_rwlock(&tb->common.rwlock);
             break;
-        case NOLCK_ACCESS:
-            return;
         default:
             erts_rwmtx_rlock(&tb->common.rwlock);
         }
@@ -679,7 +679,7 @@ static ERTS_INLINE void db_lock(DbTable* tb, db_lock_kind_t kind)
 
 static ERTS_INLINE void db_unlock(DbTable* tb, db_lock_kind_t kind)
 {
-    if (DB_LOCK_FREE(tb) || kind == NOLCK_ACCESS)
+    if (DB_LOCK_FREE(tb) || kind == LCK_NOLOCK_ACCESS)
         return;
     if (tb->common.type & DB_FINE_LOCKED) {
         if (kind == LCK_WRITE) {
@@ -712,7 +712,7 @@ static ERTS_INLINE int db_is_exclusive(DbTable* tb, db_lock_kind_t kind)
 
     return
         kind != LCK_READ &&
-        kind != NOLCK_ACCESS &&
+        kind != LCK_NOLOCK_ACCESS &&
         tb->common.is_thread_safe;
 }
 
@@ -774,7 +774,7 @@ DbTable* db_get_table_aux(Process *p,
      */
     ASSERT(erts_get_scheduler_data() && !ERTS_SCHEDULER_IS_DIRTY(erts_get_scheduler_data()));
 
-    ASSERT((what == DB_READ_TBL_STRUCT) == (kind == NOLCK_ACCESS));
+    ASSERT((what == DB_READ_TBL_STRUCT) == (kind == LCK_NOLOCK_ACCESS));
 
     if (META_DB_LOCK_FREE())
         meta_already_locked = 1;
@@ -817,13 +817,16 @@ DbTable* db_get_table_aux(Process *p,
     }
 
     if (tb) {
+        if (what == DB_READ_TBL_STRUCT)
+            return tb;
+
 	db_lock(tb, kind);
 #ifdef ETS_DBG_FORCE_TRAP
         /*
          * The ets_SUITE uses this to verify that all table lookups calls
          * can handle a failed TRAP return correctly.
          */
-        if (what != DB_READ_TBL_STRUCT && tb->common.dbg_force_trap) {
+         if (tb->common.dbg_force_trap) {
             if (!(p->flags & F_DBG_FORCED_TRAP)) {
                 db_unlock(tb, kind);
                 tb = NULL;
@@ -837,11 +840,7 @@ DbTable* db_get_table_aux(Process *p,
             }
         }
 #endif
-        if (what != DB_READ_TBL_STRUCT
-            /* IMPORTANT: the above check is necessary as the status field
-                          might be in an intermediate state when
-                          kind==NOLCK_ACCESS */
-                && ERTS_UNLIKELY(!(tb->common.status & what))) {
+        if (ERTS_UNLIKELY(!(tb->common.status & what))) {
             tb = handle_lacking_permission(p, tb, kind, freason_p);
         }
     }
@@ -1939,7 +1938,8 @@ static BIF_RETTYPE ets_insert_2_list_driver(Process* p,
             DbTable* tb;
             /* First check if another process has completed the
                operation without acquiring the lock */
-            tb = db_get_table(p, tid, DB_READ_TBL_STRUCT, NOLCK_ACCESS, &freason);
+            tb = db_get_table(p, tid, DB_READ_TBL_STRUCT, LCK_NOLOCK_ACCESS,
+                              &freason);
             ASSERT(tb || freason != TRAP);
             if (tb != NULL &&
                 (void*)erts_atomic_read_acqb(&tb->common.continuation_state) ==
@@ -1978,7 +1978,8 @@ static BIF_RETTYPE ets_insert_2_list_driver(Process* p,
         ictx.status = ETS_INSERT_2_LIST_PROCESS_LOCAL;
         ictx.tb = NULL;
         ctx = &ictx;
-        DB_GET_TABLE(ctx->tb, tid, DB_READ_TBL_STRUCT, NOLCK_ACCESS, bix, NULL, p);
+        DB_GET_TABLE(ctx->tb, tid, DB_READ_TBL_STRUCT, LCK_NOLOCK_ACCESS, bix,
+                     NULL, p);
 #if defined(DEBUG) && defined(ARCH_64)
         ycf_debug_set_stack_start(&nr_of_reductions);
 #endif
-- 
2.35.3

openSUSE Build Service is sponsored by