24
24
25
25
#![ allow( improper_ctypes) ]
26
26
27
+ #[ macro_use]
28
+ extern crate cfg_if;
29
+ extern crate libc;
30
+
27
31
use std:: cell:: Cell ;
28
32
29
33
extern {
@@ -36,7 +40,9 @@ extern {
36
40
}
37
41
38
42
thread_local ! {
39
- static STACK_LIMIT : Cell <usize > = Cell :: new( guess_os_morestack_stack_limit( ) )
43
+ static STACK_LIMIT : Cell <usize > = Cell :: new( unsafe {
44
+ guess_os_morestack_stack_limit( )
45
+ } )
40
46
}
41
47
42
48
fn get_stack_limit ( ) -> usize {
@@ -112,33 +118,69 @@ unsafe fn grow_the_stack<R, F: FnOnce() -> R>(stack_size: usize, f: F) -> R {
112
118
}
113
119
}
114
120
115
- #[ cfg( unix) ]
116
- fn guess_os_morestack_stack_limit ( ) -> usize {
117
- unsafe {
118
- __stacker_morestack_stack_limit ( )
119
- }
120
- }
121
+ cfg_if ! {
122
+ if #[ cfg( windows) ] {
123
+ // See this for where all this logic is coming from.
124
+ //
125
+ // https://github.com/adobe/webkit/blob/0441266/Source/WTF/wtf
126
+ // /StackBounds.cpp
127
+ unsafe fn guess_os_morestack_stack_limit( ) -> usize {
128
+ #[ cfg( target_pointer_width = "32" ) ]
129
+ extern {
130
+ #[ link_name = "__stacker_get_tib_32" ]
131
+ fn get_tib_address( ) -> * const usize ;
132
+ }
133
+ #[ cfg( target_pointer_width = "64" ) ]
134
+ extern "system" {
135
+ #[ link_name = "NtCurrentTeb" ]
136
+ fn get_tib_address( ) -> * const usize ;
137
+ }
138
+ // https://en.wikipedia.org/wiki/Win32_Thread_Information_Block for
139
+ // the struct layout of the 32-bit TIB. It looks like the struct
140
+ // layout of the 64-bit TIB is also the same for getting the stack
141
+ // limit: http://doxygen.reactos.org/d3/db0/structNT__TIB64.html
142
+ * get_tib_address( ) . offset( 2 )
143
+ }
144
+ } else if #[ cfg( target_os = "linux" ) ] {
145
+ use libc:: { pthread_attr_t, c_int, size_t, c_void, pthread_t} ;
146
+ use std:: mem;
147
+
148
+ unsafe fn guess_os_morestack_stack_limit( ) -> usize {
149
+ let mut attr: libc:: pthread_attr_t = mem:: zeroed( ) ;
150
+ assert_eq!( pthread_attr_init( & mut attr) , 0 ) ;
151
+ assert_eq!( pthread_getattr_np( pthread_self( ) , & mut attr) , 0 ) ;
152
+ let mut stackaddr = 0 as * mut _;
153
+ let mut stacksize = 0 ;
154
+ assert_eq!( pthread_attr_getstack( & attr, & mut stackaddr,
155
+ & mut stacksize) , 0 ) ;
156
+ assert_eq!( pthread_attr_destroy( & mut attr) , 0 ) ;
157
+ stackaddr as usize
158
+ }
121
159
122
- // See this for where all this logic is coming from.
123
- //
124
- // https://github.com/adobe/webkit/blob/0441266/Source/WTF/wtf/StackBounds.cpp
125
- #[ cfg( windows) ]
126
- fn guess_os_morestack_stack_limit ( ) -> usize {
127
- #[ cfg( target_pointer_width = "32" ) ]
128
- extern {
129
- #[ link_name = "__stacker_get_tib_32" ]
130
- fn get_tib_address ( ) -> * const usize ;
131
- }
132
- #[ cfg( target_pointer_width = "64" ) ]
133
- extern "system" {
134
- #[ link_name = "NtCurrentTeb" ]
135
- fn get_tib_address ( ) -> * const usize ;
136
- }
137
- unsafe {
138
- // See https://en.wikipedia.org/wiki/Win32_Thread_Information_Block for
139
- // the struct layout of the 32-bit TIB. It looks like the struct layout
140
- // of the 64-bit TIB is also the same for getting the stack limit:
141
- // http://doxygen.reactos.org/d3/db0/structNT__TIB64.html
142
- * get_tib_address ( ) . offset ( 2 )
160
+ extern {
161
+ fn pthread_self( ) -> pthread_t;
162
+ fn pthread_attr_init( attr: * mut pthread_attr_t) -> c_int;
163
+ fn pthread_attr_destroy( attr: * mut pthread_attr_t) -> c_int;
164
+ fn pthread_attr_getstack( attr: * const pthread_attr_t,
165
+ stackaddr: * mut * mut c_void,
166
+ stacksize: * mut size_t) -> c_int;
167
+ fn pthread_getattr_np( native: pthread_t,
168
+ attr: * mut pthread_attr_t) -> c_int;
169
+ }
170
+ } else if #[ cfg( target_os = "macos" ) ] {
171
+ use libc:: { c_void, pthread_t} ;
172
+
173
+ unsafe fn guess_os_morestack_stack_limit( ) -> usize {
174
+ pthread_get_stackaddr_np( pthread_self( ) ) as usize
175
+ }
176
+
177
+ extern {
178
+ fn pthread_self( ) -> pthread_t;
179
+ fn pthread_get_stackaddr_np( thread: pthread_t) -> * mut c_void;
180
+ }
181
+ } else {
182
+ unsafe fn guess_os_morestack_stack_limit( ) -> usize {
183
+ panic!( "cannot guess the stack limit on this platform" ) ;
184
+ }
143
185
}
144
186
}
0 commit comments