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

Per_Task_Writer Class Reference

A Per_Task_Writer emits references and kernel events for a single task. More...

#include <Per_Task_Writer.hh>

List of all members.

Public Methods

 Per_Task_Writer (const char *const output_directory_pathname, const process_ID_t process_ID, const task_ID_t task_ID)
 The constructor.

 ~Per_Task_Writer ()
 The destructor.

void append_reference_record (const reference_record_s *const reference_record, const canonical_page_ID_t canonical_page_ID, const timestamp_t virtual_cycle_time, const timestamp_t virtual_instruction_time, const timestamp_t virtual_reference_time)
 Emit the next reference record.

void append_kernel_record (const kernel_record_s *const kernel_record, const timestamp_t virtual_cycle_time, const timestamp_t virtual_instruction_time, const timestamp_t virtual_reference_time)
 Emit the next kernel record.


Protected Methods

void open_output ()
 Open the compressed output file.


Protected Attributes

char output_pathname [BUFFER_SIZE]
 The pathname of the compressed output stream.

gzFile output_stream
 The compressed output stream to which reduced records are written.

timestamp_t previous_cycle_time
 The cycle timestamp of the previously emitted record.

timestamp_t previous_instruction_time
 The instruction timestamp of the previously emitted record.

timestamp_t previous_reference_time
 The reference timestamp of the previously emitted record.

context_ID_t previous_context_ID
 The context ID of the previously emitted record.

virtual_page_ID_t previous_virtual_page_ID
 The virtual page ID of the previously emitted record.

canonical_page_ID_t previous_canonical_page_ID
 The canonical page ID of the previously emitted record.


Detailed Description

A Per_Task_Writer emits references and kernel events for a single task.

Accept a stream of reference and kernel events, and emit them to a file associated with a single task. Keep cycle, instruction, and reference clocks up-to-date for the one thread in isolation, thus emitting traces that provide timestamps that a virtualized to that thread.

Definition at line 41 of file Per_Task_Writer.hh.


Constructor & Destructor Documentation

Per_Task_Writer::Per_Task_Writer const char *const    output_directory_pathname,
const process_ID_t    process_ID,
const task_ID_t    task_ID
 

The constructor.

See also:
append_reference

append_kernel_event

Parameters:
output_directory_pathname The pathname for the base-level directory of output traces.
process_ID The ID of the process to which the owning task belongs.
task_ID The ID of the owning task itself.
Prepare a writer by constructing the pathname a new trace file within the directory of traces for the given process ID, naming the file according to its task ID. The file will not be opened until at least record (reference or kernel) is appended to the output stream. All reference and kernel records submitted to this object will be emitted into this file.

Definition at line 28 of file Per_Task_Writer.cc.

References BUFFER_SIZE, process_ID_t, and task_ID_t.

00030                           {
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

Per_Task_Writer::~Per_Task_Writer  
 

The destructor.

Flush and close the output file.

Definition at line 78 of file Per_Task_Writer.cc.

References output_stream.

00078                                    {
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


Member Function Documentation

void Per_Task_Writer::append_kernel_record const kernel_record_s *const    kernel_record,
const timestamp_t    virtual_cycle_time,
const timestamp_t    virtual_instruction_time,
const timestamp_t    virtual_reference_time
 

Emit the next kernel record.

Parameters:
kernel_record The record whose contents is to be emitted.
virtual_cycle_time The current virtual cycle time of the task performing the reference.
virtual_instruction_time The current virtual instruction time of the task performing the reference.
virtual_reference_time The current virtual reference time of the task performing the reference.
Emit this record into the output stream. If the output stream has not actually been opened (that is, this is the first record submitted to this stream), then open the output file.

Definition at line 204 of file Per_Task_Writer.cc.

References TAG_ACCEPT, TAG_FILE_CLOSE, TAG_FILE_OPEN, TAG_FILE_READ, TAG_FILE_WRITE, and timestamp_t.

00207                                            {
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

void Per_Task_Writer::append_reference_record const reference_record_s *const    reference_record,
const canonical_page_ID_t    canonical_page_ID,
const timestamp_t    virtual_cycle_time,
const timestamp_t    virtual_instruction_time,
const timestamp_t    virtual_reference_time
 

Emit the next reference record.

Parameters:
reference_record The record whose contents is to be emitted.
canonical_page_ID The canonical number of the page that is referenced.
virtual_cycle_time The current virtual cycle time of the task performing the reference.
virtual_instruction_time The current virtual instruction time of the task performing the reference.
virtual_reference_time The current virtual reference time of the task performing the reference.
Emit this record into the output stream. If the output stream has not actually been opened (that is, this is the first record submitted to this stream), then open the output file.

Definition at line 101 of file Per_Task_Writer.cc.

References canonical_page_ID_t, context_ID_t, timestamp_t, and virtual_page_ID_t.

00105                                            {
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

void Per_Task_Writer::open_output   [protected]
 

Open the compressed output file.

Open the output file, this providing a compressed stream to which records can be written. Note that this method should be called only once, upon the first addition of a record to the output stream.

Definition at line 309 of file Per_Task_Writer.cc.

References output_stream.

00309                               {
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


Member Data Documentation

char Per_Task_Writer::output_pathname[BUFFER_SIZE] [protected]
 

The pathname of the compressed output stream.

Definition at line 132 of file Per_Task_Writer.hh.

gzFile Per_Task_Writer::output_stream [protected]
 

The compressed output stream to which reduced records are written.

Definition at line 136 of file Per_Task_Writer.hh.

Referenced by open_output(), and ~Per_Task_Writer().

canonical_page_ID_t Per_Task_Writer::previous_canonical_page_ID [protected]
 

The canonical page ID of the previously emitted record.

Definition at line 157 of file Per_Task_Writer.hh.

context_ID_t Per_Task_Writer::previous_context_ID [protected]
 

The context ID of the previously emitted record.

Definition at line 150 of file Per_Task_Writer.hh.

timestamp_t Per_Task_Writer::previous_cycle_time [protected]
 

The cycle timestamp of the previously emitted record.

Definition at line 139 of file Per_Task_Writer.hh.

timestamp_t Per_Task_Writer::previous_instruction_time [protected]
 

The instruction timestamp of the previously emitted record.

Definition at line 143 of file Per_Task_Writer.hh.

timestamp_t Per_Task_Writer::previous_reference_time [protected]
 

The reference timestamp of the previously emitted record.

Definition at line 147 of file Per_Task_Writer.hh.

virtual_page_ID_t Per_Task_Writer::previous_virtual_page_ID [protected]
 

The virtual page ID of the previously emitted record.

Definition at line 153 of file Per_Task_Writer.hh.


The documentation for this class was generated from the following files:
Generated on Fri Jan 31 10:33:39 2003 for Laplace-merge by doxygen1.3-rc2