HNHacker News
TopNewBestAskShowJobs

mrkline

371 karma · joined February 21, 2017

I write software, and occasionally ramble at http://bitbashing.io/
submissionscomments
mrkline··on Unsafe at Any Speed: Tradeoffs and Values in the Rust Ecosystem
That's my main goal - and Rust seems like the language where we can have our cake and eat it too! The standard library has some amazingly performant data structures and algorithms.

Talking to one of the hyper developers, a lot of this machinery was made before it arrived in the stdlib. My response was, "neat, so we can delete the custom stuff now, right? :P" but I suppose any change carries some risk with it.

mrkline··on Unsafe at Any Speed: Tradeoffs and Values in the Rust Ecosystem
Turns out we regularly play flight sims together on weekends, but didn't know about each others' software misadventures - small world, isn't it?

If the reason I blogged about my coding hobby was to "get my 15 minutes on HN", I would be a deeply unhappy person.

mrkline··on Unsafe at Any Speed: Tradeoffs and Values in the Rust Ecosystem
The article got me in touch with one of the hyper devs, and we had a very friendly conversation that taught me a lot.

If questioning some design decisions and calling a marketing blurb a little disingenuous is mocking and condescending, they didn't seem to think so.

mrkline··on Unsafe at Any Speed: Tradeoffs and Values in the Rust Ecosystem
> If a library has 100k lines of code but the parts you use are only 1k lines of code then why is that worse than a library with 1k lines of code?

There's nothing wrong with not using the whole feature set of some library. But if library A does the same things as library B with a third of the code, isn't that better? (All other things - e.g. perf - being equal)

> That's true right until the moment you do need them and then you need to rewrite a lot of code.

There's plenty of applications that will only ever need a handful of connections. Probably most applications.

mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
- Like others have said, both malloc()/free() touch a lot of global state, so you either have contention between threads, or do as jemalloc does and keep thread-local pools that you occasionally reconcile.

- A moving (and ideally, generational) GC means that you can recompact the heap, making malloc() little more than a pointer bump.

- This also suggests subsequent allocations will have good locality, helping cache performance.

Manual memory management isn't magically pause-free, you just get to express some opinion about where you take the pauses. And I'll contend that (A) most programmers aren't especially good at choosing when that should be, and (B) lots (most?) software cares about overall throughput, so long as max latency stays under some sane bound.

mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
Go's GC is hardly state of the art.
mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
It's great! But there's nothing about it that requires futures.

It really annoys me that something like this isn't built-in: https://github.com/mrkline/channel-drain

mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
> Async/await was a terrible idea for fixing JavaScript's lack of proper blocked threading that is currently being bolted onto every language.

As fun as it is to hate on JavaScript, it's really interesting to go back and watch Ryan Dahl's talk introducing Node.js to the world (https://www.youtube.com/watch?v=EeYvFl7li9E). He's pretty ambivalent about it being JavaScript. His main goal was to find an abstraction around the epoll() I/O event loop that didn't make him want to tear his eyes out, and he tried a bunch of other stuff first.

mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
Hoare Was Right.

(But if you're only firing up a few tasks, why not just use threads? To get a nice wrapper around an I/O event loop?)

mrkline··on Maybe Rust isn’t a good tool for massively concurrent, userspace software
> The lifetime of an Arc isn’t unknowable, it’s determined by where and how you hold it.

In the same sense that the lifetime of an object in a GC'd system has a lower bound of, "as long as it's referenced", sure. But that's nearly the opposite of what the borrow checker tries to do by statically bounding objects, at compile time.

> maybe the disconnect in this article is that the author is coming at Rust and trying to force their previous mental models on to it

The opposite actually! I spent about a decade doing systems programming in C, C++, and Rust before writing a bunch of Haskell at my current job. The degree to which a big language runtime and GC weren't a boogeyman for some problem spaces was really eye-opening.

mrkline··on Comparing Floating-Point Numbers Is Tricky
Hopefully that fixes it. Sorry I suck at CSS.
mrkline··on Comparing Floating-Point Numbers Is Tricky
Is it better now?
mrkline··on C++ on Embedded Systems
You're really making a bunch of uncharitable assumptions about our situation.

First, you assume that this behavior isn't well understood, well documented, and even expected in my organization and our corner of the industry. The reason FreeRTOS has an allocator that doesn't free is because it's standard behavior in embedded systems with hard time requirements.

Then you guess that we've taken no precautions against some future developer not having this knowledge. The allocator in question asserts if the user tries to free to avoid the very scenario you describe, and attempting to use newlib's allocator asserts with an explanation of why it's unused.

Technical debt is an issue I take very seriously, and I work hard to document the design decisions we've made. Choosing to use a tool that's designed specifically for our use case, instead of taking the time to set up a general-purpose allocator with overhead we don't care for, is hardly a debt that needs to be paid off.

mrkline··on C++ on Embedded Systems
I would _love_ to write our firmware in Rust, but that's a much bigger sell than moving from C to C++.
mrkline··on C++ on Embedded Systems
I don't follow. If an allocator is optimized for our needs (i.e., allocating everything up front and never freeing), and is easier to set up than the general-purpose allocator in newlib, how is using it "technical debt"?
mrkline··on C++ on Embedded Systems
IIRC, the concern was in the details of newlib's allocator. Its sbrk looks for a linker symbol, then starts slicing memory off of that address. There were worries that unless we were careful, it might stomp on FreeRTOS. (These worries could have been unfounded, but we didn't look into it deeply. We only dynamically allocate at startup, so we'd prefer FreeRTOS's heap_1.c anyways.)
mrkline··on C++ on Embedded Systems
Great! But when you have hard timing requirements measured in microseconds, you generally need some fine-grained control over the instructions the CPU ends up running. All the knobs and levers C and C++ offer you are quite useful here.
mrkline··on C++ on Embedded Systems
Great points. In our cases, these objects were few in number and were accessed infrequently through a pointer, so I don't think there's much to be concerned about. Avoiding unnecessary vtables is definitely something to keep in mind, though.
mrkline··on C++ on Embedded Systems
The main issue with just using newlib's allocator is that we're using FreeRTOS, and (AFAIK), there isn't a good way to make the two aware of each other. One could also probably hook operator new up to to FreeRTOS, but we try to avoid dynamic memory allocation after init, like the article said.
mrkline··on C++ on Embedded Systems
> inadvertent copy constructor/assignment operator calls

This is much less of a problem (and much more controllable!) now that we have move semantics.

> automatic memory allocs

It's hard to accidentally allocate memory if you don't have a system allocator hooked up.

> heavy-weight operator overloads

No more heavy-weight than a standard function call, and usually inlined at that.

mrkline··on C++ on Embedded Systems
I'm incredibly interested in getting Rust into embedded devices, but it's a much larger sell than moving from C to C++14. And how will C++17 onward be so much different? C++11 was a huge inflection point, no doubt, but the standards committee works tirelessly to make things backwards-compatible.
mrkline··on C++ on Embedded Systems
> you just need to start from this point if you know your environment is really constrained and exceptions are too much of a cost - which is usually not the case in modern embedded ARM systems.

ARM systems really run the gamut these days - while many are quite powerful (see: my phone), many also fall on the more traditional microcontroller side, with very little in terms of flash and RAM. In case it wasn't clear, this article focused on the latter.

mrkline··on C++ on Embedded Systems
The main motivation is just that experienced C++ devs (myself included) have the rule, "base classes should have virtual destructors" drummed into their heads. Defining operator delete (even if the compiler elides it since, like you pointed out, it's never needed) allows devs to continue that habit without any negative consequences.
mrkline··on C++ on Embedded Systems
The approach I laid out makes sure that the constructors for all of your global/static objects get called. AFAIK, there's no reason you couldn't do everything "by hand", but it seems like a lot more work for questionable gain.
mrkline··on C++ on Embedded Systems
Author here - thanks! I left out advice like, "turn on all the warnings" because I was trying to focus on problems specific to embedded platforms. I'd strongly argue advice like that that is great regardless of what your target is.