@@ -139,7 +139,7 @@ pub struct bool_11 {
139
139
field10 : bool ,
140
140
}
141
141
142
- extern "C" fn bool_struct_in_11 ( arg0 : bool_11 ) { }
142
+ extern "C" fn bool_struct_in_11 ( _arg0 : bool_11 ) { }
143
143
144
144
#[ allow( unreachable_code) ] // FIXME false positive
145
145
fn main ( ) {
@@ -375,6 +375,7 @@ struct pthread_attr_t {
375
375
}
376
376
377
377
#[ link( name = "pthread" ) ]
378
+ #[ cfg( not( target_env="msvc" ) ) ]
378
379
extern "C" {
379
380
fn pthread_attr_init ( attr : * mut pthread_attr_t ) -> c_int ;
380
381
@@ -391,6 +392,86 @@ extern "C" {
391
392
) -> c_int ;
392
393
}
393
394
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
+
394
475
#[ thread_local]
395
476
#[ cfg( not( jit) ) ]
396
477
static mut TLS : u8 = 42 ;
@@ -404,21 +485,10 @@ extern "C" fn mutate_tls(_: *mut c_void) -> *mut c_void {
404
485
#[ cfg( not( jit) ) ]
405
486
fn test_tls ( ) {
406
487
unsafe {
407
- let mut attr: pthread_attr_t = zeroed ( ) ;
408
- let mut thread: pthread_t = 0 ;
409
-
410
488
assert_eq ! ( TLS , 42 ) ;
411
489
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 ( ) ;
422
492
423
493
// TLS of main thread must not have been changed by the other thread.
424
494
assert_eq ! ( TLS , 42 ) ;
0 commit comments