106 lines
2.2 KiB
C
106 lines
2.2 KiB
C
|
|
#define _GNU_SOURCE
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <unistd.h>
|
||
|
|
#include <fcntl.h>
|
||
|
|
#include <sys/mman.h>
|
||
|
|
#include <sys/stat.h>
|
||
|
|
#include <stdint.h>
|
||
|
|
#include <assert.h>
|
||
|
|
|
||
|
|
int main(void)
|
||
|
|
{
|
||
|
|
const char *filename = "test.bin";
|
||
|
|
|
||
|
|
/* Ouverture du fichier */
|
||
|
|
int fd = open(filename, O_RDONLY);
|
||
|
|
assert( fd != -1);
|
||
|
|
|
||
|
|
/* Taille du fichier */
|
||
|
|
struct stat st;
|
||
|
|
assert( fstat(fd, &st) != -1);
|
||
|
|
size_t filesize = st.st_size;
|
||
|
|
|
||
|
|
/* Taille d'une page mémoire */
|
||
|
|
long pagesize = sysconf(_SC_PAGESIZE);
|
||
|
|
assert(pagesize != -1);
|
||
|
|
|
||
|
|
/* Nombre de pages nécessaires pour mapper le fichier */
|
||
|
|
size_t npages = (filesize + pagesize - 1) / pagesize;
|
||
|
|
|
||
|
|
printf("Taille du fichier : %zu octets\n", filesize);
|
||
|
|
printf("Taille d'une page : %ld octets\n", pagesize);
|
||
|
|
printf("Nombre de pages : %zu\n", npages);
|
||
|
|
|
||
|
|
posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
|
||
|
|
|
||
|
|
/* Création du mapping */
|
||
|
|
unsigned char *p = mmap(NULL, filesize,
|
||
|
|
PROT_READ,
|
||
|
|
MAP_PRIVATE,
|
||
|
|
fd, 0);
|
||
|
|
assert(p != MAP_FAILED);
|
||
|
|
|
||
|
|
madvise(p, filesize, MADV_RANDOM);
|
||
|
|
close(fd);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Tableau utilisé par mincore().
|
||
|
|
* Un octet par page.
|
||
|
|
*/
|
||
|
|
unsigned char *vec = malloc(npages);
|
||
|
|
assert( vec != NULL);
|
||
|
|
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Interrogation initiale de la résidence des pages.
|
||
|
|
*/
|
||
|
|
|
||
|
|
assert(mincore(p, filesize, vec) != -1);
|
||
|
|
|
||
|
|
size_t resident = 0;
|
||
|
|
|
||
|
|
for (size_t i = 0; i < npages; i++) {
|
||
|
|
if (vec[i] & 1)
|
||
|
|
resident++;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("\nPages résidentes initialement : %zu / %zu\n",
|
||
|
|
resident, npages);
|
||
|
|
|
||
|
|
printf("\nAppuyez sur Entrée pour accéder à p[0]...");
|
||
|
|
getchar();
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Accès à la première page.
|
||
|
|
*/
|
||
|
|
volatile unsigned char x = p[0];
|
||
|
|
|
||
|
|
printf("Valeur lue : %u\n", x);
|
||
|
|
|
||
|
|
/*
|
||
|
|
* Nouvelle interrogation.
|
||
|
|
*/
|
||
|
|
|
||
|
|
|
||
|
|
assert(mincore(p, filesize, vec) != -1);
|
||
|
|
|
||
|
|
resident = 0;
|
||
|
|
|
||
|
|
for (size_t i = 0; i < npages; i++) {
|
||
|
|
if (vec[i] & 1)
|
||
|
|
resident++;
|
||
|
|
}
|
||
|
|
|
||
|
|
printf("Pages résidentes après p[0] : %zu / %zu\n",
|
||
|
|
resident, npages);
|
||
|
|
|
||
|
|
|
||
|
|
free(vec);
|
||
|
|
|
||
|
|
munmap(p, filesize);
|
||
|
|
|
||
|
|
return EXIT_SUCCESS;
|
||
|
|
}
|