Skip to content

Commit bce7252

Browse files
committed
dlt-qnx-system: prevent message loss in high load situations
* Add wait method, which waits up to 5 seconds for buffer space to become available. This method tries to flush the buffer via tcp every 10ms. An error will be logged when there was not enough space. The error shows up in dlt to simplify debugging. * improve cmake that more qnx compilers are detected * log missing context mapping only once, this greatly reduces noise and the load of the system, as previously the message was logged with every log of an unmapped application Signed-off-by: Alexander Mohr <[email protected]>
1 parent 354464d commit bce7252

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,8 @@ if(WITH_DLT_USE_IPv6)
180180
add_definitions(-DDLT_USE_IPv6)
181181
endif()
182182

183-
if(WITH_DLT_QNX_SYSTEM AND NOT "${CMAKE_C_COMPILER}" MATCHES "nto-qnx|qcc")
184-
message(FATAL_ERROR "Can only compile for QNX with a QNX compiler.")
183+
if(WITH_DLT_QNX_SYSTEM AND NOT "${CMAKE_C_COMPILER}" MATCHES "nto-qnx|qcc|ntoaarch64-gcc|ntox86_64-gcc")
184+
message(FATAL_ERROR "Can only compile for QNX with a QNX compiler, but found '${CMAKE_C_COMPILER}'.")
185185
endif()
186186

187187
if (WITH_DLT_FILE_LOGGING_SYSLOG_FALLBACK)

src/dlt-qnx-system/dlt-qnx-slogger2-adapter.cpp

+44-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@
2828
#include <sys/slog2.h>
2929
#include <sys/json.h>
3030
#include <slog2_parse.h>
31+
#include <thread>
32+
#include <set>
3133

3234
#include "dlt-qnx-system.h"
3335
#include "dlt_cpp_extension.hpp"
36+
using std::chrono_literals::operator""ms;
37+
using std::chrono_literals::operator""s;
3438

3539
/* Teach dlt about json_decoder_error_t */
3640
template<>
@@ -42,6 +46,7 @@ inline int32_t logToDlt(DltContextData &log, const json_decoder_error_t &value)
4246
extern DltContext dltQnxSystem;
4347

4448
static DltContext dltQnxSlogger2Context;
49+
static std::set<std::string> dltWarnedMissingMappings;
4550

4651
extern DltQnxSystemThreads g_threads;
4752
static std::unordered_map<std::string, DltContext*> g_slog2file;
@@ -118,14 +123,49 @@ static DltContext *dlt_context_from_slog2file(const char *file_name) {
118123

119124
auto search = g_slog2file.find(name);
120125
if (search == g_slog2file.end()) {
121-
DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_VERBOSE,
122-
"slog2 filename not found in mapping: ", name.c_str());
126+
// Only warn once about missing mapping.
127+
auto it = dltWarnedMissingMappings.find(name);
128+
if (it == dltWarnedMissingMappings.end()) {
129+
dltWarnedMissingMappings.insert(name);
130+
DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_INFO,
131+
"slog2 filename not found in mapping: ", name.c_str());
132+
}
133+
123134
return &dltQnxSlogger2Context;
124135
} else {
125136
return search->second;
126137
}
127138
}
128139

140+
template <class time, class period>
141+
static void wait_for_buffer_space(const double max_usage_threshold,
142+
const std::chrono::duration<time, period> max_wait_time) {
143+
int total_size = 0;
144+
int used_size = 0;
145+
double used_percent = 100.0;
146+
bool timeout = false;
147+
const auto end_time = std::chrono::steady_clock::now() + max_wait_time;
148+
149+
do {
150+
dlt_user_check_buffer(&total_size, &used_size);
151+
used_percent = static_cast<double>(used_size) / total_size;
152+
if (used_percent < max_usage_threshold) {
153+
break;
154+
}
155+
156+
dlt_user_log_resend_buffer();
157+
158+
std::this_thread::sleep_for(10ms);
159+
timeout = std::chrono::steady_clock::now() < end_time;
160+
} while (!timeout);
161+
162+
if (timeout) {
163+
DLT_LOG(dltQnxSystem, DLT_LOG_ERROR,
164+
DLT_STRING("failed to get enough buffer space"));
165+
166+
}
167+
}
168+
129169
/**
130170
* Function which is invoked by slog2_parse_all()
131171
* See slog2_parse_all api docs on qnx.com for details
@@ -171,6 +211,8 @@ static int sloggerinfo_callback(slog2_packet_info_t *info, void *payload, void *
171211
DltContextData log_local; /* Used in DLT_* macros, do not rename */
172212
DltContext *ctxt = dlt_context_from_slog2file(info->file_name);
173213

214+
wait_for_buffer_space(0.8, 5s);
215+
174216
int ret;
175217
ret = dlt_user_log_write_start(ctxt, &log_local, loglevel);
176218

0 commit comments

Comments
 (0)