Shop OBEX P1 Docs P2 Docs Learn Events
MORE about semaphores — Parallax Forums

MORE about semaphores

LoopyBytelooseLoopyByteloose Posts: 12,537
edited 2006-03-08 17:08 in Propeller 1
It seems that the discussion here has been very high level, but for me it is about catching up.

The Propeller seems to be heavily dependent on passing information via the concept of semaphores.· When I search on the internet, I either get a very simple gloss over of the concept or I get tons of discussion in detail.

Can someone narrow it down to how the Propeller mananges to avoid 'crashes' or premature removal of information.· If Parallax plans to teach this material, it might be good to start now.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
"When all think alike, no one is thinking very much.' - Walter Lippmann (1889-1974)

······································································ Warm regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan

Comments

  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-03-05 15:24
    Semaphores are not really a big deal - think of them as signals, similar to semaphores you find along railroad tracks. You may also call them "Flags".

    Propeller uses semaphores to control exclusive access to user-defined resources between multiple cogs. If a block of main memory is used to exchange information between cogs, and this memory block is wider than four bytes, the cogs will have to perform multiple reads or writes to retrieve or save the information. While one cog has access to the memory block, it is important that no other cog is allowed to have access at the same time. Imagine what might happen when a cog modifies data in the memory block while another one is still reading the same block, or what might happen when two cogs are going to write different data to the same memory block at the same time.

    To avoid such collisions, the hub handles specific semaphores. This is a bit similar to locking data records in a multi-user networked database application.

    Yes, I know, this is a very generic explanation of semaphores. To give you a fill insight, I'd have to describe the ins and outs of the hub, the various hub instructions, the vailable semaphores, etc. - IOW I would have to write (or replicate) most of the Propeller manual.

    Kramer, I'm sorry but I can't agree with you that it is a good start now, teaching such material. IMO, we should wait until the Propeller chip is finally released together with the IDE, and the complete set of documentation. This gives us an "official" version we then can talk about, and many (if not most) of the pending questions will be answered by the docs.

    If you look at the threads in this forum section, you will notice that many things discussed are based upon assumptions, rumors, rudimentary information from various sources, etc. - what a waste of time !!!

    We can't blame Parallax for this situation. They are working hard on a new product to be released as soon as possible but I would always accept more delays before the final release when this helps to end up with a better product. With "better", I mean more complete documentation, more sample code, an enhanced, rock-solid IDE, and all other material "around" the Propeller chip. AFAIK, the chip is done, and will not be subject to any changes before release date. So let's all be a bit patient, giving Parllax all the time they need to release a new perfect product.

    Besides this, don't completely forget the SX - there are so many fine applications that can be perfectly handled with a single SX, where the Propeller would really be an "overkill".

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-03-06 11:41
    Thanks Guenther, I am just trying to learn.

    I see Flags in a lot of SX assemby code, but have my doubts that I fully understand them. There is also the 'Multiplexer' in SX that I am trying to come to understand.

    These things are not in your text [noparse][[/noparse]nor should they be] and I am hoping that a additional second text might one day come forth and explain the higher level of mastering the SX.

    Meanwhile, I can be patient. I just entered the HP Printer Contest and I may be too busy with that to do much else. I am trying to sort out a way to print Chinese for it along with some other challenges.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "When all think alike, no one is thinking very much.' - Walter Lippmann (1889-1974)

    ······································································ Warm regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-06 17:01
    There is one critical difference between flags and semaphores. Semaphores have an atomic read and set, you direct the semaphore to be cleared or set and the in the process receive the previous state of the semaphore, you can only read a semaphore by setting or clearing it. Think of it as the Hiesenburg Uncertainty Principle for flags, you can only determine it's state by altering it's state.

    I am fairly certain that semaphore use will not be covered in the documentation other than providing the instructions, examples of its·use are in the applications realm, and this is one topic you can bone up on by doing a little bit of google-sluething.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10

    Post Edited (Paul Baker) : 3/6/2006 5:04:18 PM GMT
  • danieldaniel Posts: 231
    edited 2006-03-06 17:41
    Paul Baker said...
    ...you can only determine it's [noparse][[/noparse]a semaphore's]·state by altering it's state.
    This seems to be overstating the case.· I'm used to having both "test" and "seize" type of operators for semaphores.· Further, some system provide a "seize with timeout" operator.

    Agreed about the rest.

    Daniel
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-06 18:04
    Those are higher level semaphore operations, and none of those are provided for in the propeller. My post was an overstatement of semaphores in general, but not for propeller's semaphores.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10

    Post Edited (Paul Baker) : 3/6/2006 6:07:35 PM GMT
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-03-06 19:07
    Kramer,

    you can also understand flags as one-bit variables with only two possible states "up" or "down", "1" or "0", "true" or "false", or whatever else you might want to call these two states.

    Flags are often used to indicate that a certain event has happened. I know - this is the Propeller section but let me take an example from the SX-world:

    Let's assume an SX program usually executing a loop of instructions in the main program with an ISR in the background handling a serial RS-232 receiver. Here, the receiver code in the ISR could set a "CharAvail" flag when it has received a new byte via the serial line. The main program would check this flag periodically. When it detects that the flag is set, it would read and process the received data byte, and finally clear the flag again in order to "arm" the ISR for another character.

    I agree with Paul that semaphores are special flags following well-defined rules which process is allowed to set them, and which process may clear them, and under what conditions. In case of the Propeller (as far as I have learned), the semaphores are handled by the internal hub operations almost transparent to the cogs in order to make sure that no conflicts occur when two or more cogs try to concurrently access the same common memory locations. The "only" impact on the cogs is that it might take longer (i.e. more "hub-spins") for a cog to perform the desired read or write operation. I have put "only" in quotes as such extended read/write times can influence the cog's timing which might be an issue, depending what the code is designed for running on this specific cog.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-03-07 00:39
    Guenther -

    I am reading with a great deal of interest all of this Propeller semaphore information, and understand all of it, just as you and others have presented it, and as I have learned and used it over the years. One additional point might be worth making here, but I HOPE it doesn't add to any existing confusion.

    What I am about to offer is by no means a hard and fast rule. Perhpas one might call it a common convention. It IS however often found in systems supervisory or I/O control code at the systems level (as opposed to the applications level) and is an important facet in sharing system resources, particularly when one is in a multi-tasking or multi-programming environment. Indirectly, semaphores are the conduit by which successful and nearly uninterrupted system assets can be multiply used amongst the various tasks or programs.

    Semaphones, by their very nature, may be tied either directly or indirectly with or to certain sharable system resources which need to be serially (round-robin) used by multiple parties. The use of semaphores usually provides the necessary exclusivity of/for the shared asset or resource recruitment, without actually involving the asset or resource itself.

    If "you" (the task in question) want exclusive use of a system resource, you must request it by attempting to SET the semaphore. As noted earlier, it is ONLY by setting it that you can come to "know" the prior status of it. If access is granted to you, the status returned from the SET semaphone command will indicate success. Thus, you know that it had to have been FREE, READY or AVAILABLE (as may be appropriate) prior to your request. If you only want to know the status and nothing more, you immediately release it, so that it can re-enter the pool of 'free" or unallocated system resources. It IS a bit ... backwards from the way we tend to think, however.

    My single but largest concern about this or any other semaphore or shared use methodology, in a multi-tasking or multi-programming environment, is the following:

    Is "deadly embrace" (aka "deadlock") possible, and if so how do we avoid it, or do we need to be concerned about it at all?

    Here is the problem described in reasonably good detail, for those not familiar with it:
    http://en.wikipedia.org/wiki/Deadlock

    FWIW, the most common and successful method, albeit perhaps the most system-wise inefficient method that I've seen, is the use of a single, voluntary, master enqueue to a non-existant asset which must succeed before any subsequent (secondary or tertiary) enqueue requests (for the "real" asset) can be made. Denial sets you back to the end of the retry queue, if immediate retry is attempted.

    I'm certainly NOT looking for trouble, where none exists! Thanks for any thoughts you may have.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • danieldaniel Posts: 231
    edited 2006-03-07 04:14
    Me again, Paul.

    I understand your statement, and agree in principle.
    Paul Baker said...
    ...you can only read a semaphore by setting or clearing it...
    This statement bothered me a bit, in that it implies that there is no test of a semaphore.· After re-reading the Propeller Guts posted by Ken Gracey, I think that I also understand why you made this statement.·

    As expected,·the instruction·LOCKSET d WC will seize the semaphore if that semaphore is available.· However, since this instruction is non-blocking, and if the WC option is included on the command, the state of the semaphore before the attempted·seize·is returned·to the calling COG.· In other words, a failure to seize the semaphore is an implied test of that semaphore and allows a COG to know if some other process·holds the semaphore lock.

    In practice, if a COG only needed to determine how to branch based on whether a particluar semaphore was in use, it could call·LOCKSET d WC and if the COG happened to gain possesion of the semaphore, then would have to immediately release it via LOCKCLR d.

    Did I get it right?

    Daniel
  • LoopyBytelooseLoopyByteloose Posts: 12,537
    edited 2006-03-07 04:46
    Okay, this is what I understand.

    It really helps to clarify that Flags are indeed a subset of Semaphores. And that Flags do not retain many of the refinements, but are merely One Bit Variables. In some cases the Flags may be used like more formal systems of semaphores, but that requires the programer to manipulate there access to reading and writing in an appropriate manner.

    It is often too easy to begin to think of two things and synonyms and find out you are in trouble. It seems apparent that Propeller will have its own 'flavor' of semaphore technology and I am willing to wait for a straight foward presentation rather than discuss all that is possible.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    "When all think alike, no one is thinking very much.' - Walter Lippmann (1889-1974)

    ······································································ Warm regards,····· G. Herzog [noparse][[/noparse]·黃鶴 ]·in Taiwan
  • Martin HebelMartin Hebel Posts: 1,239
    edited 2006-03-07 05:06
    I'll throw in my 2 cents... Chip and Jeff said during training they have seldom found a need to use semaphores in their programming, there are usually easier ways to ensure conflicts don't happen, especially since the hub only allows 1 cog to have access to memory at a time.

    -Martin

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Martin Hebel
    Perform an Employer's Survey of Electronic Technologies Graduates· - Click here!
    Personal Links with plenty of BASIC Stamp info
    and SelmaWare Solutions - StampPlot - Graphical Data Acquisition and Control
  • GadgetmanGadgetman Posts: 2,436
    edited 2006-03-07 07:23
    From what I understand, Deadlock situations usually occurs because a programmer screwed up.
    He either didn't understand what he was doing at all, or he failed to take into consideration that a necessary resource might be locked by another task/processor at a critical point.

    It is therefore important to closely examine all tasks that may compete for resources and make certain that they:
    1. Exits gracefully from what they tried to do if they cannot lock a necessary resource, and
    2. Release all currently locked resources to let other tasks finish what they are doing.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Don't visit my new website...
  • Bruce BatesBruce Bates Posts: 3,045
    edited 2006-03-07 07:40
    George -

    I have to respectfully disagree with some of what you said, but in the most general sense. The Parallax Propeller semaphores, and how they seem to operate (I have no dox!), based now on what Daniel just offered, operate exactly as I'd learned them 30+ years ago. Nothing should have changed, and apparetly in this Propeller implementation, it hasn't <whew>.

    Here are some other concepts that _I_ use in differentiating the two (FLAGs and SEMAPHOREs), but I've never seen it stated quite this way. I can own and use a FLAG any way I want, and do with it what I choose to do with it, with impunity. Why can I do that? Because I own my own FLAGs and thus I can manipulate them as I see fit. I can also make my own rules about them and their use. If you want to use MY FLAGs (for some odd reason) you will need to play by MY rules.

    SEMAPHOREs, OTOH and by contrast, are almost always "owned" by the system. I can borrow the USE of one or more of them, but I can NEVER OWN them per se. The SYSTEM makes the rules on their use, I must use system-oriented commands when addressing them, and I MUST obey the rules, if I am to be viewed as one who "plays well with others" smile.gif

    Implicit in saying that above is that FLAGS can and do usually exist in my user space (memory) and SEMAPHORES, per se, usually exist ONLY in SYSTEM space (memory). Therein, if for no other reason, one can not or should not be viewed as a subset of the other. Do they outwardly "look" the same? Yes, often they do, but they are not the same in reality.

    I hope that is helpful and not more confusing. Based on what's also been said I wouldn't hold out a lot of hope for scads of Propeller semaphore documentation.

    Regards,

    Bruce Bates

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    <!--StartFragment -->
  • Guenther DaubachGuenther Daubach Posts: 1,321
    edited 2006-03-07 07:45
    The hub manages a total of eight semaphores (the same number as cogs are available). They are required when exclusive access to user-defined ressources, like blocks of memory) is required by two or more cogs at the same time, and when the blocks are larger than a long, i.e. four bytes, because the cogs need to perform two or more subsequent reads/writes to retrieve or update the memory block in this case. Without exclusive access granted to the cog, there is the possibility that while the cog is reading/writing one portion of the block, another one reds/writes another portion of the block.

    There are four Spin instructions to access the Semaphores though the Hub: LOCKNEW, LOCKRET, LOCKSET, and LOCKCLR. The semaphores are accessed throuth the hub only, therefore, only one cog can have access to them at a time. The Hub manages the eight semaphores, and keeps track which of them are in use, which states they have, and the cogs can check, set, clear, and free semaphores as required.

    With these instructions a cog can check if another cog has set a semaphore to indicate its exclusive access to a certain memory block, and when this is not the case, the cog can set the semaphore to indicate that it has exclusive access now. After the read/write, the cog must reset the semaphore again, and should return it to the semaphore pool by freeing it with a LOCKRET (Id) when it is no longer needed.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Greetings from Germany,

    G
  • inakiinaki Posts: 262
    edited 2006-03-07 13:08
    While waiting for a LOCK, I mean after trying to request a LOCK that is not available...

    Does the HUB put automatically the requesting COG in a waiting state when trying to acquire a LOCK that is busy ?

    Or should I manage the waiting by hand spining actively in a loop checking the LOCK periodically ?
    If this is the case, which is the best way to wait for the LOCK, is there, say, an efficient wait ?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-07 13:11
    daniel said...

    Me again, Paul.

    I understand your statement, and agree in principle.
    Paul Baker said...
    ...you can only read a semaphore by setting or clearing it...
    This statement bothered me a bit, in that it implies that there is no test of a semaphore.· After re-reading the Propeller Guts posted by Ken Gracey, I think that I also understand why you made this statement.·

    As expected,·the instruction·LOCKSET d WC will seize the semaphore if that semaphore is available.· However, since this instruction is non-blocking, and if the WC option is included on the command, the state of the semaphore before the attempted·seize·is returned·to the calling COG.· In other words, a failure to seize the semaphore is an implied test of that semaphore and allows a COG to know if some other process·holds the semaphore lock.

    In practice, if a COG only needed to determine how to branch based on whether a particluar semaphore was in use, it could call·LOCKSET d WC and if the COG happened to gain possesion of the semaphore, then would have to immediately release it via LOCKCLR d.

    Did I get it right?

    Daniel
    Yes, you are correct from what I can surmise. You have to be careful implementing a lock test feature, in that if you check it too often, you are unnessesarily locking up the resource when its not actually being used. This is because for an entire hub rotation the semaphore will be locked without it "truely" being locked (ie semaphore is locked but the resource that it protects is not being used). So just bear in mind, testing a semaphore by lockset/lockclr will introduce a 1 hub rotation latency for processors trying to gain access to the resource. Ideally Id like to see conditional execution based on a semaphore's value (this would be a test w/o effecting it's state) but this isn't possible with the current architecture.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-07 13:24
    inaki said...
    While waiting for a LOCK, I mean after trying to request a LOCK that is not available...

    Does the HUB put automatically the requesting COG in a waiting state when trying to acquire a LOCK that is busy ?

    Or should I manage the waiting by hand spining actively in a loop checking the LOCK periodically ?
    If this is the case, which is the best way to wait for the LOCK, is there, say, an efficient wait ?

    All lock functions are non-blocking, (they wait for access to the semaphore, but continue execution once that access to the hub and semaphore is achieved). You must program to repeatedly check a semaphore.

    Guys, this whole semaphore thing is getting blown up too much. Because the hub serializes access to the central memory, semaphores rarely need to be used. If you've taken programming theory courses, any software which can be reduced to a producer/consumer model does not need any semaphores. It is only when you have multiple producers or multiple modifying consumers (ie removing data from a fifo) of the same data structure are semaphores needed. But·in the majority of applications this does not occur.·

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • inakiinaki Posts: 262
    edited 2006-03-07 20:20
    Paul Baker said...
    inaki said...
    While waiting for a LOCK, I mean after trying to request a LOCK that is not available...

    Does the HUB put automatically the requesting COG in a waiting state when trying to acquire a LOCK that is busy ?

    Or should I manage the waiting by hand spining actively in a loop checking the LOCK periodically ?
    If this is the case, which is the best way to wait for the LOCK, is there, say, an efficient wait ?

    All lock functions are non-blocking, (they wait for access to the semaphore, but continue execution once that access to the hub and semaphore is achieved). You must program to repeatedly check a semaphore.

    Guys, this whole semaphore thing is getting blown up too much. Because the hub serializes access to the central memory, semaphores rarely need to be used. If you've taken programming theory courses, any software which can be reduced to a producer/consumer model does not need any semaphores. It is only when you have multiple producers or multiple modifying consumers (ie removing data from a fifo) of the same data structure are semaphores needed. But·in the majority of applications this does not occur.·
    Well, what about one writer and one reader on the same buffer. There is only a producer and a consumer, however you can still·read the wrong buffer data·if the data is longer than 32 bits, isn't it ?


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-08 06:18
    Read Chip's explanation near the bottom of this page, it's not a problem with buffers when·they are used normally.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10
  • inakiinaki Posts: 262
    edited 2006-03-08 12:50
    I quote Chip here:

    >A LOCK might be the most convenient way to share a buffer resource, say, which spans multiple bytes/words/longs. If you notice in the example cited above, only atomic read/write operations were occuring on a singular byte/word/long >variables in main memory. When you must share many bytes/words/longs, a LOCK can come in handy.



    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Paul BakerPaul Baker Posts: 6,351
    edited 2006-03-08 17:08
    If you look at my analysis of whats occuring a few posts down you'll see there is no issue of single producer-single consumer. The buffer itself is not an issue, because only one writes to it and only one reads from it. Semaphores are not nessesary unless more than one cog is writing to a location. The analysis concerns the pointers to the head and tail of the buffer. And again the pointer to the head of the buffer is only modified by the consumer, and the pointer to the tail of the buffer is only modified by the producer. The only issue that arises is that when the buffer is nearly empty or nearly full, the buffer could come back with an indication it is full or empty when it actually isn't. But this just pushes the deffered action to the next access, and using a semaphore will not change this behaviour. You don't have to believe me, you can implement semaphores if you will sleep better at night, but all it will accomplish is consume extra processor cycles, consume an uneeded resource (semaphore), and generate a whole bunch of unessesary "try again" situations when a cog tries to access the buffer.

    The way·I read·the portion of Chip's post you quoted was that he didn't agree that my example needed a·semaphore, but he was being polite in saying there may be situations one may want to use a semaphore when a direct share is occuring (which my example is not such an instance).

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    ·1+1=10

    Post Edited (Paul Baker) : 3/8/2006 5:19:03 PM GMT
Sign In or Register to comment.