// File: MemoryDiffKiller.hpp // //---------------------------------------------------------------------------// // Date Who Modification // // -------- --- ---------------------------------------------------------- // // 10/04/00 JSE die haxorz die //---------------------------------------------------------------------------// // Copyright (C) 2000, Microsoft Corp // // All Rights reserved worldwide // // This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL // //===========================================================================// #include "MW4Headers.hpp" #include "MemoryDiffKiller.hpp" #include "MWApplication.hpp" #include "MechLab.hpp" #include "Mech.hpp" //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryDiffKiller::MemoryDiffKiller(): Plug(DefaultData) { m_sourceCount = 0; for (int i = 0; i < Maximum_Sources; ++i) { m_sourceSize[i] = 0; } for (i = 0; i < Maximum_Copies; ++i) { m_copyMemory[i] = NULL; m_copySize[i] = 0; m_copySourceIndex[i] = 0; } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // MemoryDiffKiller::~MemoryDiffKiller() { for (int i = 0; i < Maximum_Copies; ++i) { if (m_copyMemory[i] != NULL) { gos_Free(m_copyMemory[i]); m_copyMemory[i] = NULL; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MemoryDiffKiller::Init() { #ifdef LAB_ONLY if (!MWApplication::MoveItAndShakeIt) return; #endif Uninit(); if (MWApplication::GetInstance()!=NULL) { MWApplication *app = MWApplication::GetInstance(); //m_sourceData[m_sourceCount].Add(app); //m_sourceSize[m_sourceCount] = sizeof(*app); //++m_sourceCount; if (app->m_serverMissionParameters) { m_sourceData[m_sourceCount].Add(app->m_serverMissionParameters); m_sourceSize[m_sourceCount] = sizeof(*app->m_serverMissionParameters); ++m_sourceCount; } if (app->m_localMissionParameters) { m_sourceData[m_sourceCount].Add(app->m_localMissionParameters); m_sourceSize[m_sourceCount] = sizeof(*app->m_localMissionParameters); ++m_sourceCount; } } if (MechLab::Instance!=NULL) { if (MechLab::Instance->m_workingMech != NULL) { // we want the mech to have a higher weight... for (int i = 0; i < 30; ++i) { m_sourceData[m_sourceCount].Add(MechLab::Instance->m_workingMech); m_sourceSize[m_sourceCount] = sizeof(*MechLab::Instance->m_workingMech); ++m_sourceCount; } ChainIteratorOf sub_iterator(&MechLab::Instance->m_workingMech->subsystemsInVehicle); Subsystem *subsystem; while((subsystem = sub_iterator.ReadAndNext()) != NULL) { m_sourceData[m_sourceCount].Add(subsystem); m_sourceSize[m_sourceCount] = sizeof(*subsystem); ++m_sourceCount; if (m_sourceCount == Maximum_Sources) break; } } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MemoryDiffKiller::Uninit() { #ifdef LAB_ONLY if (!MWApplication::MoveItAndShakeIt) return; #endif m_sourceCount = 0; for (int i = 0; i < Maximum_Sources; ++i) { if (m_sourceData[i].GetCurrent()) { m_sourceData[i].Remove(); } m_sourceSize[i] = 0; } for (i = 0; i < Maximum_Copies; ++i) { if (m_copyMemory[i] != NULL) { gos_Free(m_copyMemory[i]); m_copyMemory[i] = NULL; m_copySize[i] = 0; m_copySourceIndex[i] = 0; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // //define CHECK_ALLOC_SIZE void MemoryDiffKiller::MoveItAndShakeIt() { #ifdef LAB_ONLY if (!MWApplication::MoveItAndShakeIt) return; #endif for (int i = 0; i < Maximum_Copies; ++i) { // if our source was deleted... if ( m_sourceData[m_copySourceIndex[i]].GetCurrent() == NULL) { gos_Free(m_copyMemory[i]); m_copyMemory[i] = NULL; m_copySize[i] = 0; m_copySourceIndex[i] = 0; } else { // if the number is null we can allocate it if (m_copyMemory[i] == NULL) { // this could have gone away since the init, so go // till we find one or try 5 times // if we don't get it this time, we'll try 5 more times next time int counter = 0; while (counter < 5) { int random_number = Random::GetLessThan(m_sourceCount); if (m_sourceData[random_number].GetCurrent() != NULL) { m_copySourceIndex[i] = (BYTE)random_number; m_copySize[i] = m_sourceSize[random_number]; m_copyMemory[i] = gos_Malloc(m_copySize[i]); memcpy(m_copyMemory[i], m_sourceData[m_copySourceIndex[i]].GetCurrent(), m_copySize[i]); break; } ++counter; } } else { // if we churn too much we actually narrow down the real value. //else if we may randomly decide to remove a copy... //int random_number = Random::GetLessThan(500); //if (random_number == 0) //{ // gos_Free(m_copyMemory[i]); // m_copyMemory[i] = NULL; // m_copySize[i] = 0; // m_copySourceIndex[i] = 0; //} //else { // we go ahead and copy the source... memcpy(m_copyMemory[i], m_sourceData[m_copySourceIndex[i]].GetCurrent(), m_copySize[i]); } } } } #ifdef CHECK_ALLOC_SIZE int percentages[Maximum_Sources]; for (i = 0; i < Maximum_Sources; ++i) { percentages[i] = 0; } int total_size = 0; for (i = 0; i < Maximum_Copies; ++i) { if (m_copyMemory[i] != NULL) { ++percentages[m_copySourceIndex[i]]; total_size += m_copySize[i]; } } SPEWALWAYS(("jerryeds", "TOTAL SIZE USED : %d", total_size)); for (i = 0; i < Maximum_Sources; ++i) { float percent = ((float)percentages[i] / Maximum_Copies) * 100.0f; SPEWALWAYS(("jerryeds","%d - %d - %f", i, percentages[i], percent)); } #endif }