Shop OBEX P1 Docs P2 Docs Learn Events
Does anyone use LOCKs??? — Parallax Forums

Does anyone use LOCKs???

cgraceycgracey Posts: 14,253
edited 2009-02-06 04:24 in Propeller 1
Do any of you use the LOCK mechanisms for any purpose? While they are theoretically useful, I've never used them in any application and I've never seen anyone else use them. I'm just wondering if they would be missed in the next Propeller.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


Chip Gracey
Parallax, Inc.
«1

Comments

  • william chanwilliam chan Posts: 1,326
    edited 2009-01-23 07:50
    I also never used locks.
    I just make sure only 1 cog writes to any data, the other cogs only read.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    www.fd.com.my
    www.mercedes.com.my
  • mirrormirror Posts: 322
    edited 2009-01-23 08:07
    Yeah, I seem to remeber seeing them in some multi-cog-use FIFO thing.

    Whether or not they were actually required ... well I don't know.

    Personally, I've never used the locks, if they no longer existed I wouldn't miss them.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • AleAle Posts: 2,363
    edited 2009-01-23 08:09
    Chip,

    I have an application that uses 2 propellers. One of them takes some samples from an ADC and calculates FFT and displays the results. For that I need 32k RAM (all the HUB) and some extra RAM that has to be shared. I though using locks to signal a few states. I'll probably go that route. This is not a commercial application, just a custom machine for my thesis. As soon as I publish it I'll post it here. It uses the uniqueness of the propeller. Well, what I wanted to say was: if comm channels existed between COGS in addition to shared memory (but not as only comm medium) some things could be done easily, may be more in parallel (i.e. no waiting for a variable to change and wasting power) without putting so much pressure on HUB memory and variables that point to shared HUB addresses.
    Not to start another propeller vs. xmos thread but: Working a bit with the XMOS where shared memory is discouraged and everything should be done with channels, I started to appreciate more the benefits of shared memory. I though of new ways of using the parallelism the propeller brings to my application. May be a small channel. just a 1 or 2 longs buffer could open a very interesting applications. I have no idea how feasible that would be.

    Bottom line: when I may use them in this particular place... I will hardly miss them. The channels otoh seem like a very useful addition, I if could choose.
  • Cluso99Cluso99 Posts: 18,069
    edited 2009-01-23 08:20
    I have never used them, nor seen a requirement to do so. However, I use a mechanism to synchronise two cogs where I set a hub location by one cog and clear it with the other. This works efficiently and is foolproof (because you may not clear it until it has been set by the other, and visa versa).

    I did extensive programs in the 70's & 80's using a minicomputer with similar concepts to the Propeller (hub and cog memory and simulated multiprocessors). Software locks were used.

    So, to answer your question, I will not miss them.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Links to other interesting threads:

    · Prop Tools under Development or Completed (Index)
    · Emulators (Micros eg Altair, and Terminals eg VT100) - index
    · Search the Propeller forums (via Google)

    My cruising website is: ·www.bluemagic.biz
  • BaggersBaggers Posts: 3,019
    edited 2009-01-23 08:26
    I've never used LOCKs either [noparse]:D[/noparse] I'd go with the idea of if you have another use for the instruction space, lose them and use it [noparse]:D[/noparse] besides, I'm sure it'll be something mega important since you're asking in the first place [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    http://www.propgfx.co.uk/forum/·home of the PropGFX Lite

    ·
  • cgraceycgracey Posts: 14,253
    edited 2009-01-23 08:32
    Thanks for your input, so far,·Everyone.
    Baggers said...
    I've never used LOCKs either [noparse]:D[/noparse] I'd go with the idea of if you have another use for the instruction space, lose them and use it [noparse]:D[/noparse] besides, I'm sure it'll be something mega important since you're asking in the first place [noparse]:)[/noparse] It's just about keeping things tidy.·It's good to reduce unnecessary silicon, instructions, documentation, mindshare, etc.
    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • BaggersBaggers Posts: 3,019
    edited 2009-01-23 08:54
    very true, cluttered desk and all that lol

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    http://www.propgfx.co.uk/forum/·home of the PropGFX Lite

    ·
  • Timothy D. SwieterTimothy D. Swieter Posts: 1,613
    edited 2009-01-23 10:58
    I haven't had a situation where I have considered the locks yet. Of course, I don't think most of the stuff I do is intense enough to rank my opinion among others here. Either way, I usually prefer software handling of which cog has rights to which resources.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Timothy D. Swieter, E.I.
    www.brilldea.com - Prop Blade, LED Painter, RGB LEDs, uOLED-IOC, eProto for SunSPOT, BitScope
    www.tdswieter.com
  • RaymanRayman Posts: 14,826
    edited 2009-01-23 13:00
    I've never had the need for them in anything I've done so far.
  • heaterheater Posts: 3,370
    edited 2009-01-23 13:08
    I almost asked that question here the other day, just out of curiosity.

    Given that I only have one serious Prop project, PropAltair, and it does not need locks the answer is no.

    Then I started thinking......

    Back in the day when I used to program rack fulls of 16 bit CPUs with shared memory cards the only lock mechanism we had on those custom CPUs was a LOCK EXCHANGE instruction. That is: the read and the write of an exchange operation between CPU register and RAM could not be interleaved with any other bus activity from other processors. Using that to test and set a semaphore in shared RAM any amount of RAM or other resource on the bus could be "protected".

    Things got interesting when I was supplied with prototype CPUs without the lock and no one told me....

    Looking at the Intel x86 architecture we see the same lock idea but extended slightly so the lock works with more instructions, namely:
    * Bit test and change: BTS, BTR, BTC.
    * Exchange: XCHG.
    * Two-operand arithmetic and logical: ADD, ADC, SUB, SBB, AND, OR, XOR.
    * One-operand arithmetic and logical: INC, DEC, NOT, and NEG.

    I have a felling people only ever use the "LOCK" prefix with XCHG on x86 anyway.

    Conclusion: Looks like one could throw away the Props locks and all that checking out business and replace it with a LOCK EXCHAGE hubop, say LXLONG, LXWORD, or LXBYTE or all of them.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-01-23 14:41
    I am only beginning with the Propeller and have been involved in getting various devices and sensors working independantly. I anticipate using locks as 1 bit semaphores in the main program rather than using bytes or longs just to test for status of various states. Since they are available to both spin or pasm, it seems to be the most logical method of communications between routines. I still have more research to do though.
  • KyeKye Posts: 2,200
    edited 2009-01-23 14:55
    Heh, I actually tried to use locks once. But when I figured out it was impossible to read them, only write them and get the previous state, I decided that they were completely useless. Since I would need to have about 4 to 5 asm instructions to just use them. Also, I dislike how you have to keep count on which cog is using them anyway.

    Having the locks also makes you want to use coginit istead of cognew, which is a bad idea anyway. Beacuse as I said you need to keep count of what is using them.

    Now, if you could like literary assign memory locations to be read only or write only for certain cogs that would be interesting.

    But, yeah, I never use locks. Waste of an opticode if you ask me.

    Whats easier to use instead of locks is simply making a byte that gets set to true ($FF)·or false ($00)·when you need to synchronize stuff. Or better yet making everything FIFO buffered so you can transfer lots of data predictably.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Nyamekye,
  • Mark SwannMark Swann Posts: 124
    edited 2009-01-23 16:02
    I believe I recall seeing some objects in the OBEX that use LOCKs
  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-23 16:03
    Although LOCKs are rarely needed in practical programming, an indivisible TEST_and_SET operation is absolutely necessary and can be done much more simply if you can do a read/write hub memory cycle. It only requires that WRxxxx optionally set its flag bits (Z at least) based on the content of the memory location addressed, then sets the location to the destination value supplied, all on one exclusive hub access.

    You need the TEST_and_SET because it's always possible (but unlikely) that another cog can modify your flag location between your TEST and MOV if you try to implement a lock that way. The reason we've needed them rarely is that most everything we do with multiple cogs involves the special case of the single producer / single consumer where only one cog modifies (fills) the structure, the other cog just accesses (empties) it and this special case does not require a semaphore.
  • heaterheater Posts: 3,370
    edited 2009-01-23 16:19
    Mike, that's ingenious. A kind of locked exchange but with result in the flags. Saves having to find a new opcode. Great.

    If only there were a way to include a "wait" on such a semaphore so that a COG waiting on access to some data would go low power.

    Sounds like Chip has got a cunning and devious plan up his sleeve and would like to make space for it by removing the locks.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • mparkmpark Posts: 1,305
    edited 2009-01-23 16:24
    I used a lock for the first time just last week in my wavetable music synthesizer. It came in very handy.

    With multiple processors, some sort of locking mechanism is necessary, imho. Don't get rid of locks unless you can provide a functional equivalent.
  • Mark SwannMark Swann Posts: 124
    edited 2009-01-23 16:27
    I have found LOCKs usefull. I used Locks in a secret super-fast version of Float32 that I have been keeping hidden.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-23 16:55
    Yes, I use locks. As an example, I wrote a heap manager that allowed multi-cog access to one or several heaps. This would have been impossible without a hardware locking mechanism. I designed it with a single hardware master lock, with individual software locks for the various heaps. Here's how the master- and sub-locking was implemented:

    [b]PUB[/b] lock(heap) | lock_mask
    
    '' Lock (suspend other operations on) the given heap (one-based heap index).
    
      [b]if[/b] running [b]and[/b] heap > 0 [b]and[/b] --heap < MAXHEAPS [b]and[/b] heap_users[noparse][[/noparse]&#173;heap&#093;
                                                            'Legitimate call?
        lock_mask := 1 << heap                              '  Yes: Create a mask from the heap number.
        [b]repeat[/b]                                              '       Wait for heap to be unlocked...
          [b]repeat[/b] [b]while[/b] [b]lockset[/b](master_lock)                 '       First, lock the main gate.
          [b]if[/b] [b]not[/b] heap_lock & lock_mask                      '       Is heap locked?
            [b]quit[/b]                                            '         No:  Okay to exit loop and proceed.
          [b]lockclr[/b](master_lock)                              '         Yes: Unlock the main gate and try again.
        heap_lock |= lock_mask                              '       Heap was unlocked, so lock it with main gate still locked.
        [b]lockclr[/b](master_lock)                                '       Now unlock the main gate.   
        [b]return[/b] [b]true[/b]                                         '       Return success.
      [b]else[/b]
        [b]return[/b] [b]false[/b]                                        '  No:  Return failure.
    
    [b]PUB[/b] unlock(heap) | lock_mask
    
    '' Unlock heap (one-based heap index).
    
      [b]if[/b] running [b]and[/b] heap > 0 [b]and[/b] --heap < MAXHEAPS [b]and[/b] heap_users[noparse][[/noparse]&#173;heap&#093;
                                                            'Legitimate call?
        lock_mask := 1 << heap                              '  Yes: Create a mask from the heap number
        [b]repeat[/b] [b]while[/b] [b]lockset[/b](master_lock)                   '       Lock the main gate.
        heap_lock &= !lock_mask                             '       Unlock the heap.
        [b]lockclr[/b](master_lock)                                '       Unlock the main gate.   
        [b]return[/b] [b]true[/b]                                         '       Return success.
      [b]else[/b]
        [b]return[/b] [b]false[/b]                                        '  No:  Return failure.
    
    
    


    -Phil
  • lonesocklonesock Posts: 917
    edited 2009-01-23 17:23
    I'm working on a project right now where I was planning on using LOCKs. Here's the scenario:

    * cogA writes some data to a circular buffer, and updates a table with some info about the last data written, flagging it as new data
    * cogB checks the table for new data and may or may not use some data, but either way flags in the table that it is not longer needed by cogB
    * cogC checks the table for new data, then once enough data is collected dumps it to a SD card for storage and flags the data in the table as no longer needed by cogC
    * cogA may only overwrite a section of the buffer if the data there is flagged as unnecessary by both cogs B & C

    Also note that the situation is more complex than above, as multiple cogs get to play the roles of A,B,C.

    Is there is a failsafe way to handle something like this without LOCKs?

    thanks,
    Jonathan

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    lonesock
    Piranha are people too.
  • cgraceycgracey Posts: 14,253
    edited 2009-01-23 17:59
    It is not possible to use a location in hub RAM as a lock, since it would take TWO hub cycles to read,·(modify,)·then write any location. This would disrupt the single-cycle determinancy that now exists. This is why LOCKs were implemented as separate entities. Checking them out and·coordinating their # among cogs is a pain, but if you want to hard-code the LOCK # usage, there's no need to check out and return locks. Just write your code to use certain ones.

    I think that in the current Propeller, due to hub RAM·limitations which dictate the type of applications written, LOCKs are not commonly needed. With 256K of RAM affording more system-level apps, though, there will likely be a more frequent need for them. So, I think I'll leave them in, as they are.

    Oh, and about not having a mechanism to just read LOCKs... The conundrum is that if you read one, but don't request control (LOCKSET/LOCKCLR)·at the same time, your result is meaningless, since on the very next cycle, that LOCK's·status might change via another cog's LOCKSET/LOCKCLR activity, rendering your recent observation inaccurate. So, LOCKs are for participants, not for bystanders.

    Does anyone think that 8 LOCKs are not enough? Would 16 be better?


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.

    Post Edited (Chip Gracey (Parallax)) : 1/23/2009 6:18:15 PM GMT
  • awesomeduckawesomeduck Posts: 87
    edited 2009-01-23 18:13
    I agree with Mike Green, Test and Set instruction that is atomic is very useful. It enables you to continue processing in a loop then come back for another test instead of just hanging. While it doesn't seem that there are a lot of people saying they use the locks, I think removing hardware support for mutual exclusion on a multicore processor would be a mistake. Maybe the locks are not needed, but some hardware support for sharing resources seems very valuable, and if the next generation Prop has broader appeal in the market the need may be more apparent.
  • Mark SwannMark Swann Posts: 124
    edited 2009-01-23 18:18
    Chip,

    Since LOCK ID check-out and check-in is not really required (I did not know that), can that function be eliminated to save op-code space? I would not mind defining my own LOCK IDs.

    Mark
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-23 18:21
    Using a hardware master lock/software sub lock scheme, as many locks as there are cogs would be adequate. Too, it would be rare in any app that every cog be managing a shared resource. Although the master-/sub-locking approach is a bit cumbersome, I'd probably still use it if more locks were available, since one can't know what the other cogs might require.

    -Phil
  • cgraceycgracey Posts: 14,253
    edited 2009-01-23 18:31
    Mark Swann said...
    Chip,

    Since LOCK ID check-out and check-in is not really required (I did not know that), can that function be eliminated to save op-code space? I would not mind defining my own LOCK IDs.

    Mark
    We've got plenty of opcode space, so that's not a problem. I think I will leave in the LOCK checkout/return mechansim, though, so that people can still use LOCKs like they use cogs via COGNEW. Otherwise, it would make integration of LOCK-using objects much more difficult.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    Chip Gracey
    Parallax, Inc.
  • Chuck RiceChuck Rice Posts: 210
    edited 2009-01-23 19:25
    I have 4 propellers communicating serially. One is the communications board and the other three drive various robot functions. I use the locks on the communications propeller to ensure that traffic from one board does not clobber traffic from another when logging packets to an XBEE (serial connection to my laptop).
  • mctriviamctrivia Posts: 3,772
    edited 2009-01-23 21:57
    i have not used locks myself yet but having an upper layer of cog ram with limited capabilities would be usful. say if you could only access it through special mov op codes. if you designated specific registers as the target or sorce you could make 4 bits the sorce and the remaining 14 the destination.
  • Erik FriesenErik Friesen Posts: 1,071
    edited 2009-01-24 00:06
    I use locks for accessing the same I2C memory from different cogs. I suppose I could work without them but they are handy.
  • shanghai_foolshanghai_fool Posts: 149
    edited 2009-01-24 00:47
    Chip Gracey (Parallax) said...

    Oh, and about not having a mechanism to just read LOCKs... The conundrum is that if you read one, but don't request control (LOCKSET/LOCKCLR)·at the same time, your result is meaningless, since on the very next cycle, that LOCK's·status might change via another cog's LOCKSET/LOCKCLR activity, rendering your recent observation inaccurate. So, LOCKs are for participants, not for bystanders.


    I think I can still use locks in my scenario. I have a main routine that repeats very fast and monitors other cogs that operate asynchronoulsy. When a routine has new data, it sets a lock. The main routine then tests (lockclr) for new data but skips if there is none. As long as different routines can set/clear the lock, this should work.

    i.e.
    My main routine routine repeats every 1-2ms. New data can be from GPS (200ms), RC receiver (15ms), or ADC (5ms). I only need to do something when the data changes. So each routine sets a lock when it has new data and the main routine only processes when new data is available. It just seems easier than reading a hub memory location to test.

    I am still working on the individual routines so this test will have to wait until next week.

    Donald
  • Carl HayesCarl Hayes Posts: 841
    edited 2009-01-24 01:15
    In a multiprocessing environment, or even in a merely multiprogramming environment, some kind of locking mechanism is essential.· However, really you need only a single hardware-implemented lock.· If one needs locks for multiple resources, it is easy to make one's own software locks·with a universal hardware·lock and a tiny bit of common storage.
    ·
    One should implement two logical sorts of locks, though:· shared and exclusive.·

    One obtains a shared·lock for the resource when one wishes to read it, and doesn't want anyone writing it·at the same time.· Many tasks (programs) can hold a shared lock simultaneously, and read the locked resource simultaneously.·

    One obtains an exclusive lock when one intends to·change the resource and·doesn't want anyone else to try to read or write it·at the same time.

    With a single exclusive hardware-implemented lock, one can make one's own locks for any number of resources, using one·shared-storage bit per lock if one needs only exclusive locking, perhaps a byte if one needs both kinds (you need a count of how many tasks are sharing).· This is really easy, and I leave the details as an intellectual exercise for the reader, pointing out only that one obtains the hardware lock (waiting if necessary) whenever one obtains a software lock, and immediately releases the hardware lock.· If one designs it right, one needn't obtain the hardware lock in order to free one's exclusive software locks.

    A test-and-set instructiion, as in the IBM 360/370/390 mainframes and their successors, is an adequate substitute for locks in many cases, but requires considerably more expertise to use correctly.· The TS instruction fell into general disuse early in the history of OS/360, but was retained in the hardware for compatibility with older programs.· (Microsoft could learn a lot by a study of upward compatibility in the 360/370/390 series, by the way.· Through decades of rapid evolution in mainframes, IBM retained upward compatibility that was essentially complete for application programs.· By contrast, every time MS brings out a new release, old programs stop working.· That never happened with 360/370/390 applications.)

    Anyway, I guess a TS instruction would be nice, but a hardware lock is better -- and only one hardware lock is sufficient.

    The necessary instructions are :· (1)· Obtain the hardware lock (with an implied wait); (2) Free the hardware lock; and optionally (3)·Test to see if it's available.·The instruction for obtaining it may usefully have two variants:· wait if it's not available, or set a condition if it's not available.· If everyone's well behaved, the wait option is preferable in most cases, for no one will keep the hardware lock·longer than a few microseconds.

    There are hints and kinks to using locks, most of which are cautions to observe when one needs to hold more than one lock at a time, in order to avoid the situation in which I have A and need also B,· and you have B and need also A.· If I wait for B and you wait for A, we both wait forever.· In the mainframe world one term of art for this is "deadly embrace".

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    · -- Carl, nn5i@arrl.net

    Post Edited (Carl Hayes) : 1/24/2009 1:23:51 AM GMT
  • Chuck RiceChuck Rice Posts: 210
    edited 2009-01-24 04:52
    Carl Hayes said...
    A test-and-set instructiion, as in the IBM 360/370/390 mainframes and their successors, is an adequate substitute for locks in many cases, but requires considerably more expertise to use correctly. The TS instruction fell into general disuse early in the history of OS/360, but was retained in the hardware for compatibility with older programs. (Microsoft could learn a lot by a study of upward compatibility in the 360/370/390 series, by the way. Through decades of rapid evolution in mainframes, IBM retained upward compatibility that was essentially complete for application programs. By contrast, every time MS brings out a new release, old programs stop working. That never happened with 360/370/390 applications.)

    While test and set is not used much, the compare and swap that replaces it is based on the same idea, it just works on a full word (or doubleword) instead of testing a single bit. I think that the compare and swap would be a better model to follow than test and set. See: publibz.boulder.ibm.com/epubs/pdf/dz9zr006.pdf for the difference details.
Sign In or Register to comment.