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

nasa / trick / 14502251997

16 Apr 2025 08:46PM UTC coverage: 55.948% (+0.02%) from 55.928%
14502251997

push

github

web-flow
Updated to transmit sie files from the proper directory (#1863)

Updated to transmit sie files from the runtime sie dir instead of the default dir as the runtime sie dir is the default dir if no output dir is specified otherwise is the specified output dir. Meanwhile, restored the code inFrameLog.cpp for having DP_Product created in the specified output dir.

3 of 7 new or added lines in 2 files covered. (42.86%)

1 existing line in 1 file now uncovered.

12327 of 22033 relevant lines covered (55.95%)

81508.94 hits per line

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

71.32
/trick_source/sim_services/ThreadBase/ThreadBase.cpp
1
#include <iostream>
2
#include <stdio.h>
3
#include <signal.h>
4
#include <cstring>
5

6
#if __linux
7
#include <sys/syscall.h>
8
#include <sys/types.h>
9
#include <sched.h>
10
#endif
11

12
#include "trick/ThreadBase.hh"
13
#include "trick/message_proto.h"
14
#include "trick/message_type.h"
15

16
Trick::ThreadBase::ThreadBase(std::string in_name) :
977✔
17
 name(in_name) ,
18
 pthread_id(0) ,
19
 pid(0) ,
20
 rt_priority(0),
21
 created(false),
22
 should_shutdown(false),
23
 cancellable(true)
977✔
24
{
25
    pthread_mutex_init(&shutdown_mutex, NULL);
977✔
26
#if __linux
27
    max_cpu = sysconf( _SC_NPROCESSORS_ONLN ) ;
977✔
28
#ifdef CPU_ALLOC
29
    cpus = CPU_ALLOC(max_cpu) ;
977✔
30
    CPU_ZERO_S(CPU_ALLOC_SIZE(max_cpu), cpus) ;
977✔
31
#else
32
    cpus = (cpu_set_t *)calloc(1, sizeof(cpu_set_t)) ;
33
#endif
34
#endif
35
#if __APPLE__
36
    max_cpu = 0 ;
37
#endif
38
}
977✔
39

40
Trick::ThreadBase::~ThreadBase() {
970✔
41
#if __linux
42
#ifdef CPU_FREE
43
    CPU_FREE(cpus) ;
970✔
44
#endif
45
#endif
46
}
970✔
47

48
std::string Trick::ThreadBase::get_name() {
×
49
    return name ;
×
50
}
51

52
void Trick::ThreadBase::set_name(std::string in_name) {
×
53
    name = in_name ;
×
54
}
×
55

56
pthread_t Trick::ThreadBase::get_pthread_id() {
6,987✔
57
    return pthread_id ;
6,987✔
58
}
59

60
pid_t Trick::ThreadBase::get_pid() {
×
61
    return pid ;
×
62
}
63

64
void Trick::ThreadBase::set_pid() {
638✔
65
#if __linux
66
    pid = syscall( __NR_gettid ) ;
638✔
67
#else
68
    pid = getpid() ;
69
#endif
70
}
638✔
71

72
int Trick::ThreadBase::cpu_set(unsigned int cpu __attribute__((unused))) {
2✔
73
    int ret =  0 ;
2✔
74
#if __linux
75
    if ( cpu < max_cpu ) {
2✔
76
#ifdef CPU_SET_S
77
        CPU_SET_S(cpu, CPU_ALLOC_SIZE(max_cpu), cpus) ;
2✔
78
#else
79
        CPU_SET(cpu, cpus) ;
80
#endif
81
    } else {
82
        message_publish(MSG_WARNING, "CPU value %d is out of range (0 through %d)", cpu, max_cpu - 1) ;
×
83
        ret = -1 ;
×
84
    }
85
#endif
86
#if __APPLE__
87
    message_publish(MSG_WARNING, "Warning: Trick on Darwin does not yet support processor assignment.\n");
88
#endif
89
    return ret ;
2✔
90
}
91

92
int Trick::ThreadBase::cpu_clr(unsigned int cpu __attribute__((unused))) {
×
93
    int ret =  0 ;
×
94
#if __linux
95
    if ( cpu < max_cpu ) {
×
96
#ifdef CPU_CLR_S
97
        CPU_CLR_S(cpu, CPU_ALLOC_SIZE(max_cpu), cpus) ;
×
98
#else
99
        CPU_CLR(cpu, cpus) ;
100
#endif
101
    } else {
102
        message_publish(MSG_WARNING, "CPU value %d is out of range (0 through %d)", cpu, max_cpu - 1) ;
×
103
        ret = -1 ;
×
104
    }
105
#endif
106
#if __APPLE__
107
    message_publish(MSG_WARNING, "Warning: Trick on Darwin does not yet support processor assignment.\n");
108
#endif
109
    return ret ;
×
110
}
111

112
#if __linux
113
cpu_set_t * Trick::ThreadBase::get_cpus() {
2✔
114
    return cpus ;
2✔
115
}
116

117
void Trick::ThreadBase::copy_cpus(cpu_set_t * in_cpus) {
2✔
118
#ifdef CPU_OR_S
119
    CPU_ZERO_S(CPU_ALLOC_SIZE(max_cpu), cpus) ;
2✔
120
    CPU_OR_S(CPU_ALLOC_SIZE(max_cpu), cpus, cpus, in_cpus) ;
4✔
121
#else
122
    *cpus = *in_cpus ;
123
#endif
124
}
2✔
125
#endif
126
#if __APPLE__
127
void * Trick::ThreadBase::get_cpus() {
128
    return NULL ;
129
}
130

131
void Trick::ThreadBase::copy_cpus(void * in_cpus __attribute__((unused))) {
132
}
133
#endif
134

135
int Trick::ThreadBase::execute_cpu_affinity() {
638✔
136
#if __linux
137
#ifdef CPU_ALLOC_SIZE
138
    sched_setaffinity(pid, CPU_ALLOC_SIZE(max_cpu), cpus) ;
638✔
139
#else
140
    sched_setaffinity(pid, sizeof(cpu_set_t), cpus) ;
141
#endif
142
#endif
143
    return(0) ;
638✔
144
}
145

146
int Trick::ThreadBase::set_priority(unsigned int req_priority) {
2✔
147
    rt_priority = req_priority ;
2✔
148
    return 0 ;
2✔
149
}
150

151
#if __linux
152

153
#include <sched.h>
154
#include <errno.h>
155

156
int Trick::ThreadBase::execute_priority() {
638✔
157

158
    int max_priority;
159
    int min_priority;
160
    int proc_priority;
161
    struct sched_param sparams;
162
    int sched_policy = SCHED_FIFO;
638✔
163

164
    if ( rt_priority > 0 ) {
638✔
165
        if (sched_getparam((pid_t) 0, &sparams)) {
×
166
            message_publish(MSG_ERROR, "Failed to get process scheduling parameters: %s\n", std::strerror(errno));
×
167
        } else {
168

169
            /* Get maximum and minimum RT priority */
170
            max_priority = sched_get_priority_max(SCHED_FIFO);
×
171
            min_priority = sched_get_priority_min(SCHED_FIFO);
×
172

173
            /* Since Trick's max priority starts at 1 and moves to lower priorties as the number goes up and Linux's
174
               priorities goes up as the number goes up and maxes out at "max_priority", we need to offset as follows:
175
             */
176
            proc_priority = max_priority - (rt_priority - 1);
×
177

178
            /* Make sure priority is in bounds. */
179
            if (proc_priority < min_priority) {
×
180

181
                message_publish(MSG_WARNING, "Warning: Linux process %d priority at %d is too low.  Minimum Trick \npriority is %d.\n",
×
182
                         pid, rt_priority, (max_priority - min_priority) + 2);
×
183

184
                proc_priority = min_priority;
×
185
            }
186

187
            if (pthread_getschedparam(pthread_self(), &sched_policy, &sparams)) {
×
188

189
                message_publish(MSG_ERROR, "Failed to get process scheduling parameters: %s\n", std::strerror(errno));
×
190
            }
191

192
            /* Set the process priority. */
193
            sparams.sched_priority = proc_priority;
×
194
            if (pthread_setschedparam(pthread_self(), SCHED_FIFO, &sparams)) {
×
UNCOV
195
                message_publish(MSG_ERROR, "Failed to set thread priority: %s\n", std::strerror(errno));
×
196
            }
197
        }
198
    }
199

200
    return(0) ;
638✔
201

202
}
203
#endif
204

205
#if __APPLE__
206

207
#include <sched.h>
208
#include <errno.h>
209

210
int Trick::ThreadBase::execute_priority() {
211

212
    int ret;
213

214
    /* Declare scheduling paramters. */
215
    int max_priority;
216
    int min_priority;
217
    int prev_priority;
218
    int proc_priority;
219
    int sched_policy = SCHED_FIFO;
220
    struct sched_param param;
221

222
    if ( rt_priority > 0 ) {
223
        /* Get maximum and minimum RT priority, and current parameters. */
224
        max_priority = sched_get_priority_max(sched_policy);
225
        min_priority = sched_get_priority_min(sched_policy);
226
        pthread_getschedparam(pthread_self(), &sched_policy, &param);
227
        prev_priority = param.sched_priority;
228

229
        /* Trick's max priority starts at 1 and moves to lower priorities as the number goes up.  Darwin's thread
230
           priorities range between 15 to 47 (observed). The default priority is 31 (observed); higher priorities
231
           cause more favorable scheduling. */
232
        proc_priority = max_priority - (rt_priority - 1);
233

234
        /* Make sure priority is in bounds. */
235
        if (proc_priority < min_priority) {
236

237
            message_publish(MSG_WARNING, "Warning: Trick CPU priority at %d is too low.\n", rt_priority);
238
            message_publish(MSG_WARNING, "This corresponds to a Darwin thread priority of %d.\n", proc_priority);
239
            message_publish(MSG_WARNING, "The Darwin thread priority range is %d:%d (min:max).\n", min_priority, max_priority);
240
            message_publish(MSG_WARNING, "The corresponding minimum Trick priority is %d.\n", (max_priority - min_priority) + 1);
241
            message_publish(MSG_WARNING, "Setting Trick priority to minimum!\n");
242
            proc_priority = min_priority;
243

244
        } else if (proc_priority > max_priority) {
245

246
            message_publish(MSG_WARNING, "Warning: Trick CPU priority at %d is too high.\n", rt_priority);
247
            message_publish(MSG_WARNING, "This corresponds to a Darwin thread priority of %d.\n", proc_priority);
248
            message_publish(MSG_WARNING, "The Darwin thread priority range is %d:%d (min:max).\n", min_priority, max_priority);
249
            message_publish(MSG_WARNING, "The maximum Trick priority is 1. Setting to maximum!\n");
250
            proc_priority = max_priority;
251
        }
252

253
        /* Set the process priority. */
254
        param.sched_priority = proc_priority;
255

256
        ret = pthread_setschedparam(pthread_self(), sched_policy, &param);
257
        if (ret != 0) {
258

259
            message_publish(MSG_ERROR, "Failed to set Darwin thread priority to %d: %s\n", param.sched_priority, std::strerror(errno));
260
            message_publish(MSG_ERROR, "This should correspond to a Trick CPU priority of %d.\n", (max_priority - proc_priority) + 1);
261
            message_publish(MSG_ERROR, "The current Darwin thread priority is %d.\n", prev_priority);
262
            message_publish(MSG_ERROR, "The Darwin thread priority range is %d:%d (min:max).\n", min_priority, max_priority);
263

264
        } else {
265

266
            message_publish(MSG_INFO, "Info: Trick CPU priority set to %d.\n", (max_priority - proc_priority) + 1);
267
            message_publish(MSG_INFO, "This corresponds to a Darwin thread priority of %d.\n", param.sched_priority);
268
            message_publish(MSG_INFO, "The previous Darwin thread priority was %d.\n", prev_priority);
269
            message_publish(MSG_INFO, "The Darwin thread priority range is %d:%d (min:max).\n", min_priority, max_priority);
270
        }
271
    }
272

273
    return(0) ;
274

275
}
276

277
#endif
278

279
int Trick::ThreadBase::create_thread() {
485✔
280

281
    if (created) {
485✔
282
        message_publish(MSG_ERROR, "create_thread called on thread %s (%p) which has already been started.\n", name.c_str(), this);
×
283
        return 0;
×
284
    }
285

286
    pthread_attr_t attr;
287

288
    pthread_attr_init(&attr);
485✔
289
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
485✔
290
    pthread_create(&pthread_id, &attr, Trick::ThreadBase::thread_helper , (void *)this);
485✔
291
    created = true;
485✔
292

293
#if __linux
294
#ifdef __GNUC__
295
#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 2
296
    if ( ! name.empty() ) {
485✔
297
       std::string short_str = name.substr(0,15) ;
970✔
298
       pthread_setname_np(pthread_id, short_str.c_str()) ;
485✔
299
    }
300
#endif
301
#endif
302
#endif
303
    return(0) ;
485✔
304
}
305

306
int Trick::ThreadBase::cancel_thread() {
1,005✔
307
    pthread_mutex_lock(&shutdown_mutex);
1,005✔
308
    should_shutdown = true;
1,005✔
309
    pthread_mutex_unlock(&shutdown_mutex);
1,005✔
310

311
    if ( pthread_id != 0 ) {
1,005✔
312
        if (cancellable)
763✔
313
            pthread_cancel(pthread_id) ;
437✔
314
    }
315
    return(0) ;
1,005✔
316
}
317

318
int Trick::ThreadBase::join_thread() {
720✔
319
    if ( pthread_id != 0 ) {
720✔
320
        if ((errno = pthread_join(pthread_id, NULL)) != 0) {
478✔
321
            std::string msg = "Thread " + name + " had an error in join";
×
322
            perror(msg.c_str());
×
323
        } else {
324
            pthread_id = 0;
478✔
325
        }
326
    }
327
    return(0) ;
720✔
328
}
329

330
void Trick::ThreadBase::test_shutdown() {
3,752,471✔
331
    test_shutdown (NULL, NULL);
3,752,471✔
332
}
3,752,291✔
333

334
void Trick::ThreadBase::test_shutdown(void (*exit_handler) (void *), void * exit_arg) {
3,752,496✔
335
    pthread_mutex_lock(&shutdown_mutex);
3,752,496✔
336
    if (should_shutdown) {
3,752,496✔
337
        pthread_mutex_unlock(&shutdown_mutex);
181✔
338

339
        thread_shutdown(exit_handler, exit_arg);
181✔
340
    }
341
    pthread_mutex_unlock(&shutdown_mutex);
3,752,315✔
342
}
3,752,315✔
343

344

345
void Trick::ThreadBase::thread_shutdown() {
2✔
346
    thread_shutdown (NULL, NULL);
2✔
347
}
×
348

349
void Trick::ThreadBase::thread_shutdown(void (*exit_handler) (void *), void * exit_arg) {
188✔
350
    if (exit_handler != NULL) {
188✔
351
        exit_handler(exit_arg);
6✔
352
    }
353

354
    pthread_exit(0); 
188✔
355
}
356

357
void * Trick::ThreadBase::thread_helper( void * context ) {
485✔
358

359
    sigset_t sigs;
360
    Trick::ThreadBase * tb = (Trick::ThreadBase *)context ;
485✔
361

362
    /* block out all signals on this thread */
363
    sigfillset(&sigs);
485✔
364
    pthread_sigmask(SIG_BLOCK, &sigs, NULL);
485✔
365

366
    /* Set the cancel type to deffered, the thread will be cancelled at next cancellation point */
367
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
485✔
368

369
    tb->set_pid() ;
485✔
370

371
    /* Set thread priority and CPU affinity */
372
    tb->execute_priority() ;
485✔
373
    tb->execute_cpu_affinity() ;
485✔
374

375
    return tb->thread_body() ;
485✔
376
}
377

378
void Trick::ThreadBase::dump( std::ostream & oss ) {
150✔
379
    oss << "    from Trick::ThreadBase\n";
150✔
380
    oss << "    pthread_id = " << pthread_id << "\n";
150✔
381
    oss << "    process_id = " << pid << "\n";
150✔
382
    oss << "    rt_priority = " << rt_priority << "\n";
150✔
383
#if __linux
384
    oss << "    cpus = " ;
150✔
385
    bool first_print = true ;
150✔
386
    for ( unsigned int ii = 0 ; ii < max_cpu ; ii++ ) {
750✔
387
#ifdef CPU_ISSET_S
388
        if ( CPU_ISSET_S(ii, CPU_ALLOC_SIZE(max_cpu), cpus) ) {
600✔
389
#else
390
        if ( CPU_ISSET(ii, cpus) ) {
391
#endif
392
            if ( first_print == true ) {
×
393
                first_print = false ;
×
394
            } else {
395
                oss << "," ;
×
396
            }
397
            oss << ii ;
×
398
        }
399
    }
400
    if ( first_print ) {
150✔
401
        oss << "none assigned" ;
150✔
402
    }
403
    oss << std::endl ;
150✔
404
#endif
405
}
150✔
406

407

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