00001 00015 // =================================================================== 00016 // INCLUDES 00017 00018 #include <assert.h> 00019 #include <stdio.h> 00020 #include <stdlib.h> 00021 #include "Binary_Raw_Reader.hh" 00022 #include "types-and-constants.hh" 00023 // =================================================================== 00024 00025 00026 00027 // =================================================================== 00028 // TYPES 00029 // Definitions of types for each field in the raw reference trace. 00030 // This is adapted from tracer.cc in Laplace itself. 00031 00035 struct binary_record_s { 00036 00037 tag_t tag; 00038 timestamp_t timestamp; 00039 unsigned char length; 00040 context_ID_t context_ID; 00041 virtual_address_t virtual_address; 00042 00043 }; 00044 // =================================================================== 00045 00046 00047 00048 // =================================================================== 00049 Binary_Raw_Reader::Binary_Raw_Reader 00050 (const char* const reference_trace_pathname) : 00051 Reference_Reader(reference_trace_pathname) { 00052 00053 // Reset the clocks to zero. 00054 instruction_time = 0; 00055 reference_time = 0; 00056 00057 } // Binary_Raw_Reader 00058 // =================================================================== 00059 00060 00061 00062 // =================================================================== 00063 void 00064 Binary_Raw_Reader::read (reference_record_s* const reference_record) { 00065 00066 // Attempt to read the next record of the reference trace. 00067 binary_record_s binary_record; 00068 size_t read_result = fread(&binary_record, 00069 sizeof(binary_record), 00070 1, 00071 reference_stream); 00072 00073 // Did the read fail? 00074 if (read_result != 1) { 00075 00076 // Distinguish between an EOF and other errors, but abort 00077 // processing in either case. 00078 if (feof(reference_stream)) { 00079 fprintf(stderr, 00080 "Binary_Raw_Reader::read(): Premature EOF\n"); 00081 } else { 00082 fprintf(stderr, 00083 "Binary_Raw_Reader::read(): Read error\n"); 00084 } 00085 exit(1); 00086 } 00087 00088 // Based on the type of reference, update some data and determine 00089 // what result to return. 00090 timestamp_t current_instruction_time = instruction_time; 00091 timestamp_t current_reference_time = reference_time; 00092 switch (binary_record.tag) { 00093 00094 case TAG_USER_INSTRUCTION_FETCH: 00095 case TAG_KERNEL_INSTRUCTION_FETCH: 00096 00097 // Tick the instruction clock to reflect that _after_ this event, 00098 // instruction time will have advanced. 00099 instruction_time++; 00100 00101 // Fall through to read and parse the rest of the record... 00102 00103 case TAG_USER_READ: 00104 case TAG_KERNEL_READ: 00105 case TAG_USER_WRITE: 00106 case TAG_KERNEL_WRITE: 00107 00108 // Tick the reference clock to reflect that _after_ this event, 00109 // reference time will have advanced. 00110 reference_time++; 00111 00112 // Copy elements of the record into the given structure that 00113 // require no processing. 00114 reference_record->tag = binary_record.tag; 00115 reference_record->cycle_timestamp = binary_record.timestamp; 00116 reference_record->length = binary_record.length; 00117 reference_record->virtual_page.context_ID = 00118 binary_record.context_ID; 00119 reference_record->virtual_address = binary_record.virtual_address; 00120 00121 // Place the current instruction and reference times into the 00122 // structure. 00123 reference_record->instruction_timestamp = current_instruction_time; 00124 reference_record->reference_timestamp = current_reference_time; 00125 00126 // Comput the page ID by isolating the upper bits of the virtual 00127 // address and recording that value in the structure. 00128 reference_record->virtual_page.page_ID = 00129 binary_record.virtual_address >> PAGE_SIZE_ORDER; 00130 00131 break; 00132 00133 case TAG_KERNEL_EVENT: 00134 00135 // Read the remainder of the record. We care only about the 00136 // timestamp. 00137 reference_record->tag = binary_record.tag; 00138 reference_record->cycle_timestamp = binary_record.timestamp; 00139 reference_record->instruction_timestamp = current_instruction_time; 00140 reference_record->reference_timestamp = current_reference_time; 00141 reference_record->length = 0; 00142 reference_record->virtual_page.context_ID = 0; 00143 reference_record->virtual_page.page_ID = 0; 00144 reference_record->virtual_address = 0; 00145 break; 00146 00147 case TAG_END_OF_TRACE: 00148 00149 // Nothing to do. 00150 break; 00151 00152 default: 00153 fprintf(stderr, 00154 "Binary_Raw_Reader::read(): Invalid reference tag %c(%d)\n", 00155 reference_record->tag, 00156 (int)reference_record->tag); 00157 exit(1); 00158 00159 } 00160 00161 } // read 00162 // ===================================================================