Esempio n. 1
0
const Status BufMgr::allocBuf(unsigned int & frame) 
{ 
	// Your solution goes here
	// Phorum says we should remove the entry from BufMap too. I don't really know how to do this.
	if(numBufs == 0){
		frame = clockHand;
		return OK;
	}
	advanceClock();
	unsigned int temp = clockHand;
	//cout << "Clockhand = " << clockHand << endl;	
   	do{
       	if(bufTable[clockHand].valid == false){
       		//cout << "1" << endl;
				bufTable[clockHand].Clear();
				frame = clockHand;
				return OK;
			}
			else if(bufTable[clockHand].valid == true){
				
				if(bufTable[clockHand].loved == true){
					//cout << "2" << endl;
					bufTable[clockHand].loved = false;
					advanceClock();
				}
				else if(bufTable[clockHand].loved == false){
				//cout << " a " << endl;
					if(bufTable[clockHand].pinCnt > 0){
						//cout << "3 " << endl;
						advanceClock();
					}
					else if(bufTable[clockHand].pinCnt <= 0){
						//cout << "4? " << endl;						
						if(bufTable[clockHand].dirty == true){
							//cout << "is this ever called" << endl;
							Status tempstatus = bufTable[clockHand].file->writePage(bufTable[clockHand].pageNo, &bufPool[clockHand]);//I think this is how you flush the page to disk.
							if(tempstatus == UNIXERR){
								return UNIXERR;
							}else if(tempstatus == OK){
									bufStats.diskwrites ++;
							}
							//flush page to disk? UNIXERR if fail;
						}
						bufMap.remove(bufTable[clockHand].file, bufTable[clockHand].pageNo);
						//if(tempst == OK)  cout << "all good here" << endl;
						bufTable[clockHand].Clear();
						
						frame = clockHand;
						return OK;
					}
				}
			}
			//cout << "Clockhand = " << clockHand << endl;	
		}while(clockHand != temp);

   	return BUFFEREXCEEDED;   
}
Esempio n. 2
0
/*
* Allocates a free frame using the clock algorithm; if necessary, writing a dirty page back
* to disk.  Throws BufferExceededException if all buffer frames are pinned.  This private
* method will get called by the readPage() and allocPage() methods described below. Make
* sure that if the buffer frame allocated has a valid page in it, you remove the appropriate
* entry from the hash table.
*/
void BufMgr::allocBuf(FrameId & frame) 
{
	std::uint32_t scannedNum= 0;
	bool foundbuffer= false;
	
	while (scannedNum < numBufs)
	{
		scannedNum++;
		//advance the clock
		advanceClock();
		
		//check if buffer is valid (if already has file), if not use the buffer
		if (!bufDescTable[clockhand].valid)
		{
			break;
		}
		
		//check if refbit is set and if it is pinned. if has not been referenced and pincount is 0, use it
		if (!bufDescTable[clockhand].refbit && bufDescTable[clockhand].pinCnt==0)
		{
			foundbuffer= true;
			//remove previous entry from the hashtable
			hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo);
		//if has bee referenced clear the bit
		else
		{
			bufDescTable[clockHand].refbit= false;
		}
	}
Esempio n. 3
0
TrayIcon::TrayIcon(MainWindow* parent)
  : KStatusNotifierItem(parent)
{
    setObjectName( "Ktimetracker Tray" );
    // the timer that updates the "running" icon in the tray
    _taskActiveTimer = new QTimer(this);
    connect( _taskActiveTimer, SIGNAL( timeout() ), this,
                               SLOT( advanceClock()) );

    if (icons == 0)
    {
        icons = new QVector<QPixmap*>(8);
        for (int i=0; i<8; i++)
        {
            QPixmap *icon = new QPixmap();
        QString name;
        name.sprintf("active-icon-%d.xpm",i);
        *icon = UserIcon(name);
        icons->insert(i,icon);
        }
    }
    TimetrackerWidget *timetrackerWidget = static_cast< TimetrackerWidget * >( parent->centralWidget() );
    if ( timetrackerWidget )
    {
        KAction *action = timetrackerWidget->action( "configure_ktimetracker" );
        if ( action ) contextMenu()->addAction( action );
        action = timetrackerWidget->action( "stopAll" );
        if ( action ) contextMenu()->addAction( action );
    }
    resetClock();
    initToolTip();
}
TEST_F(CachingCorrectnessTest, FreshWithStaleRedirect)
{
    KURL redirectUrl(ParsedURLString, kResourceURL);
    const char redirectTargetUrlString[] = "http://redirect-target.com";
    KURL redirectTargetUrl(ParsedURLString, redirectTargetUrlString);

    ResourcePtr<Resource> firstResource = new Resource(ResourceRequest(redirectUrl), Resource::Raw);

    ResourceResponse stale301Response;
    stale301Response.setURL(redirectUrl);
    stale301Response.setHTTPStatusCode(301);
    stale301Response.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString);
    stale301Response.setHTTPHeaderField(HTTPNames::Location, redirectTargetUrlString);

    // Add the redirect to our request.
    ResourceRequest redirectRequest = ResourceRequest(redirectTargetUrl);
    firstResource->willFollowRedirect(redirectRequest, stale301Response);

    // Add the final response to our request.
    ResourceResponse fresh200Response;
    fresh200Response.setURL(redirectTargetUrl);
    fresh200Response.setHTTPStatusCode(200);
    fresh200Response.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString);
    fresh200Response.setHTTPHeaderField(HTTPNames::Expires, kOneDayAfterOriginalRequest);

    firstResource->setResponse(fresh200Response);
    memoryCache()->add(firstResource.get());

    advanceClock(500.);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(firstResource, fetched);
}
TEST_F(ScopedUsHistogramTimerTest, Basic)
{
    TestCustomCountHistogram scopedUsCounter("test", 0, 10000000, 50);
    {
        ScopedUsHistogramTimer timer(scopedUsCounter);
        advanceClock(0.5);
    }
    // 0.5s == 500000us
    EXPECT_EQ(500000, scopedUsCounter.histogram()->SnapshotSamples()->sum());
}
// If the image has been loaded in this "document" before, then it should have list of available images logic, and so
// normal cache testing should be bypassed.
TEST_F(CachingCorrectnessTest, ReuseImageExpiredFromExpires)
{
    ResourceResponse expired200Response;
    expired200Response.setHTTPStatusCode(200);
    expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
    expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);

    ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response, Resource::Image);

    // Advance the clock within the freshness period, and make a request to add this image to the document resources.
    advanceClock(15.);
    ResourcePtr<Resource> firstFetched = fetchImage();
    EXPECT_EQ(expired200, firstFetched);

    // Advance the clock within the expiredness period of this resource before we make a request.
    advanceClock(24. * 60. * 60. + 15.);

    ResourcePtr<Resource> fetched = fetchImage();
    EXPECT_EQ(expired200, fetched);
}
// The strong validator causes a revalidation to be launched, and the proxy and original resources leak because of their reference loop.
TEST_F(CachingCorrectnessTest, DISABLED_ExpiredFromLastModified)
{
    ResourceResponse expired200Response;
    expired200Response.setHTTPStatusCode(200);
    expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
    expired200Response.setHTTPHeaderField("Last-Modified", kOneDayBeforeOriginalRequest);

    ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);

    // Advance the clock beyond the implicit freshness period.
    advanceClock(24. * 60. * 60. * 0.2);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(expired200, fetched);
}
TEST_F(CachingCorrectnessTest, ExpiredFromMaxAge)
{
    ResourceResponse expired200Response;
    expired200Response.setHTTPStatusCode(200);
    expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
    expired200Response.setHTTPHeaderField("Cache-Control", "max-age=600");

    ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);

    // Advance the clock within the expiredness period of this resource before we make a request.
    advanceClock(700.);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(expired200, fetched);
}
TEST_F(CachingCorrectnessTest, ExpiredFromExpires)
{
    ResourceResponse expired200Response;
    expired200Response.setHTTPStatusCode(200);
    expired200Response.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
    expired200Response.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);

    ResourcePtr<Resource> expired200 = resourceFromResourceResponse(expired200Response);

    // Advance the clock within the expiredness period of this resource before we make a request.
    advanceClock(24. * 60. * 60. + 15.);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(expired200, fetched);
}
TEST_F(CachingCorrectnessTest, FreshButNoStore)
{
    ResourceResponse fresh200NostoreResponse;
    fresh200NostoreResponse.setHTTPStatusCode(200);
    fresh200NostoreResponse.setHTTPHeaderField("Date", kOriginalRequestDateAsString);
    fresh200NostoreResponse.setHTTPHeaderField("Expires", kOneDayAfterOriginalRequest);
    fresh200NostoreResponse.setHTTPHeaderField("Cache-Control", "no-store");

    ResourcePtr<Resource> fresh200Nostore = resourceFromResourceResponse(fresh200NostoreResponse);

    // Advance the clock within the freshness period of this resource before we make a request.
    advanceClock(24. * 60. * 60. - 15.);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(fresh200Nostore, fetched);
}
// FIXME: Determine if ignoring must-revalidate for blink is correct behaviour.
// See crbug.com/340088 .
TEST_F(CachingCorrectnessTest, DISABLED_FreshButMustRevalidate)
{
    ResourceResponse fresh200MustRevalidateResponse;
    fresh200MustRevalidateResponse.setHTTPStatusCode(200);
    fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Date, kOriginalRequestDateAsString);
    fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Expires, kOneDayAfterOriginalRequest);
    fresh200MustRevalidateResponse.setHTTPHeaderField(HTTPNames::Cache_Control, "must-revalidate");

    ResourcePtr<Resource> fresh200MustRevalidate = resourceFromResourceResponse(fresh200MustRevalidateResponse);

    // Advance the clock within the freshness period of this resource before we make a request.
    advanceClock(24. * 60. * 60. - 15.);

    ResourcePtr<Resource> fetched = fetch();
    EXPECT_NE(fresh200MustRevalidate, fetched);
}
Esempio n. 12
0
/*
 * Allocates a free frame using the clock algorithm; 
 * if necessary, writing a dirty page back to disk. 
 *
 * Throws BufferExceededException if all buffer frames are pinned.
 * params: FrameId & frame
 */
void BufMgr::allocBuf(FrameId & frame) 
{
  uint32_t pinnedPageCnt = 0;	
  	
  // implementation of the clock algorithm
  // remember to change the while(true)
  while(true) {  
    advanceClock();
    BufDesc* tmpbuf = &(bufDescTable[clockHand]);
	
	// if invalid then allocate this page
	if (tmpbuf->valid == false) {
      frame = clockHand;
      return;
	}
	// if refbit is set then clear and advance clock
	else if (tmpbuf->refbit == true) {
		tmpbuf->refbit = false;
		continue;
	}
	// ignore if page pinned
	else if (tmpbuf->pinCnt > 0) {
		pinnedPageCnt = pinnedPageCnt + 1;
		if(pinnedPageCnt >= numBufs) {
			throw BufferExceededException();
		}
		continue;
	}
	
	// frame can be used
	// if the page is dirty flush to disk
	if (tmpbuf->dirty == true) {
	  tmpbuf->file->writePage(bufPool[clockHand]);
	  tmpbuf->dirty = false;
	}
	
	// now we can select this frame
	frame = clockHand;
	
	//remove from hashtable
	hashTable->remove(tmpbuf->file, tmpbuf->pageNo);
    return;
  }
}
Esempio n. 13
0
/**
 * Allocates a frame using the clock algorithm. 
 * If the frame is dirty, writes it back to disk.  
 * If all buffer frames are pinned, returns BUFFEREXCEEDED.  
 * If the call to the I/O layer returned an error when a dirty page was being written to disk, returns UNIXERR.
 * Otherwise, returns OK.
 *
 * @param frame frame being allocated
 * @return status the status of the function call 
 **/ 
const Status BufMgr::allocBuf(int & frame) 
{
  // number of frames that have been pinned
  int frameCnt = 0; 
 
  while (frameCnt < numBufs) {
    advanceClock();

    if (bufTable[clockHand].valid == false){
      frame = clockHand;
      return OK;
    } else { 
      BufDesc* desc = &(bufTable[clockHand]);     
      
      if (desc->refbit) {
        desc->refbit = false;
      } else {
        if (desc->pinCnt == 0){ 

	  // if the frame is dirty, write it back to disk
	  Status status;
	  if (desc->dirty) {
	    status = (desc->file)->writePage(desc->pageNo, &(bufPool[clockHand]));
	    if (status != OK)
	      return status;
	    desc->dirty = false;
	  }
	  
	  // remove the corresponding entry in hashTable
	  hashTable->remove(bufTable[clockHand].file, bufTable[clockHand].pageNo);
          frame = clockHand;
          return OK;
        } else { 
          frameCnt++;          
        }
      }

    }
  }

  return BUFFEREXCEEDED;
}
Esempio n. 14
0
/**
* Allocate a free frame.  
*
* @param frame   	Frame reference, frame ID of allocated frame returned via this variable
* @throws BufferExceededException If no such buffer is found which can be allocated
*/
void BufMgr::allocBuf(FrameId & frame) 
{
	bool found = false;
	FrameId starting = clockHand;
	//Loop through the buffer pool until you find a valid frame to replace
	while(!found){
		advanceClock();
		if(bufDescTable[clockHand].valid){
			if(!bufDescTable[clockHand].refbit){
				if(bufDescTable[clockHand].pinCnt == 0){
					//we have found the correct frame
					found = true;
					hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo); //remove from hash table
					if(bufDescTable[clockHand].dirty){
						//write page to disk.
						bufDescTable[clockHand].file->writePage(bufPool[clockHand]);
					}
					else{
						bufDescTable[clockHand].Clear();
					}
					frame = bufDescTable[clockHand].frameNo;
				}
				else{
					if(starting == clockHand && !found){
						//we looped all the way around the buffer pool, throw an exception
						throw BufferExceededException();
					}
				}
			}
			else{
				//clear refbit
				bufDescTable[clockHand].refbit = false;
			}	
		}
		else{
			found = true;
			frame = bufDescTable[clockHand].frameNo;
		}
	}
	bufDescTable[clockHand].Clear();
}
Esempio n. 15
0
/** This function allocates a free frame using the clock algorithm;
if necessary, writing a dirty page back to disk.
Returns BUFFEREXCEEDED if all buffer frames are pinned,
UNIXERR if the call to the I/O layer returned an error when a dirty page was being written to disc; else OK.
This private method will get called by the readPage() and allocPage() methods.
If the buffer frame allocated has a valid page in it, then remove the appropriate entry from the hash table.
@param  frame-reference to the frame being allocated
@return Status-status information from function
**/
const Status BufMgr::allocBuf(int & frame) {

    int pinCount = 0;
    //unsigned int initialClockHand = clockHand;
    while(1){
        advanceClock();
        //if valid is false, clear and return frame number
        if (bufTable[clockHand].valid != false) {
            if (bufTable[clockHand].pinCnt > 0) {
                pinCount++;
            }
            //if pinCount reaches numBufs than every buffer frame is being referenced
            if (pinCount == numBufs) {
                return BUFFEREXCEEDED;
            }
            //The two loops in the logic diagram
            if (bufTable[clockHand].refbit == true) { //Check valid bit
                bufTable[clockHand].refbit = false;
                continue; //Loop if valid and refbit set
            } else if (bufTable[clockHand].refbit == false && bufTable[clockHand].pinCnt > 0){
                continue;
            // if valid, unreferenced, not pinned, and dirty; than flush page in frame to disc 
            } else if (bufTable[clockHand].refbit == false && bufTable[clockHand].pinCnt <= 0 && bufTable[clockHand].dirty == true) {
                assert(bufTable[clockHand].pinCnt == 0); //Sanity check
                /**Flush page to disk **/
                flushFile(bufTable[clockHand].file);
                bufTable[clockHand].dirty = false;
            }
            assert(bufTable[clockHand].dirty == false); //Should not be dirty
            assert(bufTable[clockHand].pinCnt == 0);    //Should be zero
            if (bufTable[clockHand].valid == true) {
                assert(bufTable[clockHand].pinCnt == 0);
                hashTable->remove(bufTable[clockHand].file, bufTable[clockHand].pageNo);
            }
        }//end valid == false
        //A frame has been selected for removal 
        bufTable[clockHand].Clear();
        frame = clockHand; //clear frame and return frame pointer
        return OK;
    }//end valid not equal to false
}// end function allocBuf
Esempio n. 16
0
void BufMgr::allocBuf(FrameId & frame) 
{ 
	std::uint32_t scanner = 0;
	bool cont = 0;
	while(scanner < 2*numBufs){
		advanceClock();
		scanner++;
		if(bufDescTable[clockHand].valid == false){
			break;
		}
		if(!(bufDescTable[clockHand].refbit)){
			if(bufDescTable[clockHand].pinCnt == 0){
				hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo);
				cont = true;
				break;

			}
		}
		else{
			bufStats.accesses++;
			bufDescTable[clockHand].refbit = false;
		}
	}
	if((!cont) && (scanner >= 2*numBufs-1)){
		throw BufferExceededException();
	}


	if(bufDescTable[clockHand].dirty && bufDescTable[clockHand].valid){
		bufStats.diskwrites++;
		bufDescTable[clockHand].file->writePage(bufPool[clockHand]);
	}
	

	bufDescTable[clockHand].Clear();
	//bufDescTable[clockHand].Set(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo);
	frame = clockHand;
}
Esempio n. 17
0
/*
 *
 * Allocate a free frame.  
 *
 * @param frame   	Frame reference, frame ID of allocated frame returned via this variable
 * @throws BufferExceededException If no such buffer is found which can be allocated
 */
void BufMgr::allocBuf(FrameId & frame) 
{
	std::uint32_t clock_count = 0;
	//clock algorithm
	while(1){
		advanceClock();
		if(bufDescTable[clockHand].valid == true){
			if(bufDescTable[clockHand].refbit == true){
				bufDescTable[clockHand].refbit = false;
				//skip all the steps below and loop again
				continue;
			}
			if(bufDescTable[clockHand].pinCnt > 0){
				clock_count++;
				//if every pages is being pinned in buffer pool, throw exception
				if(clock_count > numBufs){
					throw BufferExceededException();
				}
				continue;
			}
			if(bufDescTable[clockHand].dirty == true){
				flushFile(bufDescTable[clockHand].file);
				bufDescTable[clockHand].dirty = false;
			}
			else{
				hashTable->remove(bufDescTable[clockHand].file, bufDescTable[clockHand].pageNo);
			}
			break;
		}
		else{
			break;
		}
	}

	frame = bufDescTable[clockHand].frameNo;
}
Esempio n. 18
0
const Status BufMgr::allocBuf(int & frame) 
{
    // perform first part of clock algorithm to search for 
    // open buffer frame
    // Assumes non-concurrent access to buffer manager
    Status status = OK;
    int numScanned = 0;
    bool found = 0;
    while (numScanned < 2*numBufs)
    {
        // advance the clock
        advanceClock();
        numScanned++;

        // if invalid, use frame
        if (! bufTable[clockHand].valid)
        {
            break;
        }

        // is valid, check referenced bit
        if (! bufTable[clockHand].refbit)
        {
            // check to see if someone has it pinned
            if (bufTable[clockHand].pinCnt == 0)
            {
                // hasn't been referenced and is not pinned, use it

                // remove previous entry from hash table
                status = hashTable->remove(bufTable[clockHand].file, 
                                           bufTable[clockHand].pageNo);
                found = true;
                //if (status != OK) return status;
                break;
            }
        }
        else
        {
            // has been referenced, clear the bit
            bufStats.accesses++;
            bufTable[clockHand].refbit = false;
        }
    }
    
    // check for full buffer pool
    if (!found && numScanned >= 2*numBufs)
    {
        return BUFFEREXCEEDED;
    }
    
    // flush any existing changes to disk if necessary
    if (bufTable[clockHand].dirty)
    {
        bufStats.diskwrites++;

        status = bufTable[clockHand].file->writePage(bufTable[clockHand].pageNo,
                                                     &bufPool[clockHand]);
        if (status != OK) return status;
    }

    // return new frame number
    frame = clockHand;

    return OK;
} // end allocBuf