Browse Source

moved to display

aignacio_sf 20 years ago
parent
commit
00fe985041
2 changed files with 0 additions and 1615 deletions
  1. 0 1344
      panda/src/dxgsg9/lru.cxx
  2. 0 271
      panda/src/dxgsg9/lru.h

+ 0 - 1344
panda/src/dxgsg9/lru.cxx

@@ -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
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-//#include "stdafx.h"
-
-#define LRU_UNIT_TEST 0
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <windows.h>
-
-#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

+ 0 - 271
panda/src/dxgsg9/lru.h

@@ -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
-// [email protected] .
-//
-////////////////////////////////////////////////////////////////////
-
-#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