2

我试图在我的软件中计时一些函数调用来比较不同的实现。

为了获得所需的时序,我正在使用 RAII 结构在函数的开头和结尾读取我的 ARM A9 处理器的 PCCNTR 寄存器。

问题是编译器不尊重我的对象的构造破坏顺序。这是编译器中的错误还是允许的优化?

编译器是一个arm-none-eabi-g++ (Sourcery CodeBench Lite 2012.03-56) 4.6.3

#define GET_TICK(var) \
  asm volatile (\
      "mrc p15, 0, %0, c9, c13, 0;"\
      : "=r" (var)\
      );

struct tick{
  uint32_t &start;
  uint32_t &end;

  tick(uint32_t& s, uint32_t &e) 
    :start(s)
     , end(e)
  {
    GET_TICK(start);
  }

  ~tick(){
    GET_TICK(end);
  }
};

bool mailbox::send(uint32_t &start, uint32_t &end, uint32_t msg){
  tick t(start, end);
  /* now start should have the current timestamp */
  {
    Spinlocker lock(SPINLOCK_LOCK_REG_0); // RAII mutex locker
    uint32_t cnt = mb_msg_max_count + 1;
    do{
      cnt = count();
      if(cnt >= mb_msg_max_count){
        lock.release();
        lock.get();
      }
    }while(cnt >= mb_msg_max_count);
    *(first_message + cnt) = msg;
    inc_counter(); // free function
    MEM_BARRIER; // #define asm volatile("dsb st;")
    /* spinlock should be destroyed but it is only after t */
  }

  return true;
  /* now end should have the current timestamp */
}

生成的汇编代码:

83000a64 <mailbox::get(unsigned long&, unsigned long&)>:
83000a64: b530        push  {r4, r5, lr}
83000a66: 4604        mov r4, r0
83000a68: 680b        ldr r3, [r1, #0]
83000a6a: b083        sub sp, #12
83000a6c: 4615        mov r5, r2
83000a6e: ee19 2f1d   mrc 15, 0, r2, cr9, cr13, {0}
83000a72: f44f 41d0   mov.w r1, #26624  ; 0x6800
83000a76: 601a        str r2, [r3, #0]
83000a78: a801        add r0, sp, #4
83000a7a: f6c4 210f   movt  r1, #18959  ; 0x4a0f
83000a7e: f000 f871   bl  83000b64 <Spinlocker::Spinlocker(unsigned long volatile*)>
83000a82: 6823        ldr r3, [r4, #0]
83000a84: 681a        ldr r2, [r3, #0]
83000a86: b18a        cbz r2, 83000aac <mailbox::get(unsigned long&, unsigned long&)+0x48>
83000a88: 6819        ldr r1, [r3, #0]
83000a8a: 1e48        subs  r0, r1, #1
83000a8c: 6018        str r0, [r3, #0]
83000a8e: f3bf 8f4e   dsb st
83000a92: 6864        ldr r4, [r4, #4]
83000a94: 1e51        subs  r1, r2, #1
83000a96: f854 4021   ldr.w r4, [r4, r1, lsl #2]
83000a9a: ee19 0f1d   mrc 15, 0, r0, cr9, cr13, {0} <- timer is read before Spinlock is destroyed. Is this allowed?
83000a9e: 6028        str r0, [r5, #0]
83000aa0: a801        add r0, sp, #4
83000aa2: f000 f885   bl  83000bb0 <Spinlocker::~Spinlocker()> <- Shouldn't this be done before issuing the MCR assembly?
83000aa6: 4620        mov r0, r4
83000aa8: b003        add sp, #12
83000aaa: bd30        pop {r4, r5, pc}
83000aac: a801        add r0, sp, #4
83000aae: f000 f86b   bl  83000b88 <Spinlocker::release()>
83000ab2: a801        add r0, sp, #4
83000ab4: f000 f86e   bl  83000b94 <Spinlocker::get()>
83000ab8: 6823        ldr r3, [r4, #0]
83000aba: 681a        ldr r2, [r3, #0]
83000abc: 2a00        cmp r2, #0
83000abe: d1e3        bne.n 83000a88 <mailbox::get(unsigned long&, unsigned long&)+0x24>
83000ac0: e7f4        b.n 83000aac <mailbox::get(unsigned long&, unsigned long&)+0x48>
83000ac2: bf00        nop  
4

0 回答 0