1
#define MEMBER_OFFSET(c_type, mbr_name) ((uint32_t) (uintptr_t)(&((c_type*)0)->mbr_name))
#define CACHE_ALIGN __attribute__((aligned(EF_VI_DMA_ALIGN)))

struct pkt_buf {
    struct pkt_buf* next;
    ef_addr dma_buf_addr;
    int id;
    uint8_t dma_buf[1] CACHE_ALIGN;
};


struct pkt_buf* pkt_bufs [N_BUFS];

for( i = 0; i < N_BUFS; ++i ) {
    struct pkt_buf* pb = (struct pkt_buf*) ((char*) p + i * 2048);
    pb->id = i;
    pb->dma_buf_addr = ef_memreg_dma_addr(&memreg, i * 2048);
    pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf); // why do this?
    pkt_bufs[i] = pb;
}

Question> 我理解MEMBER_OFFSET的意思。但是,我没有得到以下行的含义:

pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf)

基本上, 的值MEMBER_OFFSET(struct pkt_buf, dma_buf)是成员变量dma_bufin的字节偏移值struct pkt_buf

4

1 回答 1

0

此代码使用“struct hack”的变体,后来被“灵活数组成员”取代。显示的代码中既没有memreg也没有p定义,函数(宏?)也没有定义ef_memreg_dma_addr(),所以这里有猜测的元素。

但是,它正在进行计算,如果

pb->dma_buf_addr = ef_memreg_dma_addr(&memreg, i * 2048);

设置pb->dma_buf_addr指向 a 的开头struct pkt_buf,然后在赋值之后:

pb->dma_buf_addr += MEMBER_OFFSET(struct pkt_buf, dma_buf);

pb->dma_buf_addr指向dma_buf数据包中数组的地址。使用的i * 2048建议p是将连续的内存块分成 2 KiB 页,并且 DMA 缓冲区紧跟在 ID 字段之后。

于 2017-07-14T21:54:01.253 回答