Moved ticketlock implementation into ticketlock_inlines.h header
file, which enables inlined version to be used inside
implementation and through API.

Signed-off-by: Petri Savolainen <petri.savolai...@nokia.com>
---
 platform/linux-generic/Makefile.am                 |  1 +
 .../include/odp/api/plat/ticketlock_inlines.h      | 87 ++++++++++++++++++++++
 platform/linux-generic/odp_ticketlock.c            | 68 +++--------------
 3 files changed, 97 insertions(+), 59 deletions(-)
 create mode 100644 
platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h

diff --git a/platform/linux-generic/Makefile.am 
b/platform/linux-generic/Makefile.am
index e3c0f56..900ac08 100644
--- a/platform/linux-generic/Makefile.am
+++ b/platform/linux-generic/Makefile.am
@@ -88,6 +88,7 @@ odpapiplatinclude_HEADERS = \
                  $(srcdir)/include/odp/api/plat/sync_inlines.h \
                  $(srcdir)/include/odp/api/plat/thread_types.h \
                  $(srcdir)/include/odp/api/plat/thrmask_types.h \
+                 $(srcdir)/include/odp/api/plat/ticketlock_inlines.h \
                  $(srcdir)/include/odp/api/plat/ticketlock_types.h \
                  $(srcdir)/include/odp/api/plat/time_types.h \
                  $(srcdir)/include/odp/api/plat/timer_types.h \
diff --git a/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h 
b/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h
new file mode 100644
index 0000000..957d22e
--- /dev/null
+++ b/platform/linux-generic/include/odp/api/plat/ticketlock_inlines.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2016, Linaro Limited
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**
+ * @file
+ *
+ * Ticketlock inline functions
+ */
+
+#ifndef _ODP_PLAT_TICKETLOCK_INLINES_H_
+#define _ODP_PLAT_TICKETLOCK_INLINES_H_
+
+#include <odp/api/ticketlock.h>
+#include <odp/api/atomic.h>
+#include <odp/api/sync.h>
+#include <odp/api/cpu.h>
+
+static inline void _odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
+{
+       uint32_t ticket;
+
+       /* Take a ticket using an atomic increment of 'next_ticket'.
+        * This can be a relaxed operation but it cannot have the
+        * acquire semantics since we haven't acquired the lock yet */
+       ticket = odp_atomic_fetch_inc_u32(&ticketlock->next_ticket);
+
+       /* Spin waiting for our turn. Use load-acquire so that we acquire
+        * all stores from the previous lock owner */
+       while (ticket != odp_atomic_load_acq_u32(&ticketlock->cur_ticket))
+               odp_cpu_pause();
+}
+
+static inline 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_cas_acq_u32(&tklock->next_ticket,
+                                          &next, next + 1))
+                       return 1;
+       }
+       return 0;
+}
+
+static inline void _odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
+{
+       /* Release the lock by incrementing 'cur_ticket'. As we are the
+        * lock owner and thus the only thread that is allowed to write
+        * 'cur_ticket', we don't need to do this with an (expensive)
+        * atomic RMW operation. Instead load-relaxed the current value
+        * and a store-release of the incremented value */
+       uint32_t cur = odp_atomic_load_u32(&ticketlock->cur_ticket);
+
+       odp_atomic_store_rel_u32(&ticketlock->cur_ticket, cur + 1);
+}
+
+static inline int _odp_ticketlock_is_locked(odp_ticketlock_t *ticketlock)
+{
+       /* Compare 'cur_ticket' with 'next_ticket'. Ideally we should read
+        * both variables atomically but the information can become stale
+        * immediately anyway so the function can only be used reliably in
+        * a quiescent system where non-atomic loads should not pose a
+        * problem */
+       return odp_atomic_load_u32(&ticketlock->cur_ticket) !=
+               odp_atomic_load_u32(&ticketlock->next_ticket);
+}
+
+#endif
diff --git a/platform/linux-generic/odp_ticketlock.c 
b/platform/linux-generic/odp_ticketlock.c
index 353af9a..f18d78f 100644
--- a/platform/linux-generic/odp_ticketlock.c
+++ b/platform/linux-generic/odp_ticketlock.c
@@ -4,10 +4,7 @@
  * SPDX-License-Identifier:     BSD-3-Clause
  */
 
-#include <odp/api/ticketlock.h>
-#include <odp/api/atomic.h>
-#include <odp/api/sync.h>
-#include <odp/api/cpu.h>
+#include <odp/api/plat/ticketlock_inlines.h>
 
 void odp_ticketlock_init(odp_ticketlock_t *ticketlock)
 {
@@ -15,69 +12,22 @@ void odp_ticketlock_init(odp_ticketlock_t *ticketlock)
        odp_atomic_init_u32(&ticketlock->cur_ticket, 0);
 }
 
-void odp_ticketlock_lock(odp_ticketlock_t *ticketlock)
+void odp_ticketlock_lock(odp_ticketlock_t *lock)
 {
-       uint32_t ticket;
-
-       /* Take a ticket using an atomic increment of 'next_ticket'.
-        * This can be a relaxed operation but it cannot have the
-        * acquire semantics since we haven't acquired the lock yet */
-       ticket = odp_atomic_fetch_inc_u32(&ticketlock->next_ticket);
-
-       /* Spin waiting for our turn. Use load-acquire so that we acquire
-        * all stores from the previous lock owner */
-       while (ticket != odp_atomic_load_acq_u32(&ticketlock->cur_ticket))
-               odp_cpu_pause();
+       return _odp_ticketlock_lock(lock);
 }
 
-int odp_ticketlock_trylock(odp_ticketlock_t *tklock)
+int odp_ticketlock_trylock(odp_ticketlock_t *lock)
 {
-       /* 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_cas_acq_u32(&tklock->next_ticket,
-                                          &next, next + 1))
-                       return 1;
-       }
-       return 0;
+       return _odp_ticketlock_trylock(lock);
 }
 
-void odp_ticketlock_unlock(odp_ticketlock_t *ticketlock)
+void odp_ticketlock_unlock(odp_ticketlock_t *lock)
 {
-       /* Release the lock by incrementing 'cur_ticket'. As we are the
-        * lock owner and thus the only thread that is allowed to write
-        * 'cur_ticket', we don't need to do this with an (expensive)
-        * atomic RMW operation. Instead load-relaxed the current value
-        * and a store-release of the incremented value */
-       uint32_t cur = odp_atomic_load_u32(&ticketlock->cur_ticket);
-
-       odp_atomic_store_rel_u32(&ticketlock->cur_ticket, cur + 1);
-
+       _odp_ticketlock_unlock(lock);
 }
 
-int odp_ticketlock_is_locked(odp_ticketlock_t *ticketlock)
+int odp_ticketlock_is_locked(odp_ticketlock_t *lock)
 {
-       /* Compare 'cur_ticket' with 'next_ticket'. Ideally we should read
-        * both variables atomically but the information can become stale
-        * immediately anyway so the function can only be used reliably in
-        * a quiescent system where non-atomic loads should not pose a
-        * problem */
-       return odp_atomic_load_u32(&ticketlock->cur_ticket) !=
-               odp_atomic_load_u32(&ticketlock->next_ticket);
+       return _odp_ticketlock_is_locked(lock);
 }
-- 
2.8.1

Reply via email to