PtexCache.h
Go to the documentation of this file.
#ifndef PtexCache_h
#define PtexCache_h
/*
PTEX SOFTWARE
Copyright 2014 Disney Enterprises, Inc. All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
Studios" or the names of its contributors may NOT be used to
endorse or promote products derived from this software without
specific prior written permission from Walt Disney Pictures.
Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include "PtexPlatform.h"
#include <cstddef>
#include "PtexMutex.h"
#include "PtexHashMap.h"
#include "PtexReader.h"
PTEX_NAMESPACE_BEGIN
// Intrusive LRU list item (to be used only by PtexLruList)
class PtexLruItem
{
PtexLruItem* _prev;
PtexLruItem* _next;
void extract() {
_next->_prev = _prev;
_prev->_next = _next;
_next = _prev = this;
}
public:
PtexLruItem() : _prev(this), _next(this) {}
// add item to end of list (pointed to by _prev)
void push(PtexLruItem* item) {
item->extract();
_prev->_next = item;
item->_next = this;
item->_prev = _prev;
_prev = item;
}
// remove item from front of list (pointed to by _next)
PtexLruItem* pop() {
if (_next == this) return 0;
PtexLruItem* item = _next;
_next->extract();
return item;
}
};
// Intrusive LRU list (with LRU item stored as member of T)
template<class T, PtexLruItem T::*item>
class PtexLruList
{
PtexLruItem _end;
public:
void push(T* node)
{
// the item is added to the intrusive pointer specified by the template
// templatization allows more than one intrusive list to be in the object
_end.push(&(node->*item));
}
T* pop()
{
PtexLruItem* it = _end.pop();
// "it" points to the intrusive item, a member within T
// subtract off the pointer-to-member offset to get a pointer to the containing T object
static const T* dummy = 0;
static const std::ptrdiff_t itemOffset = (const char*)&(dummy->*item) - (const char*)dummy;
return it ? (T*) ((char*)it - itemOffset) : 0;
}
};
class PtexReaderCache;
class PtexCachedReader : public PtexReader
{
PtexReaderCache* _cache;
volatile int32_t _refCount;
size_t _memUsedAccountedFor;
size_t _opensAccountedFor;
size_t _blockReadsAccountedFor;
PtexLruItem _openFilesItem;
PtexLruItem _activeFilesItem;
friend class PtexReaderCache;
bool trylock()
{
return AtomicCompareAndSwap(&_refCount, 0, -1);
}
void unlock()
{
AtomicStore(&_refCount, 0);
}
public:
PtexCachedReader(bool premultiply, PtexInputHandler* inputHandler, PtexErrorHandler* errorHandler, PtexReaderCache* cache)
: PtexReader(premultiply, inputHandler, errorHandler), _cache(cache), _refCount(1),
_memUsedAccountedFor(0), _opensAccountedFor(0), _blockReadsAccountedFor(0)
{
}
~PtexCachedReader() {}
void ref() {
while (1) {
int32_t oldCount = _refCount;
if (oldCount >= 0 && AtomicCompareAndSwap(&_refCount, oldCount, oldCount+1))
return;
}
}
int32_t unref() {
return AtomicDecrement(&_refCount);
}
virtual void release();
bool tryPrune(size_t& memUsedChange) {
if (trylock()) {
prune();
memUsedChange = getMemUsedChange();
unlock();
return true;
}
return false;
}
bool tryPurge(size_t& memUsedChange) {
if (trylock()) {
purge();
memUsedChange = getMemUsedChange();
unlock();
return true;
}
setPendingPurge();
return false;
}
size_t getMemUsedChange() {
size_t memUsedTmp = _memUsed;
size_t result = memUsedTmp - _memUsedAccountedFor;
_memUsedAccountedFor = memUsedTmp;
return result;
}
size_t getOpensChange() {
size_t opensTmp = _opens;
size_t result = opensTmp - _opensAccountedFor;
_opensAccountedFor = opensTmp;
return result;
}
size_t getBlockReadsChange() {
size_t blockReadsTmp = _blockReads;
size_t result = blockReadsTmp - _blockReadsAccountedFor;
_blockReadsAccountedFor = blockReadsTmp;
return result;
}
};
class PtexReaderCache : public PtexCache
{
public:
PtexReaderCache(int maxFiles, size_t maxMem, bool premultiply, PtexInputHandler* inputHandler, PtexErrorHandler* errorHandler)
: _maxFiles(maxFiles), _maxMem(maxMem), _io(inputHandler), _err(errorHandler), _premultiply(premultiply),
_memUsed(sizeof(*this)), _filesOpen(0), _mruList(&_mruLists[0]), _prevMruList(&_mruLists[1]),
_peakMemUsed(0), _peakFilesOpen(0), _fileOpens(0), _blockReads(0)
{
memset((void*)&_mruLists[0], 0, sizeof(_mruLists));
CACHE_LINE_PAD_INIT(_memUsed); // keep cppcheck happy
CACHE_LINE_PAD_INIT(_filesOpen);
CACHE_LINE_PAD_INIT(_mruLock);
}
~PtexReaderCache()
{}
virtual void release() { delete this; }
virtual void setSearchPath(const char* path)
{
// record path
_searchpath = path ? path : "";
// split into dirs
_searchdirs.clear();
if (path) {
const char* cp = path;
while (1) {
const char* delim = strchr(cp, ':');
if (!delim) {
if (*cp) _searchdirs.push_back(cp);
break;
}
int len = int(delim-cp);
if (len) _searchdirs.push_back(std::string(cp, len));
cp = delim+1;
}
}
}
virtual const char* getSearchPath()
{
return _searchpath.c_str();
}
virtual PtexTexture* get(const char* path, Ptex::String& error);
virtual void purge(PtexTexture* /*texture*/);
virtual void purge(const char* /*filename*/);
virtual void purgeAll();
virtual void getStats(Stats& stats);
void purge(PtexCachedReader* reader);
void adjustMemUsed(size_t amount) {
if (amount) {
size_t memUsed = AtomicAdd(&_memUsed, amount);
_peakMemUsed = std::max(_peakMemUsed, memUsed);
}
}
void adjustFilesOpen(size_t amount) {
if (amount) {
size_t filesOpen = AtomicAdd(&_filesOpen, amount);
_peakFilesOpen = std::max(_peakFilesOpen, filesOpen);
}
}
void logRecentlyUsed(PtexCachedReader* reader);
private:
struct Purger {
size_t memUsedChangeTotal;
Purger() : memUsedChangeTotal(0) {}
void operator() (PtexCachedReader* reader);
};
bool findFile(const char*& filename, std::string& buffer, Ptex::String& error);
void processMru();
void pruneFiles();
void pruneData();
size_t _maxFiles;
size_t _maxMem;
PtexInputHandler* _io;
PtexErrorHandler* _err;
std::string _searchpath;
std::vector<std::string> _searchdirs;
typedef PtexHashMap<StringKey,PtexCachedReader*> FileMap;
FileMap _files;
bool _premultiply;
volatile size_t _memUsed; CACHE_LINE_PAD(_memUsed,size_t);
volatile size_t _filesOpen; CACHE_LINE_PAD(_filesOpen,size_t);
Mutex _mruLock; CACHE_LINE_PAD(_mruLock,Mutex);
static const int numMruFiles = 50;
struct MruList {
volatile int next;
PtexCachedReader* volatile files[numMruFiles];
};
MruList _mruLists[2];
MruList* volatile _mruList;
MruList* volatile _prevMruList;
PtexLruList<PtexCachedReader, &PtexCachedReader::_openFilesItem> _openFiles;
PtexLruList<PtexCachedReader, &PtexCachedReader::_activeFilesItem> _activeFiles;
size_t _peakMemUsed;
size_t _peakFilesOpen;
size_t _fileOpens;
size_t _blockReads;
};
PTEX_NAMESPACE_END
#endif
PtexHashMap.h
Contains PtexHashMap, a lightweight multi-threaded hash table.
PtexMutex.h
PtexPlatform.h
Platform-specific classes, functions, and includes.
AtomicAdd
PTEX_INLINE T AtomicAdd(volatile T *target, T value)
Definition PtexPlatform.h:209
CACHE_LINE_PAD_INIT
#define CACHE_LINE_PAD_INIT(var)
Definition PtexPlatform.h:301
AtomicDecrement
PTEX_INLINE T AtomicDecrement(volatile T *target)
Definition PtexPlatform.h:247
CACHE_LINE_PAD
#define CACHE_LINE_PAD(var, type)
Definition PtexPlatform.h:300
AtomicStore
PTEX_INLINE void AtomicStore(T volatile *target, T value)
Definition PtexPlatform.h:284
AtomicCompareAndSwap
PTEX_INLINE bool AtomicCompareAndSwap(T volatile *target, T oldvalue, T newvalue)
Definition PtexPlatform.h:278
PtexReader.h
PTEX_NAMESPACE_END
#define PTEX_NAMESPACE_END
Definition PtexVersion.h:62
Mutex
Definition PtexPlatform.h:137
PtexCache
File-handle and memory cache for reading ptex files.
Definition Ptexture.h:684
PtexCachedReader
Definition PtexCache.h:109
PtexCachedReader::trylock
bool trylock()
Definition PtexCache.h:119
PtexCachedReader::_memUsedAccountedFor
size_t _memUsedAccountedFor
Definition PtexCache.h:112
PtexCachedReader::_cache
PtexReaderCache * _cache
Definition PtexCache.h:110
PtexCachedReader::_opensAccountedFor
size_t _opensAccountedFor
Definition PtexCache.h:113
PtexCachedReader::unref
int32_t unref()
Definition PtexCache.h:146
PtexCachedReader::tryPurge
bool tryPurge(size_t &memUsedChange)
Definition PtexCache.h:162
PtexCachedReader::getMemUsedChange
size_t getMemUsedChange()
Definition PtexCache.h:173
PtexCachedReader::PtexCachedReader
PtexCachedReader(bool premultiply, PtexInputHandler *inputHandler, PtexErrorHandler *errorHandler, PtexReaderCache *cache)
Definition PtexCache.h:130
PtexCachedReader::tryPrune
bool tryPrune(size_t &memUsedChange)
Definition PtexCache.h:152
PtexCachedReader::~PtexCachedReader
~PtexCachedReader()
Definition PtexCache.h:136
PtexCachedReader::release
virtual void release()
Release resources held by this pointer (pointer becomes invalid).
Definition PtexCache.cpp:83
PtexCachedReader::_activeFilesItem
PtexLruItem _activeFilesItem
Definition PtexCache.h:116
PtexCachedReader::ref
void ref()
Definition PtexCache.h:138
PtexCachedReader::_blockReadsAccountedFor
size_t _blockReadsAccountedFor
Definition PtexCache.h:114
PtexCachedReader::_openFilesItem
PtexLruItem _openFilesItem
Definition PtexCache.h:115
PtexCachedReader::getBlockReadsChange
size_t getBlockReadsChange()
Definition PtexCache.h:187
PtexCachedReader::unlock
void unlock()
Definition PtexCache.h:124
PtexCachedReader::getOpensChange
size_t getOpensChange()
Definition PtexCache.h:180
PtexCachedReader::_refCount
volatile int32_t _refCount
Definition PtexCache.h:111
PtexErrorHandler
Custom handler interface redirecting Ptex error messages.
Definition Ptexture.h:658
PtexHashMap
Definition PtexHashMap.h:152
PtexInputHandler
Custom handler interface for intercepting and redirecting Ptex input stream calls.
Definition Ptexture.h:619
PtexLruItem
Definition PtexCache.h:50
PtexLruItem::pop
PtexLruItem * pop()
Definition PtexCache.h:73
PtexLruItem::extract
void extract()
Definition PtexCache.h:54
PtexLruItem::_prev
PtexLruItem * _prev
Definition PtexCache.h:51
PtexLruItem::PtexLruItem
PtexLruItem()
Definition PtexCache.h:61
PtexLruItem::push
void push(PtexLruItem *item)
Definition PtexCache.h:64
PtexLruItem::_next
PtexLruItem * _next
Definition PtexCache.h:52
PtexLruList
Definition PtexCache.h:84
PtexLruList::_end
PtexLruItem _end
Definition PtexCache.h:85
PtexLruList::pop
T * pop()
Definition PtexCache.h:95
PtexLruList::push
void push(T *node)
Definition PtexCache.h:88
PtexReaderCache
Cache for reading Ptex texture files.
Definition PtexCache.h:198
PtexReaderCache::_activeFiles
PtexLruList< PtexCachedReader, &PtexCachedReader::_activeFilesItem > _activeFiles
Definition PtexCache.h:301
PtexReaderCache::_searchpath
std::string _searchpath
Definition PtexCache.h:282
PtexReaderCache::_io
PtexInputHandler * _io
Definition PtexCache.h:280
PtexReaderCache::~PtexReaderCache
~PtexReaderCache()
Definition PtexCache.h:211
PtexReaderCache::_maxMem
size_t _maxMem
Definition PtexCache.h:279
PtexReaderCache::adjustFilesOpen
void adjustFilesOpen(size_t amount)
Definition PtexCache.h:259
PtexReaderCache::_fileOpens
size_t _fileOpens
Definition PtexCache.h:305
PtexReaderCache::_memUsed
volatile size_t _memUsed
Definition PtexCache.h:287
PtexReaderCache::_mruLock
Mutex _mruLock
Definition PtexCache.h:289
PtexReaderCache::logRecentlyUsed
void logRecentlyUsed(PtexCachedReader *reader)
Definition PtexCache.cpp:188
PtexReaderCache::pruneFiles
void pruneFiles()
Definition PtexCache.cpp:254
PtexReaderCache::_prevMruList
MruList *volatile _prevMruList
Definition PtexCache.h:298
PtexReaderCache::_files
FileMap _files
Definition PtexCache.h:285
PtexReaderCache::adjustMemUsed
void adjustMemUsed(size_t amount)
Definition PtexCache.h:253
PtexReaderCache::_premultiply
bool _premultiply
Definition PtexCache.h:286
PtexReaderCache::_peakMemUsed
size_t _peakMemUsed
Definition PtexCache.h:303
PtexReaderCache::release
virtual void release()
Release PtexCache. Cache will be immediately destroyed and all resources will be released.
Definition PtexCache.h:214
PtexReaderCache::setSearchPath
virtual void setSearchPath(const char *path)
Set a search path for finding textures.
Definition PtexCache.h:216
PtexReaderCache::getSearchPath
virtual const char * getSearchPath()
Query the search path.
Definition PtexCache.h:239
PtexReaderCache::get
virtual PtexTexture * get(const char *path, Ptex::String &error)
Access a texture.
Definition PtexCache.cpp:121
PtexReaderCache::findFile
bool findFile(const char *&filename, std::string &buffer, Ptex::String &error)
Definition PtexCache.cpp:91
PtexReaderCache::getStats
virtual void getStats(Stats &stats)
Get stats.
Definition PtexCache.cpp:326
PtexReaderCache::pruneData
void pruneData()
Definition PtexCache.cpp:270
PtexReaderCache::PtexReaderCache
PtexReaderCache(int maxFiles, size_t maxMem, bool premultiply, PtexInputHandler *inputHandler, PtexErrorHandler *errorHandler)
Definition PtexCache.h:200
PtexReaderCache::numMruFiles
static const int numMruFiles
Definition PtexCache.h:291
PtexReaderCache::_maxFiles
size_t _maxFiles
Definition PtexCache.h:278
PtexReaderCache::_peakFilesOpen
size_t _peakFilesOpen
Definition PtexCache.h:304
PtexReaderCache::_err
PtexErrorHandler * _err
Definition PtexCache.h:281
PtexReaderCache::_openFiles
PtexLruList< PtexCachedReader, &PtexCachedReader::_openFilesItem > _openFiles
Definition PtexCache.h:300
PtexReaderCache::FileMap
PtexHashMap< StringKey, PtexCachedReader * > FileMap
Definition PtexCache.h:284
PtexReaderCache::processMru
void processMru()
Definition PtexCache.cpp:203
PtexReaderCache::purgeAll
virtual void purgeAll()
Remove all texture files from the cache.
Definition PtexCache.cpp:319
PtexReaderCache::_blockReads
size_t _blockReads
Definition PtexCache.h:306
PtexReaderCache::_filesOpen
volatile size_t _filesOpen
Definition PtexCache.h:288
PtexReaderCache::_mruList
MruList *volatile _mruList
Definition PtexCache.h:297
PtexReaderCache::purge
virtual void purge(PtexTexture *)
Remove a texture file from the cache.
Definition PtexCache.cpp:287
PtexReaderCache::_mruLists
MruList _mruLists[2]
Definition PtexCache.h:296
PtexReaderCache::_searchdirs
std::vector< std::string > _searchdirs
Definition PtexCache.h:283
PtexReader
Definition PtexReader.h:52
PtexReader::setPendingPurge
void setPendingPurge()
Definition PtexReader.h:61
PtexReader::_opens
volatile size_t _opens
Definition PtexReader.h:719
PtexReader::purge
void purge()
Definition PtexReader.cpp:115
PtexReader::prune
void prune()
Definition PtexReader.cpp:104
PtexReader::_memUsed
volatile size_t _memUsed
Definition PtexReader.h:718
PtexReader::_blockReads
volatile size_t _blockReads
Definition PtexReader.h:720
PtexTexture
Interface for reading data from a ptex file.
Definition Ptexture.h:457
Ptex::String
Memory-managed string.
Definition Ptexture.h:296
PTEX_NAMESPACE_BEGIN
Definition PtexSeparableKernel.cpp:42
PtexReaderCache::MruList
Definition PtexCache.h:292
PtexReaderCache::MruList::files
PtexCachedReader *volatile files[numMruFiles]
Definition PtexCache.h:294
PtexReaderCache::MruList::next
volatile int next
Definition PtexCache.h:293
PtexReaderCache::Purger
Definition PtexCache.h:268
PtexReaderCache::Purger::operator()
void operator()(PtexCachedReader *reader)
Definition PtexCache.cpp:311
PtexReaderCache::Purger::memUsedChangeTotal
size_t memUsedChangeTotal
Definition PtexCache.h:269
PtexReaderCache::Purger::Purger
Purger()
Definition PtexCache.h:270