From patchwork Thu Jul 21 12:06:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Milard X-Patchwork-Id: 72555 Delivered-To: patch@linaro.org Received: by 10.140.29.52 with SMTP id a49csp383125qga; Thu, 21 Jul 2016 04:19:02 -0700 (PDT) X-Received: by 10.129.125.135 with SMTP id y129mr36454836ywc.107.1469099942468; Thu, 21 Jul 2016 04:19:02 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id y144si4641175qkb.121.2016.07.21.04.19.02; Thu, 21 Jul 2016 04:19:02 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id F083B68201; Thu, 21 Jul 2016 11:19:01 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 6344068154; Thu, 21 Jul 2016 11:09:00 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id D76BB68987; Thu, 21 Jul 2016 11:08:47 +0000 (UTC) Received: from mail-lf0-f52.google.com (mail-lf0-f52.google.com [209.85.215.52]) by lists.linaro.org (Postfix) with ESMTPS id A33496172E for ; Thu, 21 Jul 2016 11:07:31 +0000 (UTC) Received: by mail-lf0-f52.google.com with SMTP id b199so58735757lfe.0 for ; Thu, 21 Jul 2016 04:07:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=zojv3VE896cFx3i4y/XpHazgb+Pn33daj3vGc96unAU=; b=Tsb9OMC5QY7zFT3Y+Y0WI0LKQxkSb4eR9dV81DHIMNZoeOghuwsTpgB+bQzKhDux2k k7w1feCx8iaKfgTN/KmMT7/GeotfXlNE4spN5Z9ss9IFclWhv96zkvR7EWADddQJ+sYS 2pSN0cQWFrS6HVxxxBeaI5nOV+hibi4AfEQROgx4lRR6KCId2uHick7t2612IzDU+Ryu Ap4cuXgBLVmL6pvKbpjc4KJXSSTuxC6GV60IpQLDq1biVmOFo2qUEbxqoK4r8IicFpWL LI/Oz2u6/btKKXm0fxAynMyJoyTd0DXn0tcowHk4wu/9ijJYFZ2dRAURUU//J+GqbEY/ 0mOg== X-Gm-Message-State: ALyK8tJyXnI7Dq+0EvbY5ofU3w8MRjQbcTJra+Zq87SPJVDNBZm2d06l+SkkmHc2LL2qSAOcLnQ= X-Received: by 10.25.165.71 with SMTP id o68mr5620060lfe.95.1469099250082; Thu, 21 Jul 2016 04:07:30 -0700 (PDT) Received: from erachmi-ericsson.ki.sw.ericsson.se (c-83-233-90-46.cust.bredband2.com. [83.233.90.46]) by smtp.gmail.com with ESMTPSA id i80sm1577861lfg.6.2016.07.21.04.07.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Jul 2016 04:07:29 -0700 (PDT) From: Christophe Milard To: mike.holmes@linaro.org, lng-odp@lists.linaro.org, balakrishna.garapati@linaro.org Date: Thu, 21 Jul 2016 14:06:22 +0200 Message-Id: <1469102786-65530-15-git-send-email-christophe.milard@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1469102786-65530-1-git-send-email-christophe.milard@linaro.org> References: <1469102786-65530-1-git-send-email-christophe.milard@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv3 14/18] drv: adding atomic.h X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Based on API interface file. Signed-off-by: Christophe Milard --- include/odp/drv/spec/atomic.h | 634 ++++++++++++++++++++++++++++++++++++++++++ platform/Makefile.inc | 1 + 2 files changed, 635 insertions(+) create mode 100644 include/odp/drv/spec/atomic.h -- 2.7.4 diff --git a/include/odp/drv/spec/atomic.h b/include/odp/drv/spec/atomic.h new file mode 100644 index 0000000..3cb6e9b --- /dev/null +++ b/include/odp/drv/spec/atomic.h @@ -0,0 +1,634 @@ +/* Copyright (c) 2016, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODPDRV atomic operations + */ + +#ifndef ODPDRV_API_ATOMIC_H_ +#define ODPDRV_API_ATOMIC_H_ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup odpdrv_atomic ODPDRV ATOMIC + * @details + * Atomic integers using relaxed memory ordering + * + * Atomic integer types (odpdrv_atomic_u32_t and odpdrv_atomic_u64_t) can be + * used to implement e.g. shared counters. If not otherwise documented, + * operations in this API are implemented using RELAXED memory ordering + * (see memory order descriptions in the C11 specification). Relaxed operations + * do not provide synchronization or ordering for other memory accesses + * (initiated before or after the operation), only atomicity of the operation + * itself is guaranteed. + * + * Operations with non-relaxed memory ordering + * + * An operation with RELEASE memory ordering + * (odpdrv_atomic_xxx_rel_xxx()) ensures that other threads loading the same + * atomic variable with ACQUIRE memory ordering see all stores (from the + * calling thread) that happened before this releasing store. + * + * An operation with ACQUIRE memory ordering + * (odpdrv_atomic_xxx_acq_xxx()) ensures that the calling thread sees all stores + * (done by the releasing thread) that happened before a RELEASE memory ordered + * store to the same atomic variable. + * + * An operation with ACQUIRE-and-RELEASE memory ordering + * (odpdrv_atomic_xxx_acq_rel_xxx()) combines the effects of ACQUIRE and RELEASE + * memory orders. A single operation acts as both an acquiring load and + * a releasing store. + * + * @{ + */ + +/** + * @typedef odpdrv_atomic_u64_t + * Atomic 64-bit unsigned integer + * + * @typedef odpdrv_atomic_u32_t + * Atomic 32-bit unsigned integer + */ + +/* + * 32-bit operations in RELAXED memory ordering + * -------------------------------------------- + */ + +/** + * Initialize atomic uint32 variable + * + * Initializes the atomic variable with 'val'. This operation is not atomic. + * Drivers must ensure that there's no race condition while initializing + * the variable. + * + * @param atom Pointer to atomic variable + * @param val Value to initialize the variable with + */ +void odpdrv_atomic_init_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Load value of atomic uint32 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable + */ +uint32_t odpdrv_atomic_load_u32(odpdrv_atomic_u32_t *atom); + +/** + * Store value to atomic uint32 variable + * + * @param atom Pointer to atomic variable + * @param val Value to store in the variable + */ +void odpdrv_atomic_store_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Fetch and add to atomic uint32 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + * + * @return Value of the variable before the addition + */ +uint32_t odpdrv_atomic_fetch_add_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Add to atomic uint32 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + */ +void odpdrv_atomic_add_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Fetch and subtract from atomic uint32 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be subracted from the variable + * + * @return Value of the variable before the subtraction + */ +uint32_t odpdrv_atomic_fetch_sub_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Subtract from atomic uint32 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable + */ +void odpdrv_atomic_sub_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Fetch and increment atomic uint32 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable before the increment + */ +uint32_t odpdrv_atomic_fetch_inc_u32(odpdrv_atomic_u32_t *atom); + +/** + * Increment atomic uint32 variable + * + * @param atom Pointer to atomic variable + */ +void odpdrv_atomic_inc_u32(odpdrv_atomic_u32_t *atom); + +/** + * Fetch and decrement atomic uint32 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable before the subtraction + */ +uint32_t odpdrv_atomic_fetch_dec_u32(odpdrv_atomic_u32_t *atom); + +/** + * Decrement atomic uint32 variable + * + * @param atom Pointer to atomic variable + */ +void odpdrv_atomic_dec_u32(odpdrv_atomic_u32_t *atom); + +/** + * Update maximum value of atomic uint32 variable + * + * Compares value of atomic variable to the new maximum value. If the new value + * is greater than the current value, writes the new value into the variable. + * + * @param atom Pointer to atomic variable + * @param new_max New maximum value to be written into the atomic variable + */ +void odpdrv_atomic_max_u32(odpdrv_atomic_u32_t *atom, uint32_t new_max); + +/** + * Update minimum value of atomic uint32 variable + * + * Compares value of atomic variable to the new minimum value. If the new value + * is less than the current value, writes the new value into the variable. + * + * @param atom Pointer to atomic variable + * @param new_min New minimum value to be written into the atomic variable + */ +void odpdrv_atomic_min_u32(odpdrv_atomic_u32_t *atom, uint32_t new_min); + +/** + * Compare and swap atomic uint32 variable + * + * Compares value of atomic variable to the value pointed by 'old_val'. + * If values are equal, the operation writes 'new_val' into the atomic variable + * and returns success. If they are not equal, the operation writes current + * value of atomic variable into 'old_val' and returns failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + * + */ +int odpdrv_atomic_cas_u32(odpdrv_atomic_u32_t *atom, uint32_t *old_val, + uint32_t new_val); + +/** + * Exchange value of atomic uint32 variable + * + * Atomically replaces the value of atomic variable with the new value. Returns + * the old value. + * + * @param atom Pointer to atomic variable + * @param new_val New value of the atomic variable + * + * @return Value of the variable before the operation + */ +uint32_t odpdrv_atomic_xchg_u32(odpdrv_atomic_u32_t *atom, uint32_t new_val); + +/* + * 64-bit operations in RELAXED memory ordering + * -------------------------------------------- + */ + +/** + * Initialize atomic uint64 variable + * + * Initializes the atomic variable with 'val'. This operation is not atomic. + * Drivers must ensure that there's no race condition while initializing + * the variable. + * + * @param atom Pointer to atomic variable + * @param val Value to initialize the variable with + */ +void odpdrv_atomic_init_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Load value of atomic uint64 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable + */ +uint64_t odpdrv_atomic_load_u64(odpdrv_atomic_u64_t *atom); + +/** + * Store value to atomic uint64 variable + * + * @param atom Pointer to atomic variable + * @param val Value to store in the variable + */ +void odpdrv_atomic_store_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Fetch and add to atomic uint64 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + * + * @return Value of the variable before the addition + */ +uint64_t odpdrv_atomic_fetch_add_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Add to atomic uint64 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + */ +void odpdrv_atomic_add_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Fetch and subtract from atomic uint64 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable + * + * @return Value of the variable before the subtraction + */ +uint64_t odpdrv_atomic_fetch_sub_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Subtract from atomic uint64 variable + * + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable + */ +void odpdrv_atomic_sub_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Fetch and increment atomic uint64 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable before the increment + */ +uint64_t odpdrv_atomic_fetch_inc_u64(odpdrv_atomic_u64_t *atom); + +/** + * Increment atomic uint64 variable + * + * @param atom Pointer to atomic variable + */ +void odpdrv_atomic_inc_u64(odpdrv_atomic_u64_t *atom); + +/** + * Fetch and decrement atomic uint64 variable + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable before the decrement + */ +uint64_t odpdrv_atomic_fetch_dec_u64(odpdrv_atomic_u64_t *atom); + +/** + * Decrement atomic uint64 variable + * + * @param atom Pointer to atomic variable + */ +void odpdrv_atomic_dec_u64(odpdrv_atomic_u64_t *atom); + +/** + * Update maximum value of atomic uint64 variable + * + * Compares value of atomic variable to the new maximum value. If the new value + * is greater than the current value, writes the new value into the variable. + * + * @param atom Pointer to atomic variable + * @param new_max New maximum value to be written into the atomic variable + */ +void odpdrv_atomic_max_u64(odpdrv_atomic_u64_t *atom, uint64_t new_max); + +/** + * Update minimum value of atomic uint64 variable + * + * Compares value of atomic variable to the new minimum value. If the new value + * is less than the current value, writes the new value into the variable. + * + * @param atom Pointer to atomic variable + * @param new_min New minimum value to be written into the atomic variable + */ +void odpdrv_atomic_min_u64(odpdrv_atomic_u64_t *atom, uint64_t new_min); + +/** + * Compare and swap atomic uint64 variable + * + * Compares value of atomic variable to the value pointed by 'old_val'. + * If values are equal, the operation writes 'new_val' into the atomic variable + * and returns success. If they are not equal, the operation writes current + * value of atomic variable into 'old_val' and returns failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_u64(odpdrv_atomic_u64_t *atom, uint64_t *old_val, + uint64_t new_val); + +/** + * Exchange value of atomic uint64 variable + * + * Atomically replaces the value of atomic variable with the new value. Returns + * the old value. + * + * @param atom Pointer to atomic variable + * @param new_val New value of the atomic variable + * + * @return Value of the variable before the operation + */ +uint64_t odpdrv_atomic_xchg_u64(odpdrv_atomic_u64_t *atom, uint64_t new_val); + +/* + * 32-bit operations in non-RELAXED memory ordering + * ------------------------------------------------ + */ + +/** + * Load value of atomic uint32 variable using ACQUIRE memory ordering + * + * Otherwise identical to odpdrv_atomic_load_u32() but ensures ACQUIRE memory + * ordering. + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable + */ +uint32_t odpdrv_atomic_load_acq_u32(odpdrv_atomic_u32_t *atom); + +/** + * Store value to atomic uint32 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_store_u32() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to store in the variable + */ +void odpdrv_atomic_store_rel_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Add to atomic uint32 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_add_u32() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + */ +void odpdrv_atomic_add_rel_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Subtract from atomic uint32 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_sub_u32() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable + */ +void odpdrv_atomic_sub_rel_u32(odpdrv_atomic_u32_t *atom, uint32_t val); + +/** + * Compare and swap atomic uint32 variable using ACQUIRE memory ordering + * + * Otherwise identical to odpdrv_atomic_cas_u32() but ensures ACQUIRE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_acq_u32(odpdrv_atomic_u32_t *atom, uint32_t *old_val, + uint32_t new_val); + +/** + * Compare and swap atomic uint32 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_cas_u32() but ensures RELEASE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_rel_u32(odpdrv_atomic_u32_t *atom, uint32_t *old_val, + uint32_t new_val); + +/** + * Compare and swap atomic uint32 variable using ACQUIRE-and-RELEASE memory + * ordering + * + * Otherwise identical to odpdrv_atomic_cas_u32() but ensures + * ACQUIRE-and-RELEASE memory ordering on success. + * Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_acq_rel_u32(odpdrv_atomic_u32_t *atom, uint32_t *old_val, + uint32_t new_val); + +/* + * 64-bit operations in non-RELAXED memory ordering + * ------------------------------------------------ + */ + +/** + * Load value of atomic uint64 variable using ACQUIRE memory ordering + * + * Otherwise identical to odpdrv_atomic_load_u64() but ensures ACQUIRE memory + * ordering. + * + * @param atom Pointer to atomic variable + * + * @return Value of the variable + */ +uint64_t odpdrv_atomic_load_acq_u64(odpdrv_atomic_u64_t *atom); + +/** + * Store value to atomic uint64 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_store_u64() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to store in the variable + */ +void odpdrv_atomic_store_rel_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Add to atomic uint64 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_add_u64() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable + */ +void odpdrv_atomic_add_rel_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Subtract from atomic uint64 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_sub_u64() but ensures RELEASE memory + * ordering. + * + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable + */ +void odpdrv_atomic_sub_rel_u64(odpdrv_atomic_u64_t *atom, uint64_t val); + +/** + * Compare and swap atomic uint64 variable using ACQUIRE memory ordering + * + * Otherwise identical to odpdrv_atomic_cas_u64() but ensures ACQUIRE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_acq_u64(odpdrv_atomic_u64_t *atom, uint64_t *old_val, + uint64_t new_val); + +/** + * Compare and swap atomic uint64 variable using RELEASE memory ordering + * + * Otherwise identical to odpdrv_atomic_cas_u64() but ensures RELEASE memory + * ordering on success. Memory ordering is RELAXED on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_rel_u64(odpdrv_atomic_u64_t *atom, uint64_t *old_val, + uint64_t new_val); + +/** + * Compare and swap atomic uint64 variable using ACQUIRE-and-RELEASE memory + * ordering + * + * Otherwise identical to odpdrv_atomic_cas_u64() but ensures + * ACQUIRE-and-RELEASE memory ordering on success. Memory ordering is RELAXED + * on failure. + * + * @param atom Pointer to atomic variable + * @param[in,out] old_val Pointer to the old value of the atomic variable. + * Operation updates this value on failure. + * @param new_val New value to be written into the atomic variable + * + * @return 0 on failure, !0 on success + */ +int odpdrv_atomic_cas_acq_rel_u64(odpdrv_atomic_u64_t *atom, uint64_t *old_val, + uint64_t new_val); + +/** + * Atomic operations + * + * Atomic operations listed in a bit field structure. + */ +typedef union odpdrv_atomic_op_t { + /** Operation flags */ + struct { + uint32_t init : 1; /**< Init atomic variable */ + uint32_t load : 1; /**< Atomic load */ + uint32_t store : 1; /**< Atomic store */ + uint32_t fetch_add : 1; /**< Atomic fetch and add */ + uint32_t add : 1; /**< Atomic add */ + uint32_t fetch_sub : 1; /**< Atomic fetch and subtract */ + uint32_t sub : 1; /**< Atomic subtract */ + uint32_t fetch_inc : 1; /**< Atomic fetch and increment */ + uint32_t inc : 1; /**< Atomic increment */ + uint32_t fetch_dec : 1; /**< Atomic fetch and decrement */ + uint32_t dec : 1; /**< Atomic decrement */ + uint32_t min : 1; /**< Atomic minimum */ + uint32_t max : 1; /**< Atomic maximum */ + uint32_t cas : 1; /**< Atomic compare and swap */ + uint32_t xchg : 1; /**< Atomic exchange */ + } op; + + /** All bits of the bit field structure. + * Operation flag mapping is architecture specific. This field can be + * used to set/clear all flags, or bitwise operations over the entire + * structure. */ + uint32_t all_bits; +} odpdrv_atomic_op_t; + +/** + * Query which atomic uint64 operations are 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. + * + * Init operations (e.g. odpdrv_atomic_init_64()) are not atomic. This function + * clears the op.init bit but will never set it to one. + * + * @param atomic_op Pointer to atomic operation structure for storing + * operation flags. All bits are initialized to zero during + * the operation. The parameter is ignored when NULL. + * @retval 0 None of the operations are lock-free + * @retval 1 Some of the operations are lock-free + * @retval 2 All operations are lock-free + */ +int odpdrv_atomic_lock_free_u64(odpdrv_atomic_op_t *atomic_op); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include +#endif diff --git a/platform/Makefile.inc b/platform/Makefile.inc index edb598f..900b023 100644 --- a/platform/Makefile.inc +++ b/platform/Makefile.inc @@ -64,6 +64,7 @@ odpapispecinclude_HEADERS = \ odpdrvspecincludedir= $(includedir)/odp/drv/spec odpdrvspecinclude_HEADERS = \ $(top_srcdir)/include/odp/drv/spec/align.h \ + $(top_srcdir)/include/odp/drv/spec/atomic.h \ $(top_srcdir)/include/odp/drv/spec/byteorder.h \ $(top_srcdir)/include/odp/drv/spec/compiler.h \ $(top_srcdir)/include/odp/drv/spec/std_types.h \