@@ -42,25 +42,70 @@ struct Inner {
42
42
cap : usize ,
43
43
}
44
44
45
+ #[ cfg( unix) ]
46
+ fn create_mapping ( capacity : usize ) -> * mut u8 {
47
+ let ptr = unsafe {
48
+ libc:: mmap (
49
+ ptr:: null_mut ( ) ,
50
+ capacity,
51
+ libc:: PROT_READ | libc:: PROT_WRITE ,
52
+ libc:: MAP_ANON | libc:: MAP_PRIVATE ,
53
+ -1 ,
54
+ 0 ,
55
+ )
56
+ } ;
57
+
58
+ ptr as * mut u8
59
+ }
60
+
61
+ #[ cfg( windows) ]
62
+ fn get_page_size ( ) -> usize {
63
+ use std:: mem;
64
+ use winapi:: um:: sysinfoapi:: GetSystemInfo ;
65
+
66
+ unsafe {
67
+ let mut info = mem:: zeroed ( ) ;
68
+ GetSystemInfo ( & mut info) ;
69
+
70
+ info. dwPageSize as usize
71
+ }
72
+ }
73
+
74
+ #[ cfg( windows) ]
75
+ fn create_mapping ( capacity : usize ) -> * mut u8 {
76
+ use std:: ptr;
77
+ use winapi:: shared:: basetsd:: SIZE_T ;
78
+ use winapi:: shared:: minwindef:: LPVOID ;
79
+ use winapi:: um:: memoryapi:: VirtualAlloc ;
80
+ use winapi:: um:: winnt:: { PAGE_READWRITE , MEM_COMMIT , MEM_RESERVE } ;
81
+
82
+ let lpAddress: LPVOID = ptr:: null_mut ( ) ;
83
+ let page_size = get_page_size ( ) ;
84
+ let len = if capacity % page_size == 0 {
85
+ capacity
86
+ } else {
87
+ capacity + page_size - ( capacity % page_size)
88
+ } ;
89
+ let flAllocationType = MEM_COMMIT | MEM_RESERVE ;
90
+ let flProtect = PAGE_READWRITE ;
91
+
92
+ let r = unsafe {
93
+ VirtualAlloc ( lpAddress, len as SIZE_T , flAllocationType, flProtect)
94
+ } ;
95
+
96
+ r as * mut u8
97
+ }
98
+
45
99
impl Arena {
46
100
/// Create an `Arena` with specified capacity.
47
101
///
48
102
/// Capacity must be a power of 2. The capacity cannot be grown after the fact.
49
103
pub fn with_capacity ( capacity : usize ) -> Arena {
50
- let head = unsafe {
51
- libc:: mmap (
52
- ptr:: null_mut ( ) ,
53
- capacity,
54
- libc:: PROT_READ | libc:: PROT_WRITE ,
55
- libc:: MAP_ANON | libc:: MAP_PRIVATE ,
56
- -1 ,
57
- 0 ,
58
- )
59
- } ;
104
+ let head = create_mapping ( capacity) ;
60
105
61
106
Arena {
62
107
inner : Rc :: new ( Inner {
63
- head : head as * mut u8 ,
108
+ head,
64
109
pos : Cell :: new ( 0 ) ,
65
110
cap : capacity,
66
111
} )
@@ -127,6 +172,7 @@ fn allocate<T>(inner: &Rc<Inner>, count: usize) -> *mut T {
127
172
ret
128
173
}
129
174
175
+ #[ cfg( unix) ]
130
176
impl Drop for Inner {
131
177
fn drop ( & mut self ) {
132
178
let res = unsafe { libc:: munmap ( self . head as * mut libc:: c_void , self . cap ) } ;
@@ -136,6 +182,20 @@ impl Drop for Inner {
136
182
}
137
183
}
138
184
185
+ #[ cfg( windows) ]
186
+ impl Drop for Inner {
187
+ fn drop ( & mut self ) {
188
+ use winapi:: shared:: minwindef:: LPVOID ;
189
+ use winapi:: um:: memoryapi:: VirtualFree ;
190
+ use winapi:: um:: winnt:: MEM_RELEASE ;
191
+
192
+ let res = unsafe { VirtualFree ( self . head as LPVOID , 0 , MEM_RELEASE ) } ;
193
+
194
+ // TODO: Do something on error
195
+ debug_assert_ne ! ( res, 0 ) ;
196
+ }
197
+ }
198
+
139
199
impl < T > Slice < T > {
140
200
pub fn iter ( & self ) -> Iter < T > {
141
201
unsafe {
0 commit comments