Does threadpool::thread_loop() not have to check if the popped coroutine is suspended before attempting to resume it?
Are they really more efficient than normal callbacks when doing async?
Does threadpool::thread_loop() not have to check if the popped coroutine is suspended before attempting to resume it?
Are they really more efficient than normal callbacks when doing async?
Take for instance, this code which relies on libuv for its event loop and co_await to retain its state during its execution: https://gist.github.com/Qix-/09532acd0f6c9a57c09bd9ce31b3023...
Lets say that you want to batch a bunch of database operations into one transaction. You could queue them up over the course of a few milliseconds, run the transaction, and then for each context that relied on different db operations simply return to each's previous point instead of having to call a handler. Granted, the handler is now inside of the `await_transform` needed to work with `co_await` but think of the possibilities. No weirdly separate callback function, no real need to make a class that encapsulates all of the operations for let's say a user's post request, and to top it all off, you can do this on a single thread. It's a tool for cleaner code but I'll be damned if it is really easy to understand.
It's just so much stupid boiler plate and a strange way of putting it together.
https://www.ptc.com/en/products/developer-tools/perc
https://www.aicas.com/wp/products-services/jamaicavm/
On the other hand there is real time where even malloc() is forbidden.
According to the third link:
> we observed a negative correlation between MISRA rule violations and observed faults
So, MISRA isn’t really helping with real time at all.
The second link claims pauses are capped at 10us, which (if true) is actually competing with careful use of malloc.
It is real time enough to drive battleship weapon systems, the kind of apps where the wrong people die when a GC goes wrong.
https://www.ptc.com/en/blogs/plm/ptc-perc-virtual-machine-te...
Then there's "things will go wrong if there's a random 8msec delay".
Then there's "people will die and/or property will be destroyed if there's a random 8msec delay".
I was referring only to the last two. And yes, that means no malloc.
https://www.ptc.com/en/blogs/plm/ptc-perc-virtual-machine-te...
On any case, that is the reason why I started with depends, just like everyone wants to do big data that fits into a USB floppy, there are those cases where CircuitPython would be more than enough, yet people insist in using Assembly.
In some cases only Ada/SPARK or MISRA will do, others not, yet all of them might fall under real time and embedded deployment.
By contrast, using a DAW with typical settings, an 8 msec delay is catastrophic within the scope of the task, even though nobody gets hurt and nothing gets destroyed.
If you think that's the case, explain why I can't decide I want to pass an argument to a function in a register:
https://stackoverflow.com/q/58339165/1593077
Also, modern C++ has actually made it possible to write much more elegant code, for many delicate tasks, without sacrificing the performance benefits. So a convenient default doesn't necessarily have to contradict non-opinionated nature.
I am an old man, and so I remember when left and right every C++ programmer was excited about how the Standard Template Library was going to make everything OK and those of us who were still jeering would be writing C++ soon. How did that go?
Many will keep hating C++, while ignoring that Java, .NET (C#, F#, VB, C++/CLI), Python, JavaScript, PHP, Ruby,.... all suffer from similar complexity, spread around 30 - 40 years of language evolution and ecosystems.
Others will cling to their outdated toolchains because the language owners played a Python 3 on them.
While some will understand that the world isn't perfect and make do with what is out there.
An example is right in the name. Today we know that "clever" operators like the pair of ++ increment operators in C++ are a bad idea. They too easily allow mistakes to hide in plain sight, the programmer writes ++n where they actually needed n++ or vice versa, and a reviewer's brain overlooks this and so it gets shipped.
If you're playing Code Golf then these operators are a big benefit, but we aren't playing Code Golf, we're writing actual software that will be used in the real world, so explicitly spelling out what you meant is good.
As a result some modern languages deliberately do not have these operators. And e.g. as I understand it Swift actually removed these operators from the language. But C++ 20 still has both operators of course, it's just that your local dialect might forbid one or both of them.
Python 3 will stay in history as a canonical example of what happens when those wishes turn into reality.
The only way to enqueue a coroutine is to call schedule() within a co_await statement/expression. In this process the coroutine is suspended. Therefore there should not be any coroutine within the queue, which we cannot immediately resume.
I'm afraid I don't have any numbers available to compare coroutines with other approaches. But nevertheless in my opinion coroutines are benefitial because they keep their state (the stack frame, local variables) alive. If you use callbacks you would have to handle all these things yourself. Think about a generator for a sequence of numbers. You would have to store at least the counter variable manually. With a coroutine this happens automatically.
The c++ implementation seems closer to lisps 'call with current continuation', though as far as I can tell all implementations achieve more or less the same thing (though thread safety might vary among the options).
Actually continuation passing style (callbacks) are another way of doing the same thing, though they have the disadvantage that they require large structural changes to the code. It wouldn't surprise me if the callback hell can therefore also occur in all versions, though some might make it easier than others (python's implementation in particular makes it somewhat less likely by encouraging information to flow one way)
The Twisted library encouraged heavy use of this before Python implemented async/await.
https://twistedmatrix.com/documents/current/core/howto/defer...