11 auto data_rec_conf =
conf->get_module_configuration()->get_request_handler()->get_data_recorder();
13 if (data_rec_conf !=
nullptr) {
14 if (!data_rec_conf->get_output_file().empty()) {
31 std::string file_full_path = data_rec_conf->get_output_file() +
inherited::m_sourceid.to_string() + std::string(
".bin");
36 if (std::remove(file_full_path.c_str()) == 0) {
37 TLOG(
TLVL_WORK_STEPS) <<
"Removed existing output file from previous run: " << file_full_path;
41 if (data_rec_conf->get_use_o_direct()) {
44 m_fd = ::open(file_full_path.c_str(),
m_oflag, 0644);
46 TLOG() <<
"Failed to open file!";
52 TLOG(
TLVL_WORK_STEPS) <<
"No output path is specified in data recorder config. Recording feature is inactive.";
55 TLOG(
TLVL_WORK_STEPS) <<
"No recording config object specified. Recording feature is inactive.";
65 const appfwk::DAQModule::CommandData_t& cmdargs)
74 int recording_time_sec = 0;
75 if (cmdargs.contains(
"duration")) {
76 recording_time_sec = cmdargs[
"duration"];
81 if (recording_time_sec == 0) {
91 TLOG() <<
"Start recording for " << duration <<
" second(s)" << std::endl;
93 auto start_of_recording = std::chrono::high_resolution_clock::now();
94 auto current_time = start_of_recording;
97 const char* current_write_pointer =
nullptr;
98 const char* start_of_buffer_pointer =
100 const char* current_end_pointer;
103 size_t bytes_written = 0;
104 size_t failed_writes = 0;
106 while (std::chrono::duration_cast<std::chrono::seconds>(current_time - start_of_recording).count() < duration) {
108 size_t considered_chunks_in_loop = 0;
124 current_time = std::chrono::high_resolution_clock::now();
128 size_t skipped_frames = 0;
129 while (
reinterpret_cast<std::uintptr_t
>(&(*begin)) % alignment_size) {
135 current_time = std::chrono::high_resolution_clock::now();
140 TLOG() <<
"Skipped " << skipped_frames <<
" frames";
141 current_write_pointer =
reinterpret_cast<const char*
>(&(*begin));
147 while (considered_chunks_in_loop < 100) {
148 auto iptr =
reinterpret_cast<std::uintptr_t
>(current_write_pointer);
149 if (iptr % alignment_size) {
151 TLOG() <<
"Error: Write pointer is not aligned";
153 bool failed_write =
false;
154 if (current_write_pointer + chunk_size < current_end_pointer) {
156 failed_write |= !::write(
m_fd, current_write_pointer, chunk_size);
158 bytes_written += chunk_size;
160 current_write_pointer += chunk_size;
161 }
else if (current_end_pointer < current_write_pointer) {
162 if (current_write_pointer + chunk_size < end_of_buffer_pointer) {
164 failed_write |= !::write(
m_fd, current_write_pointer, chunk_size);
166 bytes_written += chunk_size;
168 current_write_pointer += chunk_size;
172 fcntl(
m_fd, F_SETFL, O_CREAT | O_WRONLY);
173 failed_write |= !::write(
m_fd, current_write_pointer, end_of_buffer_pointer - current_write_pointer);
176 bytes_written += end_of_buffer_pointer - current_write_pointer;
178 current_write_pointer = start_of_buffer_pointer;
182 if (current_write_pointer == end_of_buffer_pointer) {
183 current_write_pointer = start_of_buffer_pointer;
190 considered_chunks_in_loop++;
193 reinterpret_cast<const ReadoutType*
>(
194 start_of_buffer_pointer +
195 (((current_write_pointer - start_of_buffer_pointer) / ReadoutType::fixed_payload_size) *
196 ReadoutType::fixed_payload_size))
200 current_time = std::chrono::high_resolution_clock::now();
204 if (current_write_pointer !=
nullptr) {
205 const char* last_started_frame =
206 start_of_buffer_pointer +
207 (((current_write_pointer - start_of_buffer_pointer) / ReadoutType::fixed_payload_size) *
208 ReadoutType::fixed_payload_size);
209 if (last_started_frame != current_write_pointer) {
210 fcntl(
m_fd, F_SETFL, O_CREAT | O_WRONLY);
212 current_write_pointer,
213 (last_started_frame + ReadoutType::fixed_payload_size) - current_write_pointer)) {
216 bytes_written += (last_started_frame + ReadoutType::fixed_payload_size) - current_write_pointer;
224 TLOG() <<
"Stopped recording, wrote " << bytes_written <<
" bytes. Failed write count: " << failed_writes;
226 }, recording_time_sec);