diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/odp.h | 4 | ||||
-rw-r--r-- | include/odp/api/atomic.h | 112 | ||||
-rw-r--r-- | include/odp/api/barrier.h | 11 | ||||
-rw-r--r-- | include/odp/api/classification.h | 69 | ||||
-rw-r--r-- | include/odp/api/crypto.h | 4 | ||||
-rw-r--r-- | include/odp/api/hash.h | 98 | ||||
-rw-r--r-- | include/odp/api/init.h | 4 | ||||
-rw-r--r-- | include/odp/api/packet_io.h | 9 | ||||
-rw-r--r-- | include/odp/api/rwlock.h | 19 | ||||
-rw-r--r-- | include/odp/api/rwlock_recursive.h | 97 | ||||
-rw-r--r-- | include/odp/api/spinlock.h | 11 | ||||
-rw-r--r-- | include/odp/api/spinlock_recursive.h | 85 | ||||
-rw-r--r-- | include/odp/api/std_clib.h | 64 | ||||
-rw-r--r-- | include/odp/api/sync.h | 82 | ||||
-rw-r--r-- | include/odp/api/thread.h | 9 | ||||
-rw-r--r-- | include/odp/api/thrmask.h | 2 | ||||
-rw-r--r-- | include/odp/api/ticketlock.h | 16 | ||||
-rw-r--r-- | include/odp/api/time.h | 58 | ||||
-rw-r--r-- | include/odp/api/version.h | 49 |
19 files changed, 669 insertions, 134 deletions
diff --git a/include/odp.h b/include/odp.h index fe1dc7459..2adcb8b74 100644 --- a/include/odp.h +++ b/include/odp.h @@ -24,6 +24,7 @@ extern "C" { #include <odp/std_types.h> #include <odp/compiler.h> #include <odp/align.h> +#include <odp/hash.h> #include <odp/hints.h> #include <odp/debug.h> #include <odp/byteorder.h> @@ -54,6 +55,9 @@ extern "C" { #include <odp/random.h> #include <odp/errno.h> #include <odp/thrmask.h> +#include <odp/spinlock_recursive.h> +#include <odp/rwlock_recursive.h> +#include <odp/std_clib.h> #ifdef __cplusplus } diff --git a/include/odp/api/atomic.h b/include/odp/api/atomic.h index ba5c354e2..97e86392b 100644 --- a/include/odp/api/atomic.h +++ b/include/odp/api/atomic.h @@ -18,10 +18,20 @@ extern "C" { #endif -/** @addtogroup odp_synchronizers - * Atomic types and relaxed operations. These operations cannot be used for - * synchronization. - * @{ +/** + * @defgroup odp_atomic ODP ATOMIC + * @details + * <b> Atomic integers </b> + * + * Atomic integer types (odp_atomic_u32_t and odp_atomic_u64_t) can be used to + * implement e.g. shared counters. If not otherwise documented, operations in + * this API are implemented using <b> RELAXED memory ordering </b> (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. + * + * @{ */ /** @@ -34,19 +44,16 @@ extern "C" { /** * Initialize atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[out] atom Pointer to an atomic uint32 variable - * @param val Value to initialize the variable with + * @param atom Pointer to atomic variable + * @param val Value to initialize the variable with */ void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val); - /** * Load value of atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param atom Pointer to an atomic uint32 variable + * @param atom Pointer to atomic variable * * @return Value of the variable */ @@ -54,19 +61,17 @@ uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom); /** * Store value to atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[out] atom Pointer to an atomic uint32 variable - * @param val Value to store in the variable + * @param atom Pointer to atomic variable + * @param val Value to store in the variable */ void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val); /** * Fetch and add to atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable - * @param val Value to be added to the variable + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable * * @return Value of the variable before the addition */ @@ -74,19 +79,17 @@ uint32_t odp_atomic_fetch_add_u32(odp_atomic_u32_t *atom, uint32_t val); /** * Add to atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable - * @param val A value to be added to the variable + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable */ void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val); /** * Fetch and subtract from atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable - * @param val A value to be subracted from the variable + * @param atom Pointer to atomic variable + * @param val Value to be subracted from the variable * * @return Value of the variable before the subtraction */ @@ -94,37 +97,32 @@ uint32_t odp_atomic_fetch_sub_u32(odp_atomic_u32_t *atom, uint32_t val); /** * Subtract from atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable - * @param val Value to be subtracted from the variable + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable */ void odp_atomic_sub_u32(odp_atomic_u32_t *atom, uint32_t val); /** * Fetch and increment atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable + * @param atom Pointer to atomic variable * * @return Value of the variable before the increment */ - uint32_t odp_atomic_fetch_inc_u32(odp_atomic_u32_t *atom); /** * Increment atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable + * @param atom Pointer to atomic variable */ void odp_atomic_inc_u32(odp_atomic_u32_t *atom); /** * Fetch and decrement atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable + * @param atom Pointer to atomic variable * * @return Value of the variable before the subtraction */ @@ -132,26 +130,23 @@ uint32_t odp_atomic_fetch_dec_u32(odp_atomic_u32_t *atom); /** * Decrement atomic uint32 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint32 variable + * @param atom Pointer to atomic variable */ void odp_atomic_dec_u32(odp_atomic_u32_t *atom); /** * Initialize atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[out] atom Pointer to an atomic uint64 variable - * @param val Value to initialize the variable with + * @param atom Pointer to atomic variable + * @param val Value to initialize the variable with */ void odp_atomic_init_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Load value of atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param atom Pointer to an atomic uint64 variable + * @param atom Pointer to atomic variable * * @return Value of the variable */ @@ -159,41 +154,35 @@ uint64_t odp_atomic_load_u64(odp_atomic_u64_t *atom); /** * Store value to atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[out] atom Pointer to an atomic uint64 variable - * @param val Value to store in the variable + * @param atom Pointer to atomic variable + * @param val Value to store in the variable */ void odp_atomic_store_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Fetch and add to atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable - * @param val Value to be added to the 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 odp_atomic_fetch_add_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Add to atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization - * - * @param[in,out] atom Pointer to an atomic uint64 variable - * @param val Value to be added to the variable * + * @param atom Pointer to atomic variable + * @param val Value to be added to the variable */ void odp_atomic_add_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Fetch and subtract from atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable - * @param val Value to be subtracted from the variable + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable * * @return Value of the variable before the subtraction */ @@ -201,18 +190,16 @@ uint64_t odp_atomic_fetch_sub_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Subtract from atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable - * @param val Value to be subtracted from the variable + * @param atom Pointer to atomic variable + * @param val Value to be subtracted from the variable */ void odp_atomic_sub_u64(odp_atomic_u64_t *atom, uint64_t val); /** * Fetch and increment atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable + * @param atom Pointer to atomic variable * * @return Value of the variable before the increment */ @@ -220,17 +207,15 @@ uint64_t odp_atomic_fetch_inc_u64(odp_atomic_u64_t *atom); /** * Increment atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable + * @param atom Pointer to atomic variable */ void odp_atomic_inc_u64(odp_atomic_u64_t *atom); /** * Fetch and decrement atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable + * @param atom Pointer to atomic variable * * @return Value of the variable before the decrement */ @@ -238,9 +223,8 @@ uint64_t odp_atomic_fetch_dec_u64(odp_atomic_u64_t *atom); /** * Decrement atomic uint64 variable - * @note Relaxed memory order, cannot be used for synchronization * - * @param[in,out] atom Pointer to an atomic uint64 variable + * @param atom Pointer to atomic variable */ void odp_atomic_dec_u64(odp_atomic_u64_t *atom); diff --git a/include/odp/api/barrier.h b/include/odp/api/barrier.h index 28310ba34..823eae66c 100644 --- a/include/odp/api/barrier.h +++ b/include/odp/api/barrier.h @@ -18,8 +18,15 @@ extern "C" { #endif -/** @addtogroup odp_synchronizers - * Synchronize threads. +/** + * @defgroup odp_barrier ODP BARRIER + * Thread excution and memory ordering barriers. + * + * @details + * <b> Thread execution barrier (odp_barrier_t) </b> + * + * Thread execution barrier synchronizes a group of threads to wait on the + * barrier until the entire group has reached the barrier. * @{ */ diff --git a/include/odp/api/classification.h b/include/odp/api/classification.h index 380d91b15..c9493c2e2 100644 --- a/include/odp/api/classification.h +++ b/include/odp/api/classification.h @@ -37,7 +37,7 @@ extern "C" { /** * @def ODP_COS_INVALID - * This value is returned from odp_cos_create() on failure, + * This value is returned from odp_cls_cos_create() on failure, * May also be used as a sink class of service that * results in packets being discarded. */ @@ -60,12 +60,12 @@ extern "C" { */ /** - * Class-of-service packet drop policies + * class of service packet drop policies */ -typedef enum odp_cos_drop { +typedef enum odp_cls_drop { ODP_COS_DROP_POOL, /**< Follow buffer pool drop policy */ ODP_COS_DROP_NEVER, /**< Never drop, ignoring buffer pool policy */ -} odp_drop_e; +} odp_cls_drop_t; /** * Packet header field enumeration @@ -89,14 +89,39 @@ typedef enum odp_cos_hdr_flow_fields { } odp_cos_hdr_flow_fields_e; /** + * Class of service parameters + * Used to communicate class of service creation options + */ +typedef struct odp_cls_cos_param { + odp_queue_t queue; /**< Queue associated with CoS */ + odp_pool_t pool; /**< Pool associated with CoS */ + odp_cls_drop_t drop_policy; /**< Drop policy associated with CoS */ +} odp_cls_cos_param_t; + +/** + * Initialize class of service parameters + * + * Initialize an odp_cls_cos_param_t to its default value for all fields + * + * @param param Address of the odp_cls_cos_param_t to be initialized + */ +void odp_cls_cos_param_init(odp_cls_cos_param_t *param); + +/** * Create a class-of-service * - * @param[in] name String intended for debugging purposes. + * @param name String intended for debugging purposes. * - * @return Class of service instance identifier + * @param param class of service parameters + * + * @retval class of service handle * @retval ODP_COS_INVALID on failure. + * + * @note ODP_QUEUE_INVALID and ODP_POOL_INVALID are valid values for queue + * and pool associated with a class of service and when any one of these values + * are configured as INVALID then the packets assigned to the CoS gets dropped. */ -odp_cos_t odp_cos_create(const char *name); +odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param); /** * Discard a class-of-service along with all its associated resources @@ -145,7 +170,7 @@ odp_queue_t odp_cos_queue(odp_cos_t cos_id); * * @note Optional. */ -int odp_cos_drop_set(odp_cos_t cos_id, odp_drop_e drop_policy); +int odp_cos_drop_set(odp_cos_t cos_id, odp_cls_drop_t drop_policy); /** * Get the drop policy configured for a specific class-of-service instance. @@ -155,7 +180,7 @@ int odp_cos_drop_set(odp_cos_t cos_id, odp_drop_e drop_policy); * @retval Drop policy configured with the given * class-of-service */ -odp_drop_e odp_cos_drop(odp_cos_t cos_id); +odp_cls_drop_t odp_cos_drop(odp_cos_t cos_id); /** * Request to override per-port class of service @@ -379,6 +404,32 @@ int odp_pktio_pmr_match_set_cos(odp_pmr_set_t pmr_set_id, odp_pktio_t src_pktio, odp_cos_t dst_cos); /** +* Assigns a packet pool for a specific class of service. +* All the packets belonging to the given class of service will +* be allocated from the assigned packet pool. +* The packet pool associated with class of service will supersede the +* packet pool associated with the pktio interface. +* +* @param cos_id class of service handle +* @param pool_id packet pool handle +* +* @retval 0 on success +* @retval <0 on failure +*/ +int odp_cls_cos_pool_set(odp_cos_t cos_id, odp_pool_t pool_id); + +/** +* Get the pool associated with the given class of service +* +* @param cos_id class of service handle +* +* @retval pool handle of the associated pool +* @retval ODP_POOL_INVALID if no associated pool found or +* incase of an error +*/ +odp_pool_t odp_cls_cos_pool(odp_cos_t cos_id); + +/** * Get printable value for an odp_cos_t * * @param hdl odp_cos_t handle to be printed diff --git a/include/odp/api/crypto.h b/include/odp/api/crypto.h index c62021e04..41beedbf5 100644 --- a/include/odp/api/crypto.h +++ b/include/odp/api/crypto.h @@ -70,6 +70,8 @@ typedef enum { ODP_CIPHER_ALG_3DES_CBC, /** AES128 with cipher block chaining */ ODP_CIPHER_ALG_AES128_CBC, + /** AES128 in Galois/Counter Mode */ + ODP_CIPHER_ALG_AES128_GCM, } odp_cipher_alg_t; /** @@ -82,6 +84,8 @@ typedef enum { ODP_AUTH_ALG_MD5_96, /** SHA256 with 128 bit key */ ODP_AUTH_ALG_SHA256_128, + /** AES128 in Galois/Counter Mode */ + ODP_AUTH_ALG_AES128_GCM, } odp_auth_alg_t; /** diff --git a/include/odp/api/hash.h b/include/odp/api/hash.h new file mode 100644 index 000000000..1b2a580ea --- /dev/null +++ b/include/odp/api/hash.h @@ -0,0 +1,98 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP Hash functions + */ + +#ifndef ODP_API_HASH_H_ +#define ODP_API_HASH_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <odp/std_types.h> + +/** @defgroup odp_hash ODP HASH FUNCTIONS + * ODP Hash functions + * @{ + */ + +/** +* Calculate CRC-32 +* +* Calculates CRC-32 over the data. The polynomial is 0x04c11db7. +* +* @param data Pointer to data +* @param data_len Data length in bytes +* @param init_val CRC generator initialization value +* +* @return CRC32 value +*/ +uint32_t odp_hash_crc32(const void *data, uint32_t data_len, uint32_t init_val); + +/** +* Calculate CRC-32C +* +* Calculates CRC-32C (a.k.a. CRC-32 Castagnoli) over the data. +* The polynomial is 0x1edc6f41. +* +* @param data Pointer to data +* @param data_len Data length in bytes +* @param init_val CRC generator initialization value +* +* @return CRC32C value +*/ +uint32_t odp_hash_crc32c(const void *data, uint32_t data_len, + uint32_t init_val); + +/** +* CRC parameters +* +* Supports CRCs up to 64 bits +*/ +typedef struct odp_hash_crc_param_t { + /** CRC width in bits */ + uint32_t width; + /** Polynomial (stored in 'width' LSB bits) */ + uint64_t poly; + /** 0: don't reflect, 1: reflect bits in input bytes */ + odp_bool_t reflect_in; + /** 0: don't reflect, 1: reflect bits in output bytes */ + odp_bool_t reflect_out; + /** XOR this value to CRC output (stored in 'width' LSB bits) */ + uint64_t xor_out; +} odp_hash_crc_param_t; + +/** +* Calculate up to 64 bit CRC using the given parameters +* +* Calculates CRC over the data using the given parameters. +* +* @param data Pointer to data +* @param data_len Data length in bytes +* @param init_val CRC generator initialization value +* @param crc_param CRC parameters +* @param crc Pointer for CRC output +* +* @return 0 on success, <0 on failure (e.g. not supported algorithm) +*/ +int odp_hash_crc_gen64(const void *data, uint32_t data_len, + uint64_t init_val, odp_hash_crc_param_t *crc_param, + uint64_t *crc); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/init.h b/include/odp/api/init.h index 737ff6d69..4ac521671 100644 --- a/include/odp/api/init.h +++ b/include/odp/api/init.h @@ -141,6 +141,10 @@ typedef struct odp_platform_init_t { * * This function must be called once before calling any other ODP API * functions. + * The underlying implementation may have another way to get configuration + * related to platform_params (e.g. environmental variable, configuration + * file), but if the application passes platform_params, it should always + * supersede any other configuration data the platform has. * * @param params Those parameters that are interpreted by the ODP API. * Use NULL to set all parameters to their defaults. diff --git a/include/odp/api/packet_io.h b/include/odp/api/packet_io.h index 003861017..cf9275191 100644 --- a/include/odp/api/packet_io.h +++ b/include/odp/api/packet_io.h @@ -386,6 +386,15 @@ uint64_t odp_pktio_to_u64(odp_pktio_t pktio); void odp_pktio_param_init(odp_pktio_param_t *param); /** + * Print pktio info to the console + * + * Print implementation-defined pktio debug information to the console. + * + * @param pktio Packet IO handle + */ +void odp_pktio_print(odp_pktio_t pktio); + +/** * @} */ diff --git a/include/odp/api/rwlock.h b/include/odp/api/rwlock.h index d730a7014..54f426fe7 100644 --- a/include/odp/api/rwlock.h +++ b/include/odp/api/rwlock.h @@ -17,18 +17,21 @@ extern "C" { #endif -/** @defgroup odp_synchronizers ODP SYNCRONIZERS - * Operations on reader/writer locks. - * A reader/writer lock allows multiple simultaneous readers but only one - * writer at a time. - * A thread that wants write access will have to wait until there are no - * threads that want read access. This casues a risk for starvation. - * @{ +/** + * @defgroup odp_locks ODP LOCKS + * @details + * <b> Reader / writer lock (odp_rwlock_t) </b> + * + * A reader/writer lock allows multiple simultaneous readers but only one + * writer at a time. A thread that wants write access will have to wait until + * there are no threads that want read access. This casues a risk for + * starvation. + * @{ */ /** * @typedef odp_rwlock_t - * ODP rwlock + * ODP reader/writer lock */ diff --git a/include/odp/api/rwlock_recursive.h b/include/odp/api/rwlock_recursive.h new file mode 100644 index 000000000..10b2f79ba --- /dev/null +++ b/include/odp/api/rwlock_recursive.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP recursive read/write lock + */ + +#ifndef ODP_API_RWLOCK_RECURSIVE_H_ +#define ODP_API_RWLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup odp_locks + * @details + * <b> Recursive reader/writer lock (odp_rwlock_recursive_t) </b> + * + * This is recursive version of the reader/writer lock. + * A thread can read- or write-acquire a recursive read-write lock multiple + * times without a deadlock. To release the lock, the thread must unlock it + * the same number of times. Recursion is supported only for a pure series of + * read or write lock calls. Read and write lock calls must not be mixed when + * recursing. + * + * For example, these are supported... + * * read_lock(); read_lock(); read_unlock(); read_unlock(); + * * write_lock(); write_lock(); write_unlock(); write_unlock(); + * + * ... but this is not supported. + * * read_lock(); write_lock(); write_unlock(); read_unlock(); + * @{ + */ + +/** + * @typedef odp_rwlock_recursive_t + * Recursive rwlock + */ + +/** + * Initialize recursive rwlock + * + * @param lock Pointer to a lock + */ +void odp_rwlock_recursive_init(odp_rwlock_recursive_t *lock); + +/** + * Acquire recursive rwlock for reading + * + * This call allows the thread to acquire the same lock multiple times for + * reading. The lock cannot be acquired for writing while holding it + * for reading. + * + * @param lock Pointer to a lock + */ +void odp_rwlock_recursive_read_lock(odp_rwlock_recursive_t *lock); + +/** + * Release recursive rwlock after reading + * + * @param lock Pointer to a lock + */ +void odp_rwlock_recursive_read_unlock(odp_rwlock_recursive_t *lock); + +/** + * Acquire recursive rwlock for writing + * + * This call allows the thread to acquire the same lock multiple times for + * writing. The lock cannot be acquired for reading while holding it + * for writing. + * + * @param lock Pointer to a lock + */ +void odp_rwlock_recursive_write_lock(odp_rwlock_recursive_t *lock); + +/** + * Release recursive rwlock after writing + * + * @param lock Pointer to a lock + */ +void odp_rwlock_recursive_write_unlock(odp_rwlock_recursive_t *lock); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/spinlock.h b/include/odp/api/spinlock.h index 9a5a9290a..154d0258a 100644 --- a/include/odp/api/spinlock.h +++ b/include/odp/api/spinlock.h @@ -18,9 +18,14 @@ extern "C" { #endif -/** @addtogroup odp_synchronizers - * Operations on spin locks. - * @{ +/** + * @addtogroup odp_locks + * @details + * <b> Spin lock (odp_spinlock_t) </b> + * + * Spinlock simply re-tries to acquire the lock as long as takes to succeed. + * Spinlock is not fair since some threads may succeed more often than others. + * @{ */ /** diff --git a/include/odp/api/spinlock_recursive.h b/include/odp/api/spinlock_recursive.h new file mode 100644 index 000000000..d98f2bbb6 --- /dev/null +++ b/include/odp/api/spinlock_recursive.h @@ -0,0 +1,85 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP recursive spinlock + */ + +#ifndef ODP_API_SPINLOCK_RECURSIVE_H_ +#define ODP_API_SPINLOCK_RECURSIVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup odp_locks + * @details + * <b> Recursive spin lock (odp_spinlock_recursive_t) </b> + * + * This is recursive version of the spin lock. A thread can acquire the lock + * multiple times without a deadlock. To release the lock, the thread must + * unlock it the same number of times. + * @{ + */ + +/** + * @typedef odp_spinlock_recursive_t + * Recursive spinlock + */ + +/** + * Initialize recursive spinlock. + * + * @param lock Pointer to a lock + */ +void odp_spinlock_recursive_init(odp_spinlock_recursive_t *lock); + +/** + * Acquire recursive spinlock. + * + * @param lock Pointer to a lock + */ +void odp_spinlock_recursive_lock(odp_spinlock_recursive_t *lock); + +/** + * Try to acquire recursive spinlock. + * + * @param lock Pointer to a lock + * + * @retval 1 lock acquired + * @retval 0 lock not acquired + */ +int odp_spinlock_recursive_trylock(odp_spinlock_recursive_t *lock); + +/** + * Release recursive spinlock. + * + * @param lock Pointer to a lock + */ +void odp_spinlock_recursive_unlock(odp_spinlock_recursive_t *lock); + +/** + * Check if recursive spinlock is locked. + * + * @param lock Pointer to a lock + * + * @retval 1 lock is locked + * @retval 0 lock is not locked + */ +int odp_spinlock_recursive_is_locked(odp_spinlock_recursive_t *lock); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/std_clib.h b/include/odp/api/std_clib.h new file mode 100644 index 000000000..2119ec481 --- /dev/null +++ b/include/odp/api/std_clib.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2015, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * + * ODP version of often used C library calls + */ + +#ifndef ODP_API_STD_CLIB_H_ +#define ODP_API_STD_CLIB_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup odp_std_clib ODP STD CLIB + * @details + * ODP version of often used C library calls + * @{ + */ + +/** + * Memcpy + * + * ODP version of C library memcpy function. It copies 'num' bytes from source + * to destination address. Source and destination memory blocks must not + * overlap. + * + * @param dst Pointer to destination memory block + * @param src Pointer to source memory block + * @param num Number of bytes to copy + * + * @return 'dst' address + */ +void *odp_memcpy(void *dst, const void *src, size_t num); + +/** + * Memset + * + * ODP version of C library memset function. It sets 'value' to first 'num' + * bytes of memory block pointed by 'ptr'. + * + * @param ptr Pointer to the memory block + * @param value Value to be set + * @param num Number of bytes to set + * + * @return 'ptr' address + */ +void *odp_memset(void *ptr, int value, size_t num); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/odp/api/sync.h b/include/odp/api/sync.h index b338a98a8..c6f790c6f 100644 --- a/include/odp/api/sync.h +++ b/include/odp/api/sync.h @@ -8,7 +8,7 @@ /** * @file * - * ODP synchronisation + * ODP memory barriers */ #ifndef ODP_API_SYNC_H_ @@ -18,42 +18,66 @@ extern "C" { #endif -/** @addtogroup odp_synchronizers +/** + * @addtogroup odp_barrier + * @details + * <b> Memory barriers </b> + * + * Memory barriers enforce ordering of memory load and store operations + * specified before and after the barrier. These barriers may affect both + * compiler optimizations and CPU out-of-order execution. All ODP + * synchronization mechanisms (e.g. execution barriers, locks, queues, etc ) + * include all necessary memory barriers, so these calls are not needed when + * using those. Also ODP atomic operations have memory ordered versions. These + * explicit barriers may be needed when thread synchronization is based on + * a non-ODP defined mechanism. Depending on the HW platform, heavy usage of + * memory barriers may cause significant performance degradation. + * * @{ */ /** - * Synchronise stores + * Memory barrier for release operations * - * Ensures that all CPU store operations that precede the odp_sync_stores() - * call are globally visible before any store operation that follows it. + * This memory barrier has release semantics. It synchronizes with a pairing + * barrier for acquire operations. The releasing and acquiring threads + * synchronize through shared memory. The releasing thread must call this + * barrier before signaling the acquiring thread. After the acquiring thread + * receives the signal, it must call odp_mb_acquire() before it reads the + * memory written by the releasing thread. + * + * This call is not needed when using ODP defined synchronization mechanisms. + * + * @see odp_mb_acquire() */ -static inline void odp_sync_stores(void) -{ -#if defined __x86_64__ || defined __i386__ - - __asm__ __volatile__ ("sfence\n" : : : "memory"); - -#elif defined(__arm__) -#if __ARM_ARCH == 6 - __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \ - : : "r" (0) : "memory"); -#elif __ARM_ARCH >= 7 || defined __aarch64__ - - __asm__ __volatile__ ("dmb st" : : : "memory"); -#else - __asm__ __volatile__ ("" : : : "memory"); -#endif - -#elif defined __OCTEON__ - - __asm__ __volatile__ ("syncws\n" : : : "memory"); +void odp_mb_release(void); -#else - __sync_synchronize(); -#endif -} +/** + * Memory barrier for acquire operations + * + * This memory barrier has acquire semantics. It synchronizes with a pairing + * barrier for release operations. The releasing and acquiring threads + * synchronize through shared memory. The releasing thread must call + * odp_mb_release() before signaling the acquiring thread. After the acquiring + * thread receives the signal, it must call this barrier before it reads the + * memory written by the releasing thread. + * + * This call is not needed when using ODP defined synchronization mechanisms. + * + * @see odp_mb_release() + */ +void odp_mb_acquire(void); +/** + * Full memory barrier + * + * This is a full memory barrier. It guarantees that all load and store + * operations specified before it are visible to other threads before + * all load and store operations specified after it. + * + * This call is not needed when using ODP defined synchronization mechanisms. + */ +void odp_mb_full(void); /** * @} diff --git a/include/odp/api/thread.h b/include/odp/api/thread.h index 3029342c2..37202497a 100644 --- a/include/odp/api/thread.h +++ b/include/odp/api/thread.h @@ -23,6 +23,13 @@ extern "C" { */ /** + * @def ODP_THREAD_COUNT_MAX + * Maximum number of threads supported in build time. Use + * odp_thread_count_max() for maximum number of threads supported in run time, + * which depend on system configuration and may be lower than this number. + */ + +/** * Thread type */ typedef enum odp_thread_type_e { @@ -78,7 +85,7 @@ int odp_thread_count(void); * Maximum thread count * * Returns the maximum thread count, which is a constant value and set in - * ODP initialization phase. + * ODP initialization phase. This may be lower than ODP_THREAD_COUNT_MAX. * * @return Maximum thread count */ diff --git a/include/odp/api/thrmask.h b/include/odp/api/thrmask.h index ebc31f2f6..8666166e0 100644 --- a/include/odp/api/thrmask.h +++ b/include/odp/api/thrmask.h @@ -67,7 +67,7 @@ void odp_thrmask_set(odp_thrmask_t *mask, int thr); * Set all threads in mask * * Set all possible threads in the mask. All threads from 0 to - * odp_thrmask_count() minus one are set, regardless of which threads are + * odp_thread_count_max() minus one are set, regardless of which threads are * actually active. * * @param mask Thread mask to set diff --git a/include/odp/api/ticketlock.h b/include/odp/api/ticketlock.h index e395ac4ca..3f0e3f556 100644 --- a/include/odp/api/ticketlock.h +++ b/include/odp/api/ticketlock.h @@ -18,13 +18,17 @@ extern "C" { #endif -/** @addtogroup odp_synchronizers - * Operations on ticket locks. +/** + * @addtogroup odp_locks + * @details + * <b> Ticket lock (odp_ticketlock_t) </b> + * * Acquiring a ticket lock happens in two phases. First the threads takes a - * ticket. Second it waits (spins) until it is its turn. - * Ticket locks are believed to be more fair than spin locks. - * Ticket locks shall not be used in the presence of preemption. - * @{ + * ticket. Second it waits (spins) until it is its turn. Ticket locks are + * believed to be more fair than spin locks. Ticket locks shall not be used + * if a thread may be preempted, since other threads cannot acquire the lock + * while the thread in turn is stalled. + * @{ */ /** diff --git a/include/odp/api/time.h b/include/odp/api/time.h index 50a0bf55d..efc547802 100644 --- a/include/odp/api/time.h +++ b/include/odp/api/time.h @@ -45,13 +45,28 @@ extern "C" { * Current local time * * Returns current local time stamp value. The local time source provides high - * resolution time. + * resolution time, it is initialized to zero during ODP startup and will not + * wrap around in at least 10 years. + * Local time stamps are local to the calling thread and must not be shared + * with other threads. * * @return Local time stamp. */ odp_time_t odp_time_local(void); /** + * Current global time + * + * Returns current global time stamp value. The global time source provides high + * resolution time, it is initialized to zero during ODP startup and will not + * wrap around in at least 10 years. + * Global time stamps can be shared between threads. + * + * @return Global time stamp. + */ +odp_time_t odp_time_global(void); + +/** * Time difference * * @param t2 Second time stamp @@ -90,6 +105,15 @@ uint64_t odp_time_to_ns(odp_time_t time); odp_time_t odp_time_local_from_ns(uint64_t ns); /** + * Convert nanoseconds to global time + * + * @param ns Time in nanoseconds + * + * @return Global time stamp + */ +odp_time_t odp_time_global_from_ns(uint64_t ns); + +/** * Compare two times * * @param t2 Second time @@ -100,6 +124,38 @@ odp_time_t odp_time_local_from_ns(uint64_t ns); int odp_time_cmp(odp_time_t t2, odp_time_t t1); /** + * Local time resolution in hertz + * + * @return Local time resolution in hertz + */ +uint64_t odp_time_local_res(void); + +/** + * Global time resolution in hertz + * + * @return Global time resolution in hertz + */ +uint64_t odp_time_global_res(void); + +/** + * Wait until the specified (wall clock) time has been reached + * + * The thread potentially busy loop the entire wait time. + * + * @param time Time to reach before continue + */ +void odp_time_wait_until(odp_time_t time); + +/** + * Wait the specified number of nanoseconds + * + * The thread potentially busy loop the entire wait time. + * + * @param ns Time in nanoseconds to wait + */ +void odp_time_wait_ns(uint64_t ns); + +/** * Get printable value for an odp_time_t * * @param time time to be printed diff --git a/include/odp/api/version.h b/include/odp/api/version.h index 58bb7ecfe..95fac3cf2 100644 --- a/include/odp/api/version.h +++ b/include/odp/api/version.h @@ -18,8 +18,15 @@ extern "C" { #endif -/** @defgroup odp_version ODP VERSION - * @{ +/** + * @defgroup odp_version ODP VERSION + * @details + * <b> ODP API and implementation versions </b> + * + * ODP API version is identified by ODP_VERSION_API_XXX pre-processor macros. + * In addition to these macros, API calls can be used to identify implementation + * and API version information at run time. + * @{ */ /** @@ -37,7 +44,7 @@ extern "C" { * Introduction of major new features or changes. APIs with different major * versions are likely not backward compatible. */ -#define ODP_VERSION_API_MAJOR 5 +#define ODP_VERSION_API_MAJOR 6 /** * ODP API minor version @@ -49,20 +56,42 @@ extern "C" { #define ODP_VERSION_API_MINOR 0 /** - * Returns ODP API version string + * ODP API version string + * + * The API version string defines ODP API version in this format: + * @verbatim <generation>.<major>.<minor> @endverbatim + * + * The string is null terminated. + * + * @return Pointer to API version string */ const char *odp_version_api_str(void); +/** + * Implementation name string + * + * This is a free format string which identifies the implementation with a + * unique name. The string should be compact and remain constant over multiple + * API and implementation versions. Application can use this to identify the + * underlying implementation at run time. The string is null terminated. + * + * @return Pointer to implementation name string + */ +const char *odp_version_impl_name(void); /** - * Returns ODP implementation version string + * Implementation version string + * + * This is a free format string which identifies the implementation with + * detailed version information. The string may include information about + * implementation version, bug fix level, version control tags, build number, + * etc details which exactly identify the implementation code base. + * User may include this information e.g. to bug reports. The string is null + * terminated. * - * Every implementation of ODP may receive bug fixes independent of the version - * of the API changing, this function returns that indication string. - * @note This string is implementation specific. - * @sa odp_version_api_str() + * @see odp_version_api_str(), odp_version_impl_name() * - * @return null terminated implementation specific version identifier string + * @return Pointer to implementation specific version identifier string */ const char *odp_version_impl_str(void); /** |