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

VMultiPKFile.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
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 // Last modified on Mon May 23 22:50:58 EDT 2005 by ken@xorian.net
00020 //      modified on Thu Sep 25 14:14:24 PDT 1997 by heydon
00021 
00022 #include <Basics.H>
00023 #include <FS.H>
00024 #include <VestaLog.H>
00025 #include <FP.H>
00026 #include <BitVector.H>
00027 #include <CacheState.H>
00028 
00029 #include "CacheConfigServer.H"
00030 #include "EmptyPKLog.H"
00031 #include "VPKFile.H"
00032 #include "SMultiPKFile.H"
00033 #include "VMultiPKFile.H"
00034 
00035 using std::ifstream;
00036 
00037 bool VMultiPKFile::IsFull() throw ()
00038 /* REQUIRES Sup(LL) = CacheS.mu */
00039 {
00040     bool res = (this->numNewEntries >= Config_MPKFileFlushNum)
00041         && (this->numWaiting == 0) && (!(this->autoFlushPending));
00042     if (res) this->autoFlushPending = true;
00043     return res;
00044 }
00045 
00046 bool VMultiPKFile::LockForWrite(Basics::mutex &mu, const BitVector *toDelete)
00047      throw()
00048 {
00049     // return immediately if there's no work
00050     if (this->numNewEntries == 0 && toDelete == (BitVector *)NULL) {
00051         return false;
00052     }
00053 
00054     // wait until no threads are running "ToSCache" for this MultiPKFile
00055     while (this->numRunning > 0) {
00056         assert(this->numRunning == 1);
00057         this->numWaiting++;
00058         this->noneRunning.wait(mu);
00059         this->numWaiting--;
00060     }
00061 
00062     /* If there were multiple threads waiting to go, the first one probably
00063        had work to do, but the rest probably don't. So, we check again to
00064        see if we can exit early. */
00065     if (this->numNewEntries == 0 && toDelete == (BitVector *)NULL) {
00066         return false;
00067     }
00068 
00069     // we've now committed to doing the flush
00070     assert(this->numRunning == 0);
00071     this->numRunning++;
00072     this->autoFlushPending = false;
00073 
00074     return true;
00075 }
00076 
00077 
00078 bool VMultiPKFile::ChkptForWrite(Basics::mutex &mu, const BitVector *toDelete,
00079                                  /*OUT*/ SMultiPKFile::VPKFileMap &toFlush,
00080                                  /*OUT*/ SMultiPKFile::ChkPtTbl &vpkChkptTbl)
00081      throw()
00082 {
00083     // copy "this->tbl" to "toFlush" (pointers to the VPKFiles only)
00084     mu.lock();
00085     toFlush = this->tbl;
00086     this->numNewEntries = 0;
00087     this->freeMPKFileEpoch = -1;
00088     mu.unlock();
00089 
00090     // Now checkpoint in memory the current state of the VPKFiles and
00091     // determine whether there is any work to be done.
00092     bool l_result = SMultiPKFile::ChkptForRewrite(toFlush, toDelete,
00093                                                   vpkChkptTbl);
00094 
00095     // If it turns out that we have no writing to do, update
00096     // "numRunning" and signal waiting threads (if any)
00097     if(!l_result)
00098       {
00099         this->ReleaseWriteLock(mu);
00100       }
00101 
00102     // Return the result of SMultiPKFile::ChkptForRewrite.
00103     return l_result;
00104 }
00105 
00106 void VMultiPKFile::ReleaseWriteLock(Basics::mutex &mu) throw()
00107 /* It's worth noting that, as of this writing, PrepareForWrite commits
00108    us to performing the write, and this function doesn't completely
00109    undo that.  However, all possible errors past the point of
00110    PRepareForWrite (in either flushing the graph log or writing the
00111    MultiPKFile) are currently considered fatal.  If that ever ceases
00112    to be the case, this function will need to do some more work. */
00113 {
00114   mu.lock();
00115   this->numRunning--;
00116   assert(this->numRunning == 0);
00117   mu.unlock();
00118   this->noneRunning.signal();
00119 }
00120 
00121 void VMultiPKFile::ToSCache(Basics::mutex &mu,
00122 
00123                             // From SMultiPKFile::PrepareForRewrite
00124                             bool mpkFileExists, ifstream &ifs,
00125                             SMultiPKFileRep::Header *hdr,
00126 
00127                             // From ChkptForRewrite above
00128                             SMultiPKFile::VPKFileMap &toFlush,
00129                             SMultiPKFile::ChkPtTbl &vpkChkptTbl,
00130 
00131                             const BitVector *toDelete,
00132                             EmptyPKLog *emptyPKLog,
00133                             /*INOUT*/ EntryState &state)
00134   throw (FS::Failure, FS::EndOfFile, VestaLog::Error)
00135 /* REQUIRES (forall vf: VPKFile :: Sup(LL) < vf.mu) */
00136 {
00137   // Not only should there be only one, but this thread should be it.
00138   assert(this->numRunning == 1);
00139 
00140     // flush VPKFile's in "toFlush"
00141     // This must be called without any locks!
00142     SMultiPKFile::Rewrite(prefix,
00143                           mpkFileExists, ifs, hdr,
00144                           toFlush, vpkChkptTbl,
00145                           toDelete, emptyPKLog,
00146       /*INOUT*/ state);
00147 
00148     // remove empty VPKFiles from this VMultiPKFile
00149     /*** NYI ***/
00150 
00151     // update "numRunning"; signal waiting threads (if any)
00152     this->ReleaseWriteLock(mu);
00153 } // VMultiPKFile::ToSCache
00154 
00155 bool VMultiPKFile::IsStale(int latestEpoch) throw ()
00156 /* REQUIRES Sup(LL) = CacheS.mu */
00157 {
00158     return (0 <= this->freeMPKFileEpoch
00159             && this->freeMPKFileEpoch <= (latestEpoch -
00160                                           Config_FlushNewPeriodCnt));
00161 }

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