mmap(2)
man sayfasından ve arama sonuçlarından etkilendim, bu mmap
sadece sistemin kullanılabilir adres alanları ile sınırlı, sistem ayrılmış adres alanları ile sınırlı. Yani 32 bit armv7l'de, 3GB = (4GB - 1GB) civarında olduğunu farz ediyorum. Aslında mmap
could gibiNeden 32 bit armv7l'de bir 4GB dosya mmap başarılı oldu?
Ama görünüyordu sorunsuz bir 5 GB dosya:
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;
}
}
-D_FILE_OFFSET_BITS=64
bayrağıyla Derleme:
g++ -D_FILE_OFFSET_BITS=64 test.cc
Ve sonuç verimleri:
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
Sonuçlardan, mmap gerçek trou gitmeden önce 4 kez başarılı oldu bles. Ama dosya ~ 5GB olduğundan bu yana başarılı olmamalıydı.
Sorularım şöyle olacaktır:
mmap
için beklenen bu davranış mı?- Değilse, nerede yanlış yaptım?
Düzenleme: Fiziksel addres uzantısı (PAE) 32 bit sistemlerde
can addres çok fazla 2^32 byte, o varsa.
bu 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
Sorunuzla ilgisi olmayan ve sadece FYI, ancak 'printf 'formatını kullanarak bir işaretçi yazdırırken"% p ", argüman * * bir * void * olmalıdır, bu yüzden döküm gerektirmez. Ayrıca bir [void *] işaretçisi basmak için kullanılan bir [çıkış operatör aşırı yükü] (http://en.cppreference.com/w/cpp/io/basic_ostream/operator_ltlt) vardır, bu yüzden eski C 'printf'e gerek yoktur 'işlev hiç. –
Fiziksel eklenti uzantısı (PAE) ile 32-bit sistemler, mevcutsa 2^32 bayttan çok daha fazlasını ekleyebilir. – hetepeperfan
mmap() 'işlevinin prototipi nedir? Eğer ikinci argüman sadece 32 bit ise, 64-bit 'sb.st_size' sizin kısaltılmış olabilir. –