about summary refs log tree commit diff
path: root/library/std/src/sys/solid
AgeCommit message (Collapse)AuthorLines
2023-02-16Rollup merge of #106372 - joboet:solid_id_parking, r=m-ou-seDylan DPC-2/+2
Use id-based thread parking on SOLID By using the [`slp_tsk`/`wup_tsk`](https://cs.uwaterloo.ca/~brecht/courses/702/Possible-Readings/embedded/uITRON-4.0-specification.pdf) system functions instead of an event-flag structure, `Parker` becomes cheaper to construct and SOLID can share the implementation used by NetBSD and SGX. ping ``@kawadakk`` r? ``@m-ou-se`` ``@rustbot`` label +T-libs
2023-01-17refactor[std]: do not use box syntaxjoboet-20/+12
2022-12-31std: use id-based thread parking on SOLIDjoboet-2/+2
2022-12-01kmc-solid: Address compiler warningsTomoaki Kawada-2/+1
Addresses the warn-by-default lints `unused_imports` and `unused_unsafe`.
2022-12-01kmc-solid: Add a stub implementation of `is_terminal`Tomoaki Kawada-0/+4
Copied from `unsupported/io.rs`. Fixes build failure.
2022-11-06std: remove lock wrappers in `sys_common`joboet-6/+4
2022-10-23Rollup merge of #103005 - solid-rs:patch/kmc-solid/readdir-terminator, r=m-ou-seMichael Howell-8/+12
kmc-solid: Handle errors returned by `SOLID_FS_ReadDir` Fixes the issue where the `std::fs::ReadDir` implementaton of the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets silently suppressed errors returned by the underlying `SOLID_FS_ReadDir` system function. The new implementation correctly handles all cases: - `SOLID_ERR_NOTFOUND` indicates the end of directory stream. - `SOLID_ERR_OK` + non-empty `d_name` indicates success. - Some old filesystem drivers may return `SOLID_ERR_OK` + empty `d_name` to indicate the end of directory stream. - Any other negative values (per ITRON convention) represent an error.
2022-10-13Auto merge of #102655 - joboet:windows_tls_opt, r=ChrisDentonbors-5/+0
Optimize TLS on Windows This implements the suggestion in the current TLS code to embed the linked list of destructors in the `StaticKey` structure to save allocations. Additionally, locking is avoided when no destructor needs to be run. By using one Windows-provided `Once` per key instead of a global lock, locking is more finely-grained (this unblocks #100579).
2022-10-13kmc-solid: Handle errors returned by `SOLID_FS_ReadDir`Tomoaki Kawada-8/+12
2022-10-08std: optimize TLS on Windowsjoboet-5/+0
2022-10-03Reduce CString allocations in std as much as possibleAlex Saveau-20/+20
Signed-off-by: Alex Saveau <saveau.alexandre@gmail.com>
2022-09-20Auto merge of #100581 - joboet:sync_rwlock_everywhere, r=thomccbors-2/+2
std: use `sync::RwLock` for internal statics Since `sync::RwLock` is now `const`-constructible, it can be used for internal statics, removing the need for `sys_common::StaticRwLock`. This adds some extra allocations on platforms which need to box their locks (currently SGX and some UNIX), but these will become unnecessary with the lock improvements tracked in #93740.
2022-09-19std: use `sync::RwLock` for internal staticsjoboet-2/+2
2022-08-28Support `#[unix_sigpipe = "inherit|sig_dfl|sig_ign"]` on `fn main()`Martin Nordholts-1/+1
This makes it possible to instruct libstd to never touch the signal handler for `SIGPIPE`, which makes programs pipeable by default (e.g. with `./your-program | head -n 1`) without `ErrorKind::BrokenPipe` errors.
2022-08-28Rollup merge of #97015 - nrc:read-buf-cursor, r=Mark-SimulacrumMatthias Krüger-7/+5
std::io: migrate ReadBuf to BorrowBuf/BorrowCursor This PR replaces `ReadBuf` (used by the `Read::read_buf` family of methods) with `BorrowBuf` and `BorrowCursor`. The general idea is to split `ReadBuf` because its API is large and confusing. `BorrowBuf` represents a borrowed buffer which is mostly read-only and (other than for construction) deals only with filled vs unfilled segments. a `BorrowCursor` is a mostly write-only view of the unfilled part of a `BorrowBuf` which distinguishes between initialized and uninitialized segments. For `Read::read_buf`, the caller would create a `BorrowBuf`, then pass a `BorrowCursor` to `read_buf`. In addition to the major API split, I've made the following smaller changes: * Removed some methods entirely from the API (mostly the functionality can be replicated with two calls rather than a single one) * Unified naming, e.g., by replacing initialized with init and assume_init with set_init * Added an easy way to get the number of bytes written to a cursor (`written` method) As well as simplifying the API (IMO), this approach has the following advantages: * Since we pass the cursor by value, we remove the 'unsoundness footgun' where a malicious `read_buf` could swap out the `ReadBuf`. * Since `read_buf` cannot write into the filled part of the buffer, we prevent the filled part shrinking or changing which could cause underflow for the caller or unexpected behaviour. ## Outline ```rust pub struct BorrowBuf<'a> impl Debug for BorrowBuf<'_> impl<'a> From<&'a mut [u8]> for BorrowBuf<'a> impl<'a> From<&'a mut [MaybeUninit<u8>]> for BorrowBuf<'a> impl<'a> BorrowBuf<'a> { pub fn capacity(&self) -> usize pub fn len(&self) -> usize pub fn init_len(&self) -> usize pub fn filled(&self) -> &[u8] pub fn unfilled<'this>(&'this mut self) -> BorrowCursor<'this, 'a> pub fn clear(&mut self) -> &mut Self pub unsafe fn set_init(&mut self, n: usize) -> &mut Self } pub struct BorrowCursor<'buf, 'data> impl<'buf, 'data> BorrowCursor<'buf, 'data> { pub fn clone<'this>(&'this mut self) -> BorrowCursor<'this, 'data> pub fn capacity(&self) -> usize pub fn written(&self) -> usize pub fn init_ref(&self) -> &[u8] pub fn init_mut(&mut self) -> &mut [u8] pub fn uninit_mut(&mut self) -> &mut [MaybeUninit<u8>] pub unsafe fn as_mut(&mut self) -> &mut [MaybeUninit<u8>] pub unsafe fn advance(&mut self, n: usize) -> &mut Self pub fn ensure_init(&mut self) -> &mut Self pub unsafe fn set_init(&mut self, n: usize) -> &mut Self pub fn append(&mut self, buf: &[u8]) } ``` ## TODO * ~~Migrate non-unix libs and tests~~ * ~~Naming~~ * ~~`BorrowBuf` or `BorrowedBuf` or `SliceBuf`? (We might want an owned equivalent for the async IO traits)~~ * ~~Should we rename the `readbuf` module? We might keep the name indicate it includes both the buf and cursor variations and someday the owned version too. Or we could change it. It is not publicly exposed, so it is not that important~~. * ~~`read_buf` method: we read into the cursor now, so the `_buf` suffix is a bit weird.~~ * ~~Documentation~~ * Tests are incomplete (I adjusted existing tests, but did not add new ones). cc https://github.com/rust-lang/rust/issues/78485, https://github.com/rust-lang/rust/issues/94741 supersedes: https://github.com/rust-lang/rust/pull/95770, https://github.com/rust-lang/rust/pull/93359 fixes #93305
2022-08-18Address reviewer commentsNick Cameron-1/+1
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2022-08-05non-linux platformsNick Cameron-7/+5
Signed-off-by: Nick Cameron <nrc@ncameron.org>
2022-08-04kmc-solid: Add a stub implementation of `File::set_times`Tomoaki Kawada-0/+12
2022-08-01kmc-solid: Adapt to a recent change in the `IntoInner` impl of `SocketAddr`Tomoaki Kawada-2/+2
`(x: SocketAddr).into_inner()` evaluates to `(SocketAddrCRepr, socklen_t)` instead of `(*const sockaddr, socklen_t)` as of commit 55e23db13.
2022-07-25Rollup merge of #95916 - solid-rs:feat-kmc-solid-abort, r=Mark-SimulacrumYuki Okushi-45/+5
kmc-solid: Use `libc::abort` to abort a program This PR updates the target-specific abort subroutine for the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets. The current implementation uses a `hlt` instruction, which is the most direct way to notify a connected debugger but is not the most flexible way. This PR changes it to call the `abort` libc function, making it possible for a system designer to override its behavior as they see fit.
2022-06-26Rollup merge of #97140 - joboet:solid_parker, r=m-ou-seMatthias Krüger-0/+2
std: use an event-flag-based thread parker on SOLID `Mutex` and `Condvar` are being replaced by more efficient implementations, which need thread parking themselves (see #93740). Therefore, the generic `Parker` needs to be replaced on all platforms where the new lock implementation will be used, which, after #96393, are SOLID, SGX and Hermit (more PRs coming soon). SOLID, conforming to the [μITRON specification](http://www.ertl.jp/ITRON/SPEC/FILE/mitron-400e.pdf), has event flags, which are a thread parking primitive very similar to `Parker`. However, they do not make any atomic ordering guarantees (even though those can probably be assumed) and necessitate a system call even when the thread token is already available. Hence, this `Parker`, like the Windows parker, uses an extra atomic state variable. I future-proofed the code by wrapping the event flag in a `WaitFlag` structure, as both SGX and Hermit can share the Parker implementation, they just have slightly different primitives (SGX uses signals and Hermit has a thread blocking API). `````@kawadakk````` I assume you are the target maintainer? Could you test this for me?
2022-06-06Make all {Mutex, Condvar, RwLock}::new #[inline].Mara Bos-0/+1
2022-06-03Use Drop instead of destroy() for locks.Mara Bos-1/+3
2022-05-18std: use an event flag based thread parker on SOLIDjoboet-0/+2
2022-05-09Use Rust 2021 prelude in std itself.Mara Bos-1/+1
2022-04-14library: Remove definitions and reexports of `strlen` from libstdVadim Petrochenkov-2/+0
2022-04-11kmc-solid: Use `abort` to abort a programTomoaki Kawada-45/+5
The current implementation uses a `hlt` instruction, which is the most direct way to notify a connected debugger but is not the most flexible way. This commit changes it to a call to the `abort` libc function, making it possible for a system designer to override its behavior as they see fit.
2022-04-06Rename RWLock to RwLock in std::sys.Mara Bos-9/+9
2022-03-22Move std::sys::{mutex, condvar, rwlock} to std::sys::locks.Mara Bos-2/+9
2022-03-10Use implicit capture syntax in format_argsT-O-R-U-S-3/+3
This updates the standard library's documentation to use the new syntax. The documentation is worthwhile to update as it should be more idiomatic (particularly for features like this, which are nice for users to get acquainted with). The general codebase is likely more hassle than benefit to update: it'll hurt git blame, and generally updates can be done by folks updating the code if (and when) that makes things more readable with the new format. A few places in the compiler and library code are updated (mostly just due to already having been done when this commit was first authored).
2022-02-18Rollup merge of #93847 - solid-rs:fix-kmc-solid-fs-ts, r=yaahcMatthias Krüger-1/+20
kmc-solid: Use the filesystem thread-safety wrapper Fixes the thread unsafety of the `std::fs` implementation used by the [`*-kmc-solid_*`](https://doc.rust-lang.org/nightly/rustc/platform-support/kmc-solid.html) Tier 3 targets. Neither the SOLID filesystem API nor built-in filesystem drivers guarantee thread safety by default. Although this may suffice in general embedded-system use cases, and in fact the API can be used from multiple threads without any problems in many cases, this has been a source of unsoundness in `std::sys::solid::fs`. This commit updates the implementation to leverage the filesystem thread-safety wrapper (which uses a pluggable synchronization mechanism) to enforce thread safety. This is done by prefixing all paths passed to the filesystem API with `\TS`. (Note that relative paths aren't supported in this platform.)
2022-02-10kmc-solid: Use the filesystem thread-safety wrapperTomoaki Kawada-1/+20
Neither the SOLID filesystem API nor built-in filesystems guarantee thread safety by default. Although this may suffice in general embedded- system use cases, and in fact the API can be used from multiple threads without any problems in many cases, this has been a source of unsoundness in `std::sys::solid::fs`. This commit updates the `std` code to leverage the filesystem thread- safety wrapper to enforce thread safety. This is done by prefixing all paths passed to the filesystem API with `\TS`. (Note that relative paths aren't supported in this platform.)
2022-02-08Fix `absolute` issuesChris Denton-0/+1
2022-02-08`std::path::absolute`Chris Denton-1/+6
2022-02-07Auto merge of #87869 - thomcc:skinny-io-error, r=yaahcbors-15/+11
Make io::Error use 64 bits on targets with 64 bit pointers. I've wanted this for a long time, but didn't see a good way to do it without having extra allocation. When looking at it yesterday, it was more clear what to do for some reason. This approach avoids any additional allocations, and reduces the size by half (8 bytes, down from 16). AFAICT it doesn't come additional runtime cost, and the compiler seems to do a better job with code using it. Additionally, this `io::Error` has a niche (still), so `io::Result<()>` is *also* 64 bits (8 bytes, down from 16), and `io::Result<usize>` (used for lots of io trait functions) is 2x64 bits (16 bytes, down from 24 — this means on x86_64 it can use the nice rax/rdx 2-reg struct return). More generally, it shaves a whole 64 bit integer register off of the size of basically any `io::Result<()>`. (For clarity: Improving `io::Result` (rather than io::Error) was most of the motivation for this) On 32 bit (or other non-64bit) targets we still use something equivalent the old repr — I don't think think there's improving it, since one of the fields it stores is a `i32`, so we can't get below that, and it's already about as close as we can get to it. --- ### Isn't Pointer Tagging Dodgy? The details of the layout, and why its implemented the way it is, are explained in the header comment of library/std/src/io/error/repr_bitpacked.rs. There's probably more details than there need to be, but I didn't trim it down that much, since there's a lot of stuff I did deliberately, that might have not seemed that way. There's actually only one variant holding a pointer which gets tagged. This one is the (holder for the) user-provided error. I believe the scheme used to tag it is not UB, and that it preserves pointer provenance (even though often pointer tagging does not) because the tagging operation is just `core::ptr::add`, and untagging is `core::ptr::sub`. The result of both operations lands inside the original allocation, so it would follow the safety contract of `core::ptr::{add,sub}`. The other pointer this had to encode is not tagged — or rather, the tagged repr is equivalent to untagged (it's tagged with 0b00, and has >=4b alignment, so we can reuse the bottom bits). And the other variants we encode are just integers, which (which can be untagged using bitwise operations without worry — they're integers). CC `@RalfJung` for the stuff in repr_bitpacked.rs, as my comments are informed by a lot of the UCG work, but it's possible I missed something or got it wrong (even if the implementation is okay, there are parts of the header comment that says things like "We can't do $x" which could be false). --- ### Why So Many Changes? The repr change was mostly internal, but changed one widely used API: I had to switch how `io::Error::new_const` works. This required switching `io::Error::new_const` to take the full message data (including the kind) as a `&'static`, rather than just the string. This would have been really tedious, but I made a macro that made it much simpler, but it was a wide change since `io::Error::new_const` is used everywhere. This included changing files for a lot of targets I don't have easy access to (SGX? Haiku? Windows? Who has heard of these things), so I expect there to be spottiness in CI initially, unless luck is on my side. Anyway this large only tangentially-related change is all in the first commit (although that commit also pulls the previous repr out into its own file), whereas the packing stuff is all in commit 2. --- P.S. I haven't looked at all of this since writing it, and will do a pass over it again later, sorry for any obvious typos or w/e. I also definitely repeat myself in comments and such. (It probably could use more tests too. I did some basic testing, and made it so we `debug_assert!` in cases the decode isn't what we encoded, but I don't know the degree which I can assume libstd's testing of IO would exercise this. That is: it wouldn't be surprising to me if libstds IO testing were minimal, especially around error cases, although I have no idea).
2022-02-04Hide Repr details from io::Error, and rework `io::Error::new_const`.Thom Chiovoloni-15/+11
2022-01-31kmc-solid: `SOLID_RTC_TIME::tm_mon` is 1-basedTomoaki Kawada-1/+1
2022-01-28kmc-solid: Implement `FileDesc::duplicate`Tomoaki Kawada-1/+4
2021-12-21kmc-solid: Add `std::sys::solid::fs::File::read_buf`Tomoaki Kawada-1/+27
Catching up with commit 3b263ceb5cb89b6d53b5a03b47ec447c3a7f7765
2021-12-12Address review feedbackAmanieu d'Antras-1/+1
2021-12-12Stabilize asm! and global_asm!Amanieu d'Antras-5/+5
They are also removed from the prelude as per the decision in https://github.com/rust-lang/rust/issues/87228. stdarch and compiler-builtins are updated to work with the new, stable asm! and global_asm! macros.
2021-11-08kmc-solid: Avoid the use of `asm_const`Tomoaki Kawada-7/+6
2021-09-28Add SOLID targetsTomoaki Kawada-0/+2230
SOLID[1] is an embedded development platform provided by Kyoto Microcomputer Co., Ltd. This commit introduces a basic Tier 3 support for SOLID. # New Targets The following targets are added: - `aarch64-kmc-solid_asp3` - `armv7a-kmc-solid_asp3-eabi` - `armv7a-kmc-solid_asp3-eabihf` SOLID's target software system can be divided into two parts: an RTOS kernel, which is responsible for threading and synchronization, and Core Services, which provides filesystems, networking, and other things. The RTOS kernel is a μITRON4.0[2][3]-derived kernel based on the open-source TOPPERS RTOS kernels[4]. For uniprocessor systems (more precisely, systems where only one processor core is allocated for SOLID), this will be the TOPPERS/ASP3 kernel. As μITRON is traditionally only specified at the source-code level, the ABI is unique to each implementation, which is why `asp3` is included in the target names. More targets could be added later, as we support other base kernels (there are at least three at the point of writing) and are interested in supporting other processor architectures in the future. # C Compiler Although SOLID provides its own supported C/C++ build toolchain, GNU Arm Embedded Toolchain seems to work for the purpose of building Rust. # Unresolved Questions A μITRON4 kernel can support `Thread::unpark` natively, but it's not used by this commit's implementation because the underlying kernel feature is also used to implement `Condvar`, and it's unclear whether `std` should guarantee that parking tokens are not clobbered by other synchronization primitives. # Unsupported or Unimplemented Features Most features are implemented. The following features are not implemented due to the lack of native support: - `fs::File::{file_attr, truncate, duplicate, set_permissions}` - `fs::{symlink, link, canonicalize}` - Process creation - Command-line arguments Backtrace generation is not really a good fit for embedded targets, so it's intentionally left unimplemented. Unwinding is functional, however. ## Dynamic Linking Dynamic linking is not supported. The target platform supports dynamic linking, but enabling this in Rust causes several problems. - The linker invocation used to build the shared object of `std` is too long for the platform-provided linker to handle. - A linker script with specific requirements is required for the compiled shared object to be actually loadable. As such, we decided to disable dynamic linking for now. Regardless, the users can try to create shared objects by manually invoking the linker. ## Executable Building an executable is not supported as the notion of "executable files" isn't well-defined for these targets. [1] https://solid.kmckk.com/SOLID/ [2] http://ertl.jp/ITRON/SPEC/mitron4-e.html [3] https://en.wikipedia.org/wiki/ITRON_project [4] https://toppers.jp/