The counter add function uses cmpxchg() and cmpxchg_local() on 1, 2, 4,
and 8 bytes types.
In libcounter, the 8 bytes type is only supported on 64-bit
architectures, but the 1, 2, 4 byte type code is present for all
architectures, even though only the 4 byte code is currently used by
lttng-modules.
The ARM implementation of cmpxchg uses the "__bad_cmpxchg" linker error
to report use of cmpxchg on an unsupported size.
Considering that "inline" does not strictly mean always inline (depends
on CONFIG_OPTIMIZE_INLINING on some kernels, and does not mean forced
inlining in recent kernels), the compiler is free to generate a function
rather than perform inlining. If that happens, then the __bad_cmpxchg
linker error is generated even if the 1 and 2 bytes types are unused.
Therefore, use __always_inline for functions in counter-api.h to force
inlining, and therefore removal of unused code before linking, which is
required by this Linux kernel __bad_cmpxchg linker error trick.
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I1adccd1382e71abc5880e0351d976b779245468a
/*
* Using unsigned arithmetic because overflow is defined.
*/
/*
* Using unsigned arithmetic because overflow is defined.
*/
-static inline int __lttng_counter_add(const struct lib_counter_config *config,
+static __always_inline int __lttng_counter_add(const struct lib_counter_config *config,
enum lib_counter_config_alloc alloc,
enum lib_counter_config_sync sync,
struct lib_counter *counter,
enum lib_counter_config_alloc alloc,
enum lib_counter_config_sync sync,
struct lib_counter *counter,
-static inline int __lttng_counter_add_percpu(const struct lib_counter_config *config,
+static __always_inline int __lttng_counter_add_percpu(const struct lib_counter_config *config,
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
-static inline int __lttng_counter_add_global(const struct lib_counter_config *config,
+static __always_inline int __lttng_counter_add_global(const struct lib_counter_config *config,
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
dimension_indexes, v, NULL);
}
dimension_indexes, v, NULL);
}
-static inline int lttng_counter_add(const struct lib_counter_config *config,
+static __always_inline int lttng_counter_add(const struct lib_counter_config *config,
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
struct lib_counter *counter,
const size_t *dimension_indexes, int64_t v)
{
-static inline int lttng_counter_inc(const struct lib_counter_config *config,
+static __always_inline int lttng_counter_inc(const struct lib_counter_config *config,
struct lib_counter *counter,
const size_t *dimension_indexes)
{
return lttng_counter_add(config, counter, dimension_indexes, 1);
}
struct lib_counter *counter,
const size_t *dimension_indexes)
{
return lttng_counter_add(config, counter, dimension_indexes, 1);
}
-static inline int lttng_counter_dec(const struct lib_counter_config *config,
+static __always_inline int lttng_counter_dec(const struct lib_counter_config *config,
struct lib_counter *counter,
const size_t *dimension_indexes)
{
struct lib_counter *counter,
const size_t *dimension_indexes)
{