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

nasa / trick / 11056555189

26 Sep 2024 04:40PM UTC coverage: 55.877% (+0.05%) from 55.83%
11056555189

push

github

web-flow
Preserved job queue currant index after pushing a job. (#1781)

* Peserved job queue current index after pushing a job.

* Reconciled the heinous offense of using tabs.

2 of 3 new or added lines in 1 file covered. (66.67%)

2 existing lines in 1 file now uncovered.

12288 of 21991 relevant lines covered (55.88%)

69645.22 hits per line

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

83.43
/trick_source/sim_services/ScheduledJobQueue/ScheduledJobQueue.cpp
1
#include <algorithm>
2
#include <iostream>
3
#include <sstream>
4
#include <stdlib.h>
5
#include <stdio.h>
6
#include <string.h>
7

8
#include "trick/ScheduledJobQueue.hh"
9
#include "trick/ScheduledJobQueueInstrument.hh"
10
#include "trick/TrickConstant.hh"
11

12
/**
13
@design
14
-# Set #list to NULL
15
-# Set #list_list to 0
16
-# Set #curr_index to 0
17
-# Set #next_job_time to TRICK_MAX_LONG_LONG
18
*/
19
Trick::ScheduledJobQueue::ScheduledJobQueue( ) {
7,120✔
20

21
    list = NULL ;
7,120✔
22
    list_size = 0 ;
7,120✔
23
    curr_index = 0 ;
7,120✔
24
    next_job_time = TRICK_MAX_LONG_LONG ;
7,120✔
25

26
}
7,120✔
27

28
/**
29
@design
30
-# free list if it is not empty
31
*/
32
Trick::ScheduledJobQueue::~ScheduledJobQueue( ) {
14,240✔
33
    if (list  != NULL ) {
7,120✔
34
        free(list) ;
4,082✔
35
    }
36
}
7,120✔
37

38
static bool compare_job_data(const Trick::JobData *a, const Trick::JobData *b) {
54,203✔
39
    {
40
        int ajc = a->job_class;
54,203✔
41
        int bjc = b->job_class;
54,203✔
42
        if (ajc < bjc)
54,203✔
43
            return true;
4,113✔
44
        if (ajc > bjc)
50,090✔
45
            return false;
372✔
46
    }
47
    {
48
        unsigned short ap = a->phase;
49,718✔
49
        unsigned short bp = b->phase;
49,718✔
50
        if (ap < bp)
49,718✔
51
            return true;
16,109✔
52
        if (ap > bp)
33,609✔
53
            return false;
9,161✔
54
    }
55
    {
56
        int asoi = a->sim_object_id;
24,448✔
57
        int bsoi = b->sim_object_id;
24,448✔
58
        if (asoi < bsoi)
24,448✔
59
            return true;
3✔
60
        if (asoi > bsoi)
24,445✔
61
            return false;
15,569✔
62
    }
63
    return a->id < b->id;
8,876✔
64
}
65

66
/**
67
@design
68
-# Allocate additional memory for the incoming job
69
-# Find the insertion point in the queue based on the job_class, the phase,
70
   the sim_object id, and the job_id
71
-# Move the jobs after the insertion point to the right by one.
72
-# Insert the new job at the insertion point.
73
-# Increment the size of the queue.
74
*/
75
int Trick::ScheduledJobQueue::push( JobData * new_job ) {
24,936✔
76

77
    /* Allocate additional memory for the additional job in the queue */
78
    JobData ** new_list = (JobData **)realloc(list, (list_size + 1) * sizeof(JobData *)) ;
24,936✔
79
    if (!new_list) {
24,936✔
80
        abort();
×
81
    }
82
    list = new_list;
24,936✔
83
    JobData ** list_end = list + list_size;
24,936✔
84
    JobData ** insert_pt = std::upper_bound(list, list_end, new_job, compare_job_data);
24,936✔
85
    if (insert_pt != list_end) {
24,936✔
86
        memmove(insert_pt + 1, insert_pt, (list_end - insert_pt) * sizeof(JobData *));
9,742✔
87
    }
88
    *insert_pt = new_job;
24,936✔
89

90
    new_job->set_handled(true) ;
24,936✔
91

92
    /* Increment the size of the queue */
93
    list_size++ ;
24,936✔
94
        
95
    int new_job_index = (insert_pt - list) / sizeof(JobData**);
24,936✔
96
    if(new_job_index < curr_index) {
24,936✔
NEW
97
        curr_index++;        
×
98
    }
99

100
    return(0) ;
24,936✔
101

102
}
103

104
/**
105
@design
106
-# Temporarily assign a high sim_object id to the incoming job.  This
107
   effectively removes the sim_object_id as an ordering field
108
-# Call Trick::ScheduledJobQueue::push( JobData * ) to add the job to the queue.
109
-# Restore the original sim_object id.
110
*/
111
int Trick::ScheduledJobQueue::push_ignore_sim_object( JobData * new_job ) {
55✔
112

113
    int save_sim_object_id ;
114
    int ret ;
115

116
    /* Temorarily assign a really high sim_object id  */
117
    save_sim_object_id = new_job->sim_object_id ;
55✔
118
    new_job->sim_object_id = 1000000 ;
55✔
119
    /* push the job onto the scheduling queue as normal */
120
    ret = push(new_job) ;
55✔
121
    /* restore the original sim_object id */
122
    new_job->sim_object_id = save_sim_object_id ;
55✔
123
    return(ret) ;
55✔
124
}
125

126
/**
127
@design
128
-# Traverse the list of jobs looking for the job to delete.
129
 -# If the job to delete is found
130
  -# Allocate a new list that holds 1 less job than the current list
131
  -# Copy all of the jobs that precede the deleted job to the new list
132
  -# Copy all of the jobs that are after the delete job to the new list
133
  -# Decrement the size of the list
134
  -# Free the memory associated with the current list
135
  -# Point the current list to the newly allocated list
136
*/
137
int Trick::ScheduledJobQueue::remove( JobData * delete_job ) {
×
138

139
    unsigned int ii , jj ;
140

141
    /* Find the job to delete in the queue. */
142
    for ( ii = 0 ; ii < list_size ; ii++ ) {
×
143
        if ( list[ii] == delete_job ) {
×
144
            /* allocate a new list that holds one less element than the current list. */
145
            JobData ** new_list = (JobData **)calloc( list_size - 1 , sizeof(JobData *)) ;
×
146
            /* copy all of the jobs that are before the deleted job to the new list */
147
            for ( jj = 0 ; jj < ii ; jj++ ) {
×
148
                new_list[jj] = list[jj] ;
×
149
            }
150
            /* copy all of the jobs that are after the deleted job to the new list */
151
            for ( jj = ii + 1 ; jj < list_size ; jj++ ) {
×
152
                new_list[jj-1] = list[jj] ;
×
153
            }
154
            if ( ii <= curr_index ) {
×
155
                curr_index-- ;
×
156
            }
157
            /* Decrement the size of the queue */
158
            list_size-- ;
×
159
            /* Free the old queue space */
160
            free(list) ;
×
161
            /* Assign the queue pointer to the new space */
162
            list = new_list ;
×
163
            return 0 ;
×
164
        }
165
    }
166
    return -1 ;
×
167
}
168

169
/**
170
@design
171
-# Returns the #curr_index of the queue.
172
*/
173
unsigned int Trick::ScheduledJobQueue::get_curr_index() {
3,244✔
174
    return curr_index ;
3,244✔
175
}
176

177
/**
178
@design
179
-# Sets #curr_index to the incoming value.
180
*/
181
int Trick::ScheduledJobQueue::set_curr_index(unsigned int value ) {
3,244✔
182

183
    if ( value < list_size ) {
3,244✔
184
        curr_index = value ;
2,196✔
185
    }
186
    return 0 ;
3,244✔
187
}
188

189
/**
190
@design
191
-# Sets #curr_index to 0.
192
*/
193
int Trick::ScheduledJobQueue::reset_curr_index() {
1,799,660✔
194

195
    curr_index = 0 ;
1,799,660✔
196
    return(0) ;
1,799,660✔
197
}
198

199
/**
200
@design
201
-# Returns #list_size
202
*/
203
unsigned int Trick::ScheduledJobQueue::size() {
220✔
204
    return(list_size) ;
220✔
205
}
206

207
/**
208
@design
209
-# Returns !(#list_size)
210
*/
211
bool Trick::ScheduledJobQueue::empty() {
154,699✔
212
    return(!list_size) ;
154,699✔
213
}
214

215
/**
216
@design
217
-# If #list is not NULL free it.
218
-# Set #list to NULL
219
-# Set #list_list to 0
220
-# Set #curr_index to 0
221
-# Set #next_job_time to TRICK_MAX_LONG_LONG
222
*/
223
int Trick::ScheduledJobQueue::clear() {
197✔
224

225
    /* free job list if one exists  */
226
    if (list != NULL ) {
197✔
227
        free(list) ;
176✔
228
    }
229
    /* set all list variables to initial cleared values */
230
    list = NULL ;
197✔
231
    list_size = 0 ;
197✔
232
    curr_index = 0 ;
197✔
233
    next_job_time = TRICK_MAX_LONG_LONG ;
197✔
234
    return(0) ;
197✔
235
}
236

237
/**
238
@design
239
-# If the list is empty return NULL
240
-# Else return the current job without incrementing the #curr_index index.
241
*/
242
Trick::JobData * Trick::ScheduledJobQueue::top() {
5✔
243
    /* return NULL if list is empty  */
244
    if ( list_size == 0 ) {
5✔
245
        return(NULL) ;
1✔
246
    }
247
    /* else return current list item  */
248
    return(list[curr_index]) ;
4✔
249
}
250

251

252
/**
253
@design
254
-# If the #curr_index is greater than or equal to the #list_size
255
    -# Set the #curr_index to the #list_size
256
    -# Return NULL
257
-# Else while the list #curr_list is less than the list size
258
    -# Increment the #curr_index.
259
    -# Return the current job if the job is enabled.
260
*/
261
Trick::JobData * Trick::ScheduledJobQueue::get_next_job() {
4,293,512✔
262

263
    JobData * curr_job ;
264

265
    /* return NULL if we are at the end of the list  */
266
    if ( curr_index >= list_size ) {
4,293,512✔
267
        curr_index = list_size ;
1,279,297✔
268
        return(NULL) ;
1,279,297✔
269
    } else {
270
        /* return the next enabled job, or NULL if we reach the end of the list */
271
        while (curr_index < list_size ) {
3,014,227✔
272
            curr_job = list[curr_index++] ;
3,014,227✔
273
            if ( !curr_job->disabled ) {
3,014,227✔
274
                return(curr_job) ;
3,014,215✔
275
            }
276
        }
277
    }
278
    return(NULL) ;
×
279
}
280

281
/**
282
@design
283
-# While the list #curr_list is less than the list size
284
    -# If the current queue job next call matches the incoming simulation time
285
        -# If the job class is not a system class job, calculate the next
286
           time it will be called by current time + job cycle.
287
        -# Set the next job call time to TRICK_MAX_LONG_LONG if the next job call time
288
           is greater than the stop time.
289
        -# If the job's next job call time is lower than the overall next job call time
290
           set the overall job call time to the current job's next job call time.
291
        -# Increment the #curr_index.
292
        -# Return the current job if the job is enabled.
293
    -# Else
294
        -# If the job's next job call time is lower than the overall next job call time
295
           set the overall job call time to the current job's next job call time.
296
        -# Increment the #curr_index.
297
-# Return NULL when the end of the list is reached.
298
*/
299
Trick::JobData * Trick::ScheduledJobQueue::find_next_job(long long time_tics ) {
3,273,978✔
300

301
    JobData * curr_job ;
302
    long long next_call ;
303

304
    /* Search through the rest of the queue starting at curr_index looking for
305
       the next job with it's next execution time is equal to the current simulation time. */
306
    while (curr_index < list_size ) {
3,273,978✔
307

308
        curr_job = list[curr_index] ;
2,756,488✔
309

310
        if ( curr_job->next_tics == time_tics ) {
2,756,488✔
311

312
            /* If the job does not reschedule itself (system_job_classes), calculate the next time it will be called. */
313
            if ( ! curr_job->system_job_class ) {
1,036,131✔
314
                // calculate the next job call time
315
                next_call = curr_job->next_tics + curr_job->cycle_tics ;
777,752✔
316
                /* If the next time does not exceed the stop time, set the next call time for the module */
317
                if (next_call > curr_job->stop_tics) {
777,752✔
318
                    curr_job->next_tics = TRICK_MAX_LONG_LONG ;
×
319
                } else {
320
                    curr_job->next_tics = next_call;
777,752✔
321
                }
322
                /* Track next lowest job call time after the current time for jobs that match the current time. */
323
                if ( curr_job->next_tics <  next_job_time ) {
777,752✔
324
                    next_job_time = curr_job->next_tics ;
169,834✔
325
                }
326
            }
327
            curr_index++ ;
1,036,131✔
328
            if ( !curr_job->disabled ) {
1,036,131✔
329
                return(curr_job) ;
949,715✔
330
            }
331
        } else {
332
            /* Track next lowest job call time after the current time for jobs that do not match the current time */
333
            if ( curr_job->next_tics > time_tics && curr_job->next_tics < next_job_time ) {
1,720,357✔
334
                next_job_time = curr_job->next_tics ;
15,805✔
335
            }
336
            curr_index++ ;
1,720,357✔
337
        }
338
    }
339
    return(NULL) ;
517,490✔
340
}
341

342
/**
343
@design
344
-# While the list #curr_list is less than the list size
345
    -# If the current queue job next call matches the incoming simulation time
346
        -# Increment the #curr_index.
347
        -# Return the current job if the job is enabled.
348
    -# Increment the #curr_index.
349
-# Return NULL when the end of the list is reached.
350
*/
351
Trick::JobData* Trick::ScheduledJobQueue::find_job(long long time_tics) {
24,716✔
352
    JobData * curr_job ;
353

354
    /* Search through the rest of the queue starting at curr_index looking for             */
355
    /* the next job with it's next execution time is equal to the current simulation time. */
356
    while (curr_index < list_size) {
24,716✔
357
        curr_job = list[curr_index] ;
21,884✔
358

359
        if (curr_job->next_tics == time_tics ) {
21,884✔
360
            if (!curr_job->disabled) {
5,451✔
361
                curr_index++ ;
5,451✔
362
                return(curr_job) ;
5,451✔
363
            }
364
        }
365
        curr_index++ ;
16,433✔
366
    }
367
    return(NULL) ;
2,832✔
368
}
369

370
/**
371
@details
372
-# Sets #next_job_time to the incoming time
373
*/
374
int Trick::ScheduledJobQueue::set_next_job_call_time(long long in_time) {
517,494✔
375
    next_job_time = in_time ;
517,494✔
376
    return(0) ;
517,494✔
377
}
378

379
/**
380
@details
381
-# Return the next_job_call_time in counts of tics/second
382
   Requirement [@ref r_exec_time_0]
383
*/
384
long long Trick::ScheduledJobQueue::get_next_job_call_time() {
685,682✔
385
    unsigned int temp_index = curr_index ;
685,682✔
386
    while (temp_index < list_size ) {
1,418,552✔
387
        if ( list[temp_index]->next_tics <  next_job_time ) {
732,870✔
388
            next_job_time = list[temp_index]->next_tics ;
12✔
389
        }
390
        temp_index++ ;
732,870✔
391
    }
392
    return(next_job_time) ;
685,682✔
393
}
394

395
/**
396
@details
397
-# If the current job next call time is less than the overall next job call time, and is
398
   greater than the current simulation time, set the overall next job call time to be the
399
   job next call time.
400
*/
401
int Trick::ScheduledJobQueue::test_next_job_call_time(Trick::JobData * curr_job, long long time_tics) {
258,386✔
402
    if ( curr_job->next_tics > time_tics && curr_job->next_tics < next_job_time ) {
258,386✔
403
        next_job_time = curr_job->next_tics ;
7✔
404
    }
405
    return(0) ;
258,386✔
406
}
407

408
// Executes the jobs in a queue.  saves and restores Trick::Executive::curr_job
409
int Trick::ScheduledJobQueue::execute_all_jobs() {
×
410
    Trick::JobData * curr_job ;
411
    int ret ;
412

413
    reset_curr_index() ;
×
414
    while ( (curr_job = get_next_job()) != NULL ) {
×
415
        ret = curr_job->call() ;
×
416
        if ( ret != 0 ) {
×
417
            return ret ;
×
418
        }
419
    }
420
    /* return 0 if there are no errors. */
421
    return 0 ;
×
422
}
423

424
int Trick::ScheduledJobQueue::write_sched_queue( FILE * fp ) {
1,795✔
425

426
    Trick::JobData * curr_job ;
427
    unsigned int save_index ;
428

429
    save_index = get_curr_index() ;
1,795✔
430
    reset_curr_index() ;
1,795✔
431
    while ( (curr_job = get_next_job()) != NULL ) {
4,853✔
432
        if ( curr_job->job_class_name.compare("instrumentation") ) {
3,058✔
433
            /* for each non instrumentation job write the job information to the open file pointer "fp" */
434
            fprintf(fp, "%7d | %3d |%-25s| %-5d | %08.6f | %8.6g | %8g | %5.02f | %s\n",
3,058✔
435
                    !curr_job->disabled, curr_job->thread, curr_job->job_class_name.c_str(), curr_job->phase,
3,058✔
436
                    curr_job->start, curr_job->cycle, curr_job->stop, curr_job->frame_id,
437
                    curr_job->name.c_str());
438
        }
439
    }
440
    set_curr_index(save_index) ;
1,795✔
441
    return(0) ;
1,795✔
442
}
443

444
int Trick::ScheduledJobQueue::write_non_sched_queue( FILE * fp ) {
1,440✔
445

446
    Trick::JobData * curr_job ;
447
    unsigned int save_index ;
448

449
    save_index = get_curr_index() ;
1,440✔
450
    reset_curr_index() ;
1,440✔
451
    while ( (curr_job = get_next_job()) != NULL ) {
15,223✔
452
        if ( curr_job->job_class_name.compare("instrumentation") ) {
13,783✔
453
            /* for each non instrumentation job write the job information to the open file pointer "fp" */
454
            fprintf(fp, "%7d | %3d |%-25s| %-5d |          |          |          | %5.02f | %s\n",
13,783✔
455
                    !curr_job->disabled, curr_job->thread, curr_job->job_class_name.c_str(), curr_job->phase,
13,783✔
456
                    curr_job->frame_id, curr_job->name.c_str());
457
        }
458
    }
459

460
    set_curr_index(save_index) ;
1,440✔
461
    return(0) ;
1,440✔
462
}
463

464
/**
465
@details
466
-# For all jobs in the queue
467
    -# Create a new ScheduledJobQueueInstrument instance
468
    -# Add the new instrumentation job to the "before" instrumentation job list
469
-# Return 0
470
*/
471
int Trick::ScheduledJobQueue::instrument_before(Trick::JobData * instrumentation_job) {
18✔
472

473
    unsigned int ii ;
474
    ScheduledJobQueueInstrument * new_job ;
475

476
    for ( ii = 0 ; ii < list_size ; ii++ ) {
145✔
477
        new_job = new ScheduledJobQueueInstrument( instrumentation_job, list[ii] );
127✔
478
        list[ii]->add_inst_before(new_job) ;
127✔
479
    }
480

481
    return 0 ;
18✔
482
}
483

484
/**
485
@details
486
-# For all jobs in the queue
487
    -# Create a new ScheduledJobQueueInstrument instance
488
    -# Add the new instrumentation job to the "after" instrumentation job list
489
-# Return 0
490
*/
491
int Trick::ScheduledJobQueue::instrument_after(Trick::JobData * instrumentation_job) {
17✔
492

493
    unsigned int ii ;
494
    ScheduledJobQueueInstrument * new_job ;
495

496
    /* Count the number of non-instrumentation jobs in the current queue. */
497
    for ( ii = 0 ; ii < list_size ; ii++ ) {
140✔
498
        new_job = new ScheduledJobQueueInstrument( instrumentation_job, list[ii] );
123✔
499
        list[ii]->add_inst_after(new_job) ;
123✔
500
    }
501

502
    return 0 ;
17✔
503
}
504

505
/**
506
@details
507
-# For all jobs in the queue
508
    -# Create a new ScheduledJobQueueInstrument instance
509
    -# Add the new instrumentation job to the list
510
-# Return 0
511
*/
512
int Trick::ScheduledJobQueue::instrument_remove(std::string job_name) {
×
513

514
    unsigned int ii ;
515

516
    for ( ii = 0 ; ii < list_size ; ii++ ) {
×
517
        list[ii]->remove_inst(job_name) ;
×
518
    }
519

520
    return 0 ;
×
521
}
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