00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "read_timing_common.H"
00023
00024 #include <Basics.H>
00025 #include <BasicsAllocator.H>
00026 #include <BufStream.H>
00027
00028 #include <unistd.h>
00029 #include <Atom.H>
00030
00031 #include <list>
00032
00033 using std::ostream;
00034 using std::ofstream;
00035 using std::cout;
00036 using std::cerr;
00037 using std::endl;
00038 using std::list;
00039 using Basics::OBufStream;
00040
00041 enum which_lock_t
00042 {
00043 stable,
00044 volatileRoot,
00045 userGroup
00046 };
00047
00048 void print_timeval(ostream &out, const struct timeval time)
00049 {
00050 time_t temp_secs = time.tv_sec;
00051 struct tm split_time;
00052 (void) localtime_r(&temp_secs, &split_time);
00053 char time_str_buf[512];
00054 strftime(time_str_buf, sizeof(time_str_buf),
00055 "%Y-%m-%d %H:%M:%S", &split_time);
00056
00057 out << time_str_buf << " +" << (((double) time.tv_usec) / 1000) << " ms";
00058 }
00059
00060 ostream &operator<<(ostream &out, const struct timeval time)
00061 {
00062 print_timeval(out, time);
00063 return out;
00064 }
00065
00066 struct Lock_Data
00067 {
00068 struct FileFormatError {};
00069 which_lock_t lock;
00070 struct timeval start_time;
00071 Delta_Time time_to_acquire;
00072 bool acquired;
00073 bool write;
00074 Delta_Time time_held;
00075 Delta_Time time_to_release;
00076 Atom *reason;
00077
00078 Lock_Data(which_lock_t lock)
00079 : lock(lock), reason(0)
00080 {
00081 }
00082
00083 void read_start_time(FILE *input) throw(FS::EndOfFile)
00084 {
00085
00086 unsigned int start_secs, start_usecs;
00087 size_t n_read =
00088 fread((void *) &start_secs, sizeof(unsigned int), 1, input);
00089 if(n_read < 1)
00090 {
00091 throw FS::EndOfFile();
00092 }
00093 assert(n_read == 1);
00094 n_read =
00095 fread((void *) &start_usecs, sizeof(unsigned int), 1, input);
00096 if(n_read < 1)
00097 {
00098 throw FS::EndOfFile();
00099 }
00100 assert(n_read == 1);
00101
00102 start_time.tv_sec = start_secs;
00103 start_time.tv_usec = start_usecs;
00104 }
00105
00106 void read_reason(FILE *input) throw(FS::EndOfFile)
00107 {
00108 char small_buf[1024];
00109 char *cur_buf = small_buf;
00110 unsigned int cur_buf_size = sizeof(small_buf);
00111 unsigned int buf_pos = 0;
00112 int next_char;
00113 while((next_char = getc(input)) != EOF)
00114 {
00115
00116 if(buf_pos >= cur_buf_size)
00117 {
00118 cur_buf_size *= 2;
00119 char * new_buf = NEW_PTRFREE_ARRAY(char, cur_buf_size);
00120 memcpy(new_buf, cur_buf, buf_pos);
00121 cur_buf = new_buf;
00122 }
00123 cur_buf[buf_pos++] = next_char;
00124 if(next_char == 0)
00125 break;
00126 }
00127
00128 reason = NEW_CONSTR(Atom, (cur_buf));
00129 }
00130
00131 bool read_record(FILE *input) throw(FS::EndOfFile, FileFormatError)
00132 {
00133 bool result = false;
00134 int record_byte = getc(input);
00135 switch(record_byte)
00136 {
00137 case 1:
00138
00139 write = false;
00140 read_start_time(input);
00141 break;
00142 case 2:
00143
00144 acquired = true;
00145 time_to_acquire.read(input);
00146 break;
00147 case 3:
00148
00149 acquired = false;
00150 result = true;
00151 time_to_acquire.read(input);
00152 break;
00153 case 4:
00154
00155 write = true;
00156 read_start_time(input);
00157 break;
00158 case 5:
00159
00160 acquired = true;
00161 time_to_acquire.read(input);
00162 break;
00163 case 6:
00164
00165 acquired = false;
00166 result = true;
00167 time_to_acquire.read(input);
00168 break;
00169 case 7:
00170
00171 time_held.read(input);
00172 break;
00173 case 8:
00174
00175 result = true;
00176 time_to_release.read(input);
00177 break;
00178 case 9:
00179
00180 read_reason(input);
00181 break;
00182 default:
00183
00184 throw FileFormatError();
00185 }
00186
00187 return result;
00188 }
00189
00190 void print_lock_info(ostream &out, const char *indent,
00191 const struct timeval *beginning = 0) const
00192 {
00193 out << indent;
00194 switch(lock)
00195 {
00196 case stable:
00197 out << "StableLock.";
00198 break;
00199 case volatileRoot:
00200 out << "VolatileRootLock.";
00201 break;
00202 case userGroup:
00203 out << "userGroup_lock.";
00204 break;
00205 }
00206 out << (acquired?"acquire":"try") << (write?"Write":"Read") << "():"
00207 << endl;
00208 if(beginning != 0)
00209 {
00210 if(start_time < *beginning)
00211 {
00212 Delta_Time start_delta = (*beginning - start_time);
00213 out << indent << " start: -" << start_delta.msecs()
00214 << " ms" << endl;
00215 }
00216 else
00217 {
00218 Delta_Time start_delta = (start_time - *beginning);
00219 out << indent << " start: " << start_delta.msecs()
00220 << " ms" << endl;
00221 }
00222 }
00223 else
00224 {
00225 out << indent << " start: " << start_time << endl;
00226 }
00227 out << indent << " acquire time: " << time_to_acquire.msecs() << " ms"
00228 << endl;
00229 if(acquired)
00230 {
00231 out
00232 << indent << " hold time: " << time_held.msecs() << " ms" << endl
00233 << indent << " release time: " << time_to_release.msecs() << " ms"
00234 << endl;
00235 }
00236 if(reason != 0)
00237 {
00238 out
00239 << indent << " reason: " << reason->cchars() << endl;
00240 }
00241 }
00242
00243 void plot_lock_info(unsigned int x_val,
00244 ostream &acquire_stream,
00245 ostream &hold_stream,
00246 ostream &release_stream,
00247 const struct timeval &beginning) const
00248 {
00249 double my_acquire_start;
00250 if(start_time < beginning)
00251 {
00252 Delta_Time start_delta = (beginning - start_time);
00253 my_acquire_start = -(start_delta.msecs());
00254 }
00255 else
00256 {
00257 Delta_Time start_delta = (start_time - beginning);
00258 my_acquire_start = start_delta.msecs();
00259 }
00260
00261 double my_acquire_delta = time_to_acquire.msecs();
00262 double my_hold_start = (my_acquire_start + my_acquire_delta);
00263 double my_hold_delta = time_held.msecs();
00264 double my_release_start = (my_hold_start + my_hold_delta);
00265 double my_release_delta = time_to_release.msecs();
00266
00267
00268
00269
00270
00271
00272
00273 acquire_stream << x_val << " "
00274 << (my_acquire_start + (my_acquire_delta/2)) << " "
00275 << my_acquire_start << " "
00276 << my_hold_start << endl;
00277
00278 if(acquired)
00279 {
00280 hold_stream << x_val << " "
00281 << (my_hold_start + (my_hold_delta/2)) << " "
00282 << my_hold_start << " "
00283 << my_release_start << endl;
00284
00285 release_stream << x_val << " "
00286 << (my_release_start + (my_release_delta/2)) << " "
00287 << my_release_start << " "
00288 << (my_release_start + my_release_delta) << endl;
00289 }
00290 }
00291
00292 bool operator<=(const Lock_Data & other) const
00293 {
00294
00295 if(this->start_time < other.start_time)
00296 {
00297 return true;
00298 }
00299
00300 if(this->start_time == other.start_time)
00301 {
00302 return (other.time_to_acquire >= this->time_to_acquire);
00303 }
00304
00305 return false;
00306 }
00307 };
00308
00309 typedef list<const Lock_Data *,
00310 Basics::Allocator<Lock_Data *> > Lock_Event_List;
00311
00312 void sorted_lock_insert(Lock_Event_List &lock_list,
00313 const Lock_Data *lock)
00314 {
00315 assert(lock != 0);
00316
00317 for(Lock_Event_List::iterator it = lock_list.begin();
00318 it != lock_list.end();
00319 it++)
00320 {
00321
00322 if(*lock <= *(*it))
00323 {
00324 lock_list.insert(it, lock);
00325 return;
00326 }
00327 }
00328
00329
00330 lock_list.push_back(lock);
00331 }
00332
00333
00334
00335
00336
00337
00338 struct Time_Ranges
00339 {
00340 struct time_range
00341 {
00342 struct timeval start_time, end_time;
00343 time_range()
00344 {
00345 start_time.tv_sec = 0;
00346 start_time.tv_usec = 0;
00347 end_time.tv_sec = 0;
00348 end_time.tv_usec = 0;
00349 }
00350 time_range(const struct timeval &start, const Delta_Time &delta)
00351 : start_time(start), end_time(start + delta)
00352 {
00353 }
00354 time_range(const struct time_range &other)
00355 {
00356 start_time.tv_sec = other.start_time.tv_sec;
00357 start_time.tv_usec = other.start_time.tv_usec;
00358 end_time.tv_sec = other.end_time.tv_sec;
00359 end_time.tv_usec = other.end_time.tv_usec;
00360 }
00361
00362 inline bool overlaps_end_of(const struct time_range &other) const throw()
00363 {
00364 return ((this->start_time <= other.end_time) &&
00365 (other.end_time <= this->end_time));
00366 }
00367
00368 inline bool overlaps_start_of(const struct time_range &other) const throw()
00369 {
00370 return ((this->start_time <= other.start_time) &&
00371 (other.start_time <= this->end_time));
00372 }
00373
00374 inline bool contains(const struct time_range &other) const throw()
00375 {
00376 return overlaps_end_of(other) && overlaps_start_of(other);
00377 }
00378
00379 inline bool contained_by(const struct time_range &other) const throw()
00380 {
00381 return other.contains(*this);
00382 }
00383
00384 time_range &operator=(const struct time_range &other)
00385 {
00386 start_time.tv_sec = other.start_time.tv_sec;
00387 start_time.tv_usec = other.start_time.tv_usec;
00388 end_time.tv_sec = other.end_time.tv_sec;
00389 end_time.tv_usec = other.end_time.tv_usec;
00390
00391 return *this;
00392 }
00393
00394 struct time_range merge(const struct time_range &other)
00395 {
00396 struct time_range result;
00397
00398
00399 assert(this->overlaps_end_of(other) ||
00400 this->overlaps_start_of(other) ||
00401 other.overlaps_end_of(*this) ||
00402 other.overlaps_start_of(*this));
00403
00404 if(other.start_time < this->start_time)
00405 {
00406 result.start_time = other.start_time;
00407 }
00408 else
00409 {
00410 result.start_time = this->start_time;
00411 }
00412
00413 if(other.end_time < this->end_time)
00414 {
00415 result.end_time = this->end_time;
00416 }
00417 else
00418 {
00419 result.end_time = other.end_time;
00420 }
00421
00422 return result;
00423 }
00424 };
00425
00426 typedef list<time_range> time_range_list;
00427 time_range_list ranges;
00428
00429
00430 void add_range(const struct timeval &start, const Delta_Time &delta)
00431 {
00432 time_range new_range(start, delta);
00433
00434 bool added = false;
00435
00436 for(time_range_list::iterator it = ranges.begin();
00437 !added && (it != ranges.end());
00438 it++)
00439 {
00440
00441
00442
00443 if(new_range.overlaps_end_of(*it))
00444 {
00445 time_range merged = (*it).merge(new_range);
00446 *it = merged;
00447 added = true;
00448
00449
00450 bool done = false;
00451 while(1)
00452 {
00453 time_range_list::iterator it_next = it;
00454 it_next++;
00455 if(it_next == ranges.end())
00456 {
00457 break;
00458 }
00459
00460 if((*it).overlaps_start_of(*it_next))
00461 {
00462 if(!(*it).overlaps_end_of(*it_next))
00463 {
00464
00465 merged = (*it).merge(*it_next);
00466 *it = merged;
00467 }
00468 ranges.erase(it_next);
00469 }
00470 else
00471 {
00472
00473 assert((*it).end_time < (*it_next).start_time);
00474 break;
00475 }
00476 }
00477 }
00478
00479
00480 else if(new_range.overlaps_start_of(*it))
00481 {
00482 time_range merged = (*it).merge(new_range);
00483 *it = merged;
00484 added = true;
00485
00486
00487
00488
00489 }
00490
00491 else if(new_range.contained_by(*it))
00492 {
00493 added = true;
00494 }
00495
00496
00497 else if(new_range.start_time < (*it).start_time)
00498 {
00499 ranges.insert(it, new_range);
00500 added = true;
00501 }
00502 else
00503 {
00504
00505
00506 assert((*it).end_time < new_range.start_time);
00507 }
00508 }
00509
00510
00511
00512 if(!added)
00513 {
00514 ranges.push_back(new_range);
00515 }
00516 }
00517
00518
00519 bool in_range(const struct timeval &start, const Delta_Time &delta,
00520 unsigned int &index)
00521 {
00522 if(ranges.empty())
00523 return false;
00524
00525 time_range test_range(start, delta);
00526
00527
00528
00529 time_range_list::iterator it = ranges.begin();
00530 for(unsigned int i = 0; i < index; i++)
00531 {
00532 it++;
00533 if(it == ranges.end())
00534 return false;
00535 }
00536
00537
00538
00539 while(it != ranges.end())
00540 {
00541
00542
00543 if(test_range.overlaps_start_of(*it) ||
00544 test_range.overlaps_end_of(*it) ||
00545 (*it).overlaps_start_of(test_range) ||
00546 (*it).overlaps_end_of(test_range))
00547 {
00548 return true;
00549 }
00550 else
00551 {
00552
00553 assert((test_range.end_time < (*it).start_time) ||
00554 ((*it).end_time < test_range.start_time));
00555 }
00556
00557
00558 it++; index++;
00559 }
00560
00561
00562 return false;
00563 }
00564
00565 void print(ostream &out, const char *indent,
00566 const Lock_Event_List *events = 0) const
00567 {
00568 unsigned int index = 0;
00569 for(time_range_list::const_iterator it = ranges.begin();
00570 it != ranges.end();
00571 it++, index++)
00572 {
00573 Delta_Time duration = ((*it).end_time - (*it).start_time);
00574 out << indent << "range " << index << ":" << endl
00575 << indent << " start: " << (*it).start_time << endl
00576 << indent << " end: " << (*it).end_time << endl
00577 << indent << " duration: " << duration.msecs() << " ms" << endl;
00578
00579 if(events != 0)
00580 {
00581 out << endl;
00582 Text sub_indent(indent);
00583 sub_indent += " ";
00584 for(Lock_Event_List::const_iterator event_it =
00585 events[index].begin();
00586 event_it != events[index].end();
00587 event_it++)
00588 {
00589 (*event_it)->print_lock_info(out, sub_indent.cchars(),
00590 &((*it).start_time));
00591 }
00592 }
00593 }
00594 }
00595
00596 void gen_plot(const Text &title_prefix,
00597 const Text &basename,
00598 const Lock_Event_List *events) const
00599 {
00600 unsigned int index = 0;
00601 for(time_range_list::const_iterator it = ranges.begin();
00602 it != ranges.end();
00603 it++, index++)
00604 {
00605 char range_buf[30];
00606 sprintf(range_buf, "_range%04d", index);
00607 Text ranage_base = basename+range_buf;
00608 Text cmd_fname = ranage_base+".gnuplot";
00609 Text img_name = ranage_base+".png";
00610
00611 Text ar_data_fname = ranage_base+"_acquireRead.dat";
00612 Text hr_data_fname = ranage_base+"_holdRead.dat";
00613 Text rr_data_fname = ranage_base+"_releaseRead.dat";
00614 Text aw_data_fname = ranage_base+"_acquireWrite.dat";
00615 Text hw_data_fname = ranage_base+"_holdWrite.dat";
00616 Text rw_data_fname = ranage_base+"_releaseWrite.dat";
00617
00618 ofstream cmd_stream(cmd_fname.cchars());
00619
00620 if(cmd_stream.bad())
00621 {
00622 cerr << "Couldn't open \"" << cmd_fname.cchars()
00623 << "\" for writing"
00624 << endl;
00625 exit(1);
00626 }
00627
00628 cmd_stream << "set title \"" << title_prefix.cchars()
00629 << " range " << index << "\"" << endl
00630 << "set data style yerrorbars" << endl
00631 << "set term png color" << endl
00632 << "set output \"" << img_name.cchars() << "\"" << endl
00633 << "set ylabel \"time in ms\"" << endl
00634 << "set xlabel \"time 0 = " << (*it).start_time << "\""
00635 << endl;
00636
00637 ofstream
00638 *ar_data_stream = 0,
00639 *hr_data_stream = 0,
00640 *rr_data_stream = 0,
00641 *aw_data_stream = 0,
00642 *hw_data_stream = 0,
00643 *rw_data_stream = 0;
00644
00645 unsigned int x_pos = 0;
00646 for(Lock_Event_List::const_iterator event_it =
00647 events[index].begin();
00648 event_it != events[index].end();
00649 event_it++, x_pos++)
00650 {
00651
00652 if((*event_it)->write && (aw_data_stream == 0))
00653 {
00654 aw_data_stream = NEW_CONSTR(ofstream,
00655 (aw_data_fname.cchars()));
00656 if(aw_data_stream->bad())
00657 {
00658 cerr << "Couldn't open \"" << aw_data_fname.cchars()
00659 << "\" for writing"
00660 << endl;
00661 exit(1);
00662 }
00663 hw_data_stream = NEW_CONSTR(ofstream,
00664 (hw_data_fname.cchars()));
00665 if(hw_data_stream->bad())
00666 {
00667 cerr << "Couldn't open \"" << hw_data_fname.cchars()
00668 << "\" for writing"
00669 << endl;
00670 exit(1);
00671 }
00672 rw_data_stream = NEW_CONSTR(ofstream,
00673 (rw_data_fname.cchars()));
00674 if(rw_data_stream->bad())
00675 {
00676 cerr << "Couldn't open \"" << rw_data_fname.cchars()
00677 << "\" for writing"
00678 << endl;
00679 exit(1);
00680 }
00681 }
00682 else if(!(*event_it)->write && (ar_data_stream == 0))
00683 {
00684 ar_data_stream = NEW_CONSTR(ofstream,
00685 (ar_data_fname.cchars()));
00686 if(ar_data_stream->bad())
00687 {
00688 cerr << "Couldn't open \"" << ar_data_fname.cchars()
00689 << "\" for writing"
00690 << endl;
00691 exit(1);
00692 }
00693 hr_data_stream = NEW_CONSTR(ofstream,
00694 (hr_data_fname.cchars()));
00695 if(hr_data_stream->bad())
00696 {
00697 cerr << "Couldn't open \"" << hr_data_fname.cchars()
00698 << "\" for writing"
00699 << endl;
00700 exit(1);
00701 }
00702 rr_data_stream = NEW_CONSTR(ofstream,
00703 (rr_data_fname.cchars()));
00704 if(rr_data_stream->bad())
00705 {
00706 cerr << "Couldn't open \"" << rr_data_fname.cchars()
00707 << "\" for writing"
00708 << endl;
00709 exit(1);
00710 }
00711 }
00712
00713
00714 (*event_it)->plot_lock_info(x_pos,
00715 ((*event_it)->write
00716 ? *aw_data_stream
00717 : *ar_data_stream),
00718 ((*event_it)->write
00719 ? *hw_data_stream
00720 : *hr_data_stream),
00721 ((*event_it)->write
00722 ? *rw_data_stream
00723 : *rr_data_stream),
00724 (*it).start_time);
00725 }
00726
00727 cmd_stream << "plot ";
00728 if(aw_data_stream != 0)
00729 {
00730 assert(hw_data_stream != 0);
00731 assert(rw_data_stream != 0);
00732 aw_data_stream->close();
00733 hw_data_stream->close();
00734 rw_data_stream->close();
00735 delete aw_data_stream;
00736 delete hw_data_stream;
00737 delete rw_data_stream;
00738
00739 cmd_stream << "\"" << aw_data_fname.cchars()
00740 << "\" title \"acquireWrite\", \""
00741 << hw_data_fname.cchars()
00742 << "\" title \"holdWrite\", \""
00743 << rw_data_fname.cchars()
00744 << "\" title \"releaseWrite\"";
00745 }
00746 if(ar_data_stream != 0)
00747 {
00748 assert(hr_data_stream != 0);
00749 assert(rr_data_stream != 0);
00750 ar_data_stream->close();
00751 hr_data_stream->close();
00752 rr_data_stream->close();
00753 delete ar_data_stream;
00754 delete hr_data_stream;
00755 delete rr_data_stream;
00756
00757 if(aw_data_stream != 0)
00758 {
00759 cmd_stream << ", ";
00760 }
00761 cmd_stream << "\"" << ar_data_fname.cchars()
00762 << "\" title \"acquireRead\", \""
00763 << hr_data_fname.cchars()
00764 << "\" title \"holdRead\", \""
00765 << rr_data_fname.cchars()
00766 << "\" title \"releaseRead\"";
00767 }
00768 cmd_stream << endl;
00769 }
00770 }
00771
00772 bool empty()
00773 {
00774 return ranges.empty();
00775 }
00776
00777 unsigned int range_count()
00778 {
00779 return ranges.size();
00780 }
00781 };
00782
00783 static const char *program_name = 0;
00784
00785 static void usage()
00786 {
00787 cerr << "Usage: " << program_name
00788 << " [-o <output prefix>] [-t <long acquire ms>] <lock timing file(s)>"
00789 << endl;
00790 exit(1);
00791 }
00792
00793 int main(int argc, char * const argv[])
00794 {
00795 program_name = argv[0];
00796 const char *output_prefix = "rwlock_timing.out";
00797 unsigned int long_acquire_ms = 1000;
00798
00799 int option;
00800 opterr = 0;
00801 while((option = getopt(argc, argv, "ho:t:")) != EOF)
00802 {
00803 switch(option)
00804 {
00805 case 'o':
00806 output_prefix = optarg;
00807 break;
00808 case 't':
00809 long_acquire_ms = atoi(optarg);
00810 break;
00811 case 'h':
00812 case '?':
00813 default:
00814 usage();
00815 }
00816 }
00817
00818
00819 Time_Ranges
00820 stable_long_acquireReads,
00821 stable_long_acquireWrites,
00822 volatile_long_acquireReads,
00823 volatile_long_acquireWrites,
00824 userGroup_long_acquireReads,
00825 userGroup_long_acquireWrites;
00826
00827
00828 Lock_Data
00829 *stable_longest_acquireRead = 0,
00830 *stable_longest_acquireWrite = 0,
00831 *stable_longest_held = 0,
00832 *stable_longest_release = 0,
00833 *volatile_longest_acquireRead = 0,
00834 *volatile_longest_acquireWrite = 0,
00835 *volatile_longest_held = 0,
00836 *volatile_longest_release = 0,
00837 *userGroup_longest_acquireRead = 0,
00838 *userGroup_longest_acquireWrite = 0,
00839 *userGroup_longest_held = 0,
00840 *userGroup_longest_release = 0;
00841
00842 Delta_Time
00843 stable_total_acquireRead,
00844 stable_total_acquireWrite,
00845 stable_total_held,
00846 stable_total_release,
00847 volatile_total_acquireRead,
00848 volatile_total_acquireWrite,
00849 volatile_total_held,
00850 volatile_total_release,
00851 userGroup_total_acquireRead,
00852 userGroup_total_acquireWrite,
00853 userGroup_total_held,
00854 userGroup_total_release;
00855
00856 unsigned int
00857 stable_count_acquireRead = 0,
00858 stable_count_acquireWrite = 0,
00859 stable_count_acquired = 0,
00860 volatile_count_acquireRead = 0,
00861 volatile_count_acquireWrite = 0,
00862 volatile_count_acquired = 0,
00863 userGroup_count_acquireRead = 0,
00864 userGroup_count_acquireWrite = 0,
00865 userGroup_count_acquired = 0;
00866
00867 unsigned int total_count = 0;
00868
00869 unsigned int
00870 stable_acquireRead_no_reason_count = 0,
00871 stable_acquireWrite_no_reason_count = 0,
00872 volatile_acquireRead_no_reason_count = 0,
00873 volatile_acquireWrite_no_reason_count = 0,
00874 userGroup_acquireRead_no_reason_count = 0,
00875 userGroup_acquireWrite_no_reason_count = 0;
00876
00877
00878
00879
00880 for(int arg = optind; arg < argc; arg++)
00881 {
00882 OBufStream l_cmd;
00883 l_cmd << "gunzip -q -c " << argv[arg];
00884 FILE *stream = popen(l_cmd.str(), "r");
00885 unsigned long file_count = 0;
00886
00887 Lock_Data *cur_stable = 0, *cur_volatile = 0, *cur_userGroup = 0;
00888 try
00889 {
00890 while(1)
00891 {
00892 int lock_byte = getc(stream);
00893 if(lock_byte == EOF)
00894 {
00895 break;
00896 }
00897
00898 else if(lock_byte == 1)
00899 {
00900 if(cur_stable == 0)
00901 {
00902 cur_stable = NEW_CONSTR(Lock_Data, (stable));
00903 }
00904
00905 bool done = cur_stable->read_record(stream);
00906
00907 if(done)
00908 {
00909 file_count++;
00910
00911 if(cur_stable->acquired && (cur_stable->reason == 0))
00912 {
00913 if(cur_stable->write)
00914 {
00915 stable_acquireWrite_no_reason_count++;
00916 }
00917 else
00918 {
00919 stable_acquireRead_no_reason_count++;
00920 }
00921 }
00922
00923
00924 if(cur_stable->acquired &&
00925 (cur_stable->time_to_acquire.msecs() >=
00926 long_acquire_ms))
00927 {
00928 if(cur_stable->write)
00929 {
00930 stable_long_acquireWrites.
00931 add_range(cur_stable->start_time,
00932 cur_stable->time_to_acquire);
00933 }
00934 else
00935 {
00936 stable_long_acquireReads.
00937 add_range(cur_stable->start_time,
00938 cur_stable->time_to_acquire);
00939 }
00940 }
00941
00942
00943 if(cur_stable->write)
00944 {
00945 stable_total_acquireWrite +=
00946 cur_stable->time_to_acquire;
00947 stable_count_acquireWrite++;
00948 }
00949 else
00950 {
00951 stable_total_acquireRead +=
00952 cur_stable->time_to_acquire;
00953 stable_count_acquireRead++;
00954 }
00955 if(cur_stable->acquired)
00956 {
00957 stable_total_held += cur_stable->time_held;
00958 stable_total_release += cur_stable->time_to_release;
00959 stable_count_acquired++;
00960 }
00961
00962
00963 if(cur_stable->write &&
00964 (!stable_longest_acquireWrite ||
00965 (cur_stable->time_to_acquire >
00966 stable_longest_acquireWrite->time_to_acquire)))
00967 {
00968 stable_longest_acquireWrite = cur_stable;
00969 }
00970 if(!cur_stable->write &&
00971 (!stable_longest_acquireRead ||
00972 (cur_stable->time_to_acquire >
00973 stable_longest_acquireRead->time_to_acquire)))
00974 {
00975 stable_longest_acquireRead = cur_stable;
00976 }
00977 if(cur_stable->acquired)
00978 {
00979 if(!stable_longest_held ||
00980 (cur_stable->time_held >
00981 stable_longest_held->time_held))
00982 {
00983 stable_longest_held = cur_stable;
00984 }
00985 if(!stable_longest_release ||
00986 (cur_stable->time_to_release >
00987 stable_longest_release->time_to_release))
00988 {
00989 stable_longest_release = cur_stable;
00990 }
00991 }
00992
00993 cur_stable = 0;
00994 }
00995 }
00996
00997 else if(lock_byte == 2)
00998 {
00999 if(cur_volatile == 0)
01000 {
01001 cur_volatile = NEW_CONSTR(Lock_Data, (volatileRoot));
01002 }
01003
01004 bool done = cur_volatile->read_record(stream);
01005
01006 if(done)
01007 {
01008 file_count++;
01009
01010 if(cur_volatile->acquired && (cur_volatile->reason == 0))
01011 {
01012 if(cur_volatile->write)
01013 {
01014 volatile_acquireWrite_no_reason_count++;
01015 }
01016 else
01017 {
01018 volatile_acquireRead_no_reason_count++;
01019 }
01020 }
01021
01022
01023 if(cur_volatile->acquired &&
01024 (cur_volatile->time_to_acquire.msecs() >=
01025 long_acquire_ms))
01026 {
01027 if(cur_volatile->write)
01028 {
01029 volatile_long_acquireWrites.
01030 add_range(cur_volatile->start_time,
01031 cur_volatile->time_to_acquire);
01032 }
01033 else
01034 {
01035 volatile_long_acquireReads.
01036 add_range(cur_volatile->start_time,
01037 cur_volatile->time_to_acquire);
01038 }
01039 }
01040
01041
01042 if(cur_volatile->write)
01043 {
01044 volatile_total_acquireWrite +=
01045 cur_volatile->time_to_acquire;
01046 volatile_count_acquireWrite++;
01047 }
01048 else
01049 {
01050 volatile_total_acquireRead +=
01051 cur_volatile->time_to_acquire;
01052 volatile_count_acquireRead++;
01053 }
01054 if(cur_volatile->acquired)
01055 {
01056 volatile_total_held += cur_volatile->time_held;
01057 volatile_total_release +=
01058 cur_volatile->time_to_release;
01059 volatile_count_acquired++;
01060 }
01061
01062
01063 if(cur_volatile->write &&
01064 (!volatile_longest_acquireWrite ||
01065 (cur_volatile->time_to_acquire >
01066 volatile_longest_acquireWrite->time_to_acquire)))
01067 {
01068 volatile_longest_acquireWrite = cur_volatile;
01069 }
01070 if(!cur_volatile->write &&
01071 (!volatile_longest_acquireRead ||
01072 (cur_volatile->time_to_acquire >
01073 volatile_longest_acquireRead->time_to_acquire)))
01074 {
01075 volatile_longest_acquireRead = cur_volatile;
01076 }
01077 if(cur_volatile->acquired)
01078 {
01079 if(!volatile_longest_held ||
01080 (cur_volatile->time_held >
01081 volatile_longest_held->time_held))
01082 {
01083 volatile_longest_held = cur_volatile;
01084 }
01085 if(!volatile_longest_release ||
01086 (cur_volatile->time_to_release >
01087 volatile_longest_release->time_to_release))
01088 {
01089 volatile_longest_release = cur_volatile;
01090 }
01091 }
01092
01093 cur_volatile = 0;
01094 }
01095 }
01096
01097 else if(lock_byte == 3)
01098 {
01099 if(cur_userGroup == 0)
01100 {
01101 cur_userGroup = NEW_CONSTR(Lock_Data, (userGroup));
01102 }
01103
01104 bool done = cur_userGroup->read_record(stream);
01105
01106 if(done)
01107 {
01108 file_count++;
01109
01110 if(cur_userGroup->acquired && (cur_userGroup->reason == 0))
01111 {
01112 if(cur_userGroup->write)
01113 {
01114 userGroup_acquireWrite_no_reason_count++;
01115 }
01116 else
01117 {
01118 userGroup_acquireRead_no_reason_count++;
01119 }
01120 }
01121
01122
01123 if(cur_userGroup->acquired &&
01124 (cur_userGroup->time_to_acquire.msecs() >=
01125 long_acquire_ms))
01126 {
01127 if(cur_userGroup->write)
01128 {
01129 userGroup_long_acquireWrites.
01130 add_range(cur_userGroup->start_time,
01131 cur_userGroup->time_to_acquire);
01132 }
01133 else
01134 {
01135 userGroup_long_acquireReads.
01136 add_range(cur_userGroup->start_time,
01137 cur_userGroup->time_to_acquire);
01138 }
01139 }
01140
01141
01142 if(cur_userGroup->write)
01143 {
01144 userGroup_total_acquireWrite +=
01145 cur_userGroup->time_to_acquire;
01146 userGroup_count_acquireWrite++;
01147 }
01148 else
01149 {
01150 userGroup_total_acquireRead +=
01151 cur_userGroup->time_to_acquire;
01152 userGroup_count_acquireRead++;
01153 }
01154 if(cur_userGroup->acquired)
01155 {
01156 userGroup_total_held += cur_userGroup->time_held;
01157 userGroup_total_release +=
01158 cur_userGroup->time_to_release;
01159 userGroup_count_acquired++;
01160 }
01161
01162
01163 if(cur_userGroup->write &&
01164 (!userGroup_longest_acquireWrite ||
01165 (cur_userGroup->time_to_acquire >
01166 userGroup_longest_acquireWrite->time_to_acquire)))
01167 {
01168 userGroup_longest_acquireWrite = cur_userGroup;
01169 }
01170 if(!cur_userGroup->write &&
01171 (!userGroup_longest_acquireRead ||
01172 (cur_userGroup->time_to_acquire >
01173 userGroup_longest_acquireRead->time_to_acquire)))
01174 {
01175 userGroup_longest_acquireRead = cur_userGroup;
01176 }
01177 if(cur_userGroup->acquired)
01178 {
01179 if(!userGroup_longest_held ||
01180 (cur_userGroup->time_held >
01181 userGroup_longest_held->time_held))
01182 {
01183 userGroup_longest_held = cur_userGroup;
01184 }
01185 if(!userGroup_longest_release ||
01186 (cur_userGroup->time_to_release >
01187 userGroup_longest_release->time_to_release))
01188 {
01189 userGroup_longest_release = cur_userGroup;
01190 }
01191 }
01192
01193 cur_userGroup = 0;
01194 }
01195 }
01196 }
01197 }
01198 catch(FS::EndOfFile)
01199 {
01200
01201 }
01202 catch(Lock_Data::FileFormatError)
01203 {
01204 cerr << "File format error reading " << argv[arg] << endl;
01205 }
01206
01207 cout << argv[arg] << ": " << file_count << " locks" << endl;
01208 total_count += file_count;
01209 int gunzip_status = pclose(stream);
01210 cout << "gunzip status: " << gunzip_status << endl;
01211 }
01212
01213 Text report_fname(output_prefix);
01214 report_fname += ".report";
01215 ofstream report(report_fname.cchars());
01216
01217 if(report.bad())
01218 {
01219 cerr << "Couldn't open \"" << report_fname.cchars() << "\" for writing"
01220 << endl;
01221 exit(1);
01222 }
01223
01224 report << "Total: " << total_count << " locks" << endl;
01225
01226 report << "Acquired locks with no reason:" << endl
01227 << " StableLock acquireRead: "
01228 << stable_acquireRead_no_reason_count << endl
01229 << " StableLock acquireWrite: "
01230 << stable_acquireWrite_no_reason_count << endl
01231 << " VolatileRootLock acquireRead: "
01232 << volatile_acquireRead_no_reason_count << endl
01233 << " VolatileRootLock acquireWrite: "
01234 << volatile_acquireWrite_no_reason_count << endl
01235 << " userGroup_lock acquireRead: "
01236 << userGroup_acquireRead_no_reason_count << endl
01237 << " userGroup_lock acquireWrite: "
01238 << userGroup_acquireWrite_no_reason_count << endl;
01239
01240 report << "StableLock:" << endl;
01241 if(stable_count_acquireRead > 0)
01242 {
01243 assert(stable_longest_acquireRead != 0);
01244 report
01245 << " acquireRead/tryRead:" << endl
01246 << " average: " << (stable_total_acquireRead.msecs() /
01247 stable_count_acquireRead) << " ms" << endl
01248 << " slowest: "
01249 << stable_longest_acquireRead->time_to_acquire.msecs()
01250 << " ms" << endl;
01251 if(stable_longest_acquireRead->reason)
01252 {
01253 report
01254 << " slowest reason: "
01255 << stable_longest_acquireRead->reason->cchars() << endl;
01256 }
01257 if(!stable_long_acquireReads.empty())
01258 {
01259 report << " long acquireRead periods:" << endl;
01260 stable_long_acquireReads.print(report, " ");
01261 }
01262 }
01263 if(stable_count_acquireWrite > 0)
01264 {
01265 assert(stable_longest_acquireWrite != 0);
01266 report
01267 << " acquireWrite/tryWrite:" << endl
01268 << " average: " << (stable_total_acquireWrite.msecs() /
01269 stable_count_acquireWrite) << " ms" << endl
01270 << " slowest: "
01271 << stable_longest_acquireWrite->time_to_acquire.msecs()
01272 << " ms" << endl;
01273 if(stable_longest_acquireWrite->reason)
01274 {
01275 report
01276 << " slowest reason: "
01277 << stable_longest_acquireWrite->reason->cchars() << endl;
01278 }
01279 if(!stable_long_acquireWrites.empty())
01280 {
01281 report << " long acquireWrite periods:" << endl;
01282 stable_long_acquireWrites.print(report, " ");
01283 }
01284 }
01285 if(stable_count_acquired > 0)
01286 {
01287 assert(stable_longest_held != 0);
01288 assert(stable_longest_release != 0);
01289 report
01290 << " hold:" << endl
01291 << " average: " << (stable_total_held.msecs() /
01292 stable_count_acquired) << " ms" << endl
01293 << " slowest: " << stable_longest_held->time_held.msecs()
01294 << " ms" << endl;
01295 if(stable_longest_held->reason)
01296 {
01297 report
01298 << " slowest reason: "
01299 << stable_longest_held->reason->cchars() << endl;
01300 }
01301 report
01302 << " release:" << endl
01303 << " average: " << (stable_total_release.msecs() /
01304 stable_count_acquired) << " ms" << endl
01305 << " slowest: " << stable_longest_release->time_to_release.msecs()
01306 << " ms" << endl;
01307 if(stable_longest_release->reason)
01308 {
01309 report
01310 << " slowest reason: "
01311 << stable_longest_release->reason->cchars() << endl;
01312 }
01313 }
01314 report << "VolatileRootLock:" << endl;
01315 if(volatile_count_acquireRead > 0)
01316 {
01317 assert(volatile_longest_acquireRead != 0);
01318 report
01319 << " acquireRead/tryRead:" << endl
01320 << " average: " << (volatile_total_acquireRead.msecs() /
01321 volatile_count_acquireRead) << " ms" << endl
01322 << " slowest: "
01323 << volatile_longest_acquireRead->time_to_acquire.msecs()
01324 << " ms" << endl;
01325 if(volatile_longest_acquireRead->reason)
01326 {
01327 report
01328 << " slowest reason: "
01329 << volatile_longest_acquireRead->reason->cchars() << endl;
01330 }
01331 if(!volatile_long_acquireReads.empty())
01332 {
01333 report << " long acquireRead periods:" << endl;
01334 volatile_long_acquireReads.print(report, " ");
01335 }
01336 }
01337 if(volatile_count_acquireWrite > 0)
01338 {
01339 assert(volatile_longest_acquireWrite != 0);
01340 report
01341 << " acquireWrite/tryWrite:" << endl
01342 << " average: " << (volatile_total_acquireWrite.msecs() /
01343 volatile_count_acquireWrite) << " ms" << endl
01344 << " slowest: "
01345 << volatile_longest_acquireWrite->time_to_acquire.msecs()
01346 << " ms" << endl;
01347 if(volatile_longest_acquireWrite->reason)
01348 {
01349 report
01350 << " slowest reason: "
01351 << volatile_longest_acquireWrite->reason->cchars() << endl;
01352 }
01353 if(!volatile_long_acquireWrites.empty())
01354 {
01355 report << " long acquireWrite periods:" << endl;
01356 volatile_long_acquireWrites.print(report, " ");
01357 }
01358 }
01359 if(volatile_count_acquired > 0)
01360 {
01361 assert(volatile_longest_held != 0);
01362 assert(volatile_longest_release != 0);
01363 report
01364 << " hold:" << endl
01365 << " average: " << (volatile_total_held.msecs() /
01366 volatile_count_acquired) << " ms" << endl
01367 << " slowest: " << volatile_longest_held->time_held.msecs()
01368 << " ms" << endl;
01369 if(volatile_longest_held->reason)
01370 {
01371 report
01372 << " slowest reason: "
01373 << volatile_longest_held->reason->cchars() << endl;
01374 }
01375 report
01376 << " release:" << endl
01377 << " average: " << (volatile_total_release.msecs() /
01378 volatile_count_acquired) << " ms" << endl
01379 << " slowest: " << volatile_longest_release->time_to_release.msecs()
01380 << " ms" << endl;
01381 if(volatile_longest_release->reason)
01382 {
01383 report
01384 << " slowest reason: "
01385 << volatile_longest_release->reason->cchars() << endl;
01386 }
01387 }
01388 report << "userGroup_lock [AccessControl.C]:" << endl;
01389 if(userGroup_count_acquireRead > 0)
01390 {
01391 assert(userGroup_longest_acquireRead != 0);
01392 report
01393 << " acquireRead/tryRead:" << endl
01394 << " average: " << (userGroup_total_acquireRead.msecs() /
01395 userGroup_count_acquireRead) << " ms" << endl
01396 << " slowest: "
01397 << userGroup_longest_acquireRead->time_to_acquire.msecs()
01398 << " ms" << endl;
01399 if(userGroup_longest_acquireRead->reason)
01400 {
01401 report
01402 << " slowest reason: "
01403 << userGroup_longest_acquireRead->reason->cchars() << endl;
01404 }
01405 if(!userGroup_long_acquireReads.empty())
01406 {
01407 report << " long acquireRead periods:" << endl;
01408 userGroup_long_acquireReads.print(report, " ");
01409 }
01410 }
01411 if(userGroup_count_acquireWrite > 0)
01412 {
01413 assert(userGroup_longest_acquireWrite != 0);
01414 report
01415 << " acquireWrite/tryWrite:" << endl
01416 << " average: " << (userGroup_total_acquireWrite.msecs() /
01417 userGroup_count_acquireWrite) << " ms" << endl
01418 << " slowest: "
01419 << userGroup_longest_acquireWrite->time_to_acquire.msecs()
01420 << " ms" << endl;
01421 if(userGroup_longest_acquireWrite->reason)
01422 {
01423 report
01424 << " slowest reason: "
01425 << userGroup_longest_acquireWrite->reason->cchars() << endl;
01426 }
01427 if(!userGroup_long_acquireWrites.empty())
01428 {
01429 report << " long acquireWrite periods:" << endl;
01430 userGroup_long_acquireWrites.print(report, " ");
01431 }
01432 }
01433 if(userGroup_count_acquired > 0)
01434 {
01435 assert(userGroup_longest_held != 0);
01436 assert(userGroup_longest_release != 0);
01437 report
01438 << " hold:" << endl
01439 << " average: " << (userGroup_total_held.msecs() /
01440 userGroup_count_acquired) << " ms" << endl
01441 << " slowest: " << userGroup_longest_held->time_held.msecs()
01442 << " ms" << endl;
01443 if(userGroup_longest_held->reason)
01444 {
01445 report
01446 << " slowest reason: "
01447 << userGroup_longest_held->reason->cchars() << endl;
01448 }
01449 report
01450 << " release:" << endl
01451 << " average: " << (userGroup_total_release.msecs() /
01452 userGroup_count_acquired) << " ms" << endl
01453 << " slowest: " << userGroup_longest_release->time_to_release.msecs()
01454 << " ms" << endl;
01455 if(userGroup_longest_release->reason)
01456 {
01457 report
01458 << " slowest reason: "
01459 << userGroup_longest_release->reason->cchars() << endl;
01460 }
01461 }
01462
01463
01464
01465
01466 Lock_Event_List
01467 *stable_long_acquireRead_events = 0,
01468 *stable_long_acquireWrite_events = 0,
01469 *volatile_long_acquireRead_events = 0,
01470 *volatile_long_acquireWrite_events = 0,
01471 *userGroup_long_acquireRead_events = 0,
01472 *userGroup_long_acquireWrite_events = 0;
01473
01474 if(!stable_long_acquireReads.empty())
01475 {
01476 stable_long_acquireRead_events =
01477 NEW_ARRAY(Lock_Event_List, stable_long_acquireReads.range_count());
01478 }
01479 if(!stable_long_acquireWrites.empty())
01480 {
01481 stable_long_acquireWrite_events =
01482 NEW_ARRAY(Lock_Event_List, stable_long_acquireWrites.range_count());
01483 }
01484 if(!volatile_long_acquireReads.empty())
01485 {
01486 volatile_long_acquireRead_events =
01487 NEW_ARRAY(Lock_Event_List, volatile_long_acquireReads.range_count());
01488 }
01489 if(!volatile_long_acquireWrites.empty())
01490 {
01491 volatile_long_acquireWrite_events =
01492 NEW_ARRAY(Lock_Event_List, volatile_long_acquireWrites.range_count());
01493 }
01494 if(!userGroup_long_acquireReads.empty())
01495 {
01496 userGroup_long_acquireRead_events =
01497 NEW_ARRAY(Lock_Event_List, userGroup_long_acquireReads.range_count());
01498 }
01499 if(!userGroup_long_acquireWrites.empty())
01500 {
01501 userGroup_long_acquireWrite_events =
01502 NEW_ARRAY(Lock_Event_List, userGroup_long_acquireWrites.range_count());
01503 }
01504
01505 if((stable_long_acquireRead_events == 0) &&
01506 (stable_long_acquireWrite_events == 0) &&
01507 (volatile_long_acquireRead_events == 0) &&
01508 (volatile_long_acquireWrite_events == 0) &&
01509 (userGroup_long_acquireRead_events == 0) &&
01510 (userGroup_long_acquireWrite_events == 0))
01511 {
01512 cout << "No long acquire periods: skipping second pass" << endl;
01513 return 0;
01514 }
01515
01516 cout << "Starting second pass..." << endl;
01517 for(int arg = optind; arg < argc; arg++)
01518 {
01519 OBufStream l_cmd;
01520 l_cmd << "gunzip -q -c " << argv[arg];
01521 FILE *stream = popen(l_cmd.str(), "r");
01522
01523 Lock_Data *cur_stable = 0, *cur_volatile = 0, *cur_userGroup = 0;
01524 try
01525 {
01526 while(1)
01527 {
01528 int lock_byte = getc(stream);
01529 if(lock_byte == EOF)
01530 {
01531 break;
01532 }
01533
01534 else if(lock_byte == 1)
01535 {
01536 if(cur_stable == 0)
01537 {
01538 cur_stable = NEW_CONSTR(Lock_Data, (stable));
01539 }
01540
01541 bool done = cur_stable->read_record(stream);
01542
01543 if(done)
01544 {
01545 Delta_Time total_delta;
01546 if(cur_stable->acquired)
01547 {
01548 total_delta = (cur_stable->time_to_acquire +
01549 cur_stable->time_held +
01550 cur_stable->time_to_release);
01551 }
01552 else
01553 {
01554 total_delta = cur_stable->time_to_acquire;
01555 }
01556
01557 unsigned int index = 0;
01558 while(stable_long_acquireReads
01559 .in_range(cur_stable->start_time, total_delta,
01560 index))
01561 {
01562 assert(stable_long_acquireRead_events != 0);
01563 sorted_lock_insert
01564 (stable_long_acquireRead_events[index],
01565 cur_stable);
01566
01567 index++;
01568 }
01569 index = 0;
01570 while(stable_long_acquireWrites
01571 .in_range(cur_stable->start_time, total_delta,
01572 index))
01573 {
01574 assert(stable_long_acquireWrite_events != 0);
01575 sorted_lock_insert
01576 (stable_long_acquireWrite_events[index],
01577 cur_stable);
01578
01579 index++;
01580 }
01581
01582 cur_stable = 0;
01583 }
01584 }
01585
01586 else if(lock_byte == 2)
01587 {
01588 if(cur_volatile == 0)
01589 {
01590 cur_volatile = NEW_CONSTR(Lock_Data, (volatileRoot));
01591 }
01592
01593 bool done = cur_volatile->read_record(stream);
01594
01595 if(done)
01596 {
01597 Delta_Time total_delta;
01598 if(cur_volatile->acquired)
01599 {
01600 total_delta = (cur_volatile->time_to_acquire +
01601 cur_volatile->time_held +
01602 cur_volatile->time_to_release);
01603 }
01604 else
01605 {
01606 total_delta = cur_volatile->time_to_acquire;
01607 }
01608
01609 unsigned int index = 0;
01610 while(volatile_long_acquireReads
01611 .in_range(cur_volatile->start_time, total_delta,
01612 index))
01613 {
01614 assert(volatile_long_acquireRead_events != 0);
01615 sorted_lock_insert
01616 (volatile_long_acquireRead_events[index],
01617 cur_volatile);
01618
01619 index++;
01620 }
01621 index = 0;
01622 while(volatile_long_acquireWrites
01623 .in_range(cur_volatile->start_time, total_delta,
01624 index))
01625 {
01626 assert(volatile_long_acquireWrite_events != 0);
01627 sorted_lock_insert
01628 (volatile_long_acquireWrite_events[index],
01629 cur_volatile);
01630
01631 index++;
01632 }
01633
01634 cur_volatile = 0;
01635 }
01636 }
01637
01638 else if(lock_byte == 3)
01639 {
01640 if(cur_userGroup == 0)
01641 {
01642 cur_userGroup = NEW_CONSTR(Lock_Data, (userGroup));
01643 }
01644
01645 bool done = cur_userGroup->read_record(stream);
01646
01647 if(done)
01648 {
01649 Delta_Time total_delta;
01650 if(cur_userGroup->acquired)
01651 {
01652 total_delta = (cur_userGroup->time_to_acquire +
01653 cur_userGroup->time_held +
01654 cur_userGroup->time_to_release);
01655 }
01656 else
01657 {
01658 total_delta = cur_userGroup->time_to_acquire;
01659 }
01660
01661 unsigned int index = 0;
01662 while(userGroup_long_acquireReads
01663 .in_range(cur_userGroup->start_time, total_delta,
01664 index))
01665 {
01666 assert(userGroup_long_acquireRead_events != 0);
01667 sorted_lock_insert
01668 (userGroup_long_acquireRead_events[index],
01669 cur_userGroup);
01670
01671 index++;
01672 }
01673 index = 0;
01674 while(userGroup_long_acquireWrites
01675 .in_range(cur_userGroup->start_time, total_delta,
01676 index))
01677 {
01678 assert(userGroup_long_acquireWrite_events != 0);
01679 sorted_lock_insert
01680 (userGroup_long_acquireWrite_events[index],
01681 cur_userGroup);
01682
01683 index++;
01684 }
01685
01686 cur_userGroup = 0;
01687 }
01688 }
01689 }
01690 }
01691 catch(FS::EndOfFile)
01692 {
01693
01694 }
01695 catch(Lock_Data::FileFormatError)
01696 {
01697 cerr << "File format error reading " << argv[arg] << endl;
01698 }
01699
01700 int gunzip_status = pclose(stream);
01701 }
01702
01703
01704
01705 if(!stable_long_acquireReads.empty())
01706 {
01707 assert(stable_long_acquireRead_events != 0);
01708 report << "Long StableLock acquireRead periods:" << endl;
01709 stable_long_acquireReads.print(report, " ",
01710 stable_long_acquireRead_events);
01711
01712 Text plot_prefix(output_prefix);
01713 plot_prefix += ".long_StableLock_acquireRead";
01714 stable_long_acquireReads
01715 .gen_plot("Long StableLock acquireRead",
01716 plot_prefix,
01717 stable_long_acquireRead_events);
01718 }
01719 if(!stable_long_acquireWrites.empty())
01720 {
01721 assert(stable_long_acquireWrite_events != 0);
01722 report << "Long StableLock acquireWrite periods:" << endl;
01723 stable_long_acquireWrites.print(report, " ",
01724 stable_long_acquireWrite_events);
01725
01726 Text plot_prefix(output_prefix);
01727 plot_prefix += ".long_StableLock_acquireWrite";
01728 stable_long_acquireWrites
01729 .gen_plot("Long StableLock acquireWrite",
01730 plot_prefix,
01731 stable_long_acquireWrite_events);
01732 }
01733 if(!volatile_long_acquireReads.empty())
01734 {
01735 assert(volatile_long_acquireRead_events != 0);
01736 report << "Long VolatileRootLock acquireRead periods:" << endl;
01737 volatile_long_acquireReads.print(report, " ",
01738 volatile_long_acquireRead_events);
01739
01740 Text plot_prefix(output_prefix);
01741 plot_prefix += ".long_VolatileRootLock_acquireRead";
01742 volatile_long_acquireReads
01743 .gen_plot("Long VolatileRootLock acquireRead",
01744 plot_prefix,
01745 volatile_long_acquireRead_events);
01746 }
01747 if(!volatile_long_acquireWrites.empty())
01748 {
01749 assert(volatile_long_acquireWrite_events != 0);
01750 report << "Long VolatileRootLock acquireWrite periods:" << endl;
01751 volatile_long_acquireWrites.print(report, " ",
01752 volatile_long_acquireWrite_events);
01753
01754 Text plot_prefix(output_prefix);
01755 plot_prefix += ".long_VolatileRootLock_acquireWrite";
01756 volatile_long_acquireWrites
01757 .gen_plot("Long VolatileRootLock acquireWrite",
01758 plot_prefix,
01759 volatile_long_acquireWrite_events);
01760 }
01761 if(!userGroup_long_acquireReads.empty())
01762 {
01763 assert(userGroup_long_acquireRead_events != 0);
01764 report << "Long userGroup_lock acquireRead periods:" << endl;
01765 userGroup_long_acquireReads.print(report, " ",
01766 userGroup_long_acquireRead_events);
01767
01768 Text plot_prefix(output_prefix);
01769 plot_prefix += ".long_userGroup_acquireRead";
01770 userGroup_long_acquireReads
01771 .gen_plot("Long userGroup_lock acquireRead",
01772 plot_prefix,
01773 userGroup_long_acquireRead_events);
01774 }
01775 if(!userGroup_long_acquireWrites.empty())
01776 {
01777 assert(userGroup_long_acquireWrite_events != 0);
01778 report << "Long userGroup_lock acquireWrite periods:" << endl;
01779 userGroup_long_acquireWrites.print(report, " ",
01780 userGroup_long_acquireWrite_events);
01781
01782 Text plot_prefix(output_prefix);
01783 plot_prefix += ".long_userGroup_acquireWrite";
01784 userGroup_long_acquireWrites
01785 .gen_plot("Long userGroup_lock acquireWrite",
01786 plot_prefix,
01787 userGroup_long_acquireWrite_events);
01788 }
01789
01790 return 0;
01791 }