00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "fennel/common/CommonPreamble.h"
00025 #include "fennel/test/SegmentTestBase.h"
00026 #include "fennel/segment/LinearDeviceSegment.h"
00027 #include "fennel/segment/SegPageLock.h"
00028
00029 #ifdef HAVE_SCHED_H
00030 #include <sched.h>
00031 #endif
00032
00033 #include <boost/test/test_tools.hpp>
00034
00035 using namespace fennel;
00036
00037 void SegmentTestBase::openStorage(DeviceMode openMode)
00038 {
00039 SegStorageTestBase::openStorage(openMode);
00040 cbPageUsable = pLinearSegment->getUsablePageSize();
00041 if (!pRandomSegment) {
00042 threadCounts[OP_ALLOCATE] = 0;
00043 threadCounts[OP_DEALLOCATE] = 0;
00044 }
00045 }
00046
00047 CachePage *SegmentTestBase::lockPage(OpType opType,uint iPage)
00048 {
00049 SegmentAccessor segmentAccessor(pLinearSegment,pCache);
00050 SegPageLock pageLock(segmentAccessor);
00051 if (opType == OP_ALLOCATE) {
00052 PageId pageId = pageLock.allocatePage(objId);
00053 assert(Segment::getLinearBlockNum(pageId) == iPage);
00054 CachePage &page = pageLock.getPage();
00055 fillPage(page,iPage);
00056 pageLock.dontUnlock();
00057 return &page;
00058 } else {
00059 PageId pageId = Segment::getLinearPageId(iPage);
00060
00061 if (opType == OP_WRITE_SEQ || opType == OP_WRITE_RAND ||
00062 opType == OP_WRITE_SKIP)
00063 {
00064 pLinearSegment->updatePage(pageId, true);
00065 }
00066 pageLock.lockPage(pageId,getLockMode(opType));
00067 CachePage *pPage = pageLock.isLocked() ? &(pageLock.getPage()) : NULL;
00068 pageLock.dontUnlock();
00069 return pPage;
00070 }
00071 }
00072
00073 void SegmentTestBase::unlockPage(CachePage &page,LockMode lockMode)
00074 {
00075 getCache().unlockPage(page,lockMode);
00076 }
00077
00078 void SegmentTestBase::prefetchPage(uint iPage)
00079 {
00080 PageId pageId = Segment::getLinearPageId(iPage);
00081 BlockId blockId = pLinearSegment->translatePageId(pageId);
00082 getCache().prefetchPage(blockId,pLinearSegment.get());
00083 }
00084
00085 void SegmentTestBase::prefetchBatch(uint,uint)
00086 {
00087 permAssert(false);
00088 }
00089
00090 void SegmentTestBase::testAllocate()
00091 {
00092 assert(pRandomSegment);
00093
00094 uint i;
00095 SegmentAccessor segmentAccessor(pRandomSegment,pCache);
00096 for (i = 0; i < nRandomOps; ++i) {
00097 #ifdef HAVE_SCHED_H
00098 sched_yield();
00099 #else
00100
00101 #endif
00102 SegPageLock pageLock(segmentAccessor);
00103 PageId pageId = pageLock.tryAllocatePage(objId);
00104 if (pageId == NULL_PAGE_ID) {
00105 break;
00106 }
00107 pageLock.unlock();
00108 StrictMutexGuard freeablePagesGuard(freeablePagesMutex);
00109 freeablePages.push_back(pageId);
00110 }
00111 if (i) {
00112 StrictMutexGuard logGuard(logMutex);
00113 BOOST_MESSAGE("completed " << i << " allocate ops");
00114 }
00115 }
00116
00117 void SegmentTestBase::testDeallocate()
00118 {
00119 assert(pRandomSegment);
00120
00121 uint i;
00122 SegmentAccessor segmentAccessor(pRandomSegment,pCache);
00123 for (i = 0; i < nRandomOps; ++i) {
00124 #ifdef HAVE_SCHED_H
00125 sched_yield();
00126 #else
00127
00128 #endif
00129 StrictMutexGuard freeablePagesGuard(freeablePagesMutex);
00130 if (freeablePages.empty()) {
00131 break;
00132 }
00133 uint i = generateRandomNumber(freeablePages.size());
00134 PageId pageId = freeablePages[i];
00135 freeablePages.erase(freeablePages.begin() + i);
00136 freeablePagesGuard.unlock();
00137 SegPageLock pageLock(segmentAccessor);
00138 pageLock.lockShared(pageId);
00139 pageLock.deallocateLockedPage();
00140 }
00141 if (i) {
00142 StrictMutexGuard logGuard(logMutex);
00143 BOOST_MESSAGE("completed " << i << " deallocate ops");
00144 }
00145 }
00146
00147 void SegmentTestBase::testCheckpoint()
00148 {
00149 pLinearSegment->checkpoint(CHECKPOINT_FLUSH_ALL);
00150 }
00151
00152 SegmentTestBase::SegmentTestBase()
00153 {
00154
00155 threadCounts[OP_SCRATCH] = 0;
00156 threadCounts[OP_PREFETCH_BATCH] = 0;
00157
00158 objId = ANON_PAGE_OWNER_ID;
00159 }
00160
00161 void SegmentTestBase::testSingleThread()
00162 {
00163 openStorage(DeviceMode::createNew);
00164 testAllocateAll();
00165 testSequentialRead();
00166 testSequentialWrite();
00167 testRandomRead();
00168 closeStorage();
00169 openStorage(DeviceMode::load);
00170 testRandomRead();
00171 testRandomWrite();
00172 testSequentialRead();
00173 closeStorage();
00174 freeablePages.clear();
00175 }
00176
00177