Ho avuto l'impressione dalla pagina man mmap(2)
e risultati di ricerca, che mmap
è limitato solo agli spazi di indirizzi disponibili del sistema, meno gli spazi degli indirizzi riservati del sistema. Quindi su armv7l a 32 bit, presumo che sia intorno a 3 GB = (4 GB - 1 GB).Perché mmap un file da 4 GB su armv7l a 32 bit è riuscito?
ma sembrava che ho potuto effettivamente mmap
un file di 5 GB senza alcun problema:
int main(int argc, char** argv) {
// stats
char * path = argv[1];
struct stat sb;
stat(path, &sb);
std::cout << "File size: " << sb.st_size << std::endl;
// open
int fd = open(path, O_RDONLY, S_IRWXU);
std::cout << "File descriptor: " << fd << std::endl;
int i;
for (i =0; i<10; ++i){
void *pa = mmap(
nullptr, sb.st_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0);
std::cout << "PA: " << pa
<< ", MAP_FAILED: "
<< (pa == MAP_FAILED) << ", Status: "
<< strerror(errno) << std::endl;
}
}
Compila con -D_FILE_OFFSET_BITS=64
bandiera:
g++ -D_FILE_OFFSET_BITS=64 test.cc
E i rendimenti dei risultati:
File size: 5045966585
File descriptor: 3
PA: 0x89f80000, MAP_FAILED: 0, Status: Success
PA: 0x5d34a000, MAP_FAILED: 0, Status: Success
PA: 0x30714000, MAP_FAILED: 0, Status: Success
PA: 0x3ade000, MAP_FAILED: 0, Status: Success
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
PA: 0xffffffff, MAP_FAILED: 1, Status: Cannot allocate memory
Dai risultati, mmap è riuscito per 4 volte prima di entrare in vero trou bles. Ma non dovrebbe essere successo poiché il file è ~ 5 GB.
Le mie domande sarebbero:
- È questo il comportamento previsto per
mmap
? - In caso contrario, dove ho sbagliato?
Edit:
Con estensione addres fisico (PAE) sistemi a 32 bit può Addres molto più di 2^32 byte, se è disponibile.
Non c'è alcun supporto PAE per questa CPU
$> cat /proc/cpuinfo
Processor : ARMv7 Processor rev 4 (v7l)
processor : 0
BogoMIPS : 1436.46
processor : 1
BogoMIPS : 1436.46
Features : swp half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xc07
CPU revision : 4
Hardware : sun7i
Revision : 0000
Serial : 09c11b9d52544848804857831651664b
Non correlato alla tua domanda e solo FYI, ma quando si stampa un puntatore utilizzando il 'printf' format' "% p" 'l'argomento * dovrebbe * essere un' void * ', quindi non è necessario il cast. Inoltre c'è un [overload dell'operatore di output] (http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt) che utilizza un 'void *' per stampare i puntatori, quindi non c'è bisogno del vecchio C 'printf 'funzione a tutti. –
Con estensione fisica addres (PAE) i sistemi a 32 bit possono aggiungere molto più di 2^32 byte, se disponibile. – hetepeperfan
Qual è il prototipo di funzione per 'mmap()'? Se il secondo argomento è solo a 32 bit, il tuo 'sb.st_size' a 64 bit potrebbe essere troncato. –