@@ -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( unix) ]
378379extern "C" {
379380 fn pthread_attr_init ( attr : * mut pthread_attr_t ) -> c_int ;
380381
@@ -391,6 +392,91 @@ 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( windows) ]
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+ struct Thread {
420+ #[ cfg( windows) ]
421+ handle : HANDLE ,
422+ #[ cfg( unix) ]
423+ handle : pthread_t ,
424+ }
425+
426+ impl Thread {
427+ unsafe fn create ( f : extern "C" fn ( _: * mut c_void ) -> * mut c_void ) -> Self {
428+ #[ cfg( unix) ]
429+ {
430+ let mut attr: pthread_attr_t = zeroed ( ) ;
431+ let mut thread: pthread_t = 0 ;
432+
433+ if pthread_attr_init ( & mut attr) != 0 {
434+ assert ! ( false ) ;
435+ }
436+
437+ if pthread_create ( & mut thread, & attr, f, 0 as * mut c_void ) != 0 {
438+ assert ! ( false ) ;
439+ }
440+
441+ Thread {
442+ handle : thread,
443+ }
444+ }
445+
446+ #[ cfg( windows) ]
447+ {
448+ let handle = CreateThread ( 0 as * mut c_void , 0 , f, 0 as * mut c_void , 0 , 0 as * mut u32 ) ;
449+
450+ if ( handle as u64 ) == 0 {
451+ assert ! ( false ) ;
452+ }
453+
454+ Thread {
455+ handle,
456+ }
457+ }
458+ }
459+
460+
461+ unsafe fn join ( self ) {
462+ #[ cfg( unix) ]
463+ {
464+ let mut res = 0 as * mut c_void ;
465+ pthread_join ( self . handle , & mut res) ;
466+ }
467+
468+ #[ cfg( windows) ]
469+ {
470+ // The INFINITE macro is used to signal operations that do not timeout.
471+ let infinite = 0xffffffff ;
472+ assert ! ( WaitForSingleObject ( self . handle, infinite) == 0 ) ;
473+ }
474+ }
475+ }
476+
477+
478+
479+
394480#[ thread_local]
395481#[ cfg( not( jit) ) ]
396482static mut TLS : u8 = 42 ;
@@ -404,21 +490,10 @@ extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
404490#[ cfg( not( jit) ) ]
405491fn test_tls ( ) {
406492 unsafe {
407- let mut attr: pthread_attr_t = zeroed ( ) ;
408- let mut thread: pthread_t = 0 ;
409-
410493 assert_eq ! ( TLS , 42 ) ;
411494
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) ;
495+ let thread = Thread :: create ( mutate_tls) ;
496+ thread. join ( ) ;
422497
423498 // TLS of main thread must not have been changed by the other thread.
424499 assert_eq ! ( TLS , 42 ) ;
0 commit comments