Skip to content

Commit

Permalink
[BUILD] Provide LIKELY / UNLIKELY macros (open-telemetry#2580)
Browse files Browse the repository at this point in the history
* Contributes to open-telemetry#2572

* Restored support for __builtin_expect()

* Typo
  • Loading branch information
marcalff committed Mar 11, 2024
1 parent 3e4b7d3 commit 25738f3
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 18 deletions.
110 changes: 100 additions & 10 deletions api/include/opentelemetry/common/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,112 @@

#pragma once

#if !defined(OPENTELEMETRY_LIKELY_IF) && defined(__cplusplus)
/*
Expected usage pattern:
if OPENTELEMETRY_LIKELY_CONDITION (ptr != nullptr)
{
do_something_likely();
} else {
do_something_unlikely();
}
This pattern works with gcc/clang and __builtin_expect(),
as well as with C++20.
It is unclear if __builtin_expect() will be deprecated
in favor of C++20 [[likely]] or not.
OPENTELEMETRY_LIKELY_CONDITION is preferred over OPENTELEMETRY_LIKELY,
to be revisited when C++20 is required.
*/

#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && defined(__cplusplus)
// Only use likely with C++20
# if __cplusplus >= 202002L
// GCC 9 has likely attribute but do not support declare it at the beginning of statement
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
# if __has_cpp_attribute(likely)
# define OPENTELEMETRY_LIKELY_IF(...) \
if (__VA_ARGS__) \
[[likely]]
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
# if __has_cpp_attribute(likely)
# define OPENTELEMETRY_LIKELY_CONDITION(C) (C) [[likely]]
# endif
# endif
# endif
#endif
#if !defined(OPENTELEMETRY_LIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))
// Only use if supported by the compiler
# define OPENTELEMETRY_LIKELY_CONDITION(C) (__builtin_expect(!!(C), true))
#endif
#ifndef OPENTELEMETRY_LIKELY_CONDITION
// Do not use likely annotations
# define OPENTELEMETRY_LIKELY_CONDITION(C) (C)
#endif

#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && defined(__cplusplus)
// Only use unlikely with C++20
# if __cplusplus >= 202002L
// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
# if __has_cpp_attribute(unlikely)
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C) [[unlikely]]
# endif
# endif
# endif
#endif
#if !defined(OPENTELEMETRY_LIKELY_IF) && (defined(__clang__) || defined(__GNUC__))
# define OPENTELEMETRY_LIKELY_IF(...) if (__builtin_expect(!!(__VA_ARGS__), true))
#if !defined(OPENTELEMETRY_UNLIKELY_CONDITION) && (defined(__clang__) || defined(__GNUC__))
// Only use if supported by the compiler
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (__builtin_expect(!!(C), false))
#endif
#ifndef OPENTELEMETRY_LIKELY_IF
# define OPENTELEMETRY_LIKELY_IF(...) if (__VA_ARGS__)
#ifndef OPENTELEMETRY_UNLIKELY_CONDITION
// Do not use unlikely annotations
# define OPENTELEMETRY_UNLIKELY_CONDITION(C) (C)
#endif

/*
Expected usage pattern:
if (ptr != nullptr)
OPENTELEMETRY_LIKELY
{
do_something_likely();
} else {
do_something_unlikely();
}
This pattern works starting with C++20.
See https://en.cppreference.com/w/cpp/language/attributes/likely
Please use OPENTELEMETRY_LIKELY_CONDITION instead for now.
*/

#if !defined(OPENTELEMETRY_LIKELY) && defined(__cplusplus)
// Only use likely with C++20
# if __cplusplus >= 202002L
// GCC 9 has likely attribute but do not support declare it at the beginning of statement
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
# if __has_cpp_attribute(likely)
# define OPENTELEMETRY_LIKELY [[likely]]
# endif
# endif
# endif
#endif

#ifndef OPENTELEMETRY_LIKELY
# define OPENTELEMETRY_LIKELY
#endif

#if !defined(OPENTELEMETRY_UNLIKELY) && defined(__cplusplus)
// Only use unlikely with C++20
# if __cplusplus >= 202002L
// GCC 9 has unlikely attribute but do not support declare it at the beginning of statement
# if defined(__has_cpp_attribute) && (defined(__clang__) || !defined(__GNUC__) || __GNUC__ > 9)
# if __has_cpp_attribute(unlikely)
# define OPENTELEMETRY_UNLIKELY [[unlikely]]
# endif
# endif
# endif
#endif

#ifndef OPENTELEMETRY_UNLIKELY
# define OPENTELEMETRY_UNLIKELY
#endif

/// \brief Declare variable as maybe unused
Expand Down
10 changes: 8 additions & 2 deletions api/include/opentelemetry/logs/logger.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,13 +258,19 @@ class Logger

inline bool Enabled(Severity severity, const EventId &event_id) const noexcept
{
OPENTELEMETRY_LIKELY_IF(Enabled(severity) == false) { return false; }
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(severity, event_id);
}

inline bool Enabled(Severity severity, int64_t event_id) const noexcept
{
OPENTELEMETRY_LIKELY_IF(Enabled(severity) == false) { return false; }
if OPENTELEMETRY_LIKELY_CONDITION (!Enabled(severity))
{
return false;
}
return EnabledImplementation(severity, event_id);
}

Expand Down
10 changes: 8 additions & 2 deletions exporters/otlp/src/otlp_log_recordable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,21 @@ namespace otlp

const opentelemetry::sdk::resource::Resource &OtlpLogRecordable::GetResource() const noexcept
{
OPENTELEMETRY_LIKELY_IF(nullptr != resource_) { return *resource_; }
if OPENTELEMETRY_LIKELY_CONDITION (nullptr != resource_)
{
return *resource_;
}

return opentelemetry::sdk::logs::ReadableLogRecord::GetDefaultResource();
}

const opentelemetry::sdk::instrumentationscope::InstrumentationScope &
OtlpLogRecordable::GetInstrumentationScope() const noexcept
{
OPENTELEMETRY_LIKELY_IF(nullptr != instrumentation_scope_) { return *instrumentation_scope_; }
if OPENTELEMETRY_LIKELY_CONDITION (nullptr != instrumentation_scope_)
{
return *instrumentation_scope_;
}

return opentelemetry::sdk::logs::ReadableLogRecord::GetDefaultInstrumentationScope();
}
Expand Down
10 changes: 8 additions & 2 deletions sdk/src/logs/read_write_log_record.cc
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,10 @@ const std::unordered_map<std::string, opentelemetry::common::AttributeValue>

const opentelemetry::sdk::resource::Resource &ReadWriteLogRecord::GetResource() const noexcept
{
OPENTELEMETRY_LIKELY_IF(nullptr != resource_) { return *resource_; }
if OPENTELEMETRY_LIKELY_CONDITION (nullptr != resource_)
{
return *resource_;
}

return GetDefaultResource();
}
Expand All @@ -172,7 +175,10 @@ void ReadWriteLogRecord::SetResource(
const opentelemetry::sdk::instrumentationscope::InstrumentationScope &
ReadWriteLogRecord::GetInstrumentationScope() const noexcept
{
OPENTELEMETRY_LIKELY_IF(nullptr != instrumentation_scope_) { return *instrumentation_scope_; }
if OPENTELEMETRY_LIKELY_CONDITION (nullptr != instrumentation_scope_)
{
return *instrumentation_scope_;
}

return GetDefaultInstrumentationScope();
}
Expand Down
7 changes: 5 additions & 2 deletions sdk/src/metrics/data/circular_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ struct AdaptingIntegerArrayIncrement
uint64_t operator()(std::vector<T> &backing)
{
const uint64_t result = backing[index] + count;
OPENTELEMETRY_LIKELY_IF(result <= uint64_t(std::numeric_limits<T>::max()))
if OPENTELEMETRY_LIKELY_CONDITION (result <= uint64_t(std::numeric_limits<T>::max()))
{
backing[index] = static_cast<T>(result);
return 0;
Expand Down Expand Up @@ -76,7 +76,10 @@ struct AdaptingIntegerArrayCopy
void AdaptingIntegerArray::Increment(size_t index, uint64_t count)
{
const uint64_t result = nostd::visit(AdaptingIntegerArrayIncrement{index, count}, backing_);
OPENTELEMETRY_LIKELY_IF(result == 0) { return; }
if OPENTELEMETRY_LIKELY_CONDITION (result == 0)
{
return;
}
EnlargeToFit(result);
Increment(index, count);
}
Expand Down

0 comments on commit 25738f3

Please sign in to comment.