-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathimpl.linux.cpp
123 lines (118 loc) · 3.16 KB
/
impl.linux.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#pragma once
namespace MemoryMapped
{
size_t GetPageSize()
{
return sysconf(_SC_PAGESIZE);
}
bool File::openReal(size_t mappedBytes, CacheHint hint)
{
struct stat statInfo;
// already open ?
if (isValid())
{
return false;
}
m_handle = 0;
m_filesize = 0;
m_hint = hint;
m_mappedView = NULL;
m_handle = ::open(m_filename.c_str(), O_RDONLY | O_LARGEFILE);
if(m_handle == -1)
{
m_handle = 0;
throw IOError(m_filename, "open() failed");
return false;
}
// file size
if (fstat(m_handle, &statInfo) < 0)
{
throw IOError(m_filename, "stat() failed");
return false;
}
m_filesize = statInfo.st_size;
// initial mapping
remap(0, mappedBytes);
if (!m_mappedView)
{
// remap() may throw an exception already
return false;
}
// everything's fine
return true;
}
void File::close()
{
m_filesize = 0;
// kill pointer
if (m_mappedView)
{
::munmap(m_mappedView, m_filesize);
m_mappedView = NULL;
}
//close underlying file
if(m_handle)
{
::close(m_handle);
m_handle = 0;
}
}
bool File::remap(uint64_t offset, size_t mappedBytes)
{
int linuxHint;
if (!m_handle)
{
return false;
}
if (mappedBytes == WholeFile)
{
mappedBytes = m_filesize;
}
// close old mapping
if(m_mappedView)
{
::munmap(m_mappedView, m_mappedBytes);
m_mappedView = NULL;
}
// don't go further than end of file
if(offset > m_filesize)
{
return errOffset();
}
if((offset + mappedBytes) > m_filesize)
{
mappedBytes = size_t(m_filesize - offset);
}
// new mapping
m_mappedView = ::mmap(NULL, mappedBytes, PROT_READ, MAP_SHARED, m_handle, offset);
if(m_mappedView == MAP_FAILED)
{
m_mappedBytes = 0;
m_mappedView = NULL;
throw IOError(m_filename, "mmap == MAP_FAILED");
return false;
}
m_mappedBytes = mappedBytes;
linuxHint = 0;
switch (m_hint)
{
case Normal:
linuxHint = MADV_NORMAL;
break;
case SequentialScan:
linuxHint = MADV_SEQUENTIAL;
break;
case RandomAccess:
linuxHint = MADV_RANDOM;
break;
default:
break;
}
// assume that file will be accessed soon
//linuxHint |= MADV_WILLNEED;
// assume that file will be large
//linuxHint |= MADV_HUGEPAGE;
::madvise(m_mappedView, m_mappedBytes, linuxHint);
return true;
}
}