From: Philippe Gerum <rpm@xenomai.org>
To: Jan Kiszka <jan.kiszka@siemens.com>
Cc: xenomai@xenomai.org
Subject: Re: [RFC] Rust API for evl
Date: Wed, 01 Jun 2022 10:56:51 +0200 [thread overview]
Message-ID: <87bkvcirgs.fsf@xenomai.org> (raw)
In-Reply-To: <9d47b5f3-b18e-0f75-9753-fefec5e9bdd7@siemens.com>
Jan Kiszka <jan.kiszka@siemens.com> writes:
> On 31.05.22 15:37, Philippe Gerum via Xenomai wrote:
>>
>> I've been getting my feet wet with Rust for a few weeks now, assessing
>> the real-time latency figures I could get from an existing (C++)
>> application once fully rewritten in this language. It turned out that
>> performance was on par with the original implementation with memory
>> safety on top, among other upsides (like having quite some fun coding in
>> Rust in the first place).
>>
>> Having Rust as a Tier 1 language for Xenomai4/evl along with the
>> existing C interface definitely makes sense to me. The goal would be to
>> have a 'revl' interface providing the EVL services the idiomatic Rust
>> way, available as a crate on top of the FFI bindings to libevl which
>> have just landed [1].
>>
>> Whether you are a Rustacean or not, if you are willing to discuss and
>> help with this, let me know.
>>
>> [1] https://source.denx.de/Xenomai/xenomai4/evl-sys.git
>>
>
> I think this is a very interesting experiment, and I'm excited to see
> that there are apparently no RT traps in the runtime.
There are in the std:: library, but since the original C++ application
was written from the ground up with dual kernel support in mind, this
was fairly easy to locate the time critical algorithms, designing a Rust
implementation for them.
A few takeaways so far from switching this non-trivial C++ real-time
application to Rust:
- this is not about 'porting' in the usual sense, this is about
rewriting with different idioms. As far as I'm concerned, leaving
behind the OOP playbook helped a lot. Not that we cannot or should not
use constructs which are reminiscent of OOP with Rust, but its trait
system and some influence from functional programming give a lot more
than this. Besides, monomorphization is our friend performance-wise,
so using 'trait objects' all over the map may not be the best approach
- in fact, this might even go against expressiveness in some cases
IMHO.
- since we are used to tread carefully between non-rt and rt contexts in
our ecosystem, the std:: library is ok in the processing
preparation/exit phase as usual. In addition, Rust tends to allocate
as much as possible from the stack unlike the STL (not even mentioning
Boost): this shows when comparing the assembly output for some code
involving a plain vector iterator (obviously NOT with folding or any
accumulator-based construct though). IOW, the precautions we take with
C++ also apply in a Rust context, but shenanigans were much fewer in
the Rust case AFAIC, and the audit process was much easier
source-wise, navigating the standard crate implementation. Typically,
I did not stumble on unexpected 'hidden locks' even in the standard
library (std::io has some, but this is hardly unexpected there, and
not an issue anyway). Maybe I've been lucky, but Rust tends to favor
explicit over implicit in general, so there is hope.
- for the time-critical part Rust-wise, we have the 'heapless' crate
around which gives several off-the-shelf data structures which are
guaranteed not to rely on - well - heap-based allocation. Since the
application involves zero-copy messaging at its heart, the 'flume'
crate was used to exchange message envelopes locklessly with quite
good performances. The most striking aspect of all this comes when you
realize that you did not implement any explicit refcounting of these
messages but delegated it to the language via the Arc construct, and
this Just Works (TM): no leakage, no trashing, no brainer. Of course,
there may be hidden atomic operations all over the map which do not
come for free, but still, this did not cause any significant
performance degradation on armv7 compared to the C++ version where all
of this has been handcrafted.
- we can mix the Rust std and no_std environment, both coupled to libc
in a single application. The Rust EVL interface should probably go for
no_std with some runtime guard on the global allocator, so that any
jack-in-the-box dynamic allocation is either impossible by design, or
easily caught in this API.
- any language compiler should have consideration for its users like
rustc does. Obviously, rustc has to be picky by design to honor the
promise of memory safety including safe concurrency, but this always
goes with helpful error messages, smart hints. Seriously, the work
these folks did there to help newcomers is simply fascinating.
- I found using a Rust cross-toolchain targeting armv7 from a
Yocto-generated SDK a bit bumpy in a few occasions, particularly if
bindgen is involved the build process. Likewise, 'heapless' may need
some fixup in its build script. This said, meta-rust which produces
the toolchain was merged into the OE core only fairly recently (Yocto
honister was the first Yocto release to have it IIRC), armv7 is still
Tier 2 Rust-wise, so this will improve over time. In general,
targeting x86 which is Tier 1 is already a no-brainer though.
> Do you have some
> example code somewhere as well?
>
Not yet. I have started working on the 'revl' crate implementing the EVL
interface for the Rust language though. There is not much of it yet
(clock services based on the 'embedded_time' crate, little
thread-related support, sema4 and basic mutex), but I'll push what is
there in a couple of days to a public repo.
--
Philippe.
next prev parent reply other threads:[~2022-06-01 8:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-31 13:37 [RFC] Rust API for evl Philippe Gerum
2022-06-01 5:50 ` Jan Kiszka
2022-06-01 8:56 ` Philippe Gerum [this message]
2022-06-05 14:49 ` Philippe Gerum
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bkvcirgs.fsf@xenomai.org \
--to=rpm@xenomai.org \
--cc=jan.kiszka@siemens.com \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.