@@ -139,7 +139,7 @@ pub struct bool_11 {
139139 field10 : bool ,
140140}
141141
142- extern "C" fn bool_struct_in_11 ( arg0 : bool_11 ) { }
142+ extern "C" fn bool_struct_in_11 ( _arg0 : bool_11 ) { }
143143
144144#[ allow( unreachable_code) ] // FIXME false positive
145145fn main ( ) {
@@ -375,6 +375,7 @@ struct pthread_attr_t {
375375}
376376
377377#[ link( name = "pthread" ) ]
378+ #[ cfg( not( target_env="msvc" ) ) ]
378379extern "C" {
379380 fn pthread_attr_init ( attr : * mut pthread_attr_t ) -> c_int ;
380381
@@ -391,6 +392,86 @@ extern "C" {
391392 ) -> c_int ;
392393}
393394
395+ type DWORD = u32 ;
396+ type LPDWORD = * mut u32 ;
397+
398+ type LPVOID = * mut c_void ;
399+ type HANDLE = * mut c_void ;
400+
401+ #[ link( name = "msvcrt" ) ]
402+ #[ cfg( target_env="msvc" ) ]
403+ extern "C" {
404+ fn WaitForSingleObject (
405+ hHandle : LPVOID ,
406+ dwMilliseconds : DWORD
407+ ) -> DWORD ;
408+
409+ fn CreateThread (
410+ lpThreadAttributes : LPVOID , // Technically LPSECURITY_ATTRIBUTES, but we don't use it anyway
411+ dwStackSize : usize ,
412+ lpStartAddress : extern "C" fn ( _: * mut c_void ) -> * mut c_void ,
413+ lpParameter : LPVOID ,
414+ dwCreationFlags : DWORD ,
415+ lpThreadId : LPDWORD
416+ ) -> HANDLE ;
417+ }
418+
419+ enum Thread {
420+ Windows ( HANDLE ) ,
421+ Pthread ( pthread_t )
422+ }
423+
424+ impl Thread {
425+ unsafe fn create ( f : extern "C" fn ( _: * mut c_void ) -> * mut c_void ) -> Self {
426+ #[ cfg( not( target_env="msvc" ) ) ]
427+ {
428+ let mut attr: pthread_attr_t = zeroed ( ) ;
429+ let mut thread: pthread_t = 0 ;
430+
431+ if pthread_attr_init ( & mut attr) != 0 {
432+ assert ! ( false ) ;
433+ }
434+
435+ if pthread_create ( & mut thread, & attr, f, 0 as * mut c_void ) != 0 {
436+ assert ! ( false ) ;
437+ }
438+
439+ Thread :: Pthread ( thread)
440+ }
441+
442+ #[ cfg( target_env="msvc" ) ]
443+ {
444+ let handle = CreateThread ( 0 as * mut c_void , 0 , f, 0 as * mut c_void , 0 , 0 as * mut u32 ) ;
445+
446+ if ( handle as u64 ) == 0 {
447+ assert ! ( false ) ;
448+ }
449+
450+ Thread :: Windows ( handle)
451+ }
452+ }
453+
454+
455+ unsafe fn join ( self ) {
456+ match self {
457+ #[ cfg( not( target_env="msvc" ) ) ]
458+ Thread :: Pthread ( thread) => {
459+ let mut res = 0 as * mut c_void ;
460+ pthread_join ( thread, & mut res) ;
461+ }
462+ #[ cfg( target_env="msvc" ) ]
463+ Thread :: Windows ( handle) => {
464+ let wait_time = 5000 ; // in milliseconds
465+ assert ! ( WaitForSingleObject ( handle, wait_time) == 0 ) ;
466+ }
467+ _ => assert ! ( false ) ,
468+ }
469+ }
470+ }
471+
472+
473+
474+
394475#[ thread_local]
395476#[ cfg( not( jit) ) ]
396477static mut TLS : u8 = 42 ;
@@ -404,21 +485,10 @@ extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
404485#[ cfg( not( jit) ) ]
405486fn test_tls ( ) {
406487 unsafe {
407- let mut attr: pthread_attr_t = zeroed ( ) ;
408- let mut thread: pthread_t = 0 ;
409-
410488 assert_eq ! ( TLS , 42 ) ;
411489
412- if pthread_attr_init ( & mut attr) != 0 {
413- assert ! ( false ) ;
414- }
415-
416- if pthread_create ( & mut thread, & attr, mutate_tls, 0 as * mut c_void ) != 0 {
417- assert ! ( false ) ;
418- }
419-
420- let mut res = 0 as * mut c_void ;
421- pthread_join ( thread, & mut res) ;
490+ let thread = Thread :: create ( mutate_tls) ;
491+ thread. join ( ) ;
422492
423493 // TLS of main thread must not have been changed by the other thread.
424494 assert_eq ! ( TLS , 42 ) ;
0 commit comments