diff --git a/doc/rust.md b/doc/rust.md index fe8d0a834e3..f15e767ca82 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1754,6 +1754,8 @@ names are effectively reserved. Some significant attributes include: * The `deriving` attribute, for automatically generating implementations of certain traits. * The `static_assert` attribute, for asserting that a static bool is true at compiletime +* The `thread_local` attribute, for defining a `static mut` as a thread-local. Note that this is + only a low-level building block, and is not local to a *task*, nor does it provide safety. Other attributes may be added or removed during development of the language. diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 160bc511168..66f6e6a4746 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1749,6 +1749,12 @@ pub fn SetUnnamedAddr(Global: ValueRef, Unnamed: bool) { } } +pub fn set_thread_local(global: ValueRef, is_thread_local: bool) { + unsafe { + llvm::LLVMSetThreadLocal(global, is_thread_local as Bool); + } +} + pub fn ConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef { unsafe { llvm::LLVMConstICmp(Pred as c_ushort, V1, V2) diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index 2b2c2aa74c7..a08afcfd7c5 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -816,6 +816,7 @@ fn check_heap_item(cx: &Context, it: &ast::item) { static other_attrs: &'static [&'static str] = &[ // item-level "address_insignificant", // can be crate-level too + "thread_local", // for statics "allow", "deny", "forbid", "warn", // lint options "deprecated", "experimental", "unstable", "stable", "locked", "frozen", //item stability "crate_map", "cfg", "doc", "export_name", "link_section", "no_freeze", diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 0ece7c8c024..20cc2f8944e 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -2543,6 +2543,10 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::NodeId) -> ValueRef { inlineable = true; } + if attr::contains_name(i.attrs, "thread_local") { + lib::llvm::set_thread_local(g, true); + } + if !inlineable { debug!("{} not inlined", sym); ccx.non_inlineable_statics.insert(id);