12 #ifndef __UT_ThreadSafeCache__
13 #define __UT_ThreadSafeCache__
40 : myPrev(0), myNext(0), myMemory(0)
41 , myRefCount(0), myTimeStamp(0)
42 , myAllocated(false) {}
47 virtual const char *getItemType()
const = 0;
55 virtual int64 allocate(
void *parms) = 0;
58 virtual void deallocate(
void *user_data) = 0;
62 int incRefCount() {
return myRefCount.add(1); }
63 int decRefCount() {
return myRefCount.add(-1); }
65 bool isInCache()
const {
return myNext; }
71 myPrev->myNext = myNext;
72 myNext->myPrev = myPrev;
81 void link(UT_CacheItem *before)
91 myPrev = before->myPrev;
93 before->myPrev->myNext =
this;
94 before->myPrev =
this;
109 UT_CacheItem *
volatile myNext;
110 UT_CacheItem *
volatile myPrev;
115 volatile int64 myMemory;
116 volatile uint64 myTimeStamp;
118 double myAllocationTime;
127 volatile bool myAllocated;
144 {
return myMemoryLimit; }
159 { myCheckMemoryLimit = check; }
161 {
return myCheckMemoryLimit; }
167 void access(UT_CacheItem *item,
void *parms = 0)
188 if (item->isInCache() && isNearHead(item))
194 accessLockedReorder(item, parms);
201 if (!item->decRefCount() && !item->isInCache())
209 if (!item->decRefCount())
232 void getStats(
int64 &mem_used,
237 void dumpStats(
const char *
name)
const;
254 {
return myCurr == cmp.myCurr; }
256 {
return myCurr != cmp.myCurr; }
263 if (myCurr && myCurr->myNext != myHead)
264 myCurr = myCurr->myNext;
280 const UT_CacheItem *myCurr, *myHead;
285 {
return unsafe_traverser(myHead); }
287 {
return unsafe_traverser(); }
291 void accessLockedReorder(UT_CacheItem *item,
void *parms);
293 void pruneItemsNoLock(
int64 memory_limit);
294 void addToCache(UT_CacheItem *item);
295 void removeFromCache(UT_CacheItem *item);
296 void allocateItem(UT_CacheItem *item,
void *parms)
298 if (!item->myAllocated)
301 lock(myObjLock, item);
302 if (!item->myAllocated)
308 item->myMemory = item->allocate(
309 parms ? parms : myUserData);
318 item->myAllocated =
true;
325 item->myAllocationTime = timer.
lap();
351 bool isNearHead(
const UT_CacheItem *item)
const
352 {
return myHeadTime - item->myTimeStamp <=
374 typedef std::map<const char *, FaultStats> FaultMap;
378 UT_CacheItem *myHead;
382 int64 myQuarterEntries;
387 bool myCheckMemoryLimit;
402 theCache.setMaxMemory(size_mb);
408 {
return theMemorySet; }
411 {
return theCache.getMemoryUsage(); }
415 static bool theMemorySet;
437 bool empty()
const {
return myItem == 0; }
462 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
UT_StringArray JOINTS head
void setCheckMemoryLimit(bool check)
void access(UT_CacheItem *item, void *parms=0)
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
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)