• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nasa / trick / 12125470078

02 Dec 2024 06:18PM UTC coverage: 55.93% (+0.05%) from 55.885%
12125470078

Pull #1785

github

web-flow
Merge efe90ae23 into f9d9d6ea0
Pull Request #1785: Frame Performance Tool- jperf

18 of 21 new or added lines in 1 file covered. (85.71%)

120 existing lines in 11 files now uncovered.

12322 of 22031 relevant lines covered (55.93%)

71385.65 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp
1
/*
2
   PURPOSE: (Copy data out of structures into data recording memory.)
3
   PROGRAMMERS:
4
     (((Robert W. Bailey) (LinCom Corp) (3/96) (SES upgrades))
5
      ((Alex Lin) (NASA) (6/02) (DR_changes upgrade)))
6
 */
7

8
#include <iostream>
9
#include <sstream>
10
#include <stdlib.h>
11
#include <unistd.h>
12

13
#include <signal.h>
14
#if __linux
15
#include <sys/syscall.h>
16
#endif
17

18
#include "trick/DataRecordDispatcher.hh"
19
#include "trick/exec_proto.h"
20
#include "trick/exec_proto.hh"
21
#include "trick/message_proto.h"
22
#include "trick/message_type.h"
23
#include "trick/command_line_protos.h"
24

25
Trick::DataRecordDispatcher * the_drd = NULL ;
26

27
Trick::DRDMutexes::DRDMutexes() {
177✔
28
    pthread_cond_init(&dr_go_cv, NULL);
177✔
29
    pthread_mutex_init(&dr_go_mutex, NULL);
177✔
30
    pthread_cond_init(&init_complete_cv, NULL);
177✔
31
    pthread_mutex_init(&init_complete_mutex, NULL);
177✔
32
    cancelled = false;
177✔
33
}
177✔
34

35
Trick::DRDWriterThread::DRDWriterThread(DRDMutexes & in_mutexes, std::vector <Trick::DataRecordGroup *> & in_groups) :
177✔
36
 SysThread("DR_Writer"),
37
 drd_mutexes(in_mutexes) ,
38
 groups(in_groups) {}
177✔
39

40
void * Trick::DRDWriterThread::thread_body() {
145✔
41
    pthread_mutex_lock(&(drd_mutexes.dr_go_mutex));
145✔
42

43
    /* tell the main thread that the writer is ready to go */
44
    pthread_mutex_lock(&(drd_mutexes.init_complete_mutex));
145✔
45
    pthread_cond_signal(&(drd_mutexes.init_complete_cv));
145✔
46
    pthread_mutex_unlock(&(drd_mutexes.init_complete_mutex));
145✔
47

48
    /* from now until death, wait for the condition variable,
49
       then call the write_data method for all of the groups */
50
    while(1) {
51
        pthread_cond_wait(&(drd_mutexes.dr_go_cv), &(drd_mutexes.dr_go_mutex));
30,154✔
52
        if (drd_mutexes.cancelled) {
30,154✔
53
            pthread_mutex_unlock(&(drd_mutexes.dr_go_mutex));
145✔
54
            pthread_exit(0);
145✔
55
        }
56
        for ( unsigned int ii = 0 ; ii < groups.size() ; ii++ ) {
143,164✔
57
            if ( groups[ii]->buffer_type == Trick::DR_Buffer ) {
113,155✔
58
                groups[ii]->write_data(true) ;
28,300✔
59
            }
60
        }
61
    }
30,009✔
62
    pthread_mutex_unlock(&(drd_mutexes.dr_go_mutex));
63
    return NULL ;
64
}
65

66
void Trick::DRDWriterThread::dump( std::ostream & oss ) {
×
67
    oss << "Trick::DRDWriterThread (" << name << ")" << std::endl ;
×
68
    oss << "    number of data record groups = " << groups.size() << std::endl ;
×
69
    Trick::ThreadBase::dump(oss) ;
×
70
}
×
71

72
Trick::DataRecordDispatcher::DataRecordDispatcher() : drd_writer_thread(drd_mutexes, groups) {
177✔
73
    the_drd = this ;
177✔
74
}
177✔
75

76
Trick::DataRecordDispatcher::~DataRecordDispatcher() {
177✔
77
}
177✔
78

79
int Trick::DataRecordDispatcher::remove_files() {
154✔
80

81
    std::string command;
154✔
82
    command = std::string("/bin/rm -rf ") + command_line_args_get_output_dir() + std::string("/log_*") ;
154✔
83
    system(command.c_str());
154✔
84
    return 0 ;
308✔
85
}
86

87
/**
88
@details
89
-# Initialize thread mutex and condition variable
90
-# Create a new thread calling the DataRecordThreaded Writer routine.
91
-# Wait for the data record thread to initialize before continuing.
92
*/
93
int Trick::DataRecordDispatcher::init() {
145✔
94

95
    pthread_mutex_lock(&drd_mutexes.init_complete_mutex);
145✔
96
    drd_writer_thread.create_thread() ;
145✔
97
    pthread_cond_wait(&drd_mutexes.init_complete_cv, &drd_mutexes.init_complete_mutex);
145✔
98
    pthread_mutex_unlock(&drd_mutexes.init_complete_mutex);
145✔
99

100
    return(0) ;
145✔
101
}
102

103
/**
104
add_sim_object is called by the executive when a new sim_object is added to the sim.
105
@details
106
-# Test if the incoming object is a DataRecordGroup.
107
 -# If it is add it to the list of groups we save
108
*/
109
int Trick::DataRecordDispatcher::add_sim_object(Trick::SimObject * in_object ) {
4,292✔
110
    Trick::DataRecordGroup * drg = dynamic_cast< Trick::DataRecordGroup * >(in_object) ;
4,292✔
111
    if ( drg != NULL ) {
4,292✔
112
        groups.push_back(drg) ;
46✔
113
    }
114
    return 0 ;
4,292✔
115
}
116

117
/**
118
@details
119
-# Test if the incoming data record group name has been used.
120
 -# If true return an error.
121
-# Set the group buffering type to the incoming type
122
-# Add the group to the executive.
123
*/
124
int Trick::DataRecordDispatcher::add_group(Trick::DataRecordGroup * in_group, Trick::DR_Buffering buffering) {
39✔
125

126
    unsigned int ii ;
127
    for (  ii = 0 ; ii < groups.size() ; ii++ ) {
62✔
128
        if ( !groups[ii]->group_name.compare(in_group->group_name) ) {
23✔
129
            message_publish(MSG_ERROR, "Data Record group with duplicate name %s.\n", in_group->group_name.c_str()) ;
×
130
            return -1 ;
×
131
        }
132
    }
133
    if ( buffering != Trick::DR_Not_Specified ) {
39✔
134
        in_group->set_buffer_type(buffering) ;
38✔
135
    }
136

137
    exec_add_sim_object(in_group , (char *)in_group->name.c_str()) ;
39✔
138

139
    return 0 ;
39✔
140
}
141

142

143
/**
144
@details
145
-# Remove the data recording group from the dispatcher's list of groups
146
-# Remove the group from the executive.
147
*/
148
int Trick::DataRecordDispatcher::remove_group(Trick::DataRecordGroup * in_group) {
27✔
149

150
    std::vector <Trick::DataRecordGroup *>::iterator drg_it ;
27✔
151

152

153
    // remove the group from the dispatcher vector of jobs.
154
    for ( drg_it = groups.begin() ; drg_it != groups.end() ; ) {
48✔
155
        if ( (*drg_it) == in_group ) {
21✔
156
            // erase the group from the dispatcher. Lock the mutex so we aren't in the
157
            // middle of writing data as we delete the group.
158
            pthread_mutex_lock(&drd_mutexes.dr_go_mutex) ;
×
159
            drg_it = groups.erase(drg_it) ;
×
160
            pthread_mutex_unlock(&drd_mutexes.dr_go_mutex) ;
×
161

162
            // call exec_remove_sim_object to remove the data recording jobs from the sim.
163
            exec_remove_sim_object(in_group) ;
×
164

165
            // shutdown recording for the group
166
            in_group->shutdown() ;
×
167
        } else {
168
            drg_it++ ;
21✔
169
        }
170
    }
171

172

173

174
    return 0 ;
27✔
175
}
176

177
void Trick::DataRecordDispatcher::remove_all_groups() {
×
178
    while (!groups.empty()) {
×
179
        remove_group(groups[0]);
×
180
    }
181
}
×
182

183
/**
184
 @details
185
 -# Gets the data recording group by its name
186
 */
187
Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(std::string in_name) {
6✔
188
    std::vector <Trick::DataRecordGroup *>::iterator it ;
6✔
189
    for ( it = groups.begin() ; it != groups.end() ; ++it ) {
17✔
190
        if ( ! (*it)->get_group_name().compare(in_name) )
15✔
191
            return *it ;
4✔
192
    }
193
    return NULL ;
2✔
194
}
195

196
/**
197
 @details
198
 -# Gets the data recording group by its id number
199
 */
200
Trick::DataRecordGroup * Trick::DataRecordDispatcher::get_group(int in_idx) {
6✔
201
    if (!groups.empty() && in_idx > -1 && in_idx < groups.size()) {
6✔
202
        return groups[in_idx];
4✔
203
    }
204
    return NULL ;
2✔
205
}
206

207
/**
208
 @details
209
 -# Gets the size of all added data recroding groups
210
 */
211
int Trick::DataRecordDispatcher::get_groups_size() {
2✔
212
    return groups.size();
2✔
213
}
214

215
/**
216
@details
217
-# If the writer thread condition variable is unlocked
218
   -# Signal the thread to go
219
*/
220
int Trick::DataRecordDispatcher::signal_thread() {
89,732✔
221

222
    if (!pthread_mutex_trylock(&drd_mutexes.dr_go_mutex)) {
89,732✔
223
        pthread_cond_signal(&drd_mutexes.dr_go_cv);
40,224✔
224
        pthread_mutex_unlock(&drd_mutexes.dr_go_mutex);
40,224✔
225
    }
226

227
    return(0) ;
89,732✔
228
}
229

230
/**
231
@details
232
-# Close out current data record groups
233
-# Clears the data record groups we are tracking.  The checkpoint reload will
234
   repopluate this list.
235
*/
236
int Trick::DataRecordDispatcher::preload_checkpoint() {
9✔
237
    unsigned int ii ;
238
    // close out current data record groups
239
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
16✔
240
        groups[ii]->shutdown() ;
7✔
241
    }
242
    groups.clear() ;
9✔
243
    return 0 ;
9✔
244
}
245

246
/**
247
@details
248
-# If we have not called init yet (pthread_id == 0), call init.
249
-# Delete existing log files.
250
*/
251
int Trick::DataRecordDispatcher::restart() {
9✔
252
    // if we restarted from scratch without calling init jobs, need to call init
253
    if ( drd_writer_thread.get_pthread_id() == 0 ) {
9✔
254
        init() ;
1✔
255
    }
256
    // remove the current log files
257
    remove_files() ;
9✔
258
    return 0 ;
9✔
259
}
260

261
/**
262
@details
263
-# If the thread was started,
264
   -# Wait for the thread to be available
265
   -# Cancel the thread
266
*/
267
int Trick::DataRecordDispatcher::shutdown() {
145✔
268

269
    if ( drd_writer_thread.get_pthread_id() != 0 ) {
145✔
270
        pthread_mutex_lock( &drd_mutexes.dr_go_mutex);
145✔
271
        // pthread_cancel( drd_writer_thread.get_pthread_id()) ;
272
        drd_mutexes.cancelled = true;
145✔
273
        pthread_cond_signal(&drd_mutexes.dr_go_cv);
145✔
274
        pthread_mutex_unlock( &drd_mutexes.dr_go_mutex);
145✔
275
    }
276

277
    return(0) ;
145✔
278
}
279

280
int Trick::DataRecordDispatcher::enable( const char * in_name ) {
×
281
    unsigned int ii ;
UNCOV
282
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
283
        if ( in_name == NULL or !groups[ii]->get_group_name().compare(in_name) )
×
UNCOV
284
            groups[ii]->enable() ;
×
285
    }
286
    return 0 ;
×
287
}
288

289
int Trick::DataRecordDispatcher::disable( const char * in_name ) {
×
290
    unsigned int ii ;
UNCOV
291
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
292
        if ( in_name == NULL or !groups[ii]->get_group_name().compare(in_name) )
×
UNCOV
293
            groups[ii]->disable() ;
×
294
    }
295
    return 0 ;
×
296
}
297

298
int Trick::DataRecordDispatcher::record_now_group( const char * in_name ) {
×
299
    unsigned int ii ;
300
    if ( in_name != NULL ) {
×
UNCOV
301
        for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
UNCOV
302
            if ( !groups[ii]->get_group_name().compare(in_name) )
×
UNCOV
303
                groups[ii]->data_record(exec_get_sim_time()) ;
×
304
        }
305
    }
UNCOV
306
    return 0 ;
×
307
}
308

UNCOV
309
int Trick::DataRecordDispatcher::set_group_max_file_size(const char * in_name, uint64_t bytes){
×
310
    unsigned int ii ;
311
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
UNCOV
312
        if ( in_name == NULL or !groups[ii]->get_group_name().compare(in_name) )
×
313
            groups[ii]->set_max_file_size(bytes) ;
×
314
    }
UNCOV
315
    return 0 ;
×
316
}
317

UNCOV
318
int Trick::DataRecordDispatcher::set_max_file_size(uint64_t bytes) {
×
319
    unsigned int ii ;
UNCOV
320
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
UNCOV
321
        groups[ii]->set_max_file_size(bytes) ;
×
322
    }
UNCOV
323
    return 0 ;
×
324
}
325

326
/**
327
@details
328
-# Call every group's init job - only needed when restoring checkpoint
329
-# during initialization, and the user is responsible for calling this.
330
*/
UNCOV
331
int Trick::DataRecordDispatcher::init_groups() {
×
332
    unsigned int ii ;
UNCOV
333
    for ( ii = 0 ; ii < groups.size() ; ii++ ) {
×
UNCOV
334
        groups[ii]->init() ;
×
335
    }
UNCOV
336
    return 0 ;
×
337
}
338

STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc