Skip to content

Commit dfe0964

Browse files
committed
Remove duplicate logger when used with static+dyanmic
+ Change from a pull to a push model, to push the logger instance from the loader to the validation layer to remove duplication. + Remove resource consumption when no logger is used Signed-off-by: Russell McGuire <russell.w.mcguire@intel.com>
1 parent eef543a commit dfe0964

4 files changed

Lines changed: 41 additions & 18 deletions

File tree

source/layers/validation/ze_validation_layer.cpp

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@
1111
#include "param_validation.h"
1212
#include <memory>
1313

14-
// Forward declaration — resolves at link time against ze_loader.so.
15-
extern "C" ZE_DLLEXPORT std::shared_ptr<loader::ZeLogger> *ZE_APICALL zelLoaderGetLogger();
16-
1714
namespace validation_layer
1815
{
1916
context_t& context = context_t::getInstance();
@@ -28,18 +25,16 @@ namespace validation_layer
2825
enableThreadingValidation = getenv_tobool( "ZE_ENABLE_THREADING_VALIDATION" );
2926
verboseLogging = getenv_tobool( "ZEL_LOADER_LOGGING_ENABLE_SUCCESS_PRINT" );
3027

31-
// Prefer the loader's already-constructed logger so both components
32-
// share a single file handle, mutex, and startup banner.
33-
// Fall back to creating an independent logger (e.g. static build).
34-
#ifndef L0_STATIC_LOADER_BUILD
35-
auto *loaderLog = zelLoaderGetLogger();
36-
if (loaderLog && *loaderLog) {
37-
logger = *loaderLog;
38-
} else
39-
#endif
40-
{
41-
logger = loader::createLogger("Validation Layer");
42-
}
28+
// Initialize logger to a no-op sentinel (level=off, no file/console I/O, no banner).
29+
// This is purely crash protection: in normal operation the loader calls
30+
// zelLoaderSetLogger() immediately after dlopen — before the DDI tables
31+
// go live — so no real log call ever hits this sentinel.
32+
//
33+
// Thread-safety note: zelLoaderSetLogger() writes this field once, on the
34+
// init thread, before zeDdiTable.exchange() makes the validation layer
35+
// reachable from other threads. The non-atomic shared_ptr assignment is
36+
// therefore safe in practice; no mutex is needed here.
37+
logger = std::make_shared<loader::ZeLogger>(); // no-op sentinel: no sink, no mutex, no syscalls
4338
}
4439

4540
///////////////////////////////////////////////////////////////////////////////
@@ -68,6 +63,17 @@ zelLoaderGetVersion(zel_component_version_t *version)
6863
return ZE_RESULT_SUCCESS;
6964
}
7065

66+
/// @brief Called by the loader immediately after dlopen to share its logger.
67+
/// Replaces the fallback logger created in the constructor so that
68+
/// validation-layer messages flow through the same sink as the loader.
69+
ZE_DLLEXPORT void ZE_APICALL
70+
zelLoaderSetLogger(std::shared_ptr<loader::ZeLogger> *loaderLogger)
71+
{
72+
if (loaderLogger && *loaderLogger) {
73+
validation_layer::context_t::getInstance().logger = *loaderLogger;
74+
}
75+
}
76+
7177
#if defined(__cplusplus)
7278
};
7379
#endif

source/loader/ze_loader.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,15 @@ namespace loader
778778
}
779779
#endif
780780
}
781+
// Inject this loader instance's logger into the validation layer
782+
// so both share a single file handle and mutex.
783+
using SetLoggerFn = void (*)(std::shared_ptr<loader::ZeLogger> *);
784+
auto setLogger = reinterpret_cast<SetLoggerFn>(
785+
GET_FUNCTION_PTR(validationLayer, "zelLoaderSetLogger"));
786+
if (setLogger) {
787+
setLogger(&zel_logger);
788+
}
789+
781790
auto getVersion = reinterpret_cast<getVersion_t>(
782791
GET_FUNCTION_PTR(validationLayer, "zelLoaderGetVersion"));
783792
zel_component_version_t compVersion;

source/utils/ze_logger.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,10 @@ LogLevel logLevelFromString(const std::string &s) {
167167
// ---------------------------------------------------------------------------
168168
// ZeLogger
169169
// ---------------------------------------------------------------------------
170+
ZeLogger::ZeLogger()
171+
: _level(LogLevel::off), _pattern(), _sink(nullptr)
172+
{}
173+
170174
ZeLogger::ZeLogger(const std::string &log_path, LogLevel level, const std::string &pattern)
171175
: _level(level), _pattern(pattern), _sink(new LogSink(log_path))
172176
{
@@ -192,7 +196,7 @@ LogLevel ZeLogger::getLevel() const {
192196
}
193197

194198
void ZeLogger::flush() {
195-
_sink->flush();
199+
if (_sink) _sink->flush();
196200
}
197201

198202
// ---------------------------------------------------------------------------
@@ -305,7 +309,7 @@ void ZeLogger::formatLine(LogLevel msg_level, const std::string &msg, std::strin
305309
}
306310

307311
void ZeLogger::write(LogLevel msg_level, const std::string &msg) {
308-
if (msg_level < _level) {
312+
if (!_sink || msg_level < _level) {
309313
return;
310314
}
311315
// Reuse a thread_local buffer to avoid a heap allocation per log call.
@@ -500,7 +504,8 @@ std::shared_ptr<ZeLogger> createLogger(const std::string &caller) {
500504
// logging_enabled=1, log_console=0 → file sink, configured level
501505
// logging_enabled=1, log_console=1 → console (stderr), configured level
502506
if (!logging_enabled && !log_console) {
503-
return std::make_shared<ZeLogger>(/*use_stderr=*/true, LogLevel::off, log_pattern);
507+
// Pure no-op: no sink, no mutex, no isatty() syscall, no pattern string.
508+
return std::make_shared<ZeLogger>();
504509
}
505510

506511
LogLevel level = logLevelFromString(log_level);

source/utils/ze_logger.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ struct LogSink;
4646
// are produced by this class so it can be unloaded by dlclose().
4747
class ZeLogger {
4848
public:
49+
// No-op constructor: level=off, no sink, no I/O, no syscalls, no mutex.
50+
// Use this (or createLogger() with logging disabled) for zero-overhead paths.
51+
ZeLogger();
4952
// File sink constructor
5053
ZeLogger(const std::string &log_path, LogLevel level, const std::string &pattern);
5154
// Console sink constructor (stderr or stdout)

0 commit comments

Comments
 (0)