-
Notifications
You must be signed in to change notification settings - Fork 13
Add initial MinGW support #60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,74 @@ | ||
| # See bootstrap.example.toml for documentation of available options | ||
| # | ||
| change-id = 148795 | ||
|
|
||
| [llvm] | ||
| # Will download LLVM from CI if available on your platform. | ||
| download-ci-llvm = true | ||
| # NOTE: if you set ↑ to false, disable other LLVM targets to save lots of build time! | ||
| # targets = "X86" | ||
| # experimental-targets = "" | ||
|
|
||
| [build] | ||
| build = "x86_64-unknown-linux-gnu" | ||
| target = [ | ||
| "x86_64-unknown-linux-gnu", | ||
| "x86_64-pc-windows-gnu", | ||
| "x86_64-rust9x-windows-gnu", | ||
| "i686-pc-windows-gnu", | ||
| "i686-rust9x-windows-gnu", | ||
| "i586-rust9x-windows-gnu", | ||
| ] | ||
|
|
||
| docs = false | ||
|
|
||
| # extended = true | ||
| # tools = [ | ||
| # # "cargo", | ||
| # # "clippy", | ||
| # "rustdoc", | ||
| # # "rustfmt", | ||
| # # "rust-analyzer", | ||
| # # "rust-analyzer-proc-macro-srv", | ||
| # # "analysis", | ||
| # "src", | ||
| # # "wasm-component-ld", | ||
| # # "miri", "cargo-miri" # for dev/nightly channels | ||
| # ] | ||
|
|
||
| [target.x86_64-pc-windows-gnu] | ||
| cc = "x86_64-w64-mingw32-gcc" | ||
| cxx = "x86_64-w64-mingw32-g++" | ||
|
|
||
| [target.x86_64-rust9x-windows-gnu] | ||
| cc = "x86_64-w64-mingw32-gcc" | ||
| cxx = "x86_64-w64-mingw32-g++" | ||
|
|
||
| [target.i686-pc-windows-gnu] | ||
| cc = "i686-w64-mingw32-gcc" | ||
| cxx = "i686-w64-mingw32-g++" | ||
|
|
||
| [target.i686-rust9x-windows-gnu] | ||
| cc = "i686-w64-mingw32-gcc" | ||
| cxx = "i686-w64-mingw32-g++" | ||
|
|
||
| [target.i586-rust9x-windows-gnu] | ||
| cc = "i686-w64-mingw32-gcc" | ||
| cxx = "i686-w64-mingw32-g++" | ||
|
|
||
| [install] | ||
| # for creating a downloadable package: python x.py install, then create and archive this | ||
| prefix = "../dist/rust9x-gnu" | ||
| sysconfdir = "." | ||
|
|
||
| [rust] | ||
| # enable rust-lld.exe so we don't need editbin.exe | ||
| lld = true | ||
| dist-src = false | ||
|
|
||
| # you can override this with -i/--incremental | ||
| # incremental = false | ||
| # incremental = true | ||
|
|
||
| [dist] | ||
| src-tarball = false |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| use crate::spec::Target; | ||
|
|
||
| pub(crate) fn target() -> Target { | ||
| let mut base = super::i686_rust9x_windows_gnu::target(); | ||
| base.cpu = "i586".into(); | ||
| base.llvm_target = "i586-pc-windows-gnu".into(); | ||
| // go back to x87 FPU ABI spec | ||
| base.rustc_abi = None; | ||
| base | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| use crate::spec::{Target, cvs}; | ||
|
|
||
| pub(crate) fn target() -> Target { | ||
| let mut base = super::i686_pc_windows_gnu::target(); | ||
| base.families = cvs!["windows", "rust9x"]; | ||
|
|
||
| base.metadata = crate::spec::TargetMetadata { | ||
| description: Some("64-bit GNU rust9x (Windows XP 64-bit+)".into()), | ||
| tier: Some(4), | ||
| host_tools: Some(false), | ||
| std: Some(true), | ||
| }; | ||
|
|
||
| base | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| use crate::spec::{Target, cvs}; | ||
|
|
||
| pub(crate) fn target() -> Target { | ||
| let mut base = super::x86_64_pc_windows_gnu::target(); | ||
| base.families = cvs!["windows", "rust9x"]; | ||
|
|
||
| base.metadata = crate::spec::TargetMetadata { | ||
| description: Some("32-bit GNU rust9x (Windows 98/NT4+)".into()), | ||
| tier: Some(4), | ||
| host_tools: Some(false), | ||
| std: Some(true), | ||
| }; | ||
|
|
||
| base | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -24,10 +24,15 @@ | |||||||||
| // FIXME: investigate using a fixed-size array instead, as the maximum number | ||||||||||
| // of keys is [limited to 1088](https://learn.microsoft.com/en-us/windows/win32/ProcThread/thread-local-storage). | ||||||||||
|
|
||||||||||
| #[cfg(not(target_family = "rust9x"))] | ||||||||||
| use crate::cell::UnsafeCell; | ||||||||||
| use crate::ptr; | ||||||||||
| use crate::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed, Release}; | ||||||||||
| use crate::sync::atomic::{Atomic, AtomicPtr, AtomicU32}; | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| use crate::sync::atomic::AtomicBool; | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| use crate::sync::nonpoison::Mutex; | ||||||||||
| use crate::sys::c; | ||||||||||
| use crate::sys::thread_local::guard; | ||||||||||
|
|
||||||||||
|
|
@@ -44,7 +49,12 @@ pub struct LazyKey { | |||||||||
| /// Currently, destructors cannot be unregistered, so we cannot use racy | ||||||||||
| /// initialization for keys. Instead, we need synchronize initialization. | ||||||||||
| /// Use the Windows-provided `Once` since it does not require TLS. | ||||||||||
| #[cfg(not(target_family = "rust9x"))] | ||||||||||
| once: UnsafeCell<c::INIT_ONCE>, | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| pending: AtomicBool, | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| initing: Mutex<()>, | ||||||||||
| } | ||||||||||
|
|
||||||||||
| impl LazyKey { | ||||||||||
|
|
@@ -54,7 +64,12 @@ impl LazyKey { | |||||||||
| key: AtomicU32::new(0), | ||||||||||
| dtor, | ||||||||||
| next: AtomicPtr::new(ptr::null_mut()), | ||||||||||
| #[cfg(not(target_family = "rust9x"))] | ||||||||||
| once: UnsafeCell::new(c::INIT_ONCE_STATIC_INIT), | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| pending: AtomicBool::new(true), | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| initing: Mutex::new(()), | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
|
|
@@ -67,6 +82,7 @@ impl LazyKey { | |||||||||
| } | ||||||||||
|
|
||||||||||
| #[cold] | ||||||||||
| #[cfg(not(target_family = "rust9x"))] | ||||||||||
| unsafe fn init(&'static self) -> Key { | ||||||||||
| if self.dtor.is_some() { | ||||||||||
| let mut pending = c::FALSE; | ||||||||||
|
|
@@ -123,6 +139,73 @@ impl LazyKey { | |||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| #[cold] | ||||||||||
| #[cfg(target_family = "rust9x")] | ||||||||||
| unsafe fn init(&'static self) -> Key { | ||||||||||
| if self.dtor.is_some() { | ||||||||||
| let pending = self.pending.load(Acquire); | ||||||||||
| if pending == false { | ||||||||||
|
Comment on lines
+147
to
+148
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: could store
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I kind of wanted to match the the logic from the other code but yeah I can update this.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah i see, that makes sense -- std Once also seems to agree: rust/library/std/src/sys/sync/once/futex.rs Lines 19 to 22 in 25a5ea7
am convinced, can stay as is ^^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also,
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a somewhat stylistic choice but I wanted to match the other functions pending == c::FALSE. If it really matters I can do a PR for it. |
||||||||||
| // Some other thread initialized the key, load it. | ||||||||||
| // We can use Relaxed here because pending will ensure | ||||||||||
| // key has been initialized. | ||||||||||
| self.key.load(Relaxed) - 1 | ||||||||||
| } else { | ||||||||||
| let _lock_guard = self.initing.lock(); | ||||||||||
|
|
||||||||||
| // Multiple threads may have seen pending as true and | ||||||||||
| // tried to initialize it. We have the lock now, | ||||||||||
| // but we may not have the first to get it. | ||||||||||
| // Check if it was already initialized. | ||||||||||
| let pending2 = self.pending.load(Acquire); | ||||||||||
| if pending2 == false { | ||||||||||
| return self.key.load(Relaxed) - 1; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| let key = unsafe { c::TlsAlloc() }; | ||||||||||
| if key == c::TLS_OUT_OF_INDEXES { | ||||||||||
| // Since we abort the process, there is no need to wake up | ||||||||||
| // the waiting threads. If this were a panic, the wakeup | ||||||||||
| // would need to occur first in order to avoid deadlock. | ||||||||||
| rtabort!("out of TLS indexes"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| unsafe { | ||||||||||
| register_dtor(self); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| // Store key with a Release to ensure loaders have | ||||||||||
| // access to our destructor. | ||||||||||
| self.key.store(key + 1, Release); | ||||||||||
|
|
||||||||||
| // Store pending with a release to ensure any pending | ||||||||||
| // loads see the key store value. This ensures we won't | ||||||||||
| // ever hit a situation of finding pending false and | ||||||||||
| // the key uninitialized. | ||||||||||
| self.pending.store(false, Release); | ||||||||||
|
|
||||||||||
| key | ||||||||||
| } | ||||||||||
| } else { | ||||||||||
| // If there is no destructor to clean up, we can use racy initialization. | ||||||||||
|
|
||||||||||
| let key = unsafe { c::TlsAlloc() }; | ||||||||||
| if key == c::TLS_OUT_OF_INDEXES { | ||||||||||
| rtabort!("out of TLS indexes"); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| match self.key.compare_exchange(0, key + 1, AcqRel, Acquire) { | ||||||||||
| Ok(_) => key, | ||||||||||
| Err(new) => unsafe { | ||||||||||
| // Some other thread completed initialization first, so destroy | ||||||||||
| // our key and use theirs. | ||||||||||
| let r = c::TlsFree(key); | ||||||||||
| debug_assert_eq!(r, c::TRUE); | ||||||||||
| new - 1 | ||||||||||
| }, | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| unsafe impl Send for LazyKey {} | ||||||||||
|
|
||||||||||
Uh oh!
There was an error while loading. Please reload this page.