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

nasa / trick / 21603216931

02 Feb 2026 06:53PM UTC coverage: 55.624% (+0.02%) from 55.607%
21603216931

Pull #2032

github

web-flow
Merge 623a39882 into d49130d35
Pull Request #2032: Added 2D&3D array allocation support from Python and fixed the sim build error when TRICK_CONVERT_SWIG_FLAGS = -s.

12521 of 22510 relevant lines covered (55.62%)

304915.25 hits per line

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

78.85
/trick_source/sim_services/MemoryManager/MemoryManager_write_checkpoint.cpp
1
#include <fstream>
2
#include <sstream>
3
#include <string.h>
4
#include <stdlib.h>  // free()
5
#include <algorithm> // std::sort()
6
#include "trick/MemoryManager.hh"
7

8
// GreenHills stuff
9
#if ( __ghs )
10
#include "ghs_stubs.h"
11
#endif
12

13
// MEMBER FUNCTION
14
void Trick::MemoryManager::execute_checkpoint( std::ostream& out_s ) {
49✔
15

16
    ALLOC_INFO_MAP::iterator pos;
49✔
17
    ALLOC_INFO* alloc_info;
18
    char name[256];
19
    int local_anon_var_number;
20
    int extern_anon_var_number;
21

22
    // 1) Generate declaration statements for each the allocations that we are managing.
23
    out_s << "// Variable Declarations." << std::endl;
49✔
24
    out_s.flush();
49✔
25

26
    local_anon_var_number = 0;
49✔
27
    extern_anon_var_number = 0;
49✔
28

29
    // Give names to the anonymous declarations
30
    // Also search each allocation for STLs.
31
    // STLs will be added to the dependencies vector.
32
    int n_depends = dependencies.size();
49✔
33
    for (int ii = 0 ; ii < n_depends ; ii ++) {
836✔
34
        alloc_info = dependencies[ii];
787✔
35
        /** Generate temporary names for anonymous variables. */
36
        if (alloc_info->name == NULL) {
787✔
37
            // Skip naming individual C-string allocations to eliminate unused declarations
38
            // Individual char arrays (size=1, num_index=1) represent single strings that are
39
            // included in char* arrays, so we don't need separate allocations for them
40
            if ((alloc_info->type == TRICK_CHARACTER || alloc_info->type == TRICK_UNSIGNED_CHARACTER) && 
290✔
41
                alloc_info->size == 1 && alloc_info->num_index == 1 && alloc_info->stcl == TRICK_LOCAL) {
144✔
42
                // Skip naming this individual char array allocation to prevent unused declarations
43
                continue;
116✔
44
            }
45

46
            if ( alloc_info->stcl == TRICK_LOCAL) {
174✔
47
                snprintf( name, sizeof(name), "%s%d", local_anon_var_prefix, local_anon_var_number++);
174✔
48
                alloc_info->name = strdup( name);
174✔
49
            } else if (alloc_info->stcl == TRICK_EXTERN) {
×
50
                snprintf( name, sizeof(name), "%s%d", extern_anon_var_prefix, extern_anon_var_number++);
×
51
                alloc_info->name = strdup( name);
×
52
                /** @b NOTE: We should not write declarations for external
53
                    anonymous variables, because we should not reload them.*/
54
            } else {
55
                emitError("write_checkpoint: This is bad. ALLOC_INFO object is messed up.\n") ;
×
56
            }
57
        }
58
        get_stl_dependencies(alloc_info);
671✔
59
    }
60

61
    // Write a declaration statement for all of the LOCAL variables,
62
    n_depends = dependencies.size();
49✔
63
    for (int ii = 0 ; ii < n_depends ; ii ++) {
3,149✔
64
        alloc_info = dependencies[ii];
3,100✔
65
        if ( alloc_info->stcl == TRICK_LOCAL) {
3,100✔
66
            currentCheckPointAgent->write_decl( out_s, alloc_info);
2,696✔
67
        }
68
    }
69

70
    // Write a "clear_all_vars" command.
71
    if (reduced_checkpoint) {
49✔
72
        out_s << std::endl << std::endl << "// Clear all allocations to 0." << std::endl;
49✔
73
        out_s << "clear_all_vars();" << std::endl;
49✔
74
    }
75

76
    // 2) Dump the contents of each of the dynamic and mapped allocations.
77
    out_s << std::endl << std::endl << "// Variable Assignments." << std::endl;
49✔
78
    out_s.flush();
49✔
79

80
    for (int ii = 0 ; ii < n_depends ; ii ++) {
3,149✔
81
        alloc_info = dependencies[ii];
3,100✔
82
        // Skip naming individual C-string allocations to eliminate unused declarations.
83
        // Individual char arrays (size=1, num_index=1) represent single strings that are
84
        // included in char* arrays, so we don't need separate allocations for them.
85
        // Also, safety check for NULL name before pushing to name stack later.
86
        if (!((alloc_info->type == TRICK_CHARACTER || alloc_info->type == TRICK_UNSIGNED_CHARACTER) &&
3,100✔
87
               alloc_info->size == 1 && alloc_info->num_index == 1 && alloc_info->stcl == TRICK_LOCAL) &&
144✔
88
             alloc_info->name != NULL)
2,984✔
89
        {
90
            write_var(out_s, alloc_info);
2,984✔
91
            out_s << std::endl;
2,984✔
92
        }
93
    }
94

95
    // Free all of the temporary names that were created for the checkpoint.
96

97
    for (int ii = 0 ; ii < n_depends ; ii ++) {
3,149✔
98
        alloc_info = dependencies[ii];
3,100✔
99
        // If the temporary-variable prefix occurs at the beginning of the name ...
100
        if ((alloc_info->name != NULL) &&
3,100✔
101
            (( strstr( alloc_info->name, local_anon_var_prefix ) == alloc_info->name ) ||
2,984✔
102
             ( strstr( alloc_info->name, extern_anon_var_prefix) == alloc_info->name ))) {
2,800✔
103
                free( alloc_info->name);
184✔
104
                alloc_info->name = NULL;
184✔
105
        }
106
    }
107

108
    // Delete the variables created by STLs. Remove memory in reverse order.
109
    std::vector<ALLOC_INFO*>::reverse_iterator it ;
49✔
110
    for ( it = stl_dependencies.rbegin() ; it != stl_dependencies.rend() ; it++ ) {
2,362✔
111
        delete_var((*it)->start) ;
2,313✔
112
    }
113
}
49✔
114

115
// Local sort function used in write_checkpoint.
116
static bool alloc_info_id_compare(ALLOC_INFO * lhs, ALLOC_INFO * rhs) { return ( lhs->id < rhs->id ) ; }
3,872✔
117

118
// MEMBER FUNCTION
119
void Trick::MemoryManager::write_checkpoint( std::ostream& out_s) {
16✔
120

121
    ALLOC_INFO_MAP::iterator pos;
16✔
122
    ALLOC_INFO* alloc_info;
123
    dependencies.clear();
16✔
124
    stl_dependencies.clear();
16✔
125

126
    pthread_mutex_lock(&mm_mutex);
16✔
127
    for ( pos=alloc_info_map.begin() ; pos!=alloc_info_map.end() ; pos++ ) {
738✔
128
        alloc_info = pos->second;
722✔
129
        dependencies.push_back(alloc_info);
722✔
130
    }
131

132
    // Sort the dependencies by ALLOC_INFO.id.
133
    std::sort( dependencies.begin() , dependencies.end() , alloc_info_id_compare) ;
16✔
134
    pthread_mutex_unlock(&mm_mutex);
16✔
135

136
    execute_checkpoint( out_s );
16✔
137

138
}
16✔
139

140
// MEMBER FUNCTION
141
void Trick::MemoryManager::write_checkpoint(const char* filename) {
16✔
142

143
   std::ofstream outfile( filename, std::ios::out);
32✔
144

145
    if (outfile.is_open()) {
16✔
146
        write_checkpoint( outfile);
16✔
147
    } else {
148
        std::stringstream message;
×
149
        message << "Couldn't open \"" << filename << "\".";
×
150
        emitError(message.str());
×
151
    }
152
}
16✔
153

154
// MEMBER FUNCTION
155
void Trick::MemoryManager::write_checkpoint( std::ostream& out_s, const char* var_name) {
32✔
156

157
    dependencies.clear();
32✔
158
    stl_dependencies.clear();
32✔
159

160
    pthread_mutex_lock(&mm_mutex);
32✔
161
    get_alloc_deps_in_allocation( var_name);
32✔
162
    pthread_mutex_unlock(&mm_mutex);
32✔
163

164
    execute_checkpoint( out_s );
32✔
165
}
32✔
166

167
// MEMBER FUNCTION
168
void Trick::MemoryManager::write_checkpoint(const char* filename, const char* var_name) {
×
169

170
    std::ofstream out_s( filename, std::ios::out);
×
171
    if (out_s.is_open()) {
×
172
        write_checkpoint( out_s, var_name);
×
173
    } else {
174
        std::stringstream message;
×
175
        message << "Couldn't open \"" << filename << "\".";
×
176
        emitError(message.str());
×
177
    }
178
}
×
179

180
// MEMBER FUNCTION
181
void Trick::MemoryManager::write_checkpoint( std::ostream& out_s, std::vector<const char*>& var_name_list) {
1✔
182

183
    const char* var_name;
184
    int n_names;
185

186
    dependencies.clear();
1✔
187
    stl_dependencies.clear();
1✔
188

189
    n_names = var_name_list.size();
1✔
190
    for (int ii=0; ii< n_names; ii++) {
3✔
191
        var_name = var_name_list[ii];
2✔
192
        pthread_mutex_lock(&mm_mutex);
2✔
193
        get_alloc_deps_in_allocation(var_name);
2✔
194
        pthread_mutex_unlock(&mm_mutex);
2✔
195
    }
196

197
    execute_checkpoint( out_s );
1✔
198
}
1✔
199

200
// MEMBER FUNCTION
201
void Trick::MemoryManager::write_checkpoint(const char* filename, std::vector<const char*>& var_name_list) {
×
202

203
    std::ofstream out_s( filename, std::ios::out);
×
204

205
    if (out_s.is_open()) {
×
206
        write_checkpoint( out_s, var_name_list);
×
207
    } else {
208
        std::cerr << "ERROR: Couldn't open \""<< filename <<"\"." << std::endl;
×
209
        std::cerr.flush();
×
210
    }
211
}
×
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