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

Per_Task_Writer.cc

Go to the documentation of this file.
00001 
00013 // ===================================================================
00014 // INCLUDES
00015 
00016 #include <errno.h>
00017 #include <fcntl.h>
00018 #include <stdio.h>
00019 #include <sys/stat.h>
00020 #include <sys/types.h>
00021 #include "Per_Task_Writer.hh"
00022 // ===================================================================
00023 
00024 
00025 
00026 // ===================================================================
00027 Per_Task_Writer::Per_Task_Writer
00028 (const char* const output_directory_pathname,
00029  const process_ID_t process_ID,
00030  const task_ID_t task_ID) {
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
00073 // ===================================================================
00074 
00075 
00076 
00077 // ===================================================================
00078 Per_Task_Writer::~Per_Task_Writer () {
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
00094 // ===================================================================
00095 
00096 
00097 
00098 // ===================================================================
00099 void
00100 Per_Task_Writer::append_reference_record
00101 (const reference_record_s* const reference_record,
00102  const canonical_page_ID_t canonical_page_ID,
00103  const timestamp_t virtual_cycle_time,
00104  const timestamp_t virtual_instruction_time,
00105  const timestamp_t virtual_reference_time) {
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
00197 // ===================================================================
00198 
00199 
00200 
00201 // ===================================================================
00202 void
00203 Per_Task_Writer::append_kernel_record
00204 (const kernel_record_s* const kernel_record,
00205  const timestamp_t virtual_cycle_time,
00206  const timestamp_t virtual_instruction_time,
00207  const timestamp_t virtual_reference_time) {
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
00303 // ===================================================================
00304 
00305 
00306 
00307 // ===================================================================
00308 void
00309 Per_Task_Writer::open_output () {
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
00342 // ===================================================================

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