Doe
Doe

Reputation: 675

How are foreign thread-local global variables accessed in Rust?

For each of the following thread-local storage implementations, how can an external thread-local variable be accessed in Rust programs using the standard ffi mechanisms as exposed by the compiler or standard library?

Upvotes: 9

Views: 2068

Answers (1)

rnstlr
rnstlr

Reputation: 1803

Rust has a nightly feature, which allows linking to external thread local variables. The stabilization of the feature is tracked here.

C11 / GCC TLS extension

C11 defines the _Thread_local keyword to define thread-storage duration for an object. There also exists a thread_local macro alias.

GCC also implements a Thread Local extension which uses __thread as a keyword.

Linking to both an external C11 _Thread_local and a gcc __thread variable is possible using nightly (tested with rustc 1.17.0-nightly (0e7727795 2017-02-19) and gcc 5.4)

#![feature(thread_local)]

extern crate libc;

use libc::c_int;

#[link(name="test", kind="static")]
extern {
    #[thread_local]
    static mut test_global: c_int;
}

fn main() {
    let mut threads = vec![];
    for _ in 0..5 {
        let thread = std::thread::spawn(|| {
            unsafe {
                test_global += 1;
                println!("{}", test_global);
                test_global += 1;
            }
        });
        threads.push(thread);
    }

    for thread in threads {
        thread.join().unwrap();
    }
}

This allows get access to a variable declared as either of the following:

_Thread_local extern int test_global;
extern __local int test_global;

The output of the above Rust code will be:

1
1
1
1
1

Which is expected, when the variable is defined as thread local.

Upvotes: 8

Related Questions