00001
00017
00018
00019
00020 #include <math.h>
00021 #include <stdio.h>
00022 #include <stdlib.h>
00023 #include "Instruction_Reduced_Reader.hh"
00024 #include "types-and-constants.hh"
00025
00026
00027
00028
00029
00030 Instruction_Reduced_Reader::Instruction_Reduced_Reader
00031 (const char* const reference_trace_pathname) :
00032 Reference_Reader(reference_trace_pathname) {
00033
00034
00035 instruction_time = 0;
00036 reference_time = 0;
00037
00038
00039
00040 previous_cycle_timestamp = 0;
00041 previous_context_ID = 0;
00042
00043
00044
00045
00046
00047 const unsigned int bits_per_byte = 8;
00048 const unsigned int number_possible_tags =
00049 (unsigned int)pow(2.0, (double)(sizeof(tag_t) * bits_per_byte));
00050 previous_address_table = new virtual_address_t[number_possible_tags];
00051 if (previous_address_table == 0) {
00052 fprintf(stderr,
00053 "Instruction_Reduced_Reader(): Failed address table allocation\n");
00054 exit(1);
00055 }
00056 for (unsigned int i = 0; i < number_possible_tags; i++) {
00057 previous_address_table[i] = 0;
00058 }
00059
00060 }
00061
00062
00063
00064
00065
00066 Instruction_Reduced_Reader::~Instruction_Reduced_Reader () {
00067
00068
00069 delete previous_address_table;
00070 previous_address_table = 0;
00071
00072 }
00073
00074
00075
00076
00077
00078 void
00079 Instruction_Reduced_Reader::read
00080 (reference_record_s* const reference_record) {
00081
00082
00083 char* read_result = fgets(buffer, BUFFER_SIZE, reference_stream);
00084
00085
00086 if (read_result == NULL) {
00087
00088
00089
00090 if (feof(reference_stream)) {
00091 fprintf(stderr,
00092 "Instruction_Reduced_Reader::read(): Premature EOF\n");
00093 } else {
00094 fprintf(stderr,
00095 "Instruction_Reduced_Reader::read(): Read error\n");
00096 }
00097 exit(1);
00098 }
00099
00100
00101
00102 reference_record->tag = buffer[0];
00103
00104
00105
00106
00107 unsigned int parse_result = 0;
00108 unsigned int items_to_parse = 0;
00109 timestamp_t timestamp_difference;
00110 context_ID_t context_ID;
00111 char address_difference_sign;
00112 virtual_address_t address_difference_magnitude;
00113 timestamp_t current_instruction_time = instruction_time;
00114 timestamp_t current_reference_time = reference_time;
00115 switch (reference_record->tag) {
00116
00117 case TAG_USER_INSTRUCTION_FETCH:
00118 case TAG_KERNEL_INSTRUCTION_FETCH:
00119
00120
00121
00122 instruction_time++;
00123
00124
00125
00126 case TAG_USER_READ:
00127 case TAG_KERNEL_READ:
00128 case TAG_USER_WRITE:
00129 case TAG_KERNEL_WRITE:
00130
00131
00132
00133 reference_time++;
00134
00135
00136 items_to_parse = 5;
00137 parse_result = sscanf(&buffer[2],
00138 "%qx %hx %lx %c %lx",
00139 ×tamp_difference,
00140 &reference_record->length,
00141 &context_ID,
00142 &address_difference_sign,
00143 &address_difference_magnitude);
00144
00145
00146
00147 reference_record->instruction_timestamp = current_instruction_time;
00148 reference_record->reference_timestamp = current_reference_time;
00149
00150
00151
00152 previous_cycle_timestamp += timestamp_difference;
00153 reference_record->cycle_timestamp = previous_cycle_timestamp;
00154
00155
00156
00157
00158 if (context_ID == 0) {
00159 reference_record->virtual_page.context_ID = previous_context_ID;
00160 } else {
00161 previous_context_ID = context_ID;
00162 reference_record->virtual_page.context_ID = context_ID;
00163 }
00164
00165
00166
00167
00168 if (address_difference_sign == '+') {
00169
00170 previous_address_table[reference_record->tag] +=
00171 address_difference_magnitude;
00172
00173 } else if (address_difference_sign == '-') {
00174
00175 previous_address_table[reference_record->tag] -=
00176 address_difference_magnitude;
00177
00178 } else {
00179
00180 fprintf(stderr, "Instruction_Reduced_Reader::read(): ");
00181 fprintf(stderr,
00182 "Unknown tag %c(%d) at reference time = %qx\n",
00183 address_difference_sign,
00184 (int)address_difference_sign,
00185 current_reference_time);
00186 exit(1);
00187
00188 }
00189 reference_record->virtual_address =
00190 previous_address_table[reference_record->tag];
00191
00192
00193
00194 reference_record->virtual_page.page_ID =
00195 reference_record->virtual_address >> PAGE_SIZE_ORDER;
00196
00197 break;
00198
00199 case TAG_KERNEL_EVENT:
00200
00201
00202
00203 items_to_parse = 1;
00204 parse_result = sscanf(&buffer[2],
00205 "%qx",
00206 ×tamp_difference);
00207
00208
00209
00210 previous_cycle_timestamp += timestamp_difference;
00211 reference_record->cycle_timestamp = previous_cycle_timestamp;
00212
00213
00214 reference_record->instruction_timestamp = current_instruction_time;
00215 reference_record->reference_timestamp = current_reference_time;
00216 reference_record->length = 0;
00217 reference_record->virtual_page.context_ID = 0;
00218 reference_record->virtual_page.page_ID = 0;
00219 reference_record->virtual_address = 0;
00220 break;
00221
00222 case TAG_END_OF_TRACE:
00223
00224
00225 break;
00226
00227 default:
00228 fprintf(stderr, "Instruction_Reduced_Reader::read(): ");
00229 fprintf(stderr,
00230 "Invalid reference tag %c(%d)\n",
00231 reference_record->tag,
00232 (int)reference_record->tag);
00233 exit(1);
00234
00235 }
00236
00237
00238 if (parse_result != items_to_parse) {
00239 fprintf(stderr, "Instruction_Reduced_Reader::read(): ");
00240 fprintf(stderr, "Could not parse remainder\n");
00241 fprintf(stderr,
00242 "cycle_timestamp = %qx\n",
00243 reference_record->cycle_timestamp);
00244 fprintf(stderr,
00245 "instruction_timestamp = %qx\n",
00246 reference_record->instruction_timestamp);
00247 fprintf(stderr,
00248 "reference_timestamp = %qx\n",
00249 reference_record->reference_timestamp);
00250 exit(1);
00251 }
00252
00253 }
00254