5 ms·
Okay, not quite 20 lines, but something like this: https://gist.github.com/ohazi/40746a16c7fea4593bd0b664638d7017 https://gist.github.com/ohazi/40746a16c7fea45
by ohazi 7y ago
Okay, not quite 20 lines, but something like this:
https://gist.github.com/ohazi/40746a16c7fea4593bd0b664638d7017 https://gist.github.com/ohazi/40746a16c7fea4593bd0b664638d70...
I've dressed it up to look like C11, but vendor specific macros from your microcontroller support library are more common. I think you can relax some of the memory ordering too, but I don't remember the details off-hand.
Also, sometimes you can have a modified version of queue_push / queue_pop where a DMA handles the memcpy and then you only have to update the pointers in the cleanup interrupt (along with configuring the next or next-next DMA if the queue isn't full / empty).
- gpderetta 7y agoThe atomic_signal_fence in queue pop/push seems suspicious. Unless you are doing something like asymmetric fences or actually synchronizing with signal handlers you probably want atomic_thread_fence. Still I'm not sure why you want a fence at all there. Publishing is done by the atomic_store to queue_rd and wr which already include (I'm being fast and loose here) the equivalent of a seq_cst fence.
- ohazi 7y agoThe reason you want a barrier there is to make sure the memcpy and the pointer update don't get reordered so the other thread doesn't have a chance to access that block before it's ready. You don't actually need any synchronization with the other thread, which is why I think this can work instead of atomic_thread_fence. But you could be right, anyone using this should check this carefully. Edit: I think you're right. If it is needed, it should be a thread fence. I'm not 100% clear on whether the pointer update takes care of this, so it may not actually be needed.
- gpderetta 7y agoThe block is 'published' when the store to the write pointer is performed. That's a store release which will have an implicit barrier before the store.
- ohazi 7y agoOkay yeah, you're definitely right. I didn't realize that the stdatomic load/stores were by default seq_cst. The libraries I'm familiar with have macros for standalone atomic reads and writes, but you have to place any barriers manually. If you were using a library like that, you'd place them in between the memcpy and the pointer update, but here you get that for free.