Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

nfsStats.C

Go to the documentation of this file.
00001 // Copyright (C) 2004, Kenneth C. Schalk
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // nfsStats.C - implementation of a class which gathers NFS call
00020 // statistics
00021 
00022 // Last modified on Mon May 23 21:52:28 EDT 2005 by ken@xorian.net
00023 
00024 #include "nfsStats.H"
00025 
00026 #include "ReposStats.H"
00027 
00028 Basics::mutex NFS_Call_Stats::head_mu;
00029 NFS_Call_Stats *NFS_Call_Stats::head = 0;
00030 
00031 void NFS_Call_Stats::accumulateStats(/*OUT*/ Basics::uint64 &calls,
00032                                      /*OUT*/ Basics::uint64 &secs,
00033                                      /*OUT*/ Basics::uint32 &usecs)
00034 {
00035   this->mu.lock();
00036   calls += this->call_count;
00037   secs += this->elapsed_secs;
00038   usecs += this->elapsed_usecs;
00039   this->mu.unlock();
00040 }
00041 
00042 void NFS_Call_Stats::recordCall(Basics::uint32 secs, Basics::uint32 &usecs)
00043 {
00044   this->mu.lock();
00045   // Record that another call has been completed.
00046   this->call_count++;
00047 
00048   // Add the time for this call to our running total.
00049   this->elapsed_secs += secs;
00050   this->elapsed_usecs += usecs;
00051   if(this->elapsed_usecs > USECS_PER_SEC)
00052     {
00053       this->elapsed_secs += this->elapsed_usecs/USECS_PER_SEC;
00054       this->elapsed_usecs %= USECS_PER_SEC;
00055     }
00056   this->mu.unlock();
00057 }
00058 
00059 void NFS_Call_Stats::getStats(/*OUT*/ Basics::uint64 &calls,
00060                               /*OUT*/ Basics::uint64 &secs,
00061                               /*OUT*/ Basics::uint32 &usecs)
00062 {
00063   // Reset our parameters.
00064   calls = 0;
00065   secs = 0;
00066   usecs = 0;
00067 
00068   // Get the current list of instances
00069   NFS_Call_Stats *list;
00070   NFS_Call_Stats::head_mu.lock();
00071   list = NFS_Call_Stats::head;
00072   NFS_Call_Stats::head_mu.unlock();
00073 
00074   while(list != 0)
00075     {
00076       // Accumulate into our parameters
00077       list->accumulateStats(calls, secs, usecs);
00078 
00079       // Handle usecs overflow
00080       if(usecs > USECS_PER_SEC)
00081         {
00082           secs += usecs/USECS_PER_SEC;
00083           usecs %= USECS_PER_SEC;
00084         }
00085 
00086       // Advance to the next instance.  (Note: no lock required to
00087       // access this member variable as it's set at instantiation and
00088       // never changed.)
00089       list = list->next;
00090     }
00091 }
00092 
00093 NFS_Call_Stats::NFS_Call_Stats()
00094   : next(0), call_count(0), elapsed_secs(0), elapsed_usecs(0)
00095 {
00096   // Insert ourselves into the global list
00097   NFS_Call_Stats::head_mu.lock();
00098   this->next = NFS_Call_Stats::head;
00099   NFS_Call_Stats::head = this;
00100   NFS_Call_Stats::head_mu.unlock();
00101 }
00102 
00103 NFS_Call_Stats::~NFS_Call_Stats()
00104 {
00105   // We don't ever expect to be destroyed.
00106   assert(false);
00107 }
00108 
00109 NFS_Call_Stats::Helper::Helper(NFS_Call_Stats &my_stats)
00110   : stats(my_stats)
00111 {
00112   // Save the time that this call started
00113   struct timezone unused_tz;
00114   int err = gettimeofday(&this->call_start, &unused_tz);
00115   assert(err == 0);
00116 }
00117 
00118 NFS_Call_Stats::Helper::~Helper()
00119 {
00120   // Get the time that this call ended
00121   struct timezone unused_tz;
00122   struct timeval call_end;
00123   int err = gettimeofday(&call_end, &unused_tz);
00124   assert(err == 0);
00125 
00126   // Compute the time taken by this call.
00127   Basics::uint32 call_secs, call_usecs;
00128   if(call_end.tv_sec == this->call_start.tv_sec)
00129     {
00130       call_secs = 0;
00131       if(call_end.tv_usec >= this->call_start.tv_usec)
00132         call_usecs = call_end.tv_usec - this->call_start.tv_usec;
00133       else
00134         // Time went backwards.  This can happen if the system time
00135         // gets adjusted.  Count this call as having taken 0 time.
00136         call_usecs = 0;
00137     }
00138   else if(call_end.tv_sec > this->call_start.tv_sec)
00139     {
00140       call_secs = (call_end.tv_sec - this->call_start.tv_sec) - 1;
00141       call_usecs = ((call_end.tv_usec + USECS_PER_SEC) -
00142                     this->call_start.tv_usec);
00143     }
00144   else
00145     {
00146       // Time went backwards.  This can happen if the system time gets
00147       // adjusted.  Count this call as having taken 0 time.
00148       call_secs = 0;
00149       call_usecs = 0;
00150     }
00151 
00152   // Record the time for this call in the stats recorder.
00153   stats.recordCall(call_secs, call_usecs);
00154 }

Generated on Mon May 8 00:48:45 2006 for Vesta by  doxygen 1.4.2