#include <Per_Task_Writer.hh>
Public Methods | |
Per_Task_Writer (const char *const output_directory_pathname, const process_ID_t process_ID, const task_ID_t task_ID) | |
The constructor. | |
~Per_Task_Writer () | |
The destructor. | |
void | append_reference_record (const reference_record_s *const reference_record, const canonical_page_ID_t canonical_page_ID, const timestamp_t virtual_cycle_time, const timestamp_t virtual_instruction_time, const timestamp_t virtual_reference_time) |
Emit the next reference record. | |
void | append_kernel_record (const kernel_record_s *const kernel_record, const timestamp_t virtual_cycle_time, const timestamp_t virtual_instruction_time, const timestamp_t virtual_reference_time) |
Emit the next kernel record. | |
Protected Methods | |
void | open_output () |
Open the compressed output file. | |
Protected Attributes | |
char | output_pathname [BUFFER_SIZE] |
The pathname of the compressed output stream. | |
gzFile | output_stream |
The compressed output stream to which reduced records are written. | |
timestamp_t | previous_cycle_time |
The cycle timestamp of the previously emitted record. | |
timestamp_t | previous_instruction_time |
The instruction timestamp of the previously emitted record. | |
timestamp_t | previous_reference_time |
The reference timestamp of the previously emitted record. | |
context_ID_t | previous_context_ID |
The context ID of the previously emitted record. | |
virtual_page_ID_t | previous_virtual_page_ID |
The virtual page ID of the previously emitted record. | |
canonical_page_ID_t | previous_canonical_page_ID |
The canonical page ID of the previously emitted record. |
Accept a stream of reference and kernel events, and emit them to a file associated with a single task. Keep cycle, instruction, and reference clocks up-to-date for the one thread in isolation, thus emitting traces that provide timestamps that a virtualized to that thread.
Definition at line 41 of file Per_Task_Writer.hh.
|
The constructor.
Definition at line 28 of file Per_Task_Writer.cc. References BUFFER_SIZE, process_ID_t, and task_ID_t.
00030 { 00031 00032 // Construct the pathname of the directory for the given process. 00033 char process_directory_pathname[BUFFER_SIZE]; 00034 sprintf(process_directory_pathname, 00035 "%s/%d", 00036 output_directory_pathname, 00037 process_ID); 00038 00039 // Attempt to make the directory. 00040 int mkdir_result = mkdir(process_directory_pathname, 00041 S_IRUSR | S_IWUSR | S_IXUSR); 00042 if (mkdir_result == -1) { 00043 00044 // The directory was not successfully created. If it already 00045 // exists, then we can ignore the error. 00046 if (errno != EEXIST) { 00047 fprintf(stderr, "Per_Task_Writer::Per_Task_Writer(): "); 00048 fprintf(stderr, "Failed creation of process directory\n"); 00049 exit(1); 00050 } 00051 00052 } 00053 00054 // Construct the output pathname for later use and nullify the output 00055 // stream. (The output file is opened only when the first record is 00056 // added to the filter.) 00057 sprintf(output_pathname, 00058 "%s/%hd.gz", 00059 process_directory_pathname, 00060 task_ID); 00061 output_stream = NULL; 00062 00063 // Initialize the ``last record'' values to zero, which is the 00064 // assumed starting point for difference encoding purposes. 00065 previous_cycle_time = 0; 00066 previous_instruction_time = 0; 00067 previous_reference_time = 0; 00068 previous_context_ID = 0; 00069 previous_virtual_page_ID = 0; 00070 previous_canonical_page_ID = 0; 00071 00072 } // Per_Task_Writer::Per_Task_Writer |
|
The destructor. Flush and close the output file. Definition at line 78 of file Per_Task_Writer.cc. References output_stream.
00078 { 00079 00080 // There is only work to do if the output stream was opened. 00081 if (output_stream != NULL) { 00082 00083 // Close the output stream, ensuring that is succeeded. 00084 int result = gzclose(output_stream); 00085 if (result != Z_OK) { 00086 fprintf(stderr, "Per_Task_Writer::~Per_Task_Writer(): "); 00087 fprintf(stderr, "Close failure\n"); 00088 exit(1); 00089 } 00090 00091 } 00092 00093 } // Per_Task_Writer::~Per_Task_Writer |
|
Emit the next kernel record.
Definition at line 204 of file Per_Task_Writer.cc. References TAG_ACCEPT, TAG_FILE_CLOSE, TAG_FILE_OPEN, TAG_FILE_READ, TAG_FILE_WRITE, and timestamp_t.
00207 { 00208 00209 // If the output stream is not yet open, then open it. 00210 if (output_stream == NULL) { 00211 open_output(); 00212 } 00213 00214 // Calculate the differences for each timestamp (always positive). 00215 timestamp_t cycle_timestamp_difference = 00216 virtual_cycle_time - previous_cycle_time; 00217 timestamp_t instruction_timestamp_difference = 00218 virtual_instruction_time - previous_instruction_time; 00219 timestamp_t reference_timestamp_difference = 00220 virtual_reference_time - previous_reference_time; 00221 00222 // Store the current timestamps for later. 00223 previous_cycle_time = virtual_cycle_time; 00224 previous_instruction_time = virtual_instruction_time; 00225 previous_reference_time = virtual_reference_time; 00226 00227 // Determine how to emit this record based on its type. 00228 int result = 0; 00229 switch(kernel_record->tag) { 00230 00231 case TAG_FILE_OPEN: 00232 00233 result = gzprintf(output_stream, 00234 "%c %qx %qx %qx %lx %hd %hd %s\n", 00235 kernel_record->tag, 00236 cycle_timestamp_difference, 00237 instruction_timestamp_difference, 00238 reference_timestamp_difference, 00239 kernel_record->file_ID.inode_ID, 00240 kernel_record->file_ID.major, 00241 kernel_record->file_ID.minor, 00242 kernel_record->filename); 00243 break; 00244 00245 case TAG_FILE_CLOSE: 00246 00247 result = gzprintf(output_stream, 00248 "%c %qx %qx %qx %lx %hd %hd\n", 00249 kernel_record->tag, 00250 cycle_timestamp_difference, 00251 instruction_timestamp_difference, 00252 reference_timestamp_difference, 00253 kernel_record->file_ID.inode_ID, 00254 kernel_record->file_ID.major, 00255 kernel_record->file_ID.minor); 00256 break; 00257 00258 case TAG_FILE_READ: 00259 case TAG_FILE_WRITE: 00260 00261 result = gzprintf(output_stream, 00262 "%c %qx %qx %qx %lx %hd %hd %lx %lx\n", 00263 kernel_record->tag, 00264 cycle_timestamp_difference, 00265 instruction_timestamp_difference, 00266 reference_timestamp_difference, 00267 kernel_record->file_ID.inode_ID, 00268 kernel_record->file_ID.major, 00269 kernel_record->file_ID.minor, 00270 kernel_record->file_starting_page, 00271 kernel_record->file_ending_page); 00272 break; 00273 00274 case TAG_ACCEPT: 00275 00276 result = gzprintf(output_stream, 00277 "%c %qx %qx %qx\n", 00278 kernel_record->tag, 00279 cycle_timestamp_difference, 00280 instruction_timestamp_difference, 00281 reference_timestamp_difference); 00282 break; 00283 00284 default: 00285 00286 fprintf(stderr, "Per_Task_Writer::append_kernel_record(): "); 00287 fprintf(stderr, 00288 "Invalid tag %c(%hd) for output\n", 00289 kernel_record->tag, 00290 (unsigned short int)kernel_record->tag); 00291 exit(1); 00292 00293 } 00294 00295 // Ensure that the print succeeded. 00296 if (result <= 0) { 00297 fprintf(stderr, "Per_Task_Writer::append_kernel_record(): "); 00298 fprintf(stderr, "Print failed\n"); 00299 exit(1); 00300 } 00301 00302 } // Per_Task_Writer::append_kernel_record |
|
Emit the next reference record.
Definition at line 101 of file Per_Task_Writer.cc. References canonical_page_ID_t, context_ID_t, timestamp_t, and virtual_page_ID_t.
00105 { 00106 00107 // If the output stream is not yet open, then open it. 00108 if (output_stream == NULL) { 00109 open_output(); 00110 } 00111 00112 // Calculate the differences for each timestamp (always positive). 00113 timestamp_t cycle_timestamp_difference = 00114 virtual_cycle_time - previous_cycle_time; 00115 timestamp_t instruction_timestamp_difference = 00116 virtual_instruction_time - previous_instruction_time; 00117 timestamp_t reference_timestamp_difference = 00118 virtual_reference_time - previous_reference_time; 00119 00120 // Store the current timestamps for later. 00121 previous_cycle_time = virtual_cycle_time; 00122 previous_instruction_time = virtual_instruction_time; 00123 previous_reference_time = virtual_reference_time; 00124 00125 // Calculate the context ID to emit. If it is the same as the 00126 // previous context ID, emit zero; otherwise, emit the new context 00127 // ID. 00128 context_ID_t context_ID_output = 0; 00129 if (reference_record->virtual_page.context_ID != 00130 previous_context_ID) { 00131 context_ID_output = reference_record->virtual_page.context_ID; 00132 previous_context_ID = reference_record->virtual_page.context_ID; 00133 } 00134 00135 // Calculate the virtual page ID difference. It can be positive or 00136 // negative, so we must determine both sign and magnitude. 00137 char virtual_page_ID_difference_sign; 00138 virtual_page_ID_t virtual_page_ID_difference_magnitude; 00139 if (reference_record->virtual_page.page_ID < 00140 previous_virtual_page_ID) { 00141 00142 virtual_page_ID_difference_sign = '-'; 00143 virtual_page_ID_difference_magnitude = 00144 previous_virtual_page_ID - 00145 reference_record->virtual_page.page_ID; 00146 00147 } else { 00148 00149 virtual_page_ID_difference_sign = '+'; 00150 virtual_page_ID_difference_magnitude = 00151 reference_record->virtual_page.page_ID - 00152 previous_virtual_page_ID; 00153 00154 } 00155 previous_virtual_page_ID = reference_record->virtual_page.page_ID; 00156 00157 // Calculate the canonical page ID difference. It can be positive 00158 // or negative, so we must determine both sign and magnitude. 00159 char canonical_page_ID_difference_sign; 00160 canonical_page_ID_t canonical_page_ID_difference_magnitude; 00161 if (canonical_page_ID < previous_canonical_page_ID) { 00162 00163 canonical_page_ID_difference_sign = '-'; 00164 canonical_page_ID_difference_magnitude = 00165 previous_canonical_page_ID - canonical_page_ID; 00166 00167 } else { 00168 00169 canonical_page_ID_difference_sign = '+'; 00170 canonical_page_ID_difference_magnitude = 00171 canonical_page_ID - previous_canonical_page_ID; 00172 00173 } 00174 previous_canonical_page_ID = canonical_page_ID; 00175 00176 // Print the difference encoded values to the compressed stream. 00177 int result = gzprintf(output_stream, 00178 "%c %qx %qx %qx %lx %c %lx %c %lx\n", 00179 reference_record->tag, 00180 cycle_timestamp_difference, 00181 instruction_timestamp_difference, 00182 reference_timestamp_difference, 00183 context_ID_output, 00184 virtual_page_ID_difference_sign, 00185 virtual_page_ID_difference_magnitude, 00186 canonical_page_ID_difference_sign, 00187 canonical_page_ID_difference_magnitude); 00188 00189 // Ensure that the print succeeded. 00190 if (result <= 0) { 00191 fprintf(stderr, "Per_Task_Writer::append_reference_record(): "); 00192 fprintf(stderr, "Print failed\n"); 00193 exit(1); 00194 } 00195 00196 } // Per_Task_Writer::append_reference_record |
|
Open the compressed output file. Open the output file, this providing a compressed stream to which records can be written. Note that this method should be called only once, upon the first addition of a record to the output stream. Definition at line 309 of file Per_Task_Writer.cc. References output_stream.
00309 { 00310 00311 // It is an error to open an already open output stream. 00312 if (output_stream != NULL) { 00313 fprintf(stderr, "Per_Task_Writer::open_output(): "); 00314 fprintf(stderr, "Stream already open\n"); 00315 exit(1); 00316 } 00317 00318 // Attempt to open the output file. 00319 int fd = open(output_pathname, 00320 O_WRONLY | O_CREAT | O_EXCL, 00321 S_IRUSR | S_IWUSR); 00322 00323 // Ensure that it did open. 00324 if (fd == -1) { 00325 perror("SAD_filter()::open_output(): Failed file open"); 00326 exit(1); 00327 } 00328 00329 // Link the file descriptor to a compressed output stream. Ask that 00330 // the stream be for (w)riting at the highest (9) compression level 00331 // accepting (f)iltered data. 00332 output_stream = gzdopen(fd, "w9f"); 00333 00334 // Ensure that the linking succeeded. 00335 if (output_stream == NULL) { 00336 fprintf(stderr, "Per_Task_Writer::open_output(): "); 00337 fprintf(stderr, "Failed compression open\n"); 00338 exit(1); 00339 } 00340 00341 } // Per_Task_Writer::open_output |
|
The pathname of the compressed output stream.
Definition at line 132 of file Per_Task_Writer.hh. |
|
The compressed output stream to which reduced records are written.
Definition at line 136 of file Per_Task_Writer.hh. Referenced by open_output(), and ~Per_Task_Writer(). |
|
The canonical page ID of the previously emitted record.
Definition at line 157 of file Per_Task_Writer.hh. |
|
The context ID of the previously emitted record.
Definition at line 150 of file Per_Task_Writer.hh. |
|
The cycle timestamp of the previously emitted record.
Definition at line 139 of file Per_Task_Writer.hh. |
|
The instruction timestamp of the previously emitted record.
Definition at line 143 of file Per_Task_Writer.hh. |
|
The reference timestamp of the previously emitted record.
Definition at line 147 of file Per_Task_Writer.hh. |
|
The virtual page ID of the previously emitted record.
Definition at line 153 of file Per_Task_Writer.hh. |