位域结构体多线程访问出错的问题分析

  位域结构体能节省一些内存空间,但是使用不当会产生race conditions,导致程序异常,下面简要分析错误产生的原因和解决方案。

 

  首先定义一个简单的bit field结构体。

+struct bit_filed {

+       unsigned a : 1;

+       unsigned b : 1;

+       unsigned c : 1;

+       unsigned d : 1;

+       unsigned e : 1;

+       unsigned f : 1;

+       unsigned g : 1;

+       unsigned h : 1;

+} val;

+

+

+int test_bitfield1(void)

+{

+       val.a = 1;

+       return 0;

+}

+

+int test_bitfield2(void)

+{

+       val.b = 1;

+       return 0;

+}

 

   然后反汇编

ffffffc0005421e8 <test_bitfield1>:

ffffffc0005421e8:       f0000fa1        adrp    x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>

ffffffc0005421ec:       f9426821        ldr     x1, [x1,#1232]

ffffffc0005421f0:       52800000        mov     w0, #0x0                        // #0

ffffffc0005421f4:       39400022        ldrb    w2, [x1]

ffffffc0005421f8:       32000042        orr     w2, w2, #0x1

ffffffc0005421fc:       39000022        strb    w2, [x1]

ffffffc000542200:       d65f03c0        ret

 

ffffffc000542204 <test_bitfield2>:

ffffffc000542204:       f0000fa1        adrp    x1, ffffffc000739000 <__hyp_idmap_text_end+0x4800>

ffffffc000542208:       f9426821        ldr     x1, [x1,#1232]

ffffffc00054220c:       52800000        mov     w0, #0x0                        // #0

ffffffc000542210:       39400022        ldrb    w2, [x1]

ffffffc000542214:       321f0042        orr     w2, w2, #0x2

ffffffc000542218:       39000022        strb    w2, [x1]

ffffffc00054221c:       d65f03c0        ret

  可以看到,这种情况下最小访存单元是一个byte,在上面标黄的指令中会从内存读取一个副本,如果test_bitfield1在执行黄色指令后被test_bitfield2强行插入,test_bitfield2执行完毕后test_bitfield1继续执行,

在这种情况下test_bitfield2所做的修改会被丢弃。

  所以平时如果需要用到bit filed struct, 需要注意:

  1. 不同位域变量是不是在一个storage unit(可以通过反汇编查看)里面

  2. 有没有被并发访问的可能。

 

  下面这篇文章分析了这个问题并给出了几种解决方案:

  1. One approach for preventing data races in concurrent programming is to use a mutex
  2. Another approach is to insert a non-bit-field member between any two bit-fields to ensure that each bit-field is the only one accessed within its storage unit.
  3. Use distinct non-bit-field members of a structure

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。