HNHacker News
TopNewBestAskShowJobs

jamesmunns

1,186 karma · joined September 26, 2016

james@onevariable.com
submissionscomments
jamesmunns··on Beeper acquired by Automattic
Yeah, having all of your messaging in one place is amazing. Especially since they support a decent long tail of DM services as well.
jamesmunns··on Beeper acquired by Automattic
I really like Beeper, and congrats to them for getting acquired, but my first reaction is "aw damn how long until the parts I love about Beeper get incredible journey'd away".

The new android app is really good, the desktop app has always been a step up from other Element apps I've used (it is a distant fork, these days), I don't have iMessage, but it works great with Matrix and Signal and WhatsApp a ton of other "rarely used" apps I have.

jamesmunns··on Baltimore's Key Bridge struck by cargo ship, collapses
In markdown (or at least some flavors) that is the typical way of making a hyperlink actually a link. It's equivalent to [link](link) in markdown.
jamesmunns··on Regex character "$" doesn't mean "end-of-string"
Thanks! I was AFK and didn't have a grep (or a shell) handy on my phone.
jamesmunns··on Regex character "$" doesn't mean "end-of-string"
Same, tho it'd be interesting to see if this behavior holds if the file ends without a trailing newline and your match is on the final newline-less line.
jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
ELI5: We have a shared chunk of memory, with one sender, and one receiver. We want this to work without an allocator.

Instead of pushing and popping one byte/thing at a time (inefficient, a lot of overhead), we want to have the ability to push or pop big chunks at a time.

We also don't want to pay to copy these chunks in or out, because we're going to have the hardware do it for us autonomously. This means we have to be very careful that the "one side" doesn't look or touch a chunk of memory currently being used by the "other side".

The ideal flow is that we have the CPU get some "writing space", the CPU asks DMA to fill it up, when DMA is done, the CPU marks it as "ready to read". Then at some later time, the CPU (maybe another core or thread) asks for some "ready to read space", the CPU then either uses it, or maybe asks DMA to copy it somewhere else. Then the CPU marks that data as "successfully read", and the space can be recycled the next time something wants to send.

The trick is how you coordinate access to shared memory between two CPUs, correctly, and using the least overhead, so neither side prevents the other from reading or writing, as long as theres a little slack in the line.

jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
I meant 2019, and there weren't any materials that I would consider as clear and well defined as Mara's linked docs explaining the different orderings used by C, C++, and Rust (Relaxed, Release, Acquire, AcqRel, and SeqCst).

I'm very sure there were discussions and teaching materials then, but none (that I was aware of) focused on Rust, and something I'd link to someone who had never heard of atomic ordering before.

jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
Back when this post was written, I would have agreed with you. But Mara's book makes a good case for this:

https://marabos.nl/atomics/memory-ordering.html#common-misco...

  More importantly, when reading code, SeqCst basically tells the reader:
  "this operation depends on the total order of every single SeqCst operation
  in the program," which is an incredibly far-reaching claim. The same code
  would likely be easier to review and verify if it used weaker memory ordering
  instead, if possible...
  
  It is advisable to see SeqCst as a warning sign.
jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
Yep, good catch! That's a whoops in my explanation. I don't work at FS any more, so I'm not sure I could PR that change, but you're definitely right :)
jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
Back then, there weren't as good references for explaining atomic ordering, and the blog post had gotten long enough. Mentioning SeqCst was a bit of a cop out, though both Andrea and I didn't end up using SeqCst past the inital impl anyway.

Today I would have just linked to https://marabos.nl/atomics/, Mara does a much better job of explaining atomics than I could have then or now.

jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
I am not sure! Most of the data structures I design are for embedded systems without allocators. On the desktop, I mostly defer to others.

I've used tokio's broadcast channel quite a bit before, but it is also bounded. After talking to Eliza from the tokio project, I'm fairly convinced that unbounded queues are a scary thing to have around, operationally :).

But again - this is a bit out of my actual expertise!

jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
As far as I know, it hasn't been formally verified.

Andrea Lattuada (https://andrea.lattuada.me/) is more likely to have done work in his implementation of the algorithm than I did on mine.

I have run the testing with various dynamic analysis tools, but for sure this isn't formal verification. If someone is interested in doing it, happy to chat with them!

jamesmunns··on A lock-free ring-buffer with contiguous reservations (2019)
Oh hey, one of the authors of this post here (James), happy to answer any questions.

This post has been discussed here a couple times, but AMA :)

edit, the most commented version of this post was the original:

https://news.ycombinator.com/item?id=20096946.

This is what I'm up to these days:

https://onevariable.com/

jamesmunns··on Talc – A fast and flexible allocator for no_std and WebAssembly
Yeah, just adding, in Rust, there's three main levels:

1. no_std (like no libc + no malloc in C)

2. no_std + alloc (like no libc + malloc in C)

3. std (like a full libc + malloc in C)

The difference between 1 + 2 is like three lines. The difference between 2 + 3 is a change to the entire standard library. ATM only ESP32 devices support option 3 (they build a standard library implementation on top of FreeRTOS/ESP-IDF).

jamesmunns··on FAA gives Boeing 90 days to come up with a plan to address quality issues
The FAA has authority to ground the entire fleet.

It probably won't go that far, but it does have the necessary authority to enforce a pretty huge "or else".

jamesmunns··on German credit agency earns millions through unlawful customer manipulation
Low digitalization isn't just payment - it's also needing to fill in paper forms, or making in-person visits to government and business offices.

I've been living in Germany for about a decade, and it is still behind in many of these items from when I left the US, and having a friend that recently moved from Germany to NL, he was blown away at how convenient and just not-hostile so many day to day interactions with governments and businesses were.

Like - big picture, I'm very happy in Germany, but certain things are still very archaic and sometimes needlessly so.

jamesmunns··on Measuring Stack Usage the Hard Way (2023)
At least in Rust, we have `cargo-call-stack` [0] for static analysis, but "worst case stack usage" can be challenging to measure, if you have interrupts (including nested ones at different prios so you have to add them together!), function pointers (including dyn dispatch), or recursion.

There are ways to annotate and work around this! I'm also from a safety critical background. But there aren't many (any?) OSS tools that do this completely. cargo-call-stack is the closest I've seen.

[0]: https://github.com/Dirbaio/cargo-call-stack/

I agree static analysis is preferrable, but it's also not a "just enable the check, duh" easy, sadly, and it's good to know different techniques.

jamesmunns··on Measuring Stack Usage the Hard Way (2023)
You can't generally change the direction the stack moves, at least on targets like Cortex-M. Maybe in ASM it'd be feasible to work around, but getting LLVM to do this isn't anything I've ever seen.

The "walk off the edge" technique is what is described here [0], in embedded rust we have a tool that does this automatically (from the author of the post) called `flip-link` [1]. It requires a second linker/re-linking pass to do this sizing automatically (you could also do the same manually with a linker script in one pass, if you hardcode certain sizes).

[0]: https://blog.japaric.io/stack-overflow-protection/

[1]: https://github.com/knurling-rs/flip-link

jamesmunns··on Ask HN: How many of you are self employed?
Thanks! I'm glad you enjoyed it :)
jamesmunns··on Ask HN: How many of you are self employed?
I am for a couple years now. I do consulting work [1] around Rust/Embedded Systems/Systems Engineering, usually helping teams that are either kicking off a project (so helping with planning, scoping, and backfilling knowledge gaps), or people who want help building a proof of concept (so: just build it for me asap) for existing companies exploring new ideas or for startups that are working on demos for investors, etc.

I've been active on both the open source and commercial side of embedded Rust since the beginning, so it's been fun to watch it grow both as an ecosystem as well as from a commercial adoption perspective. Doing consulting makes it easier to help do more open source docs + support in the open, and seems to be one of more sustainable ways to do OSS in my opinion, if you can swing it.

[1]: https://onevariable.com/

jamesmunns··on Avoid Async Rust at All Cost
The rest of the quote was:

> ...you'll only be pretending it doesn't exist

Which is what I was providing evidence of that Go does.

It removes coloring to the user by handling it under the hood. The linked article calls this "colorblind instead of colorless".

jamesmunns··on Avoid Async Rust at All Cost
This post discusses the issues:

https://blog.djha.skin/blog/the-down-sides-of-gos-goroutines...

From this recent discussion:

https://news.ycombinator.com/item?id=38821840

It's not to say that Go is bad in this regard! It is just (always) doing the heavy lifting for you of abstracting over different colors of functions. This may have some performance or compatibility (especially wrt FFI) concerns.

Rust chose not to do this, which approach is "right" is subjective and will likely be argued elsewhere in this thread.

jamesmunns··on The cheesy charm of the Clapper
Technology Connections recently did a video[0] on the clapper, which went over quite a bit of the tech and history of the clapper, if you're looking for a video option.

[0]: https://youtu.be/TBPVJtGBf8Y?si=XHbDwcO2LUm9elvk

jamesmunns··on Poll_next
The title is a little underwhelming, but this is a very good discussion of potential designs around async streams/iterators in Rust. Definitely worth a read.
jamesmunns··on Mini-08 single-board computer based on the 8008 CPU [video]
Text writeup is on the authors website, in case you prefer that over a video: https://www.smbaker.com/the-mini-08-8008-single-board-comput...
jamesmunns··on A bitter commentary on EuroRust conf
@dang this looks like a fairly editorialized take on the title:

Original: "EuroRust 2023 Reflections: What's a Conference For?"

Current: "A bitter commentary on EuroRust conf"

jamesmunns··on Interrupts Is Threads
I don't think that filter would like my post at all, if it considers "is" as part of "to be".
jamesmunns··on Interrupts Is Threads
Hey all, this is my somewhat silly-titled blog post about how we model interrupt handlers as threads in embedded rust, and how that allows us to leverage the same Sync and Send compile time checks to ensure interrupt-safety of data.

Happy to answer any questions!

jamesmunns··on I hacked macOS
Hell yeah, good for her!
jamesmunns··on Removing garbage collection from the Rust language (2013)
From a net-effect standpoint, Rust's implementation of async/await is fairly similar to protothreads, which were used even on smaller AVR and MSP430 targets where rtos threads weren't practical.

That being said, protothreads were implemented using wildly cursed C macros, and offered none of the safety guardrails that Rust has, nor the ergonomics, and had some insane constraints, like "you can't use local variables at all, only statics" because like rust, they were stackless coroutines that meant you would have no control of the stack across await points.

If you were VERY CAREFUL, you could get the same lightweight concurrency with almost the same fundamental model. Woe be on you if you ever had to debug though.

edit - here's a look at how protothreads were expanded: https://dunkels.com/adam/pt/expansion.html

← PreviousPage 2 of 5Next →