Fennel: /home/pub/open/dev/fennel/test/CacheTest.cpp Source File (original) (raw)

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/CacheTestBase.h" 00026 #include "fennel/test/PagingTestBase.h" 00027 #include "fennel/cache/Cache.h" 00028 #include "fennel/cache/QuotaCacheAccessor.h" 00029 #include "fennel/common/CompoundId.h" 00030 00031 #include <boost/test/test_tools.hpp> 00032 00033 #ifdef HAVE_MMAP 00034 #include <sys/resource.h> 00035 #endif 00036 00037 using namespace fennel; 00038 00039 #define SMALL_ADDR_SPACE (192 * 1024 * 1024) // 192 MB 00040 00051 class CacheTest : virtual public PagingTestBase 00052 { 00053 public: 00057 BlockId makeBlockId(uint i) 00058 { 00059 assert(i < nDiskPages); 00060 BlockId blockId(0); 00061 CompoundId::setDeviceId(blockId,dataDeviceId); 00062 CompoundId::setBlockNum(blockId,i); 00063 return blockId; 00064 } 00065 00066 virtual CachePage *lockPage(OpType opType,uint iPage) 00067 { 00068 BlockId blockId = makeBlockId(iPage); 00069 return getCache().lockPage( 00070 blockId,getLockMode(opType),opType != OP_ALLOCATE); 00071 } 00072 00073 virtual void unlockPage(CachePage &page,LockMode lockMode) 00074 { 00075 getCache().unlockPage(page,lockMode); 00076 } 00077 00078 virtual void prefetchPage(uint iPage) 00079 { 00080 BlockId blockId = makeBlockId(iPage); 00081 getCache().prefetchPage(blockId); 00082 } 00083 00084 virtual void prefetchBatch(uint iPage,uint nPagesPerBatch) 00085 { 00086 BlockId blockId = makeBlockId(iPage); 00087 getCache().prefetchBatch(blockId,nPagesPerBatch); 00088 } 00089 00090 explicit CacheTest() 00091 { 00092
00093 threadCounts[OP_ALLOCATE] = 0; 00094 threadCounts[OP_DEALLOCATE] = 0; 00095 00096 cbPageUsable = cbPageFull; 00097 00098 FENNEL_UNIT_TEST_CASE(CacheTest,testSingleThread); 00099 FENNEL_UNIT_TEST_CASE(CacheTest,testQuotaCacheAccessor); 00100 FENNEL_UNIT_TEST_CASE(PagingTestBase,testMultipleThreads); 00101 00102 #ifdef RLIMIT_AS 00103 FENNEL_EXTRA_UNIT_TEST_CASE(CacheTest,testLargeCacheInit); 00104 FENNEL_EXTRA_UNIT_TEST_CASE(CacheTest,testLargeCacheRequest); 00105 #endif 00106 } 00107 00108 void testSingleThread() 00109 { 00110 openStorage(DeviceMode::createNew); 00111 testAllocateAll(); 00112 testSequentialRead(); 00113 testRandomRead(); 00114 testScratch(); 00115 testSequentialWrite(); 00116 testRandomWrite(); 00117 closeStorage(); 00118 openStorage(DeviceMode::load); 00119 testRandomRead(); 00120 testSequentialRead(); 00121 closeStorage(); 00122 } 00123 00124 void testQuotaCacheAccessor() 00125 { 00126 openStorage(DeviceMode::createNew); 00127 QuotaCacheAccessor *pQuota = new QuotaCacheAccessor( 00128 SharedQuotaCacheAccessor(),pCache,5); 00129 SharedCacheAccessor pSharedQuota(pQuota); 00130 BOOST_CHECK_EQUAL(pQuota->getMaxLockedPages(),5U); 00131 BOOST_CHECK_EQUAL(pQuota->getLockedPageCount(),0U); 00132 CachePage *pPage = pQuota->lockPage(makeBlockId(0),LOCKMODE_S,0); 00133 BOOST_CHECK_EQUAL(pQuota->getLockedPageCount(),1U); 00134 pQuota->unlockPage(*pPage,LOCKMODE_S); 00135 BOOST_CHECK_EQUAL(pQuota->getLockedPageCount(),0U); 00136 pSharedQuota.reset(); 00137 closeStorage(); 00138 } 00139 00140 #ifdef RLIMIT_AS 00141
00142
00143 rlim_t setAddressSpaceLimit(rlim_t minLimit, struct rlimit &oldLimits) 00144 { 00145 int rv = getrlimit(RLIMIT_AS, &oldLimits); 00146 BOOST_REQUIRE(rv == 0); 00147 00148
00149 if (oldLimits.rlim_cur > minLimit) { 00150
00151 struct rlimit new_limits; 00152 new_limits.rlim_cur = minLimit; 00153 new_limits.rlim_max = oldLimits.rlim_max; 00154 00155 rv = setrlimit(RLIMIT_AS, &new_limits); 00156 BOOST_REQUIRE(rv == 0); 00157 00158 return minLimit; 00159 } 00160 00161 return oldLimits.rlim_cur; 00162 } 00163 00164
00165 void restoreAddressSpaceLimit(const struct rlimit &limits) 00166 { 00167
00168 int rv = setrlimit(RLIMIT_AS, &limits); 00169 BOOST_REQUIRE(rv == 0); 00170 } 00171 00172 uint computeMaxPagesUpperBound(uint addressSpaceSize, uint pageSize) 00173 { 00174 int guardPages = 0; 00175 #ifndef NDEBUG 00176
00177 guardPages = 2; 00178 #endif 00179 int osPageSize = getpagesize(); 00180 00181 return addressSpaceSize / (pageSize + (guardPages * osPageSize) + 4); 00182 } 00183 00184 void testLargeCacheInit() 00185 { 00186 struct rlimit savedLimits; 00187 00188 rlim_t addrSpaceSize = setAddressSpaceLimit( 00189 SMALL_ADDR_SPACE, savedLimits); 00190 00191 CacheParams params; 00192 00193
00194
00195
00196 params.nMemPagesMax = addrSpaceSize / sizeof(void *) + 100; 00197 params.nMemPagesInit = 10; 00198 00199 SharedCache pCache; 00200 00201 BOOST_CHECK_NO_THROW(pCache = Cache::newCache(params)); 00202 BOOST_CHECK_EQUAL( 00203 CacheParams::defaultMemPagesMax, 00204 pCache->getMaxAllocatedPageCount()); 00205 00206
00207
00208
00209
00210 BOOST_CHECK_EQUAL( 00211 CacheParams::defaultMemPagesMax, 00212 pCache->getAllocatedPageCount()); 00213 00214 pCache.reset(); 00215 00216
00217
00218 00219
00220
00221
00222
00223
00224
00225 params.cbPage = 32 * 1024; 00226 00227 params.nMemPagesMax = 00228 computeMaxPagesUpperBound(addrSpaceSize, params.cbPage); 00229 params.nMemPagesInit = params.nMemPagesMax; 00230 00231 BOOST_CHECK_NO_THROW(pCache = Cache::newCache(params)); 00232 BOOST_CHECK_EQUAL( 00233 CacheParams::defaultMemPagesMax, 00234 pCache->getMaxAllocatedPageCount()); 00235 00236
00237 BOOST_CHECK_EQUAL( 00238 CacheParams::defaultMemPagesMax, 00239 pCache->getAllocatedPageCount()); 00240 00241 pCache.reset(); 00242 00243 restoreAddressSpaceLimit(savedLimits); 00244 } 00245 00246 void testLargeCacheRequest() 00247 { 00248 struct rlimit savedLimits; 00249 00250 rlim_t addrSpaceSize = 00251 setAddressSpaceLimit(SMALL_ADDR_SPACE, savedLimits); 00252 00253 CacheParams params; 00254 00255
00256
00257 params.cbPage = 32 * 1024; 00258 00259 params.nMemPagesMax = 00260 computeMaxPagesUpperBound(addrSpaceSize, params.cbPage); 00261 params.nMemPagesInit = 00262 (params.nMemPagesMax / 2) < 1000 00263 ? (params.nMemPagesMax / 2) 00264 : 1000; 00265 00266 BOOST_CHECK_NO_THROW(pCache = Cache::newCache(params)); 00267 BOOST_CHECK_EQUAL( 00268 params.nMemPagesMax, 00269 pCache->getMaxAllocatedPageCount()); 00270 BOOST_CHECK_EQUAL( 00271 params.nMemPagesInit, 00272 pCache->getAllocatedPageCount()); 00273 00274 BOOST_CHECK_THROW( 00275 pCache->setAllocatedPageCount(params.nMemPagesMax), 00276 std::exception); 00277 BOOST_CHECK_EQUAL( 00278 params.nMemPagesMax, 00279 pCache->getMaxAllocatedPageCount()); 00280 BOOST_CHECK_EQUAL( 00281 params.nMemPagesInit, 00282 pCache->getAllocatedPageCount()); 00283 00284 pCache.reset(); 00285 00286 restoreAddressSpaceLimit(savedLimits); 00287 } 00288 #endif // RLIMIT_AS 00289 }; 00290 00291 FENNEL_UNIT_TEST_SUITE(CacheTest); 00292 00293