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

Page_Reduced_Reader.cc

Go to the documentation of this file.
00001 
00016 // ===================================================================
00017 // INCLUDES
00018 
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include "Page_Reduced_Reader.hh"
00022 #include "types-and-constants.hh"
00023 // ===================================================================
00024 
00025 
00026 
00027 // ===================================================================
00028 // CONSTANTS
00029 
00031 #define TASK_ID_LIST_FILENAME "task-ID-list"
00032 
00034 #define REDUCTION_MEMORY_SIZE_FILENAME "SAD-reduction-memory-size"
00035 // ===================================================================
00036 
00037 
00038 
00039 // ===================================================================
00040 // Don't use the superclass constructor, as it's not relevant here.
00041 Page_Reduced_Reader::Page_Reduced_Reader
00042 (const char* const reference_trace_directory_pathname) {
00043 
00044   // Ensure that the inhereted single reference stream is nullified.
00045   reference_stream = NULL;
00046 
00047   // Construct the pathnames for the reduction memory size file and
00048   // the task ID list file.
00049   char reduction_memory_size_pathname[BUFFER_SIZE];
00050   sprintf(reduction_memory_size_pathname,
00051     "%s/%s",
00052     reference_trace_directory_pathname,
00053     REDUCTION_MEMORY_SIZE_FILENAME);
00054   char task_ID_list_pathname[BUFFER_SIZE];
00055   sprintf(task_ID_list_pathname,
00056     "%s/%s",
00057     reference_trace_directory_pathname,
00058     TASK_ID_LIST_FILENAME);
00059 
00060   // Attempt to open these two files, checking that they opened
00061   // successfully.
00062   FILE* const reduction_memory_size_stream =
00063     fopen(reduction_memory_size_pathname, "r");
00064   if (reduction_memory_size_stream == NULL) {
00065     perror("Failed to open reduction memory size file");
00066     exit(1);
00067   }
00068   FILE* const task_ID_list_stream = fopen(task_ID_list_pathname, "r");
00069   if (task_ID_list_stream == NULL) {
00070     perror("Failed to open task ID list file");
00071     exit(1);
00072   }
00073 
00074   // Read the reduction memory size, ensuring success.
00075   unsigned int reduction_memory_size;
00076   int read_result = fscanf(reduction_memory_size_stream,
00077          "%d",
00078          &reduction_memory_size);
00079   if (read_result != 1) {
00080     fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): ");
00081     fprintf(stderr, "Failed to read reduction memory size\n");
00082     exit(1);
00083   }
00084 
00085   // Close the reduction memory size file.
00086   int close_result = fclose(reduction_memory_size_stream);
00087   if (close_result == EOF) {
00088     perror("Failed to close reduction memory size file");
00089     exit(1);
00090   }
00091 
00092   // Loop through entries in the task ID list, each time opening the
00093   // corresponding reference trace file and placing an entry in the
00094   // table that maps task IDs to reference trace streams.
00095   bool done = false;
00096   do {
00097 
00098     // Attempt to read the next entry in the task ID list.
00099     task_ID_t task_ID;
00100     int read_result = fscanf(task_ID_list_stream,
00101            "%hd\n",
00102            &task_ID);
00103 
00104     // Check the result of the read?
00105     if (read_result == 0) {
00106 
00107       // Failure to parse.
00108       fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): ");
00109       fprintf(stderr, "Failed parse of task ID\n");
00110       exit(1);
00111 
00112     } else if (read_result == EOF) {
00113 
00114       // An I/O error.  If it's an EOF, that's normal; other kinds of
00115       // errors are not.
00116       if (feof(task_ID_list_stream)) {
00117   done = true;
00118       } else {
00119   fprintf(stderr, "Page_Reduced_Reader::Page_Reduced_Reader(): ");
00120   fprintf(stderr, "Failed read of task ID list file\n");
00121   exit(1);
00122       }
00123 
00124     } else {
00125 
00126       // The read succeeded.  Create a per-task reader for this task
00127       // ID.
00128       Per_Task_Page_Reduced_Reader* per_task_reader =
00129   new Per_Task_Page_Reduced_Reader(reference_trace_directory_pathname,
00130            reduction_memory_size,
00131            task_ID);
00132 
00133       // Add a list entry to associate this task ID with its reader.
00134       task_reader_pair_t* task_reader_pair =
00135   new task_reader_pair_t(task_ID, per_task_reader);
00136       task_reader_pair_queue.push(task_reader_pair);
00137 
00138     }
00139 
00140   } while (!done);
00141 
00142   // Close the task ID list file.
00143   close_result = fclose(task_ID_list_stream);
00144   if (close_result == EOF) {
00145     perror("Failed to close task ID list file");
00146     exit(1);
00147   }
00148 
00149 } // Page_Reduced_Reader
00150 // ===================================================================
00151 
00152 
00153 
00154 // ===================================================================
00155 Page_Reduced_Reader::~Page_Reduced_Reader () {
00156 
00157   // Sanity check:  It should be the case that all of the reference
00158   // traces have been completed consumed, and thus all per-task
00159   // readers should have been eliminated.
00160   if (!task_reader_pair_queue.empty()) {
00161     fprintf(stderr, "Page_Reduced_Reader::~Page_Reduced_Reader(): ");
00162     fprintf(stderr, "Per-task readers remaining\n");
00163     exit(1);
00164   }
00165 
00166 } // ~Page_Reduced_Reader
00167 // ===================================================================
00168 
00169 
00170 
00171 // ===================================================================
00172 void
00173 Page_Reduced_Reader::read
00174 (reference_record_s* const reference_record) {
00175 
00176   // Are there any open traces with records still to read?
00177   if (task_reader_pair_queue.empty()) {
00178 
00179     // There are no more records to read from any trace.  Return an
00180     // end-of-trace record and a value that indicates that no
00181     // reference records were available.
00182     reference_record->tag = TAG_END_OF_TRACE;
00183 
00184   } else {
00185 
00186     // There is at least one more record in some task's trace to read.
00187     // Grab the task/reader pair at the top of the queue (and thus the
00188     // one with the smallest timestamp).  Remove it from the queue.
00189     task_reader_pair_t* smallest_task_reader_pair =
00190       task_reader_pair_queue.top();
00191     Per_Task_Page_Reduced_Reader* per_task_reader =
00192       smallest_task_reader_pair->second;
00193     task_reader_pair_queue.pop();
00194 
00195     // Grab the record from this task's reader.
00196     per_task_reader->get_record(reference_record);
00197 
00198     // Have we reached the end of this trace?  (That is, does the next
00199     // record indicate an end-of-trace for this task?)
00200     if (per_task_reader->at_end_of_trace()) {
00201 
00202       // There are no more records in this trace.  Delete the per task
00203       // reader and the task/reader pair.
00204       delete per_task_reader;
00205       per_task_reader = 0;
00206       delete smallest_task_reader_pair;
00207       smallest_task_reader_pair = 0;
00208 
00209     } else {
00210 
00211       // There remain more records in this trace.  Re-insert the
00212       // task/reader pair into the priority queue.
00213       task_reader_pair_queue.push(smallest_task_reader_pair);
00214 
00215     }
00216   }
00217 
00218 } // read
00219 // ===================================================================

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