More updates to imscope IQ recorder
- Added event parameter for recording which is reflected in the filename - Added event in the UE for DLSCH NACK - Added program name to the filename for ease of identification - Reworked spinlock to use atomics
This commit is contained in:
@@ -22,6 +22,18 @@
|
||||
#include "imscope_internal.h"
|
||||
#include "openair1/PHY/TOOLS/phy_scope_interface.h"
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <atomic>
|
||||
#include <new>
|
||||
|
||||
#ifdef __cpp_lib_hardware_interference_size
|
||||
using std::hardware_constructive_interference_size;
|
||||
using std::hardware_destructive_interference_size;
|
||||
#else
|
||||
// 64 bytes on x86-64 │ L1_CACHE_BYTES │ L1_CACHE_SHIFT │ __cacheline_aligned │ ...
|
||||
constexpr std::size_t hardware_constructive_interference_size = 64;
|
||||
constexpr std::size_t hardware_destructive_interference_size = 64;
|
||||
#endif
|
||||
|
||||
#define NUM_CACHED_DATA 4
|
||||
// Set maximum number of kilobytes written per recording session to 1GB. This is a safeguard against
|
||||
@@ -29,8 +41,13 @@
|
||||
#define MAX_KBYTES_WRITTEN_PER_SESSION (1000 * 1000)
|
||||
|
||||
ImScopeDataWrapper scope_array[EXTRA_SCOPE_TYPES];
|
||||
volatile int slot_to_dump = -1;
|
||||
volatile int frame_to_dump = -1;
|
||||
typedef struct alignas(hardware_destructive_interference_size) ImScopeDumpInstruction {
|
||||
int slot;
|
||||
int frame;
|
||||
const char *cause;
|
||||
} ImScopeDumpInstruction;
|
||||
|
||||
std::atomic<ImScopeDumpInstruction> dump_instruction;
|
||||
|
||||
extern "C" void imscope_record_autoinit(void *dataptr)
|
||||
{
|
||||
@@ -44,6 +61,8 @@ extern "C" void imscope_record_autoinit(void *dataptr)
|
||||
scope_array[i].data.meta = {-1, -1};
|
||||
}
|
||||
|
||||
dump_instruction.store({-1, -1, nullptr});
|
||||
|
||||
scopeData_t *scope = (scopeData_t *)calloc(1, sizeof(scopeData_t));
|
||||
scope->copyData = copyDataThreadSafe;
|
||||
scope->tryLockScopeData = tryLockScopeData;
|
||||
@@ -64,12 +83,11 @@ extern "C" void imscope_record_autoinit(void *dataptr)
|
||||
threadCreate(&thread, imscope_record_thread, dataptr, (char *)"imscope_record", -1, sched_get_priority_min(SCHED_RR));
|
||||
}
|
||||
|
||||
void dumpScopeData(int slot, int frame) {
|
||||
if (slot_to_dump == -1) {
|
||||
LOG_E(PHY, "Will dump scope data\n");
|
||||
frame_to_dump = frame;
|
||||
slot_to_dump = slot;
|
||||
}
|
||||
void dumpScopeData(int slot, int frame, const char *cause_string)
|
||||
{
|
||||
ImScopeDumpInstruction to_dump = {slot, frame, cause_string};
|
||||
ImScopeDumpInstruction expected = {-1, -1, nullptr};
|
||||
dump_instruction.compare_exchange_weak(expected, to_dump);
|
||||
}
|
||||
|
||||
void *imscope_record_thread(void *data_void_ptr)
|
||||
@@ -87,15 +105,26 @@ void *imscope_record_thread(void *data_void_ptr)
|
||||
} else {
|
||||
LOG_A(PHY, "ImScope recorder thread starts, recording data to cwd\n");
|
||||
}
|
||||
|
||||
std::string program_name(program_invocation_name);
|
||||
size_t last_slash = program_name.find_last_of("/");
|
||||
if (last_slash != std::string::npos) {
|
||||
program_name = program_name.substr(last_slash + 1);
|
||||
}
|
||||
|
||||
ImScopeData scope_cache[EXTRA_SCOPE_TYPES][NUM_CACHED_DATA];
|
||||
memset(scope_cache, 0, sizeof(scope_cache));
|
||||
uint scope_cache_index[EXTRA_SCOPE_TYPES] = {0};
|
||||
float kbytes_written = 0.0f;
|
||||
while (kbytes_written < MAX_KBYTES_WRITTEN_PER_SESSION) {
|
||||
if (slot_to_dump != -1) {
|
||||
std::string filename = std::string(path);
|
||||
filename += has_dir ? "/" : "-";
|
||||
filename += std::to_string(frame_to_dump) + std::string("-") + std::to_string(slot_to_dump) + std::string(".imscope");
|
||||
ImScopeDumpInstruction dump = dump_instruction.load(std::memory_order::memory_order_relaxed);
|
||||
if (dump.slot != -1) {
|
||||
std::string filename;
|
||||
if (has_dir) {
|
||||
filename += std::string(path) + "/";
|
||||
}
|
||||
filename += program_name + std::string("-") + dump.cause + std::string("-");
|
||||
filename += std::to_string(dump.frame) + std::string("-") + std::to_string(dump.slot) + std::string(".imscope");
|
||||
std::ofstream outf(filename, std::ios_base::out | std::ios_base::binary);
|
||||
if (!outf) {
|
||||
LOG_E(PHY, "Could not open file %s for writing\n", filename.c_str());
|
||||
@@ -104,7 +133,7 @@ void *imscope_record_thread(void *data_void_ptr)
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
for (auto j = 0U; j < NUM_CACHED_DATA; j++) {
|
||||
ImScopeData &scope_data = scope_cache[i][j];
|
||||
if (scope_data.meta.frame == frame_to_dump && scope_data.meta.slot == slot_to_dump) {
|
||||
if (scope_data.meta.frame == dump.frame && scope_data.meta.slot == dump.slot) {
|
||||
scope_data.dump_to_file(outf);
|
||||
}
|
||||
}
|
||||
@@ -113,7 +142,7 @@ void *imscope_record_thread(void *data_void_ptr)
|
||||
kbytes_written += pos / 1000.0f;
|
||||
outf.close();
|
||||
LOG_D(PHY, "ImScope done writing to %s\n", filename.c_str());
|
||||
slot_to_dump = -1;
|
||||
dump_instruction.store({-1, -1, nullptr}, std::memory_order::memory_order_relaxed);
|
||||
}
|
||||
for (auto i = 0U; i < EXTRA_SCOPE_TYPES; i++) {
|
||||
ImScopeDataWrapper &scope_data = scope_array[i];
|
||||
|
||||
Reference in New Issue
Block a user