Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-09-20 16:59:16 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-09-20 16:59:16 +0400
commita4f73c5694a44e6948665ee54d51d8df70be8e24 (patch)
tree950257b6c13f5f8c40d767f65f6617cd77ced38c /intern/memutil
parent5327c2f486ec5c5024b28816d76beb44aa71180c (diff)
Fix #32579: Sequencer crash when changing render dimensions
Memory limitor's queue could be affected when it's being iterated on enforcing limits -- that's because iteration could free color managed image buffers. Fixed by getting least priority element after every element was freed. Could be optimized a bit, but it anyway shouldn't be so slow due to specific of cache limiting and limit enforcing finish condition.
Diffstat (limited to 'intern/memutil')
-rw-r--r--intern/memutil/MEM_CacheLimiter.h56
1 files changed, 22 insertions, 34 deletions
diff --git a/intern/memutil/MEM_CacheLimiter.h b/intern/memutil/MEM_CacheLimiter.h
index 1f1088ea118..cfff5d10e4f 100644
--- a/intern/memutil/MEM_CacheLimiter.h
+++ b/intern/memutil/MEM_CacheLimiter.h
@@ -123,20 +123,11 @@ public:
parent->touch(this);
}
- void set_priority(int priority) {
- this->priority = priority;
- }
-
- int get_priority(void) {
- return this->priority;
- }
-
private:
friend class MEM_CacheLimiter<T>;
T * data;
int refcount;
- int priority;
typename std::list<MEM_CacheLimiterHandle<T> *, MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator me;
MEM_CacheLimiter<T> * parent;
};
@@ -171,7 +162,6 @@ public:
}
void enforce_limits() {
- MEM_CachePriorityQueue priority_queue;
size_t max = MEM_CacheLimiter_get_maximum();
size_t mem_in_use, cur_size;
@@ -190,12 +180,11 @@ public:
return;
}
- priority_queue = get_priority_queue();
+ while (!queue.empty() && mem_in_use > max) {
+ MEM_CacheElementPtr elem = get_least_priority_destroyable_element();
- while (!priority_queue.empty() && mem_in_use > max) {
- MEM_CacheElementPtr elem = priority_queue.top();
-
- priority_queue.pop();
+ if (!elem)
+ break;
if (getDataSize) {
cur_size = getDataSize(elem->get()->get_data());
@@ -232,14 +221,6 @@ private:
typedef std::list<MEM_CacheElementPtr, MEM_Allocator<MEM_CacheElementPtr> > MEM_CacheQueue;
typedef typename MEM_CacheQueue::iterator iterator;
- struct compare_element_priority : public std::binary_function<MEM_CacheElementPtr, MEM_CacheElementPtr, bool> {
- bool operator()(const MEM_CacheElementPtr left_elem, const MEM_CacheElementPtr right_elem) const {
- return left_elem->get_priority() > right_elem->get_priority();
- }
- };
-
- typedef std::priority_queue<MEM_CacheElementPtr, std::vector<MEM_CacheElementPtr>, compare_element_priority > MEM_CachePriorityQueue;
-
size_t total_size() {
size_t size = 0;
for (iterator it = queue.begin(); it != queue.end(); it++) {
@@ -248,28 +229,35 @@ private:
return size;
}
- MEM_CachePriorityQueue get_priority_queue(void) {
- MEM_CachePriorityQueue priority_queue;
+ 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;
- int priority;
+
+ if (!elem->can_destroy())
+ continue;
/* by default 0 means higherst priority element */
- priority = -(queue.size() - i - 1);
+ int priority = -(queue.size() - i - 1);
+ priority = getItemPriority(elem->get()->get_data(), priority);
- if (getItemPriority) {
- priority = getItemPriority(elem->get()->get_data(), priority);
+ if (priority < best_match_priority || best_match_elem == NULL) {
+ best_match_priority = priority;
+ best_match_elem = elem;
}
-
- elem->set_priority(priority);
-
- priority_queue.push(elem);
}
- return priority_queue;
+ return best_match_elem;
}
MEM_CacheQueue queue;