Skip to content

Instantly share code, notes, and snippets.

@markpapadakis
Created August 19, 2013 10:09
Show Gist options
  • Select an option

  • Save markpapadakis/6267650 to your computer and use it in GitHub Desktop.

Select an option

Save markpapadakis/6267650 to your computer and use it in GitHub Desktop.
#define __ALIGNUP_MASK(x,mask) (((x)+(mask))&~(mask))
#define ALIGNUP_TO_POWEROF2BOUNDARY(x, a) __ALIGNUP_MASK(x, (typeof(x))(a)-1)
int TouchFilePages(int fd, uint64_t offset, size_t len)
{
void *fileData;
static const size_t pageSize = getpagesize();
uint64_t upto, end;
if (len == 0)
{
struct stat64 s;
if (fstat64(fd, &s) == -1)
return -1;
end = s.st_size;
}
else
end = offset + len;
upto = Min<uint64_t>(end, ALIGNUP_TO_POWEROF2BOUNDARY(end, pageSize));
offset = ALIGNDOWN_TO_POWEROF2BOUNDARY(offset, pageSize);
len = upto - offset;
const size_t pagesCnt = ((upto - offset) + (pageSize - 1)) / pageSize;
fileData = mmap(NULL, pagesCnt * pageSize, PROT_READ, MAP_SHARED, fd, offset);
if (fileData == MAP_FAILED)
return -1;
else
{
uint8_t *const desc = (uint8_t *)malloc(pagesCnt * sizeof(uint8_t));
size_t inCoreCnt = 0;
char page[pageSize];
uint64_t it = 0;
const uint64_t contentEnd = end - offset;
const uint32_t lastPageIndex = pagesCnt - 1;
if (mincore(fileData, len, desc) == -1)
{
free(desc);
(void)munmap(fileData, len);
return -1;
}
(void)madvise(fileData, len, MADV_SEQUENTIAL);
for (uint32_t i = 0; i != lastPageIndex; ++i, it+=pageSize)
{
if (desc[i]&1)
++inCoreCnt;
else
(void)memcpy(page, (char *)fileData + it, pageSize);
}
if (desc[lastPageIndex]&1)
++inCoreCnt;
else
(void)memcpy(page, (char *)fileData + it, contentEnd - it);
free(desc);
(void)inCoreCnt; // You may want to report this somewhere
}
(void)munmap(fileData, len);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment