From 00fe985041ed5401b60e3cdfba0210f003239760 Mon Sep 17 00:00:00 2001 From: aignacio_sf <> Date: Fri, 6 Jan 2006 19:10:02 +0000 Subject: [PATCH] moved to display --- panda/src/dxgsg9/lru.cxx | 1344 -------------------------------------- panda/src/dxgsg9/lru.h | 271 -------- 2 files changed, 1615 deletions(-) delete mode 100644 panda/src/dxgsg9/lru.cxx delete mode 100644 panda/src/dxgsg9/lru.h diff --git a/panda/src/dxgsg9/lru.cxx b/panda/src/dxgsg9/lru.cxx deleted file mode 100644 index 8681094d12..0000000000 --- a/panda/src/dxgsg9/lru.cxx +++ /dev/null @@ -1,1344 +0,0 @@ -// Filename: lru.cxx -// Created by: aignacio (12Dec05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights -// reserved. -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -//#include "stdafx.h" - -#define LRU_UNIT_TEST 0 - -#include -#include -#include - -#include "lru.h" - - -static const int HIGH_PRIORITY_SCALE = 4; -static const int LOW_PRIORITY_RANGE = 25; - -//////////////////////////////////////////////////////////////////// -// Function: Lru::Constructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -Lru::Lru (int maximum_memory, int maximum_pages, int maximum_page_types) -{ - if(this) { - int index; - - memset(&this->_m, 0, sizeof (LruVariables)); - - this->_m.maximum_memory = maximum_memory; - this->_m.maximum_pages = maximum_pages; - this->_m.maximum_page_types = maximum_page_types; - this->_m.available_memory = maximum_memory; - this->_m.current_frame_identifier = 1; - this->_m.weight = 0.20f; - - this->set_maximum_frame_bandwidth_utilization(2000000.0f); - - for(index = 0; index < MAXIMUM_LRU_PAGE_TYPES; index++) { - this->_m.page_in_function_array[index] = default_page_in_function; - this->_m.page_out_function_array[index] = default_page_out_function; - } - - if(maximum_pages > 0) { - this -> _m.lru_page_pool = new LruPage * [maximum_pages]; - this -> _m.lru_page_free_pool = new LruPage * [maximum_pages]; - for(index = 0; index < maximum_pages; index++) { - LruPage * lru_page; - - lru_page = new LruPage ( ); - if(lru_page) { - lru_page->_m.pre_allocated = true; - this->_m.lru_page_pool[index] = lru_page; - } - else { -// ERROR - } - } - } - - if(maximum_page_types > 0) { - this -> _m.page_type_statistics_array = - new PageTypeStatistics [maximum_page_types]; - } - -#if ENABLE_MUTEX - this -> _m.mutex = new Mutex ( ); -#endif - - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::Destructor -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -Lru::~Lru ( ) -{ - int index; - LruPage * lru_page; - - // free pre-allocated LruPages - if(this->_m.maximum_pages > 0) { - if(this->_m.lru_page_free_pool) { - for(index = 0; index < this->_m.maximum_pages; index++) { - lru_page = this->_m.lru_page_pool[index]; - if(lru_page->_m.in_lru) { - this->remove_page(lru_page); - } - - delete lru_page; - } - - delete this -> _m.lru_page_free_pool; - } - if(this->_m.lru_page_pool) { - delete this -> _m.lru_page_pool; - } - } - - // free dynamically allocated LruPages - for(index = 0; index < LPP_TotalPriorities; index++) { - LruPage * next_lru_page; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - delete lru_page; - - lru_page = next_lru_page; - } - } - - if(this->_m.page_type_statistics_array) { - delete this -> _m.page_type_statistics_array; - } - -#if ENABLE_MUTEX - if(this->_m.mutex) { - delete this -> _m.mutex; - } -#endif - -} - -//////////////////////////////////////////////////////////////////// -// Function: LruPage::Constructor -// Access: Protected -// Description: Internal function only. -// Call Lru::allocate_page instead. -//////////////////////////////////////////////////////////////////// -LruPage::LruPage ( ) -{ - if(this) { - memset(&this->_m, 0, sizeof (LruPageVariables)); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: LruPage::Destructor -// Access: Protected -// Description: Internal function only. -// Call Lru::free_page instead. -//////////////////////////////////////////////////////////////////// -LruPage::~LruPage ( ) -{ - -} - -//////////////////////////////////////////////////////////////////// -// Function: LruPage::change_priority -// Access: Protected -// Description: -//////////////////////////////////////////////////////////////////// -void LruPage::change_priority (int delta) -{ - this->_m.priority_change += delta; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::register_lru_page_type -// Access: Public -// Description: Registers a specific type of page and its -// required page in and out functions. -//////////////////////////////////////////////////////////////////// -bool Lru::register_lru_page_type (int index, - LruPageTypeFunction page_in_function, - LruPageTypeFunction page_out_function) -{ - bool state; - - state = false; - if(index >= 0 && index < MAXIMUM_LRU_PAGE_TYPES) { - this->_m.page_in_function_array[index] = page_in_function; - this->_m.page_out_function_array[index] = page_out_function; - state = true; - } - - return state; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::allocate_page -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -LruPage *Lru::allocate_page (int size) -{ - LruPage * lru_page; - - lru_page = 0; - if(size <= this->_m.maximum_memory) { - if(this->_m.maximum_pages) { - if(this->_m.total_lru_pages_in_free_pool > 0) { - lru_page = - this->_m.lru_page_free_pool [this->_m.total_lru_pages_in_free_pool - 1]; - this->_m.total_lru_pages_in_free_pool--; - - memset (&lru_page -> _m, 0, sizeof (LruPage::LruPageVariables)); - lru_page->_m.pre_allocated = true; - } - else { - if(this->_m.total_lru_pages_in_pool < this->_m.maximum_pages) { - lru_page = this->_m.lru_page_pool[this->_m.total_lru_pages_in_pool]; - this->_m.total_lru_pages_in_pool++; - } - else { - // out of pre-allocated LruPages so dynamically allocate a page - lru_page = new LruPage ( ); - } - } - } - else { - lru_page = new LruPage; - } - if(lru_page) { - lru_page->_m.lru = this; - lru_page->_m.size = size; - lru_page->_m.first_frame_identifier = this->_m.current_frame_identifier; - lru_page->_m.last_frame_identifier = this->_m.current_frame_identifier; - - lru_page->_m.allocated = true; - lru_page->_m.identifier = this->_m.identifier; - - lru_page->_m.average_frame_utilization = 1.0f; - - this->_m.total_pages++; - this->_m.identifier++; - } - else { - -// ERROR: could not allocate LruPage - - } - } - else { - -// ERROR: requested page size is larger than maximum memory size - - } - - return lru_page; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::update_start_update_lru_page -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::update_start_update_lru_page (LruPage *lru_page) -{ - if(lru_page) { - if(this->_m.start_update_lru_page == lru_page) { - if(lru_page->_m.next) { - this->_m.start_update_lru_page = lru_page->_m.next; - } - else { - if((this->_m.start_priority_index + 1) >= LPP_TotalPriorities) { - this->_m.start_priority_index = 0; - } - else { - this->_m.start_priority_index = this->_m.start_priority_index + 1; - } - - this->_m.start_update_lru_page = 0; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::free_page -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::free_page (LruPage *lru_page) -{ - if(this->_m.total_pages > 0) { - if(lru_page) { - LruMutexHolder(this->_m.mutex); - - this->update_start_update_lru_page(lru_page); - - if(lru_page->_m.in_cache) { - this->_m.available_memory += lru_page->_m.size; - } - - if(lru_page->_m.pre_allocated) { - if(this->_m.maximum_pages) { - lru_page->_m.allocated = false; - this->_m.lru_page_free_pool [this->_m.total_lru_pages_in_free_pool] = - lru_page; - this->_m.total_lru_pages_in_free_pool++; - } - else { -// ERROR: this case should not happen - } - } - else { - delete lru_page; - } - - this->_m.total_pages--; - } - } - else { - -// ERROR: tried to free a page when 0 pages allocated - - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::add_page -// Access: Public -// Description: Adds a page to the LRU based on the given priority. -//////////////////////////////////////////////////////////////////// -void Lru::add_page (LruPagePriority priority, LruPage *lru_page) -{ - if(lru_page) { - LruMutexHolder(this->_m.mutex); - - LruPage * first_lru_page; - - lru_page->_m.priority = priority; - - first_lru_page = this->_m.lru_page_array[lru_page->_m.priority]; - if(first_lru_page) { - first_lru_page->_m.previous = lru_page; - lru_page->_m.next = first_lru_page; - } - - this->_m.lru_page_array[lru_page->_m.priority] = lru_page; - - lru_page->_m.in_lru = true; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::add_cached_page -// Access: Public -// Description: Adds a page that is already paged in to the LRU -// based on the given priority. -//////////////////////////////////////////////////////////////////// -void Lru::add_cached_page (LruPagePriority priority, LruPage *lru_page) -{ - if(lru_page) { - LruMutexHolder(this->_m.mutex); - - lru_page->_m.in_cache = true; - - if(lru_page->_m.size > this->_m.available_memory) { - int memory_required; - - memory_required = lru_page->_m.size - this->_m.available_memory; - - // unload page(s) - this->page_out_lru(memory_required); - } - - this->_m.available_memory -= lru_page->_m.size; - - this->add_page(priority, lru_page); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::remove_page -// Access: Public -// Description: Removes a page from the LRU. -//////////////////////////////////////////////////////////////////// -void Lru::remove_page (LruPage *lru_page) -{ - if(this) { - if(this->_m.total_pages > 0) { - if(lru_page) { - LruMutexHolder(this->_m.mutex); - - this->update_start_update_lru_page(lru_page); - - if(lru_page->_m.previous) { - lru_page->_m.previous->_m.next = lru_page->_m.next; - if(lru_page->_m.next) { - lru_page->_m.next->_m.previous = lru_page->_m.previous; - } - } - else { - this->_m.lru_page_array[lru_page->_m.priority] = - lru_page->_m.next; - if(lru_page->_m.next) { - lru_page->_m.next->_m.previous = 0; - } - } - - lru_page->_m.next = 0; - lru_page->_m.previous = 0; - - lru_page->_m.in_lru = false; - } - } - else { - -// ERROR: tried to remove a page when 0 pages are allocated - - } - } - else { - -// ERROR: Lru == 0, this should not happen - - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::lock_page -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::lock_page (LruPage *lru_page) -{ - lru_page->_m.lock = true; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::unlock_page -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::unlock_page (LruPage *lru_page) -{ - lru_page->_m.lock = false; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::access_page -// Access: Public -// Description: This must always be called before accessing or -// using a page's memory since it pages in the page -// if it is currently paged out. -//////////////////////////////////////////////////////////////////// -void Lru::access_page (LruPage *lru_page) -{ - if(lru_page) { - if(lru_page->_m.current_frame_identifier - == this->_m.current_frame_identifier) { - lru_page->_m.current_frame_usage++; - this->_m.total_page_all_access_size += lru_page->_m.size; - } - else { - // first update this frame - lru_page->_m.last_frame_identifier = lru_page->_m.current_frame_identifier; - lru_page->_m.current_frame_identifier = this->_m.current_frame_identifier; - lru_page->_m.last_frame_usage = lru_page->_m.current_frame_usage; - lru_page->_m.current_frame_usage = 1; - lru_page->_m.total_frame_page_faults = 0; - - this->_m.total_page_access_size += lru_page->_m.size; - } - - // check if the page is out - if(lru_page->_m.in_cache == false) { - bool state; - - state = true; - - LruMutexHolder(this->_m.mutex); - - // check memory usage - if(lru_page->_m.size > this->_m.available_memory) { - int memory_required; - - memory_required = lru_page->_m.size - this->_m.available_memory; - - // unload page(s) - state = this->page_out_lru(memory_required); - } - - // load the page in - if(state) { - // PAGE IN CALLBACK - if(this->_m.page_in_function_array[lru_page->_m.type](lru_page)) { - this->_m.available_memory -= lru_page->_m.size; - lru_page->_m.in_cache = true; - - // CHANGE THE PAGE PRIORITY FROM LPP_PageOut TO LPP_New - this->remove_page(lru_page); - this->add_page(LPP_New, lru_page); - - this->_m.total_lifetime_page_ins++; - } - } - - lru_page->_m.total_frame_page_faults++; - lru_page->_m.total_page_faults++; - } - - lru_page->_m.total_usage++; - lru_page->_m.update_total_usage++; - - this->_m.total_page_access++; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::set_maximum_frame_bandwidth_utilization -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::set_maximum_frame_bandwidth_utilization - (float maximum_frame_bandwidth_utilization) -{ - this->_m.maximum_frame_bandwidth_utilization = - maximum_frame_bandwidth_utilization; - - this->_m.frame_bandwidth_factor = (float) LPP_TotalPriorities - / this->_m.maximum_frame_bandwidth_utilization; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::begin_frame -// Access: Public -// Description: This must be called before each frame. -//////////////////////////////////////////////////////////////////// -void Lru::begin_frame ( ) -{ - this->_m.current_frame_identifier++; - - this->_m.total_page_ins_last_frame = this->_m.total_page_ins; - this->_m.total_page_outs = this->_m.total_page_outs; - - this->_m.total_page_ins = 0; - this->_m.total_page_outs = 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::update_page_priorities -// Access: Public -// Description: This updates the priority of a page that has a -// change in priority. -//////////////////////////////////////////////////////////////////// -void Lru::update_page_priorities (void) -{ - int index; - LruPage *lru_page; - - for(index = 0; index < this->_m.total_lru_page_priority_changes; index++) { - int priority; - - lru_page = this->_m.lru_page_priority_change_array[index]; - - this->remove_page(lru_page); - - priority = (( int ) lru_page->_m.priority + lru_page->_m.priority_change); - if(priority < 0) { - priority = 0; - } - if(priority >= LPP_TotalPriorities) { - priority = LPP_TotalPriorities - 1; - } - - this->add_page((LruPagePriority) priority, lru_page); - lru_page->_m.priority_change = 0; - } - this->_m.total_lru_page_priority_changes = 0; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::update_lru_page -// Access: Public -// Description: This updates the page's average utilization. -// Priority LPP_New is considered to be average usage -// of 1.0 (which means the page is used once per frame -// on average). Priorities < LPP_New are for pages -// used more than once per frame and Priorities > -// LPP_New are for pages used less than once per frame. -// If there was a change in priority, then adds it to -// the array of lru pages with changed priorities -// which will be updated later. -//////////////////////////////////////////////////////////////////// -void Lru::update_lru_page (LruPage *lru_page) -{ - -#if LRU_UNIT_TEST - if(false) { - char string[256]; - - sprintf(string, " UPDATE %d\n", lru_page->_m.identifier); - OutputDebugString(string); - } -#endif - - if(lru_page->_m.lock == false && lru_page->_m.in_cache) { - int delta_priority; - int lifetime_frames; - - delta_priority = 0; - - lifetime_frames = this->_m.current_frame_identifier - - lru_page->_m.first_frame_identifier; - if(lifetime_frames >= 1) { - if(lru_page->_m.update_frame_identifier) { - int target_priority; - int integer_update_frames; - float update_frames; - float one_over_update_frames; - float update_average_frame_utilization; - - integer_update_frames = (this->_m.current_frame_identifier - - lru_page->_m.update_frame_identifier); - if(integer_update_frames > 0) { - update_frames = ( float ) integer_update_frames; - one_over_update_frames = 1.0f / update_frames; - - update_average_frame_utilization = - (float) (lru_page->_m.update_total_usage)* one_over_update_frames; - - lru_page->_m.average_frame_utilization = - calculate_exponential_moving_average( - update_average_frame_utilization, this->_m.weight, - lru_page->_m.average_frame_utilization); - - target_priority = lru_page->_m.priority; - if(lru_page->_m.average_frame_utilization >= 1.0f) { - int integer_average_frame_utilization; - - integer_average_frame_utilization = - (int) ((lru_page->_m.average_frame_utilization - 1.0f) * - (float) HIGH_PRIORITY_SCALE); - if(integer_average_frame_utilization >= LPP_New) { - integer_average_frame_utilization = LPP_New; - } - integer_average_frame_utilization = LPP_New - - integer_average_frame_utilization; - target_priority = integer_average_frame_utilization; - } - else { - int integer_average_frame_utilization; - - integer_average_frame_utilization = (int) - (lru_page->_m.average_frame_utilization * - (float) LOW_PRIORITY_RANGE); - integer_average_frame_utilization = LOW_PRIORITY_RANGE - - integer_average_frame_utilization; - target_priority = LPP_New + integer_average_frame_utilization; - } - - delta_priority = target_priority - lru_page->_m.priority; - lru_page->change_priority(delta_priority); - } - } - - lru_page->_m.update_frame_identifier = this->_m.current_frame_identifier; - lru_page->_m.update_total_usage = 0; - } - - if(lru_page->_m.priority_change) { - if(this->_m.total_lru_page_priority_changes - < FRAME_MAXIMUM_PRIORITY_CHANGES) - { - this->_m.lru_page_priority_change_array - [this->_m.total_lru_page_priority_changes] = lru_page; - this->_m.total_lru_page_priority_changes++; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::update_lru_page_old -// Access: Public -// Description: This updates the page's average utilization and -// adds it to the array of pages with changed -// priorities if there was a change in priority. -// Old method. -//////////////////////////////////////////////////////////////////// -void Lru::update_lru_page_old (LruPage *lru_page) -{ - -#if LRU_UNIT_TEST - if(false) { - char string[256]; - - sprintf(string, " UPDATE %d\n", lru_page->_m.identifier); - OutputDebugString(string); - } -#endif - - if(lru_page->_m.lock == false) { - int delta_priority; - - delta_priority = 0; - if(false && lru_page->_m.total_usage > 0) { - int lifetime_frames; - - lifetime_frames = this->_m.current_frame_identifier - - lru_page->_m.first_frame_identifier; - if(lifetime_frames >= 10) { - float one_over_update_frames; - - if(lru_page->_m.update_frame_identifier) { - int target_priority; - int integer_update_frames; - float update_frames; - float update_average_frame_utilization; - float average_frame_bandwidth_utilization; - - integer_update_frames = (this->_m.current_frame_identifier - - lru_page->_m.update_frame_identifier); - if(integer_update_frames > 0) { - update_frames = ( float ) integer_update_frames; - one_over_update_frames = 1.0f / update_frames; - - update_average_frame_utilization = - (float) (lru_page->_m.update_total_usage) * - one_over_update_frames; - - lru_page->_m.average_frame_utilization = - calculate_exponential_moving_average ( - update_average_frame_utilization, this->_m.weight, - lru_page->_m.average_frame_utilization); - - average_frame_bandwidth_utilization = - lru_page->_m.average_frame_utilization * - lru_page->_m.size; - - target_priority = (int) (average_frame_bandwidth_utilization * - this->_m.frame_bandwidth_factor); - - target_priority = (LPP_TotalPriorities - 1) - target_priority; - if(target_priority < 0) { - target_priority = 0; - } - if(target_priority >= LPP_TotalPriorities) { - target_priority = LPP_TotalPriorities - 1; - } - - delta_priority = target_priority - lru_page->_m.priority; - lru_page->change_priority(delta_priority); - } - } - - lru_page->_m.update_frame_identifier = - this->_m.current_frame_identifier; - - lru_page->_m.update_total_usage = 0; - } - } - - if(delta_priority == 0) { - if(this->_m.current_frame_identifier - == lru_page->_m.current_frame_identifier) { - // page used during this frame twice or more => - // increase priority - if(lru_page->_m.current_frame_usage >= 2) { - if(lru_page->_m.priority >= LPP_High) { - lru_page->change_priority(-2); - } - } - - if(lru_page->_m.total_frame_page_faults >= 1) { - // multiple page faults this frame => increase priority - if(lru_page->_m.total_frame_page_faults >= 2) { - if(lru_page->_m.priority >= LPP_High) { - lru_page->change_priority(-2); - } - } - else { - // single page faults this frame => increase priority - if(lru_page->_m.priority >= LPP_High) { - lru_page->change_priority(-1); - } - } - } - } - else { - // page not used this frame - int last_access_delta; - - last_access_delta - = this->_m.current_frame_identifier - - lru_page->_m.current_frame_identifier; - if(last_access_delta > 1) { - if(lru_page->_m.priority < LPP_Low) { - lru_page->change_priority(+1); - } - } - } - } - - if(lru_page->_m.priority_change) { - if(this->_m.total_lru_page_priority_changes - < FRAME_MAXIMUM_PRIORITY_CHANGES) { - this->_m.lru_page_priority_change_array - [this->_m.total_lru_page_priority_changes ]= lru_page; - this->_m.total_lru_page_priority_changes++; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::update_entire_lru -// Access: Public -// Description: This updates all the pages in the Lru. -// Lru::partial_lru_update should be called instead -// due to performance reasons. -//////////////////////////////////////////////////////////////////// -void Lru::update_entire_lru ( ) -{ - if(this->_m.total_pages > 0) { - int index; - LruPage *lru_page; - - LruMutexHolder(this->_m.mutex); - - for(index = 0; index < LPP_TotalPriorities; index++) { - - LruPage * next_lru_page; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - this->update_lru_page(lru_page); - - lru_page = next_lru_page; - } - } - - this->update_page_priorities( ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::partial_lru_update -// Access: Public -// Description: This only updates a number of pages up to the -// specified maximum_updates. -//////////////////////////////////////////////////////////////////// -void Lru::partial_lru_update (int maximum_updates) -{ - int total_page_updates; - - if (maximum_updates <= 0) { - // enforce a minimum number of updates - maximum_updates = 1; - } - - total_page_updates = 0; - if(this->_m.total_pages > 0) { - int index; - int start_priority; - LruPage *lru_page; - - LruMutexHolder(this->_m.mutex); - - start_priority = this->_m.start_priority_index; - - { - for(index = start_priority; index < LPP_TotalPriorities; index++) { - - LruPage *next_lru_page; - - if(index == start_priority) { - if(this->_m.start_update_lru_page) { - lru_page = this->_m.start_update_lru_page; - } - else { - lru_page = this->_m.lru_page_array[index]; - } - } - else { - lru_page = this->_m.lru_page_array[index]; - } - while(lru_page) { - next_lru_page = lru_page->_m.next; - - this->update_lru_page(lru_page); - - total_page_updates++; - if(total_page_updates >= maximum_updates) { - if(next_lru_page) { - this->_m.start_priority_index = index; - this->_m.start_update_lru_page = next_lru_page; - } - else { - if((index + 1) >= LPP_TotalPriorities) { - this->_m.start_priority_index = 0; - } - else { - this->_m.start_priority_index = index + 1; - } - - this->_m.start_update_lru_page = 0; - } - - break; - } - - lru_page = next_lru_page; - } - - if(total_page_updates >= maximum_updates) { - break; - } - } - } - - if(total_page_updates < maximum_updates) { - for(index = 0; index <= start_priority; index++) { - LruPage *next_lru_page; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - this->update_lru_page(lru_page); - - total_page_updates++; - if(total_page_updates >= maximum_updates) { - if(next_lru_page) { - this->_m.start_priority_index = index; - this->_m.start_update_lru_page = next_lru_page; - } - else { - if((index + 1) >= LPP_TotalPriorities) { - this->_m.start_priority_index = 0; - } - else { - this->_m.start_priority_index = index + 1; - } - - this->_m.start_update_lru_page = 0; - } - - break; - } - - lru_page = next_lru_page; - } - - if(total_page_updates >= maximum_updates) { - break; - } - } - } - - if(total_page_updates < maximum_updates) { - this->_m.start_priority_index = 0; - this->_m.start_update_lru_page = 0; - } - - this->update_page_priorities( ); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::unlock_all_pages -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -void Lru::unlock_all_pages (void) -{ - if(this->_m.total_pages > 0) { - int index; - - for(index = 0; index < LPP_TotalPriorities; index++) { - LruPage *lru_page; - LruPage *next_lru_page; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - lru_page->_m.lock = false; - - lru_page = next_lru_page; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::page_out_lru -// Access: Public -// Description: Pages out the lowest priority pages until the -// memory_required is satisfied. This will unlock -// all pages if needed. -//////////////////////////////////////////////////////////////////// -bool Lru::page_out_lru (int memory_required) -{ - bool state; - int attempts; - - state = false; - attempts = 0; - if(this->_m.total_pages > 0) { - LruMutexHolder(this->_m.mutex); - - do { - int index; - - // page out lower priority pages first - for(index = LPP_PageOut - 1; index >= 0; index--) { - LruPage *lru_page; - LruPage *next_lru_page; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - if(lru_page->_m.lock == false && lru_page->_m.in_cache) { - memory_required -= lru_page->_m.size; - this->_m.available_memory += lru_page->_m.size; - lru_page->_m.in_cache = false; - - // PAGE OUT CALLBACK - this->_m.page_out_function_array[lru_page->_m.type](lru_page); - this->_m.total_lifetime_page_outs++; - - // MOVE THE PAGE TO THE LPP_PageOut PRIORITY - this->remove_page(lru_page); - this->add_page(LPP_PageOut, lru_page); - - if(memory_required <= 0) { - break; - } - } - - lru_page = next_lru_page; - } - - if(memory_required <= 0) { - break; - } - } - - if(memory_required > 0) { - // WARNING: pages could not be freed, all pages unlocked - this->unlock_all_pages( ); - state = false; - } - else { - state = true; - } - - attempts++; - } while(state == false && attempts < 2); - } - - return state; -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::count_priority_level_pages -// Access: Public -// Description: Debug function. Counts the number of pages for each -// priority level. -//////////////////////////////////////////////////////////////////// -void Lru::count_priority_level_pages (void) -{ - int index; - - LruMutexHolder(this->_m.mutex); - - for(index = 0; index < LPP_TotalPriorities; index++) { - int total_pages; - LruPage *lru_page; - LruPage *next_lru_page; - - total_pages = 0; - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - next_lru_page = lru_page->_m.next; - - total_pages++; - - lru_page = next_lru_page; - } - - this->_m.lru_page_count_array[index] = total_pages; - } -} - -//////////////////////////////////////////////////////////////////// -// Function: Lru::calculate_lru_statistics -// Access: Public -// Description: Debug function. -//////////////////////////////////////////////////////////////////// -void Lru::calculate_lru_statistics (void) -{ - LruMutexHolder(this->_m.mutex); - - if(this->_m.maximum_page_types > 0) { - int index; - - memset(this->_m.page_type_statistics_array, 0, - sizeof (PageTypeStatistics) * this->_m.maximum_page_types); - for(index = 0; index < LPP_TotalPriorities; index++) { - LruPage *lru_page; - LruPage *next_lru_page; - PageTypeStatistics *page_type_statistics; - - lru_page = this->_m.lru_page_array[index]; - while(lru_page) { - int type; - - next_lru_page = lru_page->_m.next; - - type = lru_page->_m.type; - page_type_statistics = &this->_m.page_type_statistics_array[type]; - page_type_statistics->total_pages++; - - if(lru_page->_m.in_cache) { - page_type_statistics->total_pages_in++; - page_type_statistics->total_memory_in += lru_page->_m.size; - } - else { - page_type_statistics->total_pages_out++; - page_type_statistics->total_memory_out += lru_page->_m.size; - } - - lru_page = next_lru_page; - } - } - } -} - -//////////////////////////////////////////////////////////////////// -// Function: calculate_exponential_moving_average -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -float calculate_exponential_moving_average(float value, - float weight, float average) -{ - return ((value - average) * weight) + average; -} - -//////////////////////////////////////////////////////////////////// -// Function: default_page_in_function -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -bool default_page_in_function(LruPage *lru_page) -{ - -#if LRU_UNIT_TEST - char string[256]; - - sprintf(string, " PAGE IN %d\n", lru_page->_m.identifier); - OutputDebugString(string); -#endif - - return true; -} - -//////////////////////////////////////////////////////////////////// -// Function: default_page_out_function -// Access: Public -// Description: -//////////////////////////////////////////////////////////////////// -bool default_page_out_function(LruPage *lru_page) -{ - -#if LRU_UNIT_TEST - char string[256]; - - sprintf(string, " PAGE OUT %d\n", lru_page->_m.identifier); - OutputDebugString(string); -#endif - - return true; -} - -#if LRU_UNIT_TEST - -//////////////////////////////////////////////////////////////////// -// Function: test_ema -// Access: -// Description: Unit test function for ema. -//////////////////////////////////////////////////////////////////// -void test_ema(void) -{ - int index; - float usage; - float weight; - float average; - - weight = 0.2f; - average = 1.0f; - for(index = 0; index < 50; index++) { - if(index < 25) { - usage = (float) (index & 0x01); - } - else { - usage = 0.0f; - } - average = - calculate_exponential_moving_average(usage, weight, average); - - char string[256]; - sprintf(string, "%d %f\n", index, average); - OutputDebugString(string); - } -} - -//////////////////////////////////////////////////////////////////// -// Function: test_lru -// Access: -// Description: Unit test function for Lru. -//////////////////////////////////////////////////////////////////// -void test_lru(void) -{ - int maximum_memory; - int maximum_pages; - int maximum_page_types; - Lru *lru; - - test_ema( ); - - maximum_memory = 3000000; - maximum_pages = 3; - maximum_page_types = 4; - lru = new Lru (maximum_memory, maximum_pages, maximum_page_types); - if(lru) { - lru->_m.minimum_memory = 1000000; - - LruPage *lru_page_0; - LruPage *lru_page_1; - LruPage *lru_page_2; - LruPage *lru_page_3; - LruPage *lru_page_4; - LruPage *lru_page_5; - - lru_page_0 = lru->allocate_page(1000000); - if(lru_page_0) { - lru->add_page(LPP_PageOut, lru_page_0); - } - - lru_page_1 = lru->allocate_page(1000000); - if(lru_page_1) { - lru->add_page(LPP_PageOut, lru_page_1); - } - - lru_page_2 = lru->allocate_page(1000000); - if(lru_page_2) { - lru->add_page(LPP_PageOut, lru_page_2); - } - - lru_page_3 = lru->allocate_page(1000000); - if(lru_page_3) { - lru->add_page(LPP_PageOut, lru_page_3); - } - - lru_page_4 = lru->allocate_page(1000000); - if(lru_page_4) { - lru->add_page(LPP_PageOut, lru_page_4); - } - - lru_page_5 = lru->allocate_page(1000000); - if(lru_page_5) { - lru->add_page(LPP_PageOut, lru_page_5); - } - - int index; - int total_frames; - - total_frames = 300; - for(index = 0; index < total_frames; index++) { - char string[256]; - - sprintf(string, "FRAME %d\n", index); - OutputDebugString(string); - - lru->begin_frame( ); - - if(index <= 5) { - lru->access_page(lru_page_0); - } - - lru->access_page(lru_page_1); - lru->access_page(lru_page_1); - - if(index & 0x01) { - lru->access_page(lru_page_2); - } - - if((index % 10) == 0) { - lru->access_page(lru_page_3); - } - - if(index >= 100) { - lru->access_page(lru_page_4); - } - - if(index >= 200) { - lru->access_page(lru_page_5); - } - - if(false) { - lru->update_entire_lru( ); - } - else { - int maximum_updates; - - maximum_updates = 3; - lru->partial_lru_update(maximum_updates); - } - } - - if(!true) { - lru->remove_page(lru_page_2); - lru->free_page(lru_page_2); - - lru->remove_page(lru_page_3); - lru->free_page(lru_page_3); - - lru->remove_page(lru_page_1); - lru->free_page(lru_page_1); - } - - delete lru; - } -} - -#endif diff --git a/panda/src/dxgsg9/lru.h b/panda/src/dxgsg9/lru.h deleted file mode 100644 index 38143e5b7c..0000000000 --- a/panda/src/dxgsg9/lru.h +++ /dev/null @@ -1,271 +0,0 @@ -// Filename: lru.h -// Created by: aignacio (12Dec05) -// -//////////////////////////////////////////////////////////////////// -// -// PANDA 3D SOFTWARE -// Copyright (c) 2001 - 2006, Disney Enterprises, Inc. All rights -// reserved. -// All use of this software is subject to the terms of the Panda 3d -// Software license. You should have received a copy of this license -// along with this source code; you will also find a current copy of -// the license at http://etc.cmu.edu/panda3d/docs/license/ . -// -// To contact the maintainers of this program write to -// panda3d-general@lists.sourceforge.net . -// -//////////////////////////////////////////////////////////////////// - -#ifndef LRU_H -#define LRU_H - -#define ENABLE_MUTEX 1 - -#if ENABLE_MUTEX -#include "pmutex.h" -#include "mutexHolder.h" -#define LruMutexHolder(mutex) MutexHolder(mutex) -#else -#define LruMutexHolder(mutex) -#endif - - -static const int MAXIMUM_LRU_PAGE_TYPES = 8; -static const int FRAME_MAXIMUM_PRIORITY_CHANGES = 256; - - -class Lru; -class LruPage; - -enum LruPagePriority -{ - LPP_Highest = 0, - LPP_High = 10, - LPP_New = 20, - LPP_Normal = 25, - LPP_Intermediate = 30, - LPP_Low = 40, - LPP_TotalPriorities = 50, - - LPP_PageOut = LPP_TotalPriorities - 1 -}; - -typedef union _LruPageType -{ - void *pointer; - -} -LruPageType; - -typedef struct -{ - int total_pages; - int total_pages_in; - int total_pages_out; - int total_memory_in; - int total_memory_out; -} -PageTypeStatistics; - -typedef bool (*LruPageTypeFunction) (LruPage *lru_page); - -class EXPCL_PANDADX LruPage -{ - -protected: - - LruPage ( ); - ~LruPage ( ); - void change_priority (int delta); - -public: - - typedef struct _LruPageVariables - { - LruPageType lru_page_type; // pointer to memory type - - int size; - LruPagePriority priority; - int priority_change; - - struct - { - unsigned int type : 8; - unsigned int lock : 1; - unsigned int in_cache : 1; - unsigned int in_memory : 1; - unsigned int on_disk : 1; - unsigned int pre_allocated : 1; - unsigned int allocated : 1; - unsigned int in_lru : 1; - }; - - int first_frame_identifier; // creation time - int last_frame_identifier; // previous time page was used - int current_frame_identifier; - int update_frame_identifier; - - int current_frame_usage; - int last_frame_usage; - - int total_frame_page_faults; - int total_page_faults; - - int total_usage; - int update_total_usage; - - int identifier; - - float average_frame_utilization; - - LruPage *previous; - LruPage *next; - Lru *lru; - } - LruPageVariables; - - LruPageVariables _m; - - friend class Lru; -}; - -//////////////////////////////////////////////////////////////////// -// Class : Lru -// Description : Least Recently Used algorithm implementation: -// In the Lru, each "memory page" has an associated class LruPage. -// The Lru has a range of priorities from LPP_Highest to -// LPP_PagedOut. Each priority has a doubly linked list of LruPages. -// The algorithim uses an adaptive method based on the average -// utilization of each page per frame (or time slice). The -// average utilization is calculated with an exponetial moving -// average. This is superior to a standard average since a standard -// average becomes less and less adaptive the longer a page exists. -// The average utilization is used to set the priority of each page. -// A higher average utilization automatically raises the priority -// of a page and a lower average utilization automatically lowers -// the priority of a page. Therefore, pages with a higher average -// utilization have a higher chance of being kept in memory or -// cached and pages with a lower average utilization have a higher -// chance of being paged out. When a page is paged in and there -// is not enough memory available, then the lowest priority pages -// will be paged out first until there is enough memory available. -//////////////////////////////////////////////////////////////////// -class EXPCL_PANDADX Lru -{ -public: - - Lru (int maximum_memory, int maximum_pages, int maximum_page_types); - ~Lru ( ); - - bool register_lru_page_type (int index, LruPageTypeFunction page_in_function, LruPageTypeFunction page_out_function); - - LruPage *allocate_page (int size); - void update_start_update_lru_page (LruPage *lru_page); - - void free_page (LruPage *lru_page); - - void add_page (LruPagePriority priority, LruPage *lru_page); - void add_cached_page (LruPagePriority priority, LruPage *lru_page); - void remove_page (LruPage *lru_page); - - void lock_page (LruPage *lru_page); - void unlock_page (LruPage *lru_page); - - void access_page (LruPage *lru_page); - - void set_maximum_frame_bandwidth_utilization (float maximum_frame_bandwidth_utilization); - - void begin_frame ( ); - - void update_entire_lru ( ); - void partial_lru_update (int maximum_updates); - - // set maximum number of page updates per frame - // pause/resume updates/current_frame_identifier - - void unlock_all_pages (void); - - void count_priority_level_pages (void); - - void calculate_lru_statistics (void); - - bool page_out_lru (int memory_required); - -private: - void update_page_priorities (void); - void update_lru_page (LruPage *lru_page); - void update_lru_page_old (LruPage *lru_page); - -public: - typedef struct _LruVariables - { - // LruPagePriority lists - LruPage *lru_page_array [LPP_TotalPriorities]; - - int total_pages; - int available_memory; - int current_frame_identifier; - - int maximum_memory; - int minimum_memory; // target amount of memory to keep free if possible - int maximum_page_types; - - int total_lifetime_page_ins; - int total_lifetime_page_outs; - - int total_page_ins_last_frame; - int total_page_outs_last_frame; - - int total_page_ins; - int total_page_outs; - - int total_page_access; - double total_page_access_size; - double total_page_all_access_size; - - int start_priority_index; - LruPage *start_update_lru_page; - - int identifier; // the number of pages created during the lifetime of the LRU - - float weight; // used for exponential moving average - float maximum_frame_bandwidth_utilization; - - float frame_bandwidth_factor; - - LruPageTypeFunction page_in_function_array [MAXIMUM_LRU_PAGE_TYPES]; - LruPageTypeFunction page_out_function_array [MAXIMUM_LRU_PAGE_TYPES]; - - int total_lru_page_priority_changes; - LruPage *lru_page_priority_change_array [FRAME_MAXIMUM_PRIORITY_CHANGES]; - - int maximum_pages; - int total_lru_pages_in_pool; - int total_lru_pages_in_free_pool; - LruPage **lru_page_pool; - LruPage **lru_page_free_pool; - - int lru_page_count_array [LPP_TotalPriorities]; - PageTypeStatistics *page_type_statistics_array; - - void *context; // user specified data - -#if ENABLE_MUTEX - Mutex *mutex; -#endif - } - LruVariables; - - LruVariables _m; - - friend class LruPage; -}; - -float calculate_exponential_moving_average (float value, float weight, float average); -bool default_page_in_function (LruPage *lru_page); -bool default_page_out_function (LruPage *lru_page); - -void test_ema (void); -void test_lru (void); - -#endif