我正在使用gcc为单处理器32位微控制器编写代码.
我需要从链表中消耗带时间戳的对象.代码的另一部分可以是异步的(可能在ISR中)将它们添加到列表中.
关键部分通过关闭中断和使用该barrier()功能来实现.
我很困惑gcc优化可以通过缓存指向列表项的指针(下一个要删除的最新项目,列表头或空闲列表)来破坏我的代码.我不希望while循环中的任何内容从前一个循环中缓存.内存屏障是否会保护我免受编译器决定在函数启动时加载一次指针而永远不会重新加载它?所有这些列表指针都可以在生产者代码的关键部分中修改(未示出).我试图理解是否pqueue_first应该是一个易失性指针,例如.
据推测,如果没有循环(这是添加到列表的情况),如果函数中的所有代码都在关键部分,我可以吗?
请不要只指向一些关于易失性或关键部分的通用文章,因为我已经阅读了很多部分,但是我很难看到如何将它应用于这个特定的代码.我知道volatile确保编译器每次引用时都会重新加载变量.但我不了解优化的可能范围及其与内存障碍的相互作用.
typedef struct {
EV_EventQueueEntry_t *pqueue_alloc; // allocation (never changes)
EV_EventQueueEntry_t *pqueue_head; // head of active queue (ISR can change it)
EV_EventQueueEntry_t *pqueue_free; // head of free list (ISR can change it)
EV_EventQueueEntry_t *pqueue_first; // soonest item in queue (ISR can change it)
EV_EventQueueEntry_t *pqueue_first_prev; // back pointer from soonest item (ISR can change it)
EV_UInt_t max_event_count;
} EV_EventQueue_t;
void RunLoop(EV_EventQueue_t *pev)
{
while(not timeout)
{
// Enter critical section
disable_interrupts(); …Run Code Online (Sandbox Code Playgroud) c volatile producer-consumer critical-section memory-barriers