Changeset: de90ccd28a1c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/de90ccd28a1c
Modified Files:
        gdk/gdk_system.c
        gdk/gdk_system.h
Branch: Jul2021
Log Message:

Make lock stats faster to use by using a doubly linked list.
Deleting random entries from a singly linked list is really expensive.


diffs (127 lines):

diff --git a/gdk/gdk_system.c b/gdk/gdk_system.c
--- a/gdk/gdk_system.c
+++ b/gdk/gdk_system.c
@@ -73,6 +73,7 @@ sortlocklist(MT_Lock *l)
                r = r->next;
        }
        ll->next = NULL;        /* break list into two */
+       r->prev = NULL;
        /* recursively sort both sublists */
        l = sortlocklist(l);
        r = sortlocklist(r);
@@ -92,6 +93,7 @@ sortlocklist(MT_Lock *l)
                                t = ll = l;
                        } else {
                                ll->next = l;
+                               l->prev = ll;
                                ll = ll->next;
                        }
                        l = l->next;
@@ -102,13 +104,20 @@ sortlocklist(MT_Lock *l)
                                t = ll = r;
                        } else {
                                ll->next = r;
+                               r->prev = ll;
                                ll = ll->next;
                        }
                        r = r->next;
                }
        }
        /* append rest of remaining list */
-       ll->next = l ? l : r;
+       if (l) {
+               ll->next = l;
+               l->prev = ll;
+       } else {
+               ll->next = r;
+               r->prev = ll;
+       }
        return t;
 }
 
@@ -143,7 +152,9 @@ GDKlockstatistics(int what)
                return;
        }
        GDKlocklist = sortlocklist(GDKlocklist);
-       fprintf(stderr, "lock 
name\tcount\tcontention\tsleep\tlocked\t(un)locker\tthread\n");
+       fprintf(stderr, "%-18s\t%s\t%s\t%s\t%s\t%s\t%s\n",
+               "lock name", "count", "content", "sleep",
+               "locked", "locker", "thread");
        for (l = GDKlocklist; l; l = l->next) {
                n++;
                if (what == 0 ||
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -212,6 +212,9 @@ gdk_export int MT_join_thread(MT_Id t);
                        while (ATOMIC_TAS(&GDKlocklistlock) != 0)       \
                                ;                                       \
                        (l)->next = GDKlocklist;                        \
+                       (l)->prev = NULL;                               \
+                       if (GDKlocklist)                                \
+                               GDKlocklist->prev = (l);                \
                        GDKlocklist = (l);                              \
                        ATOMIC_CLEAR(&GDKlocklistlock);                 \
                }                                                       \
@@ -230,16 +233,17 @@ gdk_export int MT_join_thread(MT_Id t);
                /* SQL storage allocator, and hence we have no control */ \
                /* over when the lock is destroyed and the memory freed */ \
                if (strncmp((l)->name, "sa_", 3) != 0) {                \
-                       MT_Lock * volatile _p;                          \
                        while (ATOMIC_TAS(&GDKlocklistlock) != 0)       \
                                ;                                       \
-                       for (_p = GDKlocklist; _p; _p = _p->next)       \
-                               assert(_p != (l));                      \
+                       if (GDKlocklist)                                \
+                               GDKlocklist->prev = (l);                \
                        (l)->next = GDKlocklist;                        \
+                       (l)->prev = NULL;                               \
                        GDKlocklist = (l);                              \
                        ATOMIC_CLEAR(&GDKlocklistlock);                 \
                } else {                                                \
                        (l)->next = NULL;                               \
+                       (l)->prev = NULL;                               \
                }                                                       \
        } while (0)
 
@@ -250,14 +254,14 @@ gdk_export int MT_join_thread(MT_Id t);
                /* SQL storage allocator, and hence we have no control */ \
                /* over when the lock is destroyed and the memory freed */ \
                if (strncmp((l)->name, "sa_", 3) != 0) {                \
-                       MT_Lock * volatile *_p;                         \
                        while (ATOMIC_TAS(&GDKlocklistlock) != 0)       \
                                ;                                       \
-                       for (_p = &GDKlocklist; *_p; _p = &(*_p)->next) \
-                               if ((l) == *_p) {                       \
-                                       *_p = (l)->next;                \
-                                       break;                          \
-                               }                                       \
+                       if ((l)->next)                                  \
+                               (l)->next->prev = (l)->prev;            \
+                       if ((l)->prev)                                  \
+                               (l)->prev->next = (l)->next;            \
+                       else if (GDKlocklist == (l))                    \
+                               GDKlocklist = (l)->next;                \
                        ATOMIC_CLEAR(&GDKlocklistlock);                 \
                        ATOMIC_DESTROY(&(l)->contention);               \
                        ATOMIC_DESTROY(&(l)->sleep);                    \
@@ -285,7 +289,8 @@ typedef struct MT_Lock {
        size_t count;
        ATOMIC_TYPE contention;
        ATOMIC_TYPE sleep;
-       struct MT_Lock * volatile next;
+       struct MT_Lock *volatile next;
+       struct MT_Lock *volatile prev;
        const char *locker;
        const char *thread;
 #endif
@@ -383,7 +388,8 @@ typedef struct MT_Lock {
        size_t count;
        ATOMIC_TYPE contention;
        ATOMIC_TYPE sleep;
-       struct MT_Lock * volatile next;
+       struct MT_Lock *volatile next;
+       struct MT_Lock *volatile prev;
        const char *locker;
        const char *thread;
 #endif
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to