00001 #ifndef GCACHE_TOKEN_H 00002 #define GCACHE_TOKEN_H 00003 00004 #include <wrap/system/multithreading/atomic_int.h> 00005 00006 /* QAtomic int count keep trak of token status: 00007 >0: locked (possibly multiple times) 00008 0: data ready in last cache 00009 -1: not in last cache 00010 -2: to removed from all caches 00011 -3: out of caches 00012 */ 00013 00018 namespace vcg { 00019 00020 template <typename Priority> 00021 class Token { 00022 public: 00024 /*** - LOCKED: resource in the higher cache and locked 00025 - READY: resource in the higher cache 00026 - CACHE: resource in some cache (not the highest) 00027 - REMOVE: resource in some cache and scheduled for removal 00028 - OUTSIDE: resource not in the cache system */ 00029 enum Status { LOCKED = 1, READY = 0, CACHE = -1, REMOVE = -2, OUTSIDE = -3 }; 00032 Priority priority; 00034 Priority new_priority; 00036 mt::atomicInt count; 00037 00038 public: 00039 Token(): count(OUTSIDE) {} 00040 00042 void setPriority(const Priority &p) { 00043 new_priority = p; 00044 } 00045 00046 //set and get are safe to call in the controller thread. 00047 Priority getPriority() { 00048 return new_priority; 00049 } 00050 00052 bool lock() { 00053 if(count.fetchAndAddAcquire(1) >= 0) return true; 00054 count.deref(); 00055 return false; 00056 } 00057 00059 bool unlock() { 00060 return count.deref(); 00061 } 00062 00064 bool remove() { 00065 count.testAndSetOrdered(READY, REMOVE); 00066 count.testAndSetOrdered(CACHE, REMOVE); 00067 #if(QT_VERSION < 0x050000) 00068 return count <= REMOVE; 00069 #else 00070 return count.load() <= REMOVE; //might have become OUSIDE in the meanwhile 00071 #endif 00072 } 00073 00074 bool isLocked() { 00075 #if(QT_VERSION < 0x050000) 00076 return count > 0; 00077 #else 00078 return count.load() > 0; 00079 #endif 00080 } 00081 bool isInCache() { return count != OUTSIDE; } //careful, can be used only when provider thread is locked. 00082 00084 void pushPriority() { 00085 priority = new_priority; 00086 } 00087 00088 bool operator<(const Token &a) const { 00089 #if(QT_VERSION < 0x050000) 00090 if(count == a.count) 00091 return priority < a.priority; 00092 return count < a.count; 00093 #else 00094 if(count.load() == a.count.load()) 00095 return priority < a.priority; 00096 return count.load() < a.count.load(); 00097 #endif 00098 } 00099 bool operator>(const Token &a) const { 00100 #if(QT_VERSION < 0x050000) 00101 if(count == a.count) 00102 return priority > a.priority; 00103 return count > a.count; 00104 #else 00105 if(count.load() == a.count.load()) 00106 return priority > a.priority; 00107 return count.load() > a.count.load(); 00108 #endif 00109 } 00110 }; 00111 00112 } //namespace 00113 #endif // GCACHE_H