Signed-off-by: Ola Liljedahl <[email protected]>
---
(This document/code contribution attached is provided under the terms of
agreement LES-LTM-21309)
Implemented the missing odp_ticketlock_trylock().

 platform/linux-generic/odp_ticketlock.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/platform/linux-generic/odp_ticketlock.c 
b/platform/linux-generic/odp_ticketlock.c
index 682b01b..6525786 100644
--- a/platform/linux-generic/odp_ticketlock.c
+++ b/platform/linux-generic/odp_ticketlock.c
@@ -34,6 +34,36 @@ void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
                odp_spin();
 }
 
+int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
+{
+       /* We read 'next_ticket' and 'cur_ticket' non-atomically which should
+        * not be a problem as they are not independent of each other.
+        * 'cur_ticket' is always <= to 'next_ticket' and if we see an
+        * older value of 'cur_ticket', this only means the lock will
+        * look busy and trylock will fail. */
+       uint32_t next = odp_atomic_load_u32(&tklock->next_ticket);
+       uint32_t cur = odp_atomic_load_u32(&tklock->cur_ticket);
+       /* First check that lock is available and possible to take without
+        * spinning. */
+       if (next == cur) {
+               /* Then try to take the lock by incrementing 'next_ticket'
+                * but only if it still has the original value which is
+                * equal to 'cur_ticket'.
+                * We don't have to include 'cur_ticket' in the comparison
+                * because it cannot be larger than 'next_ticket' (only
+                * smaller if the lock is busy).
+                * If CAS fails, it means some other thread intercepted and
+                * took a ticket which means the lock is not available
+                * anymore */
+               if (_odp_atomic_u32_cmp_xchg_strong_mm(&tklock->next_ticket,
+                                                      &next,
+                                                      next + 1,
+                                                      _ODP_MEMMODEL_ACQ,
+                                                      _ODP_MEMMODEL_RLX))
+                       return 1;
+       }
+       return 0;
+}
 
 void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
 {
-- 
1.9.1


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to