12 #ifndef __UT_ThreadSafeCache__
13 #define __UT_ThreadSafeCache__
43 : myPrev(0), myNext(0), myMemory(0)
44 , myRefCount(0), myTimeStamp(0)
45 , myAllocated(false) {}
50 virtual const char *getItemType()
const = 0;
61 virtual void deallocate(
void *user_data) = 0;
65 int incRefCount() {
return myRefCount.add(1); }
66 int decRefCount() {
return myRefCount.add(-1); }
68 bool isInCache()
const {
return myNext; }
74 myPrev->myNext = myNext;
75 myNext->myPrev = myPrev;
84 void link(UT_CacheItem *before)
94 myPrev = before->myPrev;
96 before->myPrev->myNext =
this;
97 before->myPrev =
this;
112 UT_CacheItem *
volatile myNext;
113 UT_CacheItem *
volatile myPrev;
118 volatile int64 myMemory;
119 volatile uint64 myTimeStamp;
121 double myAllocationTime;
130 volatile bool myAllocated;
147 {
return myMemoryLimit; }
162 { myCheckMemoryLimit = check; }
164 {
return myCheckMemoryLimit; }
191 if (item->isInCache() && isNearHead(item))
197 accessLockedReorder(item,
parms);
204 if (!item->decRefCount() && !item->isInCache())
212 if (!item->decRefCount())
235 void getStats(
int64 &mem_used,
240 void dumpStats(
const char *
name)
const;
257 {
return myCurr == cmp.myCurr; }
259 {
return myCurr != cmp.myCurr; }
266 if (myCurr && myCurr->myNext != myHead)
267 myCurr = myCurr->myNext;
283 const UT_CacheItem *myCurr, *myHead;
288 {
return unsafe_traverser(myHead); }
290 {
return unsafe_traverser(); }
294 void accessLockedReorder(UT_CacheItem *item,
void *
parms);
296 void pruneItemsNoLock(
int64 memory_limit);
297 void addToCache(UT_CacheItem *item);
298 void removeFromCache(UT_CacheItem *item);
299 void allocateItem(UT_CacheItem *item,
void *
parms)
301 if (!item->myAllocated)
304 lock(myObjLock, item);
305 if (!item->myAllocated)
311 item->myMemory = item->allocate(
312 parms ? parms : myUserData);
321 item->myAllocated =
true;
328 item->myAllocationTime = timer.
lap();
354 bool isNearHead(
const UT_CacheItem *item)
const
355 {
return myHeadTime - item->myTimeStamp <=
378 typedef std::map<const char *, FaultStats> FaultMap;
382 UT_CacheItem *myHead;
386 int64 myQuarterEntries;
391 bool myCheckMemoryLimit;
406 theCache.setMaxMemory(size_mb);
412 {
return theMemorySet; }
415 {
return theCache.getMemoryUsage(); }
419 static bool theMemorySet;
441 bool empty()
const {
return myItem == 0; }
466 void access(
T *item,
void *parm)
void reset(T *item, void *parm=0)
T * item() const
Returns the current item being accessed.
static void setMaxMemory(int size_mb)
Set the amount of memory to be used by the cache, in MB.
int64 getMemoryUsage() const
void setCheckMemoryLimit(bool check)
void access(UT_CacheItem *item, void *parms=0)
constexpr SYS_MemoryOrder SYS_MEMORY_ORDER_SEQ_CST
unsigned long long uint64
void setMaxMemoryBytes(int64 size_bytes, bool prune=false)
IMATH_HOSTDEVICE constexpr int cmp(T a, T b) IMATH_NOEXCEPT
unsafe_traverser unsafe_begin() const
~UT_UnifiedCacheAccessor()
Release the currently accessed cache item, if any.
void release(UT_CacheItem *item)
void releaseAndDeallocate(UT_CacheItem *item)
GLuint GLint GLboolean GLint GLenum access
void setUserData(void *data)
bool getCheckMemoryLimit() const
static cache_type & get()
void pruneItems(int64 memory_limit)
static bool isMaxMemorySet()
Check whether the memory limit has been set.
int operator!=(const unsafe_traverser &cmp) const
GLuint const GLchar * name
int64 getMemoryUsage() const
unsafe_traverser unsafe_end() const
GA_API const UT_StringHolder parms
friend class UT_ThreadSafeCache
int operator==(const unsafe_traverser &cmp) const
const unsafe_traverser & operator=(const unsafe_traverser &src)
unsafe_traverser(const unsafe_traverser &src)
Scoped accessor object for accessing unified cache items.
static int64 getMemoryUsage()
int64 getMaxMemoryBytes() const
void setMaxMemory(int64 size_mb, bool prune=false)
UT_UnifiedCacheAccessor(T *item=0, void *parm=0)
unsafe_traverser & operator++()
bool empty() const
Returns true if no item is being accessed.
void freeItem(UT_CacheItem *item)