The atomic_flag_test_and_set_explicit seems to be a standard thing since C11, has anyone here used it in their code for anything?
They are really only useful for building synchronization primitives. But those have been already been available for a long time now. IIRC pthreads was standardized way back in the 90's. So unless you are working on some truly obscure, low-level problem (eg. designing an operating system), you probably won't ever have to bother with such fiddly atomic operations.The atomic_flag_test_and_set_explicit seems to be a standard thing since C11, has anyone here used it in their code for anything?
OK Yes, that is definitely better, no need to disable higher priority interrupts during the insertion of the element.I'd want to use atomic_compare_exchange instead. With a single word (pointer) version of this can add an
element to the top of a list (push down) and also remove the whole list (can't just remove one element).
https://en.cppreference.com/w/c/atomic/atomic_compare_exchange
https://en.wikipedia.org/wiki/Compare-and-swap
So the IRQ routine creates an element containing a link pointer (to be set), the address of the function to run later,
and a parm pointer for the function. It uses atomic_compare_exchange to add this element to the top of the
"run later" list. So the new top of list points to the new element and the new element points to the old top of
list.
Later, some code removes the whole list (compare against current top and exchange in 0, this is safe, trying
to remove just the top element isn't safe). If run order is important it can reverse the order of the elements.
The run them until it runs out of elements to run (and then go get another whole list.
There's no way to remove an element if you change your mind. Also don't trying adding an element
which is already queued.
I've used this many times on IBM 370 type systems...
Yes, a very interesting question. I haven't really finalized that yet. I'm toying with the idea of allocating a "memory pool" from the heap. This would be a do-once allocate at app start. The memory pool would then be used to "allocate" these callback nodes. The pool would effectively be N x node_size and the pool would internally use a bitmap to record free/busy blocks.The tricky part is where do you get the storage for the element from?
In at least some cases, you only need one element (per later routine) and it can be static.
I'm going to need to refresh my memory on the compare/exchange, really forgot a lot about that operation. Really all I'm doing is simple, but I can't help but abstract stuff like this, the small app I am writing does use interrupts and one can easily just write crude code that "just works" but I want to be cognizant of these interrupts that are happening asynchronously and doing work.The atomic test and set can be used to know if the static element needs to be queued.
Assuming set means that the element is already queued (or to be queued or running)
then the non-later routine can do the test & set and if already sent it's done. If not set then
it can queue the element.
The "later" routine should clear the flag sometime in it's run. There are several
choices on when to clear the flag. Be careful, it's best of the "later" routine
is idempotent:
see the computer science section in: https://en.wikipedia.org/wiki/Idempotence
Ouch, I just discovered that the standard C "malloc" and "free" are not thread safe, not surprising with hindsight but we do need better than that, do developers in C and C++ rely on "malloc" or something or do they use custom, high performance heap libraries?The tricky part is where do you get the storage for the element from?
In at least some cases, you only need one element (per later routine) and it can be static.
The atomic test and set can be used to know if the static eiement needs to be queued.
Assuming set means that the element is already queued (or to be queued or running)
then the non-later routine can do the test & set and if already sent it's done. If not set then
it can queue the element.
The "later" routine should clear the flag sometime in it's run. There are several
choices on when to clear the flag. Be careful, it's best of the "later" routine
is idempotent:
see the computer science section in: https://en.wikipedia.org/wiki/Idempotence
Any library function for that matter which relies on some global (ie. static) state is strictly speaking not thread safe. For C programs, you should simply replace malloc/free calls with synchronized analogs. C++ on the other hand allows you to override new and delete, which does make things quite a bit more straight-forward.Ouch, I just discovered that the standard C "malloc" and "free" are not thread safe, not surprising with hindsight but we do need better than that, do developers in C and C++ rely on "malloc" or something or do they use custom, high performance heap libraries?
I imagine if using C++ you're metaphorically f****d because every reference to "new" is a call into a heap allocation of some form, at least in C all allocates/frees are explicit.
To avoid corruption in multithreaded applications, mutexes are used in‐
ternally to protect the memory-management data structures employed by
these functions. In a multithreaded application in which threads si‐
multaneously allocate and free memory, there could be contention for
these mutexes. To scalably handle memory allocation in multithreaded
applications, glibc creates additional memory allocation arenas if mu‐
tex contention is detected. Each arena is a large region of memory
that is internally allocated by the system (using brk(2) or mmap(2)),
and managed with its own mutexes.
Yes, this is all true, malloc is a bit of a pig. Do people in the MCU world ever use 3rd party heap manager libraries ever?from "man malloc" on linux debian 11 bullseye libc6:
Thread starter | Similar threads | Forum | Replies | Date |
---|---|---|---|---|
![]() |
How do you spell "Chickfans"? anyone here from UK? | Off-Topic | 2 | |
S | is anyone here mining? | Off-Topic | 5 | |
T | Can anyone help me out here - I applied 24V to a 5V board | General Electronics Chat | 10 | |
![]() |
Anyone here use Mathematica? | General Science, Physics & Math | 15 | |
![]() |
Anyone here using the latest Firefox 89.0 browser? | Off-Topic | 15 |