[Bf-blender-cvs] [aeee711] master: Cache limiter cleanup and small fixes

Sergey Sharybin noreply at git.blender.org
Wed Dec 11 11:33:08 CET 2013


Commit: aeee7118ae939304028ee7d1ea688a89b5d61be4
Author: Sergey Sharybin
Date:   Tue Dec 10 15:07:10 2013 +0600
http://developer.blender.org/rBaeee7118ae939304028ee7d1ea688a89b5d61be4

Cache limiter cleanup and small fixes

- Made code a bit less cluttered to follow
- Fixed possible deadlock when enforcing limit
  and highest priority element is still referenced.

===================================================================

M	intern/memutil/MEM_CacheLimiter.h

===================================================================

diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index dec4d0b..32f97a2 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -138,8 +138,8 @@ public:
 	typedef size_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
 	typedef int    (*MEM_CacheLimiter_ItemPriority_Func) (void *item, int default_priority);
 
-	MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_)
-		: getDataSize(getDataSize_) {
+	MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func data_size_func)
+		: data_size_func(data_size_func) {
 	}
 
 	~MEM_CacheLimiter() {
@@ -162,10 +162,16 @@ public:
 	}
 
 	size_t get_memory_in_use() {
-		if (getDataSize)
-			return total_size();
-		else
-			return MEM_get_memory_in_use();
+		size_t size = 0;
+		if (data_size_func) {
+			for (iterator it = queue.begin(); it != queue.end(); it++) {
+				size += data_size_func((*it)->get()->get_data());
+			}
+		}
+		else {
+			size = MEM_get_memory_in_use();
+		}
+		return size;
 	}
 
 	void enforce_limits() {
@@ -188,15 +194,15 @@ public:
 			if (!elem)
 				break;
 
-			if (getDataSize) {
-				cur_size = getDataSize(elem->get()->get_data());
+			if (data_size_func) {
+				cur_size = data_size_func(elem->get()->get_data());
 			}
 			else {
 				cur_size = mem_in_use;
 			}
 
 			if (elem->destroy_if_possible()) {
-				if (getDataSize) {
+				if (data_size_func) {
 					mem_in_use -= cur_size;
 				}
 				else {
@@ -207,15 +213,21 @@ public:
 	}
 
 	void touch(MEM_CacheLimiterHandle<T> * handle) {
-		queue.push_back(handle);
-		queue.erase(handle->me);
-		iterator it = queue.end();
-		--it;
-		handle->me = it;
+		/* If we're using custom priority callback re-arranging the queue
+		 * doesn't make much sense because we'll iterate it all to get
+		 * least priority element anyway.
+		 */
+		if (item_priority_func == NULL) {
+			queue.push_back(handle);
+			queue.erase(handle->me);
+			iterator it = queue.end();
+			--it;
+			handle->me = it;
+		}
 	}
 
 	void set_item_priority_func(MEM_CacheLimiter_ItemPriority_Func item_priority_func) {
-		getItemPriority = item_priority_func;
+		this->item_priority_func = item_priority_func;
 	}
 
 private:
@@ -223,41 +235,42 @@ private:
 	typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
 	typedef typename MEM_CacheQueue::iterator iterator;
 
-	size_t total_size() {
-		size_t size = 0;
-		for (iterator it = queue.begin(); it != queue.end(); it++) {
-			size+= getDataSize((*it)->get()->get_data());
-		}
-		return size;
-	}
-
 	MEM_CacheElementPtr get_least_priority_destroyable_element(void) {
 		if (queue.empty())
 			return NULL;
 
-		if (!getItemPriority)
-			return *queue.begin();
-
 		MEM_CacheElementPtr best_match_elem = NULL;
-		int best_match_priority = 0;
-		iterator it;
-		int i;
-
-		for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
-			MEM_CacheElementPtr elem = *it;
-
-			if (!elem->can_destroy())
-				continue;
 
-			/* by default 0 means highest priority element */
-			/* casting a size type to int is questionable,
-			   but unlikely to cause problems */
-			int priority = -((int)(queue.size()) - i - 1);
-			priority = getItemPriority(elem->get()->get_data(), priority);
-
-			if (priority < best_match_priority || best_match_elem == NULL) {
-				best_match_priority = priority;
+		if (!item_priority_func) {
+			for (iterator it = queue.begin(); it != queue.end(); it++) {
+				MEM_CacheElementPtr elem = *it;
+				if (!elem->can_destroy())
+					continue;
 				best_match_elem = elem;
+				break;
+			}
+		}
+		else {
+			int best_match_priority = 0;
+			iterator it;
+			int i;
+
+			for (it = queue.begin(), i = 0; it != queue.end(); it++, i++) {
+				MEM_CacheElementPtr elem = *it;
+
+				if (!elem->can_destroy())
+					continue;
+
+				/* by default 0 means highest priority element */
+				/* casting a size type to int is questionable,
+				   but unlikely to cause problems */
+				int priority = -((int)(queue.size()) - i - 1);
+				priority = item_priority_func(elem->get()->get_data(), priority);
+
+				if (priority < best_match_priority || best_match_elem == NULL) {
+					best_match_priority = priority;
+					best_match_elem = elem;
+				}
 			}
 		}
 
@@ -265,8 +278,8 @@ private:
 	}
 
 	MEM_CacheQueue queue;
-	MEM_CacheLimiter_DataSize_Func getDataSize;
-	MEM_CacheLimiter_ItemPriority_Func getItemPriority;
+	MEM_CacheLimiter_DataSize_Func data_size_func;
+	MEM_CacheLimiter_ItemPriority_Func item_priority_func;
 };
 
-#endif // __MEM_CACHELIMITER_H__
+#endif  // __MEM_CACHELIMITER_H__




More information about the Bf-blender-cvs mailing list