Files
Lang Hames b1c56fb53a [orc-rt] Add os_log logging backend (Darwin only) (#209081)
Implement the os_log backend, selected with ORC_RT_LOG_BACKEND=os_log.
With this backend selected, the ORC_RT_LOG macros expand at the call
site to os_log_with_type. Each ORC runtime log level maps to an
os_log_type_t (error -> ERROR, warning -> DEFAULT, info -> INFO, debug
-> DEBUG). The compile-time ORC_RT_LOG_LEVEL floor still applies, but
runtime filtering is left to the system (e.g. `log config`), so the
printf backend's ORC_RT_LOG and ORC_RT_LOG_OUTPUT have no effect.

Records go to the "org.llvm.orc-rt" subsystem with the category as the
os_log category. (Per-category handles are created on first use and
cached).

Add regression tests under test/regression/logging/os_log:
no-printf-output.test checks that the backend produces no console
output, and an opt-in delivery test (llvm-lit --param
run-os-log-tests=1) scrapes `log show` to confirm records reach the
expected subsystem and category.
2026-07-13 15:08:09 +10:00

46 lines
1.9 KiB
C++

//===- Logging_oslog.cpp - os_log logging backend ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Runtime support for the os_log logging backend declared in
// orc-rt-c/Logging.h.
//
// The log records themselves are emitted at the call site by os_log_with_type
// (see the ORC_RT_LOG_* macros). The only runtime support needed here is a
// per-category os_log_t handle, which orc_rt_log_osLogHandle reads inline; this
// file homes the cache and provides the cold path that fills it.
//
//===----------------------------------------------------------------------===//
#include "orc-rt-c/Logging.h"
#include <os/log.h>
// Cache for the inline accessor (declared in Logging.h). Zero-initialized, so
// no static constructor runs; slots are filled lazily by the cold path below.
os_log_t orc_rt_log_OSLogHandles[orc_rt_log_Category_Count];
extern "C" os_log_t
orc_rt_log_osLogHandleSlow(orc_rt_log_Category Category) noexcept {
// Category is already range-checked by the inline caller.
//
// ORC rt logs to the "org.llvm.orc-rt" subsystem.
//
// Combined with the per-category name it lets records be filtered in Console
// or `log` (e.g. `log stream --predicate 'subsystem == "org.llvm.orc-rt"'`).
//
// Note: os_log_create deduplicates by (subsystem, category), so if two
// threads race here they get the same handle back; storing either one is
// correct and no lock is needed. The store publishes it for future warm-path
// loads.
os_log_t Handle =
os_log_create("org.llvm.orc-rt", orc_rt_log_Category_getName(Category));
__atomic_store_n(&orc_rt_log_OSLogHandles[Category], Handle,
__ATOMIC_RELEASE);
return Handle;
}