Shop OBEX P1 Docs P2 Docs Learn Events
Sharing locks between PASM and Spin — Parallax Forums

Sharing locks between PASM and Spin

Hello,

I'm trying to share a lock between a SPIN and a PASM cog.

PASM code:
:loop         waitcnt   asm_cnt,asm_cycles              'wait for next CNT value (timing is determinant after WAITCNT)
              call #S_Lin2Alaw
              mov pbuf, par_x

         
              cmps counter, #16 wz
      if_z    call #setFlagBufA
              cmps counter, #16 wz, wc 'setFlagBufA overwrites c so we have to cmp again
 if_z_or_c    jmp #:write               'counter <= 16 -> write
              cmps counter, #32 wz,wc 
     if_z     mov counter, MAX_VAL           'counter == 32 -> counter:= 0, set flag
     if_z     call #setFlagBufB 
                     
:write      add pbuf, counter
              wrbyte aval, pbuf     'write byte to buf
                                    
              adds counter, #1
           
              call #S_Alaw2Lin 'in:aval out: r1

              [...]
              jmp    #:loop



setFlagBufA 
:l                  lockset c_sem wc
       if_c         jmp #:l
                    wrbyte _1, c_flag         '1 means a is full
                    lockclr c_sem
setFlagBufA_ret     ret

setFlagBufB
:l                  lockset c_sem wc
       if_c         jmp #:l
                    wrbyte _2, c_flag         '2 means b is full
                    lockclr c_sem
setFlagBufB_ret     ret


Spin code:
  repeat while(True) 
    waitcnt(2_000_000 + cnt)
    repeat until not lockset(sem)
    
    temp := flag_buf_full[0]
        if (temp <> 0)
            prinarr(@flag_buf_full, 1, string("flag_buf_full="))
            byte[flag_buf_full] := 0               
    lockclr(sem)


c_sem and sem contain the same values.
It seems like the Spin part does not clear the lock, because the PASM cog is stuck forever. When i remove the lock-code from the Spin code however, the PASM code works as expected.
The PASM loop takes 10_000 cycles.

Does anybody have an idea what could have gone wrong?

Thanks!

Comments

  • Found the problem: 10_000 cycles is too little. The time it takes for the PASM cog to acquire the lock is bigger than 10_000, this leads to asm_cnt being smaller than cnt.
  • At first glance, the given code looks okay. However, to reduce the amount of time the lock is held in spin, could you do something similar to:
      repeat while(True) 
        waitcnt(2_000_000 + cnt)
        repeat until not lockset(sem)
          
        temp := flag_buf_full[0]
        byte[flag_buf_full] := 0               
       
        lockclr(sem)
       
        if (temp <> 0)
          prinarr(@temp, 1, string("flag_buf_full="))
    
  • @Seairth:
    That's exactly what I just tried. prinarr and some other function that is called while the lock is held were taking too much time. It's working now.
    Thank you!
Sign In or Register to comment.