13 if (data_rec_conf !=
nullptr) {
14 if (!data_rec_conf->get_output_file().empty()) {
32 std::string file_full_path =
37 if (std::remove(file_full_path.c_str()) == 0) {
38 TLOG(
TLVL_WORK_STEPS) <<
"Removed existing output file from previous run: " << file_full_path;
42 if (data_rec_conf->get_use_o_direct()) {
45 m_fd = ::open(file_full_path.c_str(),
m_oflag, 0644);
47 TLOG() <<
"Failed to open file!";
53 TLOG(
TLVL_WORK_STEPS) <<
"No output path is specified in data recorder config. Recording feature is inactive.";
56 TLOG(
TLVL_WORK_STEPS) <<
"No recording config object specified. Recording feature is inactive.";
66 const appfwk::DAQModule::CommandData_t& cmdargs)
75 int recording_time_sec = 0;
76 if (cmdargs.contains(
"duration")) {
77 recording_time_sec = cmdargs[
"duration"];
82 if (recording_time_sec == 0) {
92 TLOG() <<
"Start recording for " << duration <<
" second(s)" << std::endl;
94 auto start_of_recording = std::chrono::high_resolution_clock::now();
95 auto current_time = start_of_recording;
98 const char* current_write_pointer =
nullptr;
99 const char* start_of_buffer_pointer =
101 const char* current_end_pointer;
102 const char* end_of_buffer_pointer =
105 size_t bytes_written = 0;
106 size_t failed_writes = 0;
108 while (std::chrono::duration_cast<std::chrono::seconds>(current_time - start_of_recording).count() < duration) {
110 size_t considered_chunks_in_loop = 0;
126 current_time = std::chrono::high_resolution_clock::now();
130 size_t skipped_frames = 0;
131 while (
reinterpret_cast<std::uintptr_t
>(&(*begin)) % alignment_size) {
137 current_time = std::chrono::high_resolution_clock::now();
142 TLOG() <<
"Skipped " << skipped_frames <<
" frames";
143 current_write_pointer =
reinterpret_cast<const char*
>(&(*begin));
149 while (considered_chunks_in_loop < 100) {
150 auto iptr =
reinterpret_cast<std::uintptr_t
>(current_write_pointer);
151 if (iptr % alignment_size) {
153 TLOG() <<
"Error: Write pointer is not aligned";
155 bool failed_write =
false;
156 if (current_write_pointer + chunk_size < current_end_pointer) {
158 failed_write |= !::write(
m_fd, current_write_pointer, chunk_size);
160 bytes_written += chunk_size;
162 current_write_pointer += chunk_size;
163 }
else if (current_end_pointer < current_write_pointer) {
164 if (current_write_pointer + chunk_size < end_of_buffer_pointer) {
166 failed_write |= !::write(
m_fd, current_write_pointer, chunk_size);
168 bytes_written += chunk_size;
170 current_write_pointer += chunk_size;
174 fcntl(
m_fd, F_SETFL, O_CREAT | O_WRONLY);
175 failed_write |= !::write(
m_fd, current_write_pointer, end_of_buffer_pointer - current_write_pointer);
178 bytes_written += end_of_buffer_pointer - current_write_pointer;
180 current_write_pointer = start_of_buffer_pointer;
184 if (current_write_pointer == end_of_buffer_pointer) {
185 current_write_pointer = start_of_buffer_pointer;
192 considered_chunks_in_loop++;
195 reinterpret_cast<const ReadoutType*
>(
196 start_of_buffer_pointer +
197 (((current_write_pointer - start_of_buffer_pointer) / ReadoutType::fixed_payload_size) *
198 ReadoutType::fixed_payload_size))
202 current_time = std::chrono::high_resolution_clock::now();
206 if (current_write_pointer !=
nullptr) {
207 const char* last_started_frame =
208 start_of_buffer_pointer +
209 (((current_write_pointer - start_of_buffer_pointer) / ReadoutType::fixed_payload_size) *
210 ReadoutType::fixed_payload_size);
211 if (last_started_frame != current_write_pointer) {
212 fcntl(
m_fd, F_SETFL, O_CREAT | O_WRONLY);
214 current_write_pointer,
215 (last_started_frame + ReadoutType::fixed_payload_size) - current_write_pointer)) {
218 bytes_written += (last_started_frame + ReadoutType::fixed_payload_size) - current_write_pointer;
226 TLOG() <<
"Stopped recording, wrote " << bytes_written <<
" bytes. Failed write count: " << failed_writes;