Shop OBEX P1 Docs P2 Docs Learn Events
Using Semaphore — Parallax Forums

Using Semaphore

Kevin L.Kevin L. Posts: 10
edited 2006-07-31 19:34 in Propeller 1
I have two cogs that access the same memory, one running Spin the other Assembly.

Here is a code segment:

CON
  FIFO_SIZE = 32
  FIFO_MASK = FIFO_SIZE - 1
VAR
  long  fifoSize
  long  fifoHead
  long  fifoTail
  long  fifoBuff[noparse][[/noparse]FIFO_SIZE]
PUB Insert(val)
  if (fifoSize < (FIFO_SIZE - 1))
    fifoBuff[noparse][[/noparse]fifoHead] := val
    fifoHead := (fifoHead + 1) & (FIFO_MASK)
    fifoSize++
Dat
                        
                        mov     t1,par                  'Point to fifoSize
                        rdlong  fifo_size, t1
                        sub     fifo_size, #1
                        wrlong  fifo_size, t1           'update fifoSize--
                        
t1                      res     1
fifo_size               res     1



fifoSize is being use by both routines, but because the the assembly code takes three instructions to update the value, I was wondering if Semaphores should be use to lock out the other routine when one routine is using it.

If I do need to use semaphores, how do I go about inserting the LOCKNEW,·LOCKSET, LOCKCLR code in the assembly?

Thanks.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2006-07-31 19:34
    You don't have to use semaphores to make a fifo if you only have a read pointer and a write pointer. Only one routine changes the read pointer and only one routine changes the write pointer. The pointers wrap around at the end of the buffer. There's always at least one free location in the buffer. The read routine has nothing to read if the pointers are equal. If the write pointer is one less than the read pointer (with wraparound), there's nowhere to put anything. There are no race conditions, because, at worst, the read routine will think there's nothing there while the write routine is in the process of updating its pointer. Similarly, the write routine will think there's no room to put anything while the read routine is in the process of freeing up some space.

    If you want to use semaphores anyway, the instructions work the same in assembly as in SPIN with the previous value of the lock put in the carry flag (if wc is given). In this simple case, better to avoid them. You do need to access two values (read and write pointers) which are word values. Do not write them together as a long value! You can read them together if they're aligned on a long boundary. If the read routine is in assembly, you can put the read pointer first, get the values with one RDLONG, and update the read pointer with a WRWORD, both using the value in the PAR register.
    In SPIN, declare the pointers as a long (say FifoPtrs) and access them with WORD[noparse][[/noparse]@FifoPtrs] for the read pointer and WORD[noparse][[/noparse]@FifoPtrs+2] for the write pointer.

    Post Edited (Mike Green) : 7/31/2006 7:39:12 PM GMT
Sign In or Register to comment.