#include <iostream>
#include <sys/mman.h>
#include <sys/stat.h>
#include <limits.h>
#include <errno.h>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <sys/types.h>
#include <fcntl.h>
#include <inttypes.h>
#include <unistd.h>
#include <ctime>
extern int errno;
using namespace std;
const off64_t PAGE_SIZE=1 * 1024 * 1024 * 1024;
char buffer[PAGE_SIZE]={'a'};
int main(int argc, char** argv)
{
if (argc < 2)
{
cout << "usage: filename [size]" << endl;
return -1;
}
off64_t size = 0;
if (argc == 3)
{
if (sscanf(argv[2], "%jd", &size) < 0)
{
cout << "argv[2] [" << argv[2] << "] is not valid size:" << strerror(errno) << endl;
perror("sscanf failed");
return -1;
}
}
int fd = open(argv[1], O_RDWR);
if (fd > 0)
{
if (size == 0)
{
struct stat64 sb;
if (fstat64(fd, &sb) == 0)
{
size = sb.st_size;
if (size == 0)
{
char spath[PATH_MAX];
char npath[PATH_MAX];
char *rpath, *basename;
snprintf(spath, PATH_MAX, "/sys/dev/char/%d:%d/subsystem",
major(sb.st_rdev), minor(sb.st_rdev));
rpath = realpath(spath, npath);
if (!rpath)
{
perror("realpath failed");
}
else
{
basename = strrchr(rpath, '/');
if (!basename || strcmp("dax", basename+1))
{
perror("basename failed");
}
else
{
snprintf(spath, PATH_MAX, "/sys/dev/char/%d:%d/size",
major(sb.st_rdev), minor(sb.st_rdev));
FILE* sfile = fopen(spath, "r");
if (!sfile)
{
perror("fopen failed");
}
else
{
if (fscanf(sfile, "%jd", &size) < 0)
{
perror("fscanf failed");
}
else
{
cout << "success to get file size of devdax:" << size<< endl;
}
fclose(sfile);
}
}
}
}
}
}
cout << "about to mmap ["<<argv[1] <<"] of size:"<< size << endl;
char * pAddr = (char*)mmap(NULL, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (pAddr != MAP_FAILED)
{
time_t start = time(NULL);
for (off64_t i = 0; i+PAGE_SIZE < size; i+=PAGE_SIZE)
{
memcpy(pAddr+i, buffer, PAGE_SIZE);
msync(pAddr+i,PAGE_SIZE, MS_SYNC);
}
time_t end = time(NULL);
cout << "time elapsed:" << end-start << endl;
munmap(pAddr, size);
}
else
{
perror("mmap failed");
}
close(fd);
}
else
{
perror("open failed");
}
return 0;
}