我有一个在其上运行FreeRTOS的PCI端点。该端点(EP)连接到在其上运行Linux的Root Complex(RC)。
我已经实现了使用环形阵列在RC和EP之间进行通信的软件处理器间通信(IPC)机制。环形阵列结构和内存在EP上分配,并且该内存通过EP BAR暴露给主机。
有一个坐在主机上的生产者正在向环形阵列填充数据,而坐在EP上的消费者正在使用数据。反之亦然(EP的生产者和RC的消费者)也可以通信
圆形数组的实现如下所示,
/** buffer ring common metadata between RC and EP */
typedef struct ipc_bd_ring_md {
uint32_t pi; /**< Producer index */
uint32_t ci; /**< Consumer index */
uint32_t queue_size; /**< Used to roll-over pi/ci */
uint32_t msg_size; /**< max size of the each buffer */
} __attribute__((packed)) ipc_br_md_t;
/** IPC buffer descriptor */
typedef struct ipc_buffer_desc {
uint64_t rc_addr; /**< msg's rc address */
uint32_t ep_addr; /**< msg's ep address */
uint32_t len; /**< msg len */
uint64_t crc; /**< crc */
} __attribute__((packed)) ipc_bd_t;
/** ipc msg bd ring */
typedef struct ipc_bd_ring_msg {
ipc_br_md_t md;
ipc_bd_t bd[IPC_MAX_DEPTH]; /** Max number of buffers possible in queue */
} __attribute__((packed)) ipc_bd_ring_msg_t;
ipc_bd_ring_msg_t
的实例已在EP上分配,并且RC也可以访问它。该实例用于执行RC和EP之间的IPC通信。
现在,我想实现算法以了解圆形数组是空还是满。由于RC和EP之间没有硬件锁定机制,因此可能存在争用条件,可以通过软件更新变量(主机在生产,而EP在同时消耗)。 我当时在考虑使用一个变量来保持缓冲区计数,该变量将由RC递增,而由EP递减,但是由于可能的竞争条件,我对此想法不满意。
有人可以提出可能的解决方案吗?我确信这是通用问题,并且可以解决,但我不满意。