Files
V2TMUMemTester/FaultSources.c
2026-03-07 15:10:59 +01:00

190 lines
5.7 KiB
C

/* V2MemTest - A CLI Tool to test & fix Voodoo² TMU System
* Copyright (C) 2026 ChaCha
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <string.h>
#include "FaultSources.h"
#include "Utils.h"
def_sFaultSourceScoreRec ar_dFaultScores[NB_FAULT_SOURCE] =
{
{
.eThisFaultSource = VOODOO_BOARD,
.szName = "VOODOO_BOARD",
.szLoc = "Main Board",
.eParrentFaultSource = _INVALID_FAULT_SOURCE_,
.dScore = 0.0,
.dWeight = 1.0,
},
FAULT_SOURCES(GEN_FAULT_SOURCES_ARRAY)
};
def_sFaultSourceScoreRec ar_dFaultScores_sorted[NB_FAULT_SOURCE];
void
FaultSource_Reset()
{
for(def_eFaultSource idx = 0; idx < NB_FAULT_SOURCE; idx++ )
ar_dFaultScores[idx].dScore = 0.0;
}
static unsigned long
FaultSource_getNbDeps(const def_eFaultSource eFaultSource)
{
unsigned long res = 0;
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
if(ar_dFaultScores[idx].eParrentFaultSource == eFaultSource)
res++;
return res;
}
void
FaultSource_AddScore( def_eFaultSource eFaultSource,
double dScore)
{
double dDivider = 1.0;
do
{
dScore /= dDivider;
ar_dFaultScores[eFaultSource].dScore += dScore;
eFaultSource = ar_dFaultScores[eFaultSource].eParrentFaultSource;
dDivider = FaultSource_getNbDeps(eFaultSource);
if(dDivider <= 0)
dDivider = 1.0;
}while(eFaultSource != _INVALID_FAULT_SOURCE_);
}
static unsigned long
FaultSource_Sort_GetIdx(const def_eFaultSource eFaultSource)
{
for(unsigned long idx = 0; idx < NB_FAULT_SOURCE; idx++ )
if(ar_dFaultScores_sorted[idx].eThisFaultSource == eFaultSource)
return idx;
return _INVALID_FAULT_SOURCE_;
}
static inline void
FaultSource_Sort_Swap( const def_eFaultSource eFaultSourceCurrentA,
const def_eFaultSource eFaultSourceCurrentB)
{
static def_sFaultSourceScoreRec tmp;
memcpy(&tmp, &ar_dFaultScores_sorted[eFaultSourceCurrentA], sizeof(def_sFaultSourceScoreRec));
memcpy(&ar_dFaultScores_sorted[eFaultSourceCurrentA], &ar_dFaultScores_sorted[eFaultSourceCurrentB], sizeof(def_sFaultSourceScoreRec));
memcpy(&ar_dFaultScores_sorted[eFaultSourceCurrentB], &tmp, sizeof(def_sFaultSourceScoreRec));
}
void
FaultSource_Sort()
{
unsigned char bSwapped = 1;
memcpy(ar_dFaultScores_sorted,ar_dFaultScores,sizeof(ar_dFaultScores_sorted));
for(long eFaultSourceCurrentComp=0;
eFaultSourceCurrentComp < (NB_FAULT_SOURCE - 1);
eFaultSourceCurrentComp++ )
ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore *= ar_dFaultScores_sorted[eFaultSourceCurrentComp].dWeight;
// shaker sort
while(bSwapped)
{
bSwapped = 0;
for(long eFaultSourceCurrentComp=0;
eFaultSourceCurrentComp < (NB_FAULT_SOURCE - 1);
eFaultSourceCurrentComp++ )
{
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
{
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
bSwapped = 1;
break;
}
}
for(long eFaultSourceCurrentComp = (NB_FAULT_SOURCE-2);
eFaultSourceCurrentComp >= 0;
eFaultSourceCurrentComp-- )
{
if( ar_dFaultScores_sorted[eFaultSourceCurrentComp].dScore
< ar_dFaultScores_sorted[eFaultSourceCurrentComp + 1].dScore)
{
FaultSource_Sort_Swap(eFaultSourceCurrentComp, eFaultSourceCurrentComp + 1);
bSwapped = 1;
break;
}
}
}
// updating refs
for(long eFaultSourceIdx = 0;
eFaultSourceIdx < NB_FAULT_SOURCE;
eFaultSourceIdx++ )
{
unsigned long idx = FaultSource_Sort_GetIdx(ar_dFaultScores_sorted[eFaultSourceIdx].eParrentFaultSource);
ar_dFaultScores_sorted[eFaultSourceIdx].eParrentFaultSource = idx;
}
for(long eFaultSourceIdx = 0;
eFaultSourceIdx < NB_FAULT_SOURCE;
eFaultSourceIdx++ )
ar_dFaultScores_sorted[eFaultSourceIdx].eThisFaultSource = eFaultSourceIdx;
}
void
FaultSource_GetLoc(def_eFaultSource eFaultSource, char* loc)
{
loc[0]='\0';
strcpy(loc, ar_dFaultScores_sorted[eFaultSource].szLoc);
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
while(eFaultSource != _INVALID_FAULT_SOURCE_)
{
static char buff[1024];
sprintf(buff, "%s->%s", ar_dFaultScores_sorted[eFaultSource].szLoc, loc);
strcpy(loc, buff);
eFaultSource = ar_dFaultScores_sorted[eFaultSource].eParrentFaultSource;
}
}
void
FaultSource_Display()
{
double dScoreSum = 0;
for(def_eFaultSource eFaultSourceCurrent = 0;
eFaultSourceCurrent < NB_FAULT_SOURCE && ar_dFaultScores_sorted[eFaultSourceCurrent].dScore > 0;
eFaultSourceCurrent++ )
dScoreSum += ar_dFaultScores_sorted[eFaultSourceCurrent].dScore;
printf("------------------------------------------------\n");
printf("\nDefects list:\n\n");
printf("Score\tElement [Loc]\n");
printf("------------------------------------------------\n");
for(def_eFaultSource eFaultSourceCurrent = 0;
eFaultSourceCurrent < NB_FAULT_SOURCE
&& (ar_dFaultScores_sorted[eFaultSourceCurrent].dScore > 0);
eFaultSourceCurrent++ )
{
static char buff[1024];
FaultSource_GetLoc(eFaultSourceCurrent, buff);
printf("%02.3f\t%s [%s]\n",
100 * ar_dFaultScores_sorted[eFaultSourceCurrent].dScore / dScoreSum,
ar_dFaultScores_sorted[eFaultSourceCurrent].szName,
buff );
}
}