Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Per_Task_Page_Reduced_Reader.cc

Go to the documentation of this file.
00001 
00015 // ===================================================================
00016 // INCLUDES
00017 
00018 #include <stdio.h>
00019 #include "Per_Task_Page_Reduced_Reader.hh"
00020 // ===================================================================
00021 
00022 
00023 
00024 // ===================================================================
00025 Per_Task_Page_Reduced_Reader::Per_Task_Page_Reduced_Reader
00026 (const char* const reference_trace_directory_pathname,
00027  const unsigned int reduction_memory_size,
00028  const task_ID_t task_ID) {
00029 
00030   // Construct the pathname of the reference trace corresponding to
00031   // this task ID.
00032   char reference_trace_pathname[BUFFER_SIZE];
00033   sprintf(reference_trace_pathname,
00034     "%s/%hd.sad-%d.gz",
00035     reference_trace_directory_pathname,
00036     task_ID,
00037     reduction_memory_size);
00038 
00039   // Open this task's reference trace.
00040   input_stream = gzopen(reference_trace_pathname, "r");
00041   if (input_stream == NULL) {
00042     perror("Failed to open reference stream");
00043     exit(1);
00044   }
00045 
00046   // Read the first record, thus making the timestamp of the next
00047   // record available.
00048   read_record();
00049 
00050 } // Page_Reduced_Reader
00051 // ===================================================================
00052 
00053 
00054 
00055 // ===================================================================
00056 Per_Task_Page_Reduced_Reader::~Per_Task_Page_Reduced_Reader () {
00057 
00058   // Close the input stream, ensuring success.
00059   int close_result = gzclose(input_stream);
00060   if (close_result != Z_OK) {
00061     fprintf(stderr, "Per_Task_Page_Reduced_Reader::~Per_Task_Page_Reduced_Reader(): ");
00062     fprintf(stderr, "Failed close of trace file\n");
00063     exit(1);
00064   }
00065 
00066 } // ~Per_Task_Page_Reduced_Reader
00067 // ===================================================================
00068 
00069 
00070 
00071 // ===================================================================
00072 void
00073 Per_Task_Page_Reduced_Reader::get_record
00074 (reference_record_s* const reference_record) {
00075 
00076   // Copy the current record into the provided structure.
00077   *reference_record = this->reference_record;
00078 
00079   // Read the next record from the trace file.
00080   read_record();
00081 
00082 } // Per_Task_Page_Reduced_Reader::get_record
00083 // ===================================================================
00084 
00085 
00086 
00087 // ===================================================================
00088 bool
00089 Per_Task_Page_Reduced_Reader::at_end_of_trace () const {
00090 
00091   return (reference_record.tag == TAG_END_OF_TRACE);
00092 
00093 } // Per_Task_Page_Reduced_Reader::at_end_of_trace
00094 // ===================================================================
00095 
00096 
00097 
00098 // ===================================================================
00099 timestamp_t
00100 Per_Task_Page_Reduced_Reader::next_cycle_timestamp () const {
00101 
00102   return reference_record.cycle_timestamp;
00103 
00104 } // Per_Task_Page_Reduced_Reader::next_timestamp
00105 // ===================================================================
00106 
00107 
00108 
00109 // ===================================================================
00110 void
00111 Per_Task_Page_Reduced_Reader::read_record () {
00112 
00113   // Read the next record, ensuring success.
00114   char buffer[BUFFER_SIZE];
00115   char* read_result = gzgets(input_stream, buffer, BUFFER_SIZE);
00116   if (read_result == Z_NULL) {
00117     fprintf(stderr, "Per_Task_Page_Reduced_Reader::read_record(): ");
00118     fprintf(stderr, "Failed read\n");
00119     exit(1);
00120   }
00121 
00122   // Determine how to parse this record based on its type.  If it an
00123   // end-of-trace record, then there's nothing left to do.  Otherwise,
00124   // read the full entry.
00125   reference_record.tag = buffer[0];
00126   if (reference_record.tag != TAG_END_OF_TRACE) {
00127 
00128     // Attempt to parse the remainder of the record.
00129     timestamp_t cycle_timestamp_difference;
00130     timestamp_t instruction_timestamp_difference;
00131     timestamp_t reference_timestamp_difference;
00132     context_ID_t context_ID_input;
00133     char page_ID_difference_sign;
00134     virtual_page_ID_t page_ID_difference_magnitude;
00135     int items_to_parse = 6;
00136     int read_result = sscanf(&buffer[2],
00137            "%qx %qx %qx %lx %c %lx",
00138            &cycle_timestamp_difference,
00139            &instruction_timestamp_difference,
00140            &reference_timestamp_difference,
00141            &context_ID_input,
00142            &page_ID_difference_sign,
00143            &page_ID_difference_magnitude);
00144 
00145     // Ensure that the parse succeeded.
00146     if (read_result != items_to_parse) {
00147       fprintf(stderr, "Per_Task_Page_Reduced_Reader::read_record(): ");
00148       fprintf(stderr, "Failed parse\n");
00149       exit(1);
00150     }
00151 
00152     // Calculate the absolute timestamp values.
00153     reference_record.cycle_timestamp =
00154       previous_cycle_timestamp + cycle_timestamp_difference;
00155     reference_record.instruction_timestamp =
00156       previous_instruction_timestamp + instruction_timestamp_difference;
00157     reference_record.reference_timestamp =
00158       previous_reference_timestamp + reference_timestamp_difference;
00159 
00160     // Update the previous timestamps for later.
00161     previous_cycle_timestamp = reference_record.cycle_timestamp;
00162     previous_instruction_timestamp =
00163       reference_record.instruction_timestamp;
00164     previous_reference_timestamp = reference_record.reference_timestamp;
00165 
00166     // If the record indicated a context ID of 0, then it implies that
00167     // the context ID is the same as the last record; otherwise, it is
00168     // a new context ID, different from the last record's.
00169     if (context_ID_input == 0) {
00170       reference_record.virtual_page.context_ID = previous_context_ID;
00171     } else {
00172       reference_record.virtual_page.context_ID = context_ID_input;
00173       previous_context_ID = context_ID_input;
00174     }
00175 
00176     // Calculate the absolute page ID based on the difference from the
00177     // previous record.
00178     switch (page_ID_difference_sign) {
00179 
00180     case '+':
00181       reference_record.virtual_page.page_ID =
00182   previous_page_ID + page_ID_difference_magnitude;
00183       break;
00184 
00185     case '-':
00186       reference_record.virtual_page.page_ID =
00187   previous_page_ID - page_ID_difference_magnitude;
00188       break;
00189 
00190     default:
00191       fprintf(stderr, "Per_Task_Page_Reduced_Reader::read_record(): ");
00192       fprintf(stderr,
00193         "Invalid difference sign %c(%d)\n",
00194         page_ID_difference_sign,
00195         (unsigned int)page_ID_difference_sign);
00196       exit(1);
00197 
00198     }
00199     previous_page_ID = reference_record.virtual_page.page_ID;
00200 
00201     // Set the length of the reference to 0, as this value is
00202     // meaningless in this context.
00203     reference_record.length = 0;
00204 
00205     // Set the virtual address referenced to the first byte of the
00206     // indicated page.
00207     reference_record.virtual_address =
00208       reference_record.virtual_page.page_ID << PAGE_SIZE_ORDER;
00209 
00210   }
00211 
00212 } // Per_Task_Page_Reduced_Reader::read_record
00213 // ===================================================================

Generated on Fri Jan 31 10:33:35 2003 for Laplace-merge by doxygen1.3-rc2