Ein paar (konstruktiv gemeinte) Anmerkungen noch zu Deinem Code, damit ich nicht ganz umsonst reingeschaut hab
1) Bitte solche Initialisierungsstunts, wie
Code: Alles auswählen
struct List bla;
NewList(&bla);
Code: Alles auswählen
struct List *bla = NULL;
bla = (struct List *)AllocSysObjectTags(ASOT_LIST, TAG_DONE);
/* Nodes allokieren, hinzufügen, entfernen, freigegeben */
FreeSysObject(ASOT_LIST, bla); /* Die Liste MUSS hier bereits leer sein! */
bla = NULL;
Code: Alles auswählen
NewObject(NULL, ...., TAG_DONE)
Krempel etwas übersichtlicher zu machen. Ist im Prinzip Geschmackssache, aber ich persönlich finde sowas
Code: Alles auswählen
LAYOUT_AddChild, HGroupObject,
LAYOUT_AddChild, ChooserObject,
GA_ID, ...,
ChooserEnd,
EndHGroup,
3) Der wichtigste Punkt zuletzt, den ich auch erst lernen mußte
MEMF_SHARED ist in 99% der Fälle absolut unnötig und sinnlose Speicherverschwendung, denn: MEMF_SHARED impliziert einen Lock des angeforderten Speicherbereichs(*). Das heißt, daß dieser Speicher nicht durch den Pager ausgelagert werden kann, was gerade auf Maschinen mit arg beschränkten Arbeitsspeicher (Classics!) einen enormen Nachteil darstellt und daher wirklich nur in absolut notwendingen Fällen gemacht werden sollte.
Wann ist also MEMF_SHARED tatsächlich notwendig? Antwort: Nur dann, wenn der Speicher in Interrupts genutzt werden soll (Obacht! Dazu gehört auch das Scheduling, sprich Task-Strukturen müssen auch gelockt sein!). ALLES andere kann und sollte mit MEMF_PRIVATE angefordert werden, denn hier macht es nichts aus, ob irgendeine Struktur erst vom Pager wieder geholt werden muß. Dauert dann halt nur etwas länger.
Einzige Ausnahme von dieser Regel betrifft Situationen, wo ein Forbid() nicht gebrochen werden darf. Denn der Pager würde das Forbid() brechen (Nebenbei: Forbid() bitte auch nur sehr sparsam einsetzen, wenn unbedingt nötig!).
Also nochmal zusammenfassend:
- MEMF_SHARED für Speicher, der in Interrupts oder während des Schedulings benutzt werden muß oder dessen Nutzung ein Forbid() nicht brechen darf.
- MEMF_PRIVATE für alles andere!
So, das war's mit dem kleinen Exkurs ins neue Speichersystem für heute, liebe Kinder. Jetzt könnt Ihr ja.. abschalten
Ach, die Fußnote fehlt noch:
(*) Alles unter 8KB passt in einen Slaballokator und wird sowieso nicht ausgelagert. Ab 8KB Größe wird aber ausgelagert, was nur mit nicht-gelocktem Speicher möglich ist. Bei MEMF_SHARED wird implizit gelockt, was - falls man semantisch absolut korrekt sein will - eigentlich bedeutet, daß man vor einem FreeVec() von MEMF_SHARED Speicher eigentlich erst ein Unlock() aufrufen müßte! Glücklicherweise wird solcher MEMF_SHARED nach FreeVec() auch aus dem Mapping genommen, wodurch das Locking nicht mehr ins Gewicht fällt. Ruft man allerdings explizit Lock() auf oder setzt AVT_Lock, TRUE - insbesondere bei kleinen Speicherbereichen -, dann muß man auch zwingend Unlock() aufrufen.