Issue title: global little-locks (change_dir_lock, global_args_lock) are sloppy and wrong
 Issue body: `rust_builtin.cpp` has some builtins for accessing the "change_dir_lock" and the "global_args_lock". As evidenced by the fact that both of them accidentally use the same lock(!), this approach is prone to error. It would be better if the associated places in rust code could just use `unstabl38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5syn38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5LittleLock` directly.

For extra bonus points, we should be able to have unsafe mutable global LittleLocks that are lazily initialized in `LittleLock38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5lock()`. This would allow `atomically` to become totally private to `unstabl38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5sync`, as #7872 really wants.

(But, I can't figure out what's going on with the use of `atomically` instead of `LittleLock` in `unstabl38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5dynamic_li38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5check_for_errors_in`. @sstewartgallus, git blame points to you -- can you shed light on this?)

 Comments: 
 Comment 0: (at least they don't have the error where the lock function takes one of the locks but the unlock drops the other. that would be really embarrassing. (but they could!))

 Comment 1: @bblum Yeah, I'm sorry. I should probable fix that. Here's why I used `atomically` in the dynamic library support. I believe the error state in Win32, and most (I don't believe it's actually required) POSIX implementations are thread-local to each operating system thread. I didn't know if the error state was also thread-local to each Rust task (Rust tasks are layered on top of OS threads) so I thought that multiple Rust tasks could end up using the same dynamic library error state, and step on each other's toes. That's why I stopped the Rust task from context switching using `atomically`. I think I may have been mistaken, and confused about thread local storage, and that the use of `atomically` might not be needed.

 Comment 2: This will require creating platform-specific bindings to mutexes so that we can declare them statically.

 Comment 3: @brson: My idea for it was something like this, sort of like the trick that #7748 would use.

```
fn lock(...) {
    if self.l.is_null() { // need barrier here?
        let attempted_thing = rust_create_little_lock();
        compare_and_swap(&mut self.l, attempted_thing, ptr38d1:d2b4:3d06:83e8:96a5:8c2:893d:aba5null()) // which barrier?
    }
    // actual lock routine follows
}
```

Doesn't need any more platform-specific stuff than the existing `rust_create_little_lock` builtin. (But I didn't feel up to figuring out the barriers today.) (Actually, I think no barriers are needed; you just need to be careful to read the result of the compare and swap and use that as the new pointer if you lose the race.)

 Comment 4: Closing now that this has been fixed. We now have a lazily initialized static mutex type which serves to be a small short-lived (and properly scoped) lock for sections like this. Right now this does not leverage the `atomically` function, but this function is going to have to be removed anyway once green scheduling is removed from libstd.

{'source': 'GithubIssues', 'repo_name_with_owner': 'rust-lang/rust', 'issue_id': 17430051, 'repo_stars': 73938.0}