W związku z wydaniem AmigaOS 4.1 FinalEdition i dostępnością tej wersji dla klasyków oraz WinUAE z obsługą PPC pojawiło się kilka wątków związanych z limitem pamięci (do 128mb) na kartach CyberStormPPC. To z kolei wznowiło kolejne dywagacja na temat obsługi pamięci SWAP oraz kart które mogą działać jako SWAP pod kontrolą AmigaOS 4.1.
Poniżej przedstawiam krótki programik, który pozwala przetestować działania podsystemu pamięci w AmigaOS 4.1 oraz różnice pomiędzy MEMF_PRIVATE a MEMF_SHARED. Jeśli będzie jakieś zainteresowanie tym tematem to może zamienię poniższy kod w jakiś dłuższy tekst. Na razie organiczę się tylko do kilku stwierdzeń:
1) Do AmigaOS 4.1 Update 6 podsystem zarządzania pamięcią jest ograniczony do 2GB adresowalenej przestrzeni dla pamięci wirtualnej. W takim przypadku SWAP nie ma sensu bo i tak nie będzie zaadresowany. W przypadku kart z PPC to oczywiście nie ma zastosowania bo max można mieć 256MB w przypadku BPPC i 128MB w przypadku CSPPC.
2) Karty typu BigRam i ZorRam nie mogą pracowac jako pamięć RAM, bo dostęp do tej pamięci jest za wolny. To było testowane i takie są wyniki. Dlatego mogą pełnić jedynie funkcję SWAP podobnie jak dedykowana partycja na dysku.
3) To czy program będzie korzystał z pamięci SWAP zależy od niego. Użycie taga MEMF_SHARED powoduje że pamięć nie jest swapowalna.
A teraz obiecany kod - do kompilacji potrzebny jest aktualny oficjalny SDK do pobrania ze strony Hyperionu.
Kompilacja:
gcc -o memswaptest memswaptest.c
lub aby alokować pamięć z flagą MEMF_SHARED
gcc -o memswaptest-shared memswaptest.c -D SHARED
Użycie:
memswaptest 1024
// compile with AmigaOS 4.1 SDK:
// gcc -o memswaptest memswaptest.c
#include <proto/exec.h>
#include <proto/dos.h>
#define MAX_CHUNK 10
#define MEM_CHUNK_SIZE 262144 //256kb
#ifndef SHARED
#define MEM_TYPE MEMF_PRIVATE
#else
#define MEM_TYPE MEMF_SHARED
#endif
BOOL isos41(void)
{
if(SysBase->lib_Version >= 53)
return TRUE;
else
return FALSE;
}
int main(int argc, char **argv)
{
int exit_code = RETURN_FAIL;
int i, limit = MAX_CHUNK, mem_chunk = 0;
uint32 total_mem, virt_mem, chip_mem, free_mem; //ULONG
UBYTE *memaddr_ptr;
if(isos41())
{
IExec->DebugPrintF("\nFound AOS 4.1 system\n");
if(argc > 1)
limit = atoi(argv[1]);
total_mem = IExec->AvailMem(MEMF_TOTAL)/1024/1024;
virt_mem = IExec->AvailMem(MEMF_VIRTUAL)/1024/1024;
chip_mem = IExec->AvailMem(MEMF_CHIP)/1024/1024;
free_mem = IExec->AvailMem(MEMF_ANY | MEMF_LARGEST)/1024/1024;
IDOS->Printf("Total memory: %4ld MB\n", total_mem);
IDOS->Printf("Virtual memory: %4ld MB\n", virt_mem);
IDOS->Printf("Chip memory: %4ld MB\n", chip_mem);
IDOS->Printf("Free memory: %4ld MB\n", free_mem);
IExec->DebugPrintF("Free %ld MB from %ld MB", free_mem, total_mem);
IDOS->Printf("Allocating %ld chunks\n", limit);
for(i = 1;i <= limit;i++)
{
IDOS->Printf("#%04ld mem chunk (256kb): ", mem_chunk);
IExec->DebugPrintF("%04ld mem chunk:", mem_chunk);
if((memaddr_ptr = (UBYTE*) IExec->AllocVecTags(MEM_CHUNK_SIZE, AVT_Type,MEM_TYPE, AVT_ClearWithValue,0, TAG_DONE)))
IDOS->Printf("allocated");
else
IDOS->Printf("FAILED");
free_mem = IExec->AvailMem(MEMF_ANY | MEMF_LARGEST);
IDOS->Printf(" free mem: %ld\n", free_mem);
mem_chunk++;
}
IDOS->Printf("\nDone.\n");
IExec->DebugPrintF("\nDone.\n");
exit_code = RETURN_OK;
}
else
IDOS->Printf("AmigaOS 4.1 or higer is needed.\n");
return(exit_code);
}
Jeśli ktoś ma problem z kompilacją mogę udostępnić binarki.