]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mt_list: Implement mt_list_try_lock_prev().
authorOlivier Houchard <ohouchard@haproxy.com>
Tue, 25 Mar 2025 16:17:56 +0000 (16:17 +0000)
committerOlivier Houchard <cognet@ci0.org>
Tue, 1 Apr 2025 16:05:30 +0000 (18:05 +0200)
Implement mt_list_try_lock_prev(), that does the same thing
as mt_list_lock_prev(), exceot if the list is locked, it
returns { NULL, NULL } instaed of waiting.

doc/internals/api/mt_list.txt
include/import/mt_list.h

index 8a6bd88ae7f5841dd754bed4c3785c0f327cabf4..46d86eaf76dfc59f41fa689e5256c9ad0dc38996 100644 (file)
@@ -376,6 +376,9 @@ mt_list_lock_prev(elt)
   Return    A  elt
   value:    <===>
 
+mt_list_try_lock_prev(elt)
+    Does the same thing as mt_list_lock_prev(), except if the list is
+    locked already, it returns { NULL, NULL } instead of waiting.
 
 mt_list_lock_elem(elt)
     Locks the element only. Both of its pointers are replaced by two locked
index 86d44e51784b9891a72ffa893f5f606639a72741..9339d0e076dd067e8cef02dbd2c67118ce3c0011 100644 (file)
@@ -780,6 +780,28 @@ static MT_INLINE struct mt_list mt_list_lock_prev(struct mt_list *lh)
        return el;
 }
 
+/*
+ * Same as mt_list_lock_prev(), except it doesn't wait if the prev
+ * is locked already, and just returns { NULL, NULL }
+ */
+static MT_INLINE struct mt_list mt_list_try_lock_prev(struct mt_list *lh)
+{
+       struct mt_list el;
+       struct mt_list missed = { NULL, NULL };
+
+       el.prev = __atomic_exchange_n(&lh->prev, MT_LIST_BUSY, __ATOMIC_RELAXED);
+       if (el.prev == MT_LIST_BUSY)
+               return missed;
+
+       el.next = __atomic_exchange_n(&el.prev->next, MT_LIST_BUSY, __ATOMIC_RELAXED);
+       if (el.next == MT_LIST_BUSY) {
+               lh->prev = el.prev;
+               __atomic_thread_fence(__ATOMIC_RELEASE);
+               return missed;
+       }
+       return el;
+}
+
 
 /* Element <el> is locked on both sides, but the list around it isn't touched.
  * A copy of the previous element is returned, and may be used to pass to