Skip to content

Commit

Permalink
Rollup merge of rust-lang#50538 - michaelwoerister:atomic-cnums, r=Zoxc
Browse files Browse the repository at this point in the history
 Make CrateNum allocation more thread-safe.

This PR makes sure that we can't have race conditions when assigning CrateNums. It's a slight improvement but a larger refactoring of the CrateStore/CrateLoader infrastructure would be good, I think.

r? @Zoxc
  • Loading branch information
alexcrichton committed May 10, 2018
2 parents 8982c67 + 4537025 commit d8c8a1b
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 23 deletions.
5 changes: 1 addition & 4 deletions src/librustc_metadata/creader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ pub struct Library {
pub struct CrateLoader<'a> {
pub sess: &'a Session,
cstore: &'a CStore,
next_crate_num: CrateNum,
local_crate_name: Symbol,
}

Expand Down Expand Up @@ -102,7 +101,6 @@ impl<'a> CrateLoader<'a> {
CrateLoader {
sess,
cstore,
next_crate_num: cstore.next_crate_num(),
local_crate_name: Symbol::intern(local_crate_name),
}
}
Expand Down Expand Up @@ -198,8 +196,7 @@ impl<'a> CrateLoader<'a> {
self.verify_no_symbol_conflicts(span, &crate_root);

// Claim this crate number and cache it
let cnum = self.next_crate_num;
self.next_crate_num = CrateNum::from_u32(cnum.as_u32() + 1);
let cnum = self.cstore.alloc_new_crate_num();

// Stash paths for top-most crate locally if necessary.
let crate_paths = if root.is_none() {
Expand Down
42 changes: 23 additions & 19 deletions src/librustc_metadata/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,32 +97,34 @@ pub struct CStore {
impl CStore {
pub fn new(metadata_loader: Box<MetadataLoader + Sync>) -> CStore {
CStore {
metas: RwLock::new(IndexVec::new()),
// We add an empty entry for LOCAL_CRATE (which maps to zero) in
// order to make array indices in `metas` match with the
// corresponding `CrateNum`. This first entry will always remain
// `None`.
metas: RwLock::new(IndexVec::from_elem_n(None, 1)),
extern_mod_crate_map: Lock::new(FxHashMap()),
metadata_loader,
}
}

/// You cannot use this function to allocate a CrateNum in a thread-safe manner.
/// It is currently only used in CrateLoader which is single-threaded code.
pub fn next_crate_num(&self) -> CrateNum {
CrateNum::new(self.metas.borrow().len() + 1)
pub(super) fn alloc_new_crate_num(&self) -> CrateNum {
let mut metas = self.metas.borrow_mut();
let cnum = CrateNum::new(metas.len());
metas.push(None);
cnum
}

pub fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
pub(super) fn get_crate_data(&self, cnum: CrateNum) -> Lrc<CrateMetadata> {
self.metas.borrow()[cnum].clone().unwrap()
}

pub fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
use rustc_data_structures::indexed_vec::Idx;
let mut met = self.metas.borrow_mut();
while met.len() <= cnum.index() {
met.push(None);
}
met[cnum] = Some(data);
pub(super) fn set_crate_data(&self, cnum: CrateNum, data: Lrc<CrateMetadata>) {
let mut metas = self.metas.borrow_mut();
assert!(metas[cnum].is_none(), "Overwriting crate metadata entry");
metas[cnum] = Some(data);
}

pub fn iter_crate_data<I>(&self, mut i: I)
pub(super) fn iter_crate_data<I>(&self, mut i: I)
where I: FnMut(CrateNum, &Lrc<CrateMetadata>)
{
for (k, v) in self.metas.borrow().iter_enumerated() {
Expand All @@ -132,14 +134,16 @@ impl CStore {
}
}

pub fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
pub(super) fn crate_dependencies_in_rpo(&self, krate: CrateNum) -> Vec<CrateNum> {
let mut ordering = Vec::new();
self.push_dependencies_in_postorder(&mut ordering, krate);
ordering.reverse();
ordering
}

pub fn push_dependencies_in_postorder(&self, ordering: &mut Vec<CrateNum>, krate: CrateNum) {
pub(super) fn push_dependencies_in_postorder(&self,
ordering: &mut Vec<CrateNum>,
krate: CrateNum) {
if ordering.contains(&krate) {
return;
}
Expand All @@ -154,7 +158,7 @@ impl CStore {
ordering.push(krate);
}

pub fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
pub(super) fn do_postorder_cnums_untracked(&self) -> Vec<CrateNum> {
let mut ordering = Vec::new();
for (num, v) in self.metas.borrow().iter_enumerated() {
if let &Some(_) = v {
Expand All @@ -164,11 +168,11 @@ impl CStore {
return ordering
}

pub fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
pub(super) fn add_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId, cnum: CrateNum) {
self.extern_mod_crate_map.borrow_mut().insert(emod_id, cnum);
}

pub fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
pub(super) fn do_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option<CrateNum> {
self.extern_mod_crate_map.borrow().get(&emod_id).cloned()
}
}
Expand Down

0 comments on commit d8c8a1b

Please sign in to comment.