Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit e018a72

Browse files
authored
Merge pull request #2952 from jacob-carlborg/page-size
Add `pageSize` and `defaultPageSize` merged-on-behalf-of: Mathias LANG <pro.mathias.lang@gmail.com>
2 parents dee4e4d + cbc2258 commit e018a72

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

changelog/page_size.dd

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Add `core.memory.pageSize` and `minimumPageSize`.
2+
3+
`pageSize` contains the size of a system page in bytes.
4+
5+
---
6+
import core.memory : pageSize;
7+
ubyte[] buffer = new ubyte[pageSize];
8+
---
9+
10+
`minimumPageSize` contains the minimum size of a system page in bytes.
11+
12+
This is a compile time, platform specific value. This value might not
13+
be accurate, since it might be possible to change this value. Whenever possible,
14+
please use `pageSize` instead, which is initialized during runtime.
15+
16+
The minimum size is useful when the context requires a compile time known value,
17+
like the size of a static array: `ubyte[minimumPageSize] buffer`.
18+
19+
---
20+
import core.memory : minimumPageSize;
21+
ubyte[minimumPageSize] buffer;
22+
---

src/core/memory.d

+96
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@
104104

105105
module core.memory;
106106

107+
version (ARM)
108+
version = AnyARM;
109+
else version (AArch64)
110+
version = AnyARM;
111+
112+
version (iOS)
113+
version = AppleARM;
114+
else version (TVOS)
115+
version = AppleARM;
116+
else version (WatchOS)
117+
version = AppleARM;
107118

108119
private
109120
{
@@ -151,6 +162,91 @@ private
151162
package extern (C) bool gc_inFinalizer() nothrow @nogc @safe;
152163
}
153164

165+
version (CoreDoc)
166+
{
167+
/**
168+
* The minimum size of a system page in bytes.
169+
*
170+
* This is a compile time, platform specific value. This value might not
171+
* be accurate, since it might be possible to change this value. Whenever
172+
* possible, please use $(LREF pageSize) instead, which is initialized
173+
* during runtime.
174+
*
175+
* The minimum size is useful when the context requires a compile time known
176+
* value, like the size of a static array: `ubyte[minimumPageSize] buffer`.
177+
*/
178+
enum minimumPageSize : size_t;
179+
}
180+
else version (AnyARM)
181+
{
182+
version (AppleARM)
183+
enum size_t minimumPageSize = 16384;
184+
else
185+
enum size_t minimumPageSize = 4096;
186+
}
187+
else
188+
enum size_t minimumPageSize = 4096;
189+
190+
///
191+
unittest
192+
{
193+
ubyte[minimumPageSize] buffer;
194+
}
195+
196+
/**
197+
* The size of a system page in bytes.
198+
*
199+
* This value is set at startup time of the application. It's safe to use
200+
* early in the start process, like in shared module constructors and
201+
* initialization of the D runtime itself.
202+
*/
203+
immutable size_t pageSize;
204+
205+
///
206+
unittest
207+
{
208+
ubyte[] buffer = new ubyte[pageSize];
209+
}
210+
211+
// The reason for this elaborated way of declaring a function is:
212+
//
213+
// * `pragma(crt_constructor)` is used to declare a constructor that is called by
214+
// the C runtime, before C main. This allows the `pageSize` value to be used
215+
// during initialization of the D runtime. This also avoids any issues with
216+
// static module constructors and circular references.
217+
//
218+
// * `pragma(mangle)` is used because `pragma(crt_constructor)` requires a
219+
// function with C linkage. To avoid any name conflict with other C symbols,
220+
// standard D mangling is used.
221+
//
222+
// * The extra function declaration, without the body, is to be able to get the
223+
// D mangling of the function without the need to hardcode the value.
224+
//
225+
// * The extern function declaration also has the side effect of making it
226+
// impossible to manually call the function with standard syntax. This is to
227+
// make it more difficult to call the function again, manually.
228+
private void initialize();
229+
pragma(crt_constructor)
230+
pragma(mangle, initialize.mangleof)
231+
private extern (C) void initialize() @system
232+
{
233+
version (Posix)
234+
{
235+
import core.sys.posix.unistd : sysconf, _SC_PAGESIZE;
236+
237+
(cast() pageSize) = cast(size_t) sysconf(_SC_PAGESIZE);
238+
}
239+
else version (Windows)
240+
{
241+
import core.sys.windows.winbase : GetSystemInfo, SYSTEM_INFO;
242+
243+
SYSTEM_INFO si;
244+
GetSystemInfo(&si);
245+
(cast() pageSize) = cast(size_t) si.dwPageSize;
246+
}
247+
else
248+
static assert(false, __FUNCTION__ ~ " is not implemented on this platform");
249+
}
154250

155251
/**
156252
* This struct encapsulates all garbage collection functionality for the D

0 commit comments

Comments
 (0)