News for hackers. Stuff that matters.
Re:How to trigger races reliably in the Linux kernel by jerf on Tuesday May 05, 2020 @09:27AM (#23079788)
While true, it is still generally a mistake to leave a race condition in your code, because your human understanding of the possible interleavings is very unlikely to be correct. In addition to the way the code appears to be written, understanding the impact of a race condition requires you to fully understand the memory model in play, fully understanding all compiler optimizations that may have been made, which may include instruction reordering, fully understand all memory alignment issues on all machines you may execute this on and all their little differences, including on machines that don't exist yet that your code may run on in the future, and fully understand the entire stack of code involved in the race condition from the level of abstraction you're using pretty much all the way down to the compiled and optimized assembler. It also makes testing harder... all kinds of testing, automated and otherwise, because whether or not your tests can get to a given part of the state space becomes nondeterministic.

The average developer assessment that some race condition is completely harmless is wrong; there's usually a bug in the complicated state space somewhere.

A performance optimization involving a deliberate race condition should be pretty much your last resort.

Even the obvious ones are often less of a good idea than they may look, like a leaky incrementing counter for logging purposes. You might model that as being unlikely to lose more than a couple of percent, but I've seen cases where it lost the majority of logged events. Granted, this probably won't crash your program, but it can still result in surprisingly deceptive logging.

Re:How to trigger races reliably in the Linux kernel by chrisseaton on Tuesday May 05, 2020 @09:38AM (#23079882)
I think you might possibly be overstating how complex a race condition needs to be.

For example two consumers pushing results to a single result queue is a race condition, because the order in which they arrive depends on timing and is non-deterministic. That's a pretty normal thing to have.

Many languages people think of as being safe and high level are extremely racey - Erlang is my go-to example - two processes sending messages to a third is a race. Which message do you get first? It's non-deterministic. But it doesn't have to be a problem.

Re:How to trigger races reliably in the Linux kernel by isaachier on Tuesday May 05, 2020 @11:42AM (#23081235)
What you are describing sounds like non-deterministic behavior of a thread-safe primitive, e.g. non-deterministic ordering in a synchronized queue. On the other hand, a true race condition in the queue could mean messages overwriting each other.
Re:How to trigger races reliably in the Linux kernel by chrisseaton on Tuesday May 05, 2020 @12:57PM (#23082121)
> What you are describing sounds like non-deterministic behavior of a thread-safe primitive, e.g. non-deterministic ordering in a synchronized queue.

That's what a race condition is - non-deterministic behavior of a thread-safe primitive.

> On the other hand, a true race condition in the queue could mean messages overwriting each other.

That's a data race, not a race condition.

Re:How to trigger races reliably in the Linux kernel by jfkebwjsbx on Tuesday May 05, 2020 @09:34AM (#23079850)
Not all race conditions are as complex as you make them to be, in particular if they are done on purpose.

And many race conditions don't have anything to do with the memory model or compiler optimizations.

Re:How to trigger races reliably in the Linux kernel by MaxBarraclough on Tuesday May 05, 2020 @10:01AM (#23080086)
> And many race conditions don't have anything to do with the memory model or compiler optimizations.

For example, poorly structured response-handlers in JavaScript. If the code assumes that request R1 always returns before request R2, things may misbehave if that assumption is violated. That's a race condition, but as you say, it's nothing to do with memory models or compiler trickery, as JavaScript gives you just the one thread (not counting workers).

Re:How to trigger races reliably in the Linux kernel by throwaway2048 on Tuesday May 05, 2020 @11:26AM (#23081033)
If R2 returns before R1 that is still a race condition, but it might not be a bug.
Re:How to trigger races reliably in the Linux kernel by MaxBarraclough on Tuesday May 05, 2020 @11:43AM (#23081244)
> If R2 returns before R1 that is still a race condition

That's not correct. Look at chrisseaton's definition.

If the observable program behaviour doesn't change depending on the order in which the requests complete, there's no race condition. (In JavaScript this might be done with Promise.all.) You're right that not all race conditions are bugs.

Re:How to trigger races reliably in the Linux kernel by gildas on Tuesday May 05, 2020 @12:27PM (#23081778)
There is even Promise.race provided for that purpose in JavaScript. You can typically use it to implement a watchdog.
Re:How to trigger races reliably in the Linux kernel by AnimalMuppet on Tuesday May 05, 2020 @01:00PM (#23082163)
Particularly if they are done on purpose???

Can you give an example of when one would (sanely) want to create a race condition?

Re:How to trigger races reliably in the Linux kernel by chrisseaton on Tuesday May 05, 2020 @01:50PM (#23082709)
I don’t think you ever want a race condition for the sake of it but there are many daily cases where you don’t care that it races and fixing it would have terrible downsides. In a distributed system they’re practically unavoidable I think!