|
SpeicherTest.c |
/*
* SpeicherTest.c
*
* ============================================================================================================
* Das Modul Testet die Freispeicherverwaltung auf Herz, Nieren und verlorene Pointer
* ============================================================================================================
*/
#include "mxMMU.h"
#include "mxUhr.h"
#include "mxVektor.h"
#include "mxSystem.h"
#include "mxAbbruch.h"
#include "mxAusgabe.h"
#include "mxSpeicher.h"
#include "mxProzess.h"
/* -------------------------------------------------------------------------------------------------------------------- */
/************
** Defines **
************/
#define cST_Blockgroesse 8 /* Schaetzung fuer sizeof(tFreispeicherKnoten) */
#define cST_FuellZeichen 0x00 /* zum ueberschreiben der Header */
#define cST_TimeOut (60 * cTicksProSekunde)
#define STget(charptr) *((long*)(charptr)) /* bel. Pointer derefenrenzieren als long */
/* -------------------------------------------------------------------------------------------------------------------- */
/***************
** Strukturen **
***************/
typedef enum {
eST_notNULL,
eST_address,
eST_round,
eST_NULL,
eST_wrongfreemem,
eST_badnext,
eST_badsize,
eST_result,
eST_init
} tST_Fehler;
/* -------------------------------------------------------------------------------------------------------------------- */
/**********************
** Globale Variablen **
**********************/
static int ST_RestZeit;
static long ST_Frei;
static long *ST_Start;
static int ST_next;
static int ST_size;
/* -------------------------------------------------------------------------------------------------------------------- */
/***************
** Funktionen **
***************/
/* --------------------------------------------------------------------------------------------------------------------
* TimeOut
* -------------------------------------------------------------------------------------------------------------------- */
void ST_TimeOut(void)
{
Lock();
asm(/*MOVEM.L D0-D7/A0-A6,-(SP) */);/* Adress- und Datenregister retten */
ST_RestZeit--;
if(ST_RestZeit <= 0)
{
kprintf(/*\nSpeicherTest TimeOut!!!\n%c*/, cEndeZeichen); /* Termination anzeigen */
StelleInterruptVektorenWiederHerUndSperreUhrInterrupt(); /* genau das */
_exit(42); /* fertig */
}
asm(/*MOVEM.L (SP)+,D0-D7/A0-A6 */);/* Adress- und Datenregister vom Stack holen */
asm(/*RTE */);/* Beenden der Uhren-Unterbrechung */
}
/* --------------------------------------------------------------------------------------------------------------------
* die Speichertestroutinen
* -------------------------------------------------------------------------------------------------------------------- */
void ST_Fehler( tST_Fehler FehlerNummer )
{
kprintf("\nFehler: ");
switch(FehlerNummer) /* entsprechend der Fehlernummer */
{ /* einen Fehlerstring ausgeben */
case eST_notNULL: kprintf("Es wurde nicht der NULL-Pointer uebergeben!"); break;
case eST_address: kprintf("Nicht erwartete Segmentadresse erhalten!"); break;
case eST_round: kprintf("Die uebergebene Speichergroesse wurde nicht aufgerundet!"); break;
case eST_NULL: kprintf("Speicher holen gescheitert, obwohl noch Speicher vorhanden!"); break;
case eST_wrongfreemem: kprintf("Gesamtmenge des freien Speichers in der Liste ist falsch!"); break;
case eST_badnext: kprintf("Ungueltiger Verkettungszeiger gefunden!"); break;
case eST_badsize: kprintf("Ungueltige Bloeckgroesse gefunden!"); break;
case eST_result: kprintf("Block der letzten Operation hat falschen Zustand!"); break;
case eST_init: kprintf("Datenstruktur ist falsch, implementierte Version nicht feststellbar!"); break;
default: kprintf("Unbekannter Fehler!"); break;
}
kprintf("\n");
while(1); /* bis TimeOut */
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_HeaderLoeschen( char* SpeicherAdresse )
/* Ueberschreibt den Header des Speichersegments
*/
{
int i;
for(i=0; i<cST_Blockgroesse; i++)
{
SpeicherAdresse[i] = (char)cST_FuellZeichen;
}
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_WhichImpl( void )
{
ST_Start = (long*)cFreispeicherStart;
ST_Frei = (long)cRAMEnd - (long)cFreispeicherStart;
if (ST_Start[0] == 0 && ST_Start[1] == ST_Frei) {
ST_next = 0;
ST_size = 1;
} else if (ST_Start[1] == 0 && ST_Start[0] == ST_Frei) {
ST_next = 1;
ST_size = 0;
} else {
ST_Fehler(eST_init);
}
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_ListWalk( void* Adresse, long Wieviel, int shouldbefree )
{
long *p;
long freisum = 0;
int isfree = 0;
if (ST_Frei == 0) return;
for (p = ST_Start; p; freisum += p[ST_size], p = (long*)(p[ST_next])) {
/* Test des Verkettungszeigers */
if ((p[ST_next] && p[ST_next] < (long)p + p[ST_size] + 8) ||
p[ST_next] > (long)cRAMEnd - 8 ||
(p[ST_next] & 7) != 0) {
kprintf("\n Block=%d Block.next=%d Block.size=%d", (long)p, p[ST_next], p[ST_size]);
ST_Fehler(eST_badnext);
}
/* Test der Blockgroesse */
if ((p[ST_size] & 7) != 0 ||
p[ST_size] <= 0 ||
p[ST_size] > ST_Frei ||
(long)p + p[ST_size] > (long)cRAMEnd) {
kprintf("\n Block=%d Block.next=%d Block.size=%d", (long)p, p[ST_next], p[ST_size]);
ST_Fehler(eST_badsize);
}
/* Test des angegebenen Blocks */
if ((long)p <= (long)Adresse && (long)p + p[ST_size] > (long)Adresse) {
isfree = 1;
if ((long)p + p[ST_size] < (long)Adresse + Wieviel) {
kprintf("\n Block=%d Block.next=%d Block.size=%d", (long)p, p[ST_next], p[ST_size]);
ST_Fehler(eST_result);
}
}
if (Adresse && (long)Adresse < (long)p && (long)Adresse + Wieviel > (long)p) {
kprintf("\n Block=%d Block.next=%d Block.size=%d", (long)p, p[ST_next], p[ST_size]);
ST_Fehler(eST_result);
}
}
if (Adresse && isfree != shouldbefree) {
ST_Fehler(eST_result);
}
if (freisum != ST_Frei) {
kprintf("\n Frei=%d erwartet=%d", freisum, ST_Frei);
ST_Fehler(eST_wrongfreemem);
}
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_HolenTest( char* String, long Wieviel, void* Adresse )
{
char* segment;
long* next;
long size;
if (String[0]) kprintf(String);
next = (long*)ST_Start[ST_next];
size = ST_Start[ST_size];
segment = SpeicherHolen(Wieviel);
if (Wieviel & 7)
{
Wieviel = (Wieviel & ~7) + 8;
}
if((segment == NULL ) && (Adresse != NULL))
{
ST_Fehler(eST_NULL);
}
else if(((long)segment & 7) != 0)
{
ST_Fehler(eST_round);
}
else if(segment != Adresse)
{
if(Adresse != NULL)
{
ST_Fehler(eST_address);
}
else
{
ST_Fehler(eST_notNULL);
}
}
if(Adresse != NULL) {
ST_Frei -= Wieviel;
if (Adresse == ST_Start) ST_Start = (Wieviel == size? next : Adresse + Wieviel);
}
ST_ListWalk(Adresse, Wieviel, 0);
if(Adresse != NULL)
{ /* Header l"oschen falls Speicher */
ST_HeaderLoeschen(segment); /* angefordert werden konnte */
}
if (String[0]) kprintf(" ok\n");
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_FreigebenTest( char* String, void* Wo, long Wieviel )
{
if (String[0]) kprintf(String);
SpeicherFreigeben(Wo,Wieviel);
if (Wieviel & 7)
{
Wieviel = (Wieviel & ~7) + 8;
}
if (Wo == NULL || Wieviel == 0) {
Wo = NULL;
Wieviel = 0;
} else {
ST_Frei += Wieviel;
if (ST_Start==NULL || (long)Wo < (long)ST_Start) ST_Start = Wo;
}
ST_ListWalk(Wo, Wieviel, 1);
if (String[0]) kprintf(" ok\n");
}
/* -------------------------------------------------------------------------------------------------------------------- */
void ST_Zusammenlegen( void* First, long Blockgroesse )
/* gibt drei Speicherbl"ocke in unterschiedlicher Reihenfolge frei und fordert den frei werdenden Speicher wieder an
* pre : die freien Speicherbloecke vor first m"ussen kleiner als die blockgroesse sein,
* der Speicher von first bis first + ( blockgroesse * 3 ) ist belegt
*/
{
char* second = First + Blockgroesse; /* hier liegen die folgenen Bl"ocke */
char* third = second + Blockgroesse; /* die Adressen der drei Speicherbl"ocke*/
long wieviel = Blockgroesse - 1; /* die angeforderte Speichergroesse */
/* zwei angrenzende Bloecke freigeben -- das vordere zuerst */
kprintf("Zwei angrenzende Bloecke freigeben -- das vordere zuerst:");
ST_FreigebenTest(/**/, First, wieviel); /* den ersten Block freigeben */
ST_FreigebenTest(/**/, second,wieviel); /* und den anschlie|3enden Block auch */
ST_HolenTest(/**/, (Blockgroesse * 2 ) - 1, First); /* einen doppelt so grossen Block anf. */
ST_HolenTest(/**/, Blockgroesse, NULL); /* soviel Speicher darf nicht mehr */
kprintf(" ok\n");
/* s.o. diesmal allerdings das hintere zuerst */
kprintf("Zwei angrenzende Bloecke freigeben -- das hintere zuerst:");
ST_FreigebenTest(/**/, second,wieviel); /* den zweiten Block freigeben */
ST_FreigebenTest(/**/, First, wieviel); /* den ersten ebenfalls freigeben */
ST_HolenTest(/**/, (Blockgroesse * 2 ) - 1, First); /* den doppelten Speicher anfordern */
ST_HolenTest(/**/, Blockgroesse, NULL); /* soviel Speicher darf nicht mehr */
kprintf(" ok\n");
/* drei angrenzende Bl"ocke freigeben -- mittlerer zuletzt */
kprintf("Drei angrenzende Bloecke freigeben -- das mittlere zuletzt:");
ST_FreigebenTest(/**/, First, wieviel); /* ersten Block freigeben */
ST_FreigebenTest(/**/, third, wieviel); /* den letzten Block freigeben */
ST_FreigebenTest(/**/, second,wieviel); /* und auch den mittleren freigeben */
ST_HolenTest(/**/, (Blockgroesse * 3 ) - 1, First); /* den gesamten Speicher anfordern */
ST_HolenTest(/**/, Blockgroesse, NULL); /* soviel Speicher darf nicht mehr */
kprintf(" ok\n");
}
/* -------------------------------------------------------------------------------------------------------------------- */
void SpeicherTest(void)
{
char* speicher; /* Anfangsadresse des Speichers */
long gesamt; /* zu verwaltender Speicher */
long wieviel;
long blockgroesse;
void (*alteUhrUnterbrechungsBehandlungsRoutine)();
/* Bildschirm loeschen und Cursor in die linke obere Ecke platzieren */
kprintf("\033[2J");
kprintf("\033[1;1H");
/* TimeOut anwerfen */
ST_RestZeit = cST_TimeOut;
Lock();
alteUhrUnterbrechungsBehandlungsRoutine = LiesInterruptVektor(cUhrInterruptVektor);
SetzeInterruptVektor(cUhrInterruptVektor,ST_TimeOut);
Unlock();
/* Variablen initialisieren */
speicher = (char*)cFreispeicherStart;
gesamt = (long)cRAMEnd - (long)speicher;
ST_WhichImpl();
kprintf("### Grundlegender Funktionstest\n");
ST_HolenTest( "Anfordern eines Speicherblocks mit Groesse 0:", 0, NULL );
ST_HolenTest( "Einen Speicherblock holen:", 1024, speicher );
ST_FreigebenTest( "und wieder freigeben:" , speicher, 1024 );
wieviel = 1024 - 4; /* 1KB anfordern */
blockgroesse = (( wieviel + 7 ) / 8 ) * 8; /* aufrunden */
ST_HolenTest( "Anfordern eines Speicherblocks > 0:", wieviel, speicher );
ST_HolenTest( "Test ob naechster Block direkt dahinter liegt:", 1, speicher + blockgroesse );
ST_FreigebenTest( "Der gesamte Speicher wird auf einmal freigegeben:", speicher, blockgroesse + 1 );
kprintf("### Test mit vollstaendiger Speicherbelegung\n");
/* den ges. Speicher am Stück holen */
ST_HolenTest( "Anfordern des gesamten Speichers in einem Segment:", gesamt, speicher );
ST_HolenTest( "Scheitert naechstes SpeicherHolen?", 1, NULL );
/* nichts freigeben */
ST_FreigebenTest( "Freigeben eines leeren Speicherblocks:", speicher, 0 );
ST_FreigebenTest( "Freigeben eines NULL-Pointers:", NULL,42 );
ST_HolenTest( "Scheitert naechstes SpeicherHolen immer noch?", 1, NULL );
ST_FreigebenTest( "Der gesamte Speicher wird wieder freigeben:",
speicher, gesamt ); /* und wieder Friegeben */
ST_HolenTest( "Einen Speicherblock holen:", 1024, speicher );
ST_FreigebenTest( " und wieder freigeben:" , speicher, 1024 );
kprintf("### Test, ob First-Fit richtig funktioniert\n");
ST_HolenTest( "Anfordern des gesamten Speichers in einem Segment:", gesamt, speicher );
ST_FreigebenTest( "1KB nach 1KB freigeben:", speicher+1024, 1024 );
ST_FreigebenTest( "2KB nach 3KB freigeben:", speicher+3*1024, 2*1024 );
ST_FreigebenTest( "3KB nach 6KB freigeben:", speicher+6*1024, 3*1024 );
ST_HolenTest( "Anfordern 3KB:", 3*1024, speicher+6*1024 );
ST_FreigebenTest( "3KB wieder freigeben:", speicher+6*1024, 3*1024 );
ST_HolenTest( "Anfordern 2KB:", 2*1024, speicher+3*1024 );
ST_FreigebenTest( "2KB wieder freigeben:", speicher+3*1024, 2*1024 );
ST_HolenTest( "Anfordern 1.5KB:", 1600, speicher+3*1024 );
ST_HolenTest( "Anfordern 1KB:", 1024, speicher+1024 );
ST_HolenTest( "kann noch 4KB Block gefunden werden?", 4*1024, NULL );
ST_HolenTest( "kann noch 0.5KB Block gefunden werden?", 2*1024-1600, speicher+3*1024+1600 );
ST_HolenTest( "kann noch 3KB Block gefunden werden?", 3*1024, speicher+6*1024 );
ST_HolenTest( "Ist der gesamte Speicher jetzt belegt?", 1, NULL );
ST_Zusammenlegen( speicher + 1024, 1024 );
ST_FreigebenTest( "Vor den drei Segmenten wird ein kleiner Speicherblock freigegeben:", speicher, 1024 / 2 );
ST_Zusammenlegen( speicher + 1024, 1024 );
ST_HolenTest( "Kleiner Speicherblock wird wieder belegt:", 1024 / 2, speicher );
ST_FreigebenTest( "Gesamter Speicher wird wieder freigegeben:", speicher, gesamt);
kprintf("### Test, ob freie Bloecke richtig zusammengelegt werden\n");
ST_HolenTest( "Belegen des ersten Speicherviertels:", gesamt/4, speicher+0*(gesamt/4));
ST_HolenTest( "Belegen des zweiten Speicherviertels:", gesamt/4, speicher+1*(gesamt/4));
ST_HolenTest( "Belegen des dritten Speicherviertels:", gesamt/4, speicher+2*(gesamt/4));
ST_HolenTest( "Belegen des vierten Speicherviertels:", gesamt/4, speicher+3*(gesamt/4));
ST_FreigebenTest( "Freigeben des zweiten Speicherviertels:", speicher+1*(gesamt/4), gesamt/4);
ST_FreigebenTest( "Freigeben des vierten Speicherviertels:", speicher+3*(gesamt/4), gesamt/4);
ST_FreigebenTest( "Freigeben des dritten Speicherviertels:", speicher+2*(gesamt/4), gesamt/4);
ST_HolenTest( "Koennen jetzt 3/4 der Gesamtgroesse belegt werden?", 3*(gesamt/4), speicher+1*(gesamt/4));
ST_FreigebenTest( "Freigeben des dritten Speicherviertels:", speicher+2*(gesamt/4), gesamt/4);
ST_FreigebenTest( "Freigeben des vierten Speicherviertels:", speicher+3*(gesamt/4), gesamt/4);
ST_FreigebenTest( "Freigeben des zweiten Speicherviertels:", speicher+1*(gesamt/4), gesamt/4);
ST_FreigebenTest( "Freigeben des ersten Speicherviertels:", speicher+0*(gesamt/4), gesamt/4);
kprintf("### Test, ob immer noch der ganze Speicher da ist\n");
ST_HolenTest( "Anfordern des gesamten Speichers in einem Segment:", gesamt, speicher );
ST_HolenTest( "Scheitert naechstes SpeicherHolen?", 1, NULL );
ST_FreigebenTest( "Gesamten Speicher zum Abschluss freigeben:", speicher, gesamt);
kprintf("\n >>>>> SpeicherTest hat keinen Fehler gefunden! <<<<<");
/* Ende */
Lock();
SetzeInterruptVektor(cUhrInterruptVektor,alteUhrUnterbrechungsBehandlungsRoutine);
Unlock();
Schlafe(10000);
}
Bei Problemen mit der Seite bitte eine Mail an Marek
Converted with C2HTML V0.669 by Iluvatar
Prozeßdatenverarbeitung