On 10/27/2015 17:48, Petri Savolainen wrote:
Platforms may support some uint64 operations lock-free and
others not. For example, inc_64 can be natively supported but
cas_64 (or max_64/min_64) not. User may be able to switch to
32 bit variables when a 64 bit operation uses locks. The same
atomic operation enum could be used for platform init to guide
lock vs. lock-free implementation (e.g. if cas_64 is never
called, inc_64 can be lock-free).

Signed-off-by: Petri Savolainen <[email protected]>
---
  include/odp/api/atomic.h                    | 51 +++++++++++++++++++++++++++++
  platform/linux-generic/include/odp/atomic.h | 28 ++++++++++++++++
  2 files changed, 79 insertions(+)

diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h
index 316f13a..1613405 100644
--- a/include/odp/api/atomic.h
+++ b/include/odp/api/atomic.h
@@ -388,6 +388,57 @@ void odp_atomic_add_rls_u32(odp_atomic_u32_t *atom, 
uint32_t val);
  void odp_atomic_sub_rls_u32(odp_atomic_u32_t *atom, uint32_t val);
/**
+ * @enum odp_atomic_operation_t
+ * Atomic operations
+ *
+ * @var ODP_ATOMIC_OP_ALL
+ * All atomic operations
+ * @var ODP_ATOMIC_OP_INIT
+ * Atomic init
+ * @var ODP_ATOMIC_OP_LOAD
+ * Atomic load
+ * @var ODP_ATOMIC_OP_STORE
+ * Atomic store
+ * @var ODP_ATOMIC_OP_FETCH_ADD
+ * Atomic fetch add
+ * @var ODP_ATOMIC_OP_ADD
+ * Atomic add
+ * @var ODP_ATOMIC_OP_FETCH_SUB
+ * Atomic fetch sub
+ * @var ODP_ATOMIC_OP_SUB
+ * Atomic sub
+ * @var ODP_ATOMIC_OP_FETCH_INC
+ * Atomic fetch inc
+ * @var ODP_ATOMIC_OP_INC
+ * Atomic inc
+ * @var ODP_ATOMIC_OP_FETCH_DEC
+ * Atomic fetch dec
+ * @var ODP_ATOMIC_OP_DEC
+ * Atomic dec
+ * @var ODP_ATOMIC_OP_MIN
+ * Atomic min
+ * @var ODP_ATOMIC_OP_MAX
+ * Atomic max
+ * @var ODP_ATOMIC_OP_CAS
+ * Atomic compare and swap
+ */
+
+/**
+ * Determine if an atomic uint64 operation is lock-free
+ *
+ * Lock-free implementations have higher performance and scale better than
+ * implementations using locks. User can decide to use e.g. uint32 atomic
+ * variables instead of uint64 to optimize performance on platforms that
+ * implement a performance critical operation using locks.
+ *
+ * @param op      Atomic operation
+ *
+ * @retval 0  Operation is implemented with locks
+ * @retval 1  Operation is lock-free
+ */
+int odp_atomic_is_lock_free_u64(odp_atomic_operation_t op);
+
+/**
   * @}
   */
diff --git a/platform/linux-generic/include/odp/atomic.h b/platform/linux-generic/include/odp/atomic.h
index 005a0cd..481d13a 100644
--- a/platform/linux-generic/include/odp/atomic.h
+++ b/platform/linux-generic/include/odp/atomic.h
@@ -25,6 +25,34 @@ extern "C" {
   *  @{
   */
+typedef enum odp_atomic_operation_t {
+       ODP_ATOMIC_OP_ALL = 0,
+       ODP_ATOMIC_OP_INIT,
+       ODP_ATOMIC_OP_LOAD,
+       ODP_ATOMIC_OP_STORE,
+       ODP_ATOMIC_OP_FETCH_ADD,
+       ODP_ATOMIC_OP_ADD,
+       ODP_ATOMIC_OP_FETCH_SUB,
+       ODP_ATOMIC_OP_SUB,
+       ODP_ATOMIC_OP_FETCH_INC,
+       ODP_ATOMIC_OP_INC,
+       ODP_ATOMIC_OP_FETCH_DEC,
+       ODP_ATOMIC_OP_DEC,
+       ODP_ATOMIC_OP_MIN,
+       ODP_ATOMIC_OP_MAX,
+       ODP_ATOMIC_OP_CAS
+} odp_atomic_operation_t;
+
+static inline int odp_atomic_is_lock_free_u64(odp_atomic_operation_t op)
+{
+       (void)op;
+#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
+       return 0;
+#else
+       return 1;
+#endif
+}

How about change it:
struct odp_atomic_operation_t
{
uint32_t all;

int ODP_ATOMIC_OP_INIT:1;

int _DEC:1;

}

/* Return bit field with free lock operations set to 1.*/

odp_atomic_operation_t odp_atomic_lock_free_u64()


But actually it's not really clear for me how app will use that. That is not platform specific, it's toolchain specific optimizations. And supported optimization level should be selected
on ./configure stage and not on app  run time.

Maxim.



+
  static inline void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
  {
        __atomic_store_n(&atom->v, val, __ATOMIC_RELAXED);

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

Reply via email to