eal: introduce bit operations API
Bitwise operation APIs are defined and used in a lot of PMDs, which caused a huge code duplication. To reduce duplication, this patch consolidates them into a common API family. Signed-off-by: Joyce Kong <joyce.kong@arm.com> Reviewed-by: Gavin Hu <gavin.hu@arm.com> Reviewed-by: Phil Yang <phil.yang@arm.com> Acked-by: Morten Brørup <mb@smartsharesystems.com>
This commit is contained in:
parent
2a5d547a4a
commit
7f3aa08639
|
@ -246,6 +246,10 @@ F: lib/librte_eal/common/rte_service.c
|
|||
F: doc/guides/prog_guide/service_cores.rst
|
||||
F: app/test/test_service_cores.c
|
||||
|
||||
Bitops
|
||||
M: Joyce Kong <joyce.kong@arm.com>
|
||||
F: lib/librte_eal/include/rte_bitops.h
|
||||
|
||||
Bitmap
|
||||
M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
|
||||
F: lib/librte_eal/include/rte_bitmap.h
|
||||
|
|
|
@ -166,6 +166,7 @@ The public API headers are grouped by topics:
|
|||
[ip4_node] (@ref rte_node_ip4_api.h)
|
||||
|
||||
- **basic**:
|
||||
[bitops] (@ref rte_bitops.h),
|
||||
[approx fraction] (@ref rte_approx.h),
|
||||
[random] (@ref rte_random.h),
|
||||
[config file] (@ref rte_cfgfile.h),
|
||||
|
|
|
@ -6,6 +6,7 @@ includes += include_directories('.')
|
|||
headers += files(
|
||||
'rte_alarm.h',
|
||||
'rte_bitmap.h',
|
||||
'rte_bitops.h',
|
||||
'rte_branch_prediction.h',
|
||||
'rte_bus.h',
|
||||
'rte_class.h',
|
||||
|
|
258
lib/librte_eal/include/rte_bitops.h
Normal file
258
lib/librte_eal/include/rte_bitops.h
Normal file
|
@ -0,0 +1,258 @@
|
|||
/* SPDX-License-Identifier: BSD-3-Clause
|
||||
* Copyright(c) 2020 Arm Limited
|
||||
*/
|
||||
|
||||
#ifndef _RTE_BITOPS_H_
|
||||
#define _RTE_BITOPS_H_
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Bit Operations
|
||||
*
|
||||
* This file defines a family of APIs for bit operations
|
||||
* without enforcing memory ordering.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <rte_debug.h>
|
||||
#include <rte_compat.h>
|
||||
|
||||
/*------------------------ 32-bit relaxed operations ------------------------*/
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Get the target bit from a 32-bit value without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The target bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint32_t
|
||||
rte_bit_relaxed_get32(unsigned int nr, volatile uint32_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 32);
|
||||
|
||||
uint32_t mask = UINT32_C(1) << nr;
|
||||
return (*addr) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Set the target bit in a 32-bit value to 1 without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to set.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline void
|
||||
rte_bit_relaxed_set32(unsigned int nr, volatile uint32_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 32);
|
||||
|
||||
uint32_t mask = UINT32_C(1) << nr;
|
||||
*addr = (*addr) | mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Clear the target bit in a 32-bit value to 0 without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to clear.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline void
|
||||
rte_bit_relaxed_clear32(unsigned int nr, volatile uint32_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 32);
|
||||
|
||||
uint32_t mask = UINT32_C(1) << nr;
|
||||
*addr = (*addr) & (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Return the original bit from a 32-bit value, then set it to 1 without
|
||||
* memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get and set.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The original bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint32_t
|
||||
rte_bit_relaxed_test_and_set32(unsigned int nr, volatile uint32_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 32);
|
||||
|
||||
uint32_t mask = UINT32_C(1) << nr;
|
||||
uint32_t val = *addr;
|
||||
*addr = val | mask;
|
||||
return val & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Return the original bit from a 32-bit value, then clear it to 0 without
|
||||
* memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get and clear.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The original bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint32_t
|
||||
rte_bit_relaxed_test_and_clear32(unsigned int nr, volatile uint32_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 32);
|
||||
|
||||
uint32_t mask = UINT32_C(1) << nr;
|
||||
uint32_t val = *addr;
|
||||
*addr = val & (~mask);
|
||||
return val & mask;
|
||||
}
|
||||
|
||||
/*------------------------ 64-bit relaxed operations ------------------------*/
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Get the target bit from a 64-bit value without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The target bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint64_t
|
||||
rte_bit_relaxed_get64(unsigned int nr, volatile uint64_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 64);
|
||||
|
||||
uint64_t mask = UINT64_C(1) << nr;
|
||||
return (*addr) & mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Set the target bit in a 64-bit value to 1 without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to set.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline void
|
||||
rte_bit_relaxed_set64(unsigned int nr, volatile uint64_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 64);
|
||||
|
||||
uint64_t mask = UINT64_C(1) << nr;
|
||||
(*addr) = (*addr) | mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Clear the target bit in a 64-bit value to 0 without memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to clear.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline void
|
||||
rte_bit_relaxed_clear64(unsigned int nr, volatile uint64_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 64);
|
||||
|
||||
uint64_t mask = UINT64_C(1) << nr;
|
||||
*addr = (*addr) & (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Return the original bit from a 64-bit value, then set it to 1 without
|
||||
* memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get and set.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The original bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint64_t
|
||||
rte_bit_relaxed_test_and_set64(unsigned int nr, volatile uint64_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 64);
|
||||
|
||||
uint64_t mask = UINT64_C(1) << nr;
|
||||
uint64_t val = *addr;
|
||||
*addr = val | mask;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @warning
|
||||
* @b EXPERIMENTAL: this API may change, or be removed, without prior notice
|
||||
*
|
||||
* Return the original bit from a 64-bit value, then clear it to 0 without
|
||||
* memory ordering.
|
||||
*
|
||||
* @param nr
|
||||
* The target bit to get and clear.
|
||||
* @param addr
|
||||
* The address holding the bit.
|
||||
* @return
|
||||
* The original bit.
|
||||
*/
|
||||
__rte_experimental
|
||||
static inline uint64_t
|
||||
rte_bit_relaxed_test_and_clear64(unsigned int nr, volatile uint64_t *addr)
|
||||
{
|
||||
RTE_ASSERT(nr < 64);
|
||||
|
||||
uint64_t mask = UINT64_C(1) << nr;
|
||||
uint64_t val = *addr;
|
||||
*addr = val & (~mask);
|
||||
return val & mask;
|
||||
}
|
||||
|
||||
#endif /* _RTE_BITOPS_H_ */
|
Loading…
Reference in a new issue