LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Occurence doesn't wait: 'ignore previous (T)' bug

Solved!
Go to solution

Hi all,

 

I always wondered why help on occurance states that you should not use them.. Just ran into a bug using them, just like to share this with all of you as you may run into this as well.

 

What did I do:

1) I used occurrence on vi's that are dynamically loaded

2) I terminate this vi either on wait for occurance time out OR some piece of code ends

3) I set the 'ignore previous' flag to false (as the wait may execute later then setting the occurrence)

 

Now what happens is something rolfK mentioned, being it without adding details. If 'set occurrence' is called after 'wait for occurrence' is no longer called, the occurence is 'cached' until the next time the vi is run. Also adding multiple 'wait for occurrences' on a vi gives multiple issues.

 

As far as I could track down, the issue is that any 'create occurence' instance creates an occurence instance when the vi is loaded/recompiled, not when the vi is executed. Any 'wait for occurence' Vi evaluates this occurrence as soon as the Vi is run, not when it is supposed to run as intended by dataflow.

 

As long as the 'ignore previous' flag is set to true (default) and there is only one 'wait for occurance' instance, all is fine. However otherwise strange effects may happen.

 

See attached vi to play with this.

 

As a solution I plan to make some wrappers around the notifier to implement my own version of the notifier as it is such a nice and clean way to synchronise stuff or change my implementation so the 'ignore previous' flag can always be true.

 

beuvink_0-1659366246221.png

 

 

-- FYI --

Not a new topic, just added with a new title to make it easier to find. Also see

 

https://forums.ni.com/t5/LabVIEW/Occurrences-vs-Notifications/m-p/152098

rolfK: "Because they support data and have a higher level interface which is
somewhat easier to understand. Also occurrences have a little side
effect in that the occurrence can stay in a triggered state for one Wait
Occurrence evaluation when you restart a VI."

 

https://forums.ni.com/t5/LabVIEW/Community-Nugget-1-29-2007/m-p/469822#M226491

A way to work around.. but probably better just to avoid them at all..

0 Kudos
Message 1 of 11
(330 Views)

I've never had to use occurrences before.  Either my code is too simple to need them, or I'm just so used to controlling things with dataflow that I never ran across a need to use them - or both explanations, even.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 2 of 11
(313 Views)
Solution
Accepted by beuvink

Occurrences are a leftovers from the stone age of LabVIEW and probably just retained for backwards compatibility. They were sometimes useful before we had the event structure!

 

Don't use them for new designs and use notifiers as the help correctly states.

 

altenbach_0-1659368775880.png

 

0 Kudos
Message 3 of 11
(308 Views)

Fully agree that this is some stone-age LabView function and their operation -including bugs- must be kept as-is for compatibility.

 

Don't fully agree that help states they shouldn't be used. 'Encourage to use something else' is a bit vague and there is no explanation why they shouldn't be used. It is also still in the default template and didn't even get another colour like some other 'obsolete' functions received.

 

Fully disagree that events/notifiers are a good replacement. I can't find a cleaner & easier way to implement the following:

beuvink_0-1659369474557.png

 

Fully agree that the above code is not good practice.. not that code isn't good but only because NI says you shouldn't do this..

0 Kudos
Message 4 of 11
(293 Views)

For me the biggest confusion about them came about when I discovered that an "Occurrence" from the "Generate Occurrence" node was essentially a block diagram constant and not code to generate a reference.  

 

You can see that an Occurrence, unlike a Notifier or a Queue, does not generate a new copy of itself when called twice:

Kyle97330_0-1659370687929.png

This does mean it can't cause memory leaks (it can't even be wired into a Close Reference node) but it can be a trap for anyone thinking that it's an easy way to sync things up inside loops without having to associated data types or connect error wires.

Message 5 of 11
(271 Views)

While the LabVIEW help file is silent on this point many years of experience has let me to a few general observations about some of the lesser used primitives and thier usage.  Most have a better choice than that function I'll mention 4 and state that if you do chose to use them, they belong on the root BD:

  • First Call? .  Use a boolean Feedback node initialized T on compile or load.  Expect trouble if you want to have First Call without error in? in a subvi with error handling template!  The FBN however, can stay true in the error in case.
  • Create Occurance.  You found that! don't expect the occurrence refnum to be invalid when the vi starts.  It is valid Then! Use a Notifier or Channel for 1:1 or 1:n synchronization 
  • Call Chain. No better Function! but it's evaluation can't change by hiding it can it?
  • This VI / This App. again, the evaluation cannot change! but when you stick them inside any case structure,  Event structure or Stacked Sequence (please don't use SSS) someone else may try to inline your vi and curse you for hiding an Asynchronous node

And that's the real reason for my reply. Asynchronous Nodes! Yep, Asynchronous Nodes evaluate Asynchronously.  They don't follow dataflow they break the paradigm without even saying "sorry" first.  They evaluate at compile or load and seem to act like constants at runtime. 


"Should be" isn't "Is" -Jay
0 Kudos
Message 6 of 11
(258 Views)

@beuvink wrote:

Fully agree that this is some stone-age LabView function and their operation -including bugs- must be kept as-is for compatibility.

 

Don't fully agree that help states they shouldn't be used. 'Encourage to use something else' is a bit vague and there is no explanation why they shouldn't be used. It is also still in the default template and didn't even get another colour like some other 'obsolete' functions received.

 

Fully disagree that events/notifiers are a good replacement. I can't find a cleaner & easier way to implement the following:

beuvink_0-1659369474557.png

 

Fully agree that the above code is not good practice.. not that code isn't good but only because NI says you shouldn't do this..


Your tiny code fragment does not really tell us much. I am sure there is much more to the entire architecture.

 

Why would a UI update loop ever need to stop? If this is the end of the program, OK! If not, the UI loop should always do something or another in parallel to other important tasks.

0 Kudos
Message 7 of 11
(243 Views)

I like occurrences, don't use them often, but prefer them over a Notifier. Too bad they are deprecated. Oldies can be goodies. 🙂

 

They worked well on a FPGA for syncing a DSA and SAR module. See this link

0 Kudos
Message 8 of 11
(218 Views)
Solution
Accepted by beuvink

Thanks everyone for the feedback.

 

Just like the occurrences I am also from the LabVIEW stone age (LV 4.. more the bronze age...). So when I started I had to use occurrences as there were no other ways to do certain things. Still like them as they allow for very clean code.

 

In the last 25 years I didn't run into the 'caching issue' or any other. Does anyone know of more suprises that are hidden? Of course these functions could be as old as LV1 and this flaw was never found/fixed. Also the way of using isn't like queues and notifiers.

 

I have made a new implementation that fixes this bug and keeps the good stuff:

- Clean diagram

- Create a single instance per 'generate occurrence' instance on the diagram so there is no need to destroy anything or cause memory leaks

- Simple use only 1:1 replacement

 

I did keep the trikcy stuff

- No error handling

- Generate occurrence still can't be called in a loop to create multiple (would conflict with the memory leak feature above)

 

Made some functional changes to fix the bug

- Renamed 'generate occurrence' to 'reset occurrence' to make function more clear

- When 'generate occurrence' is executed it also removes any 'cached' occurrences

- Added some examples where occurrences can be usefull/easy to use and how to trigger the bug

 

About the examples. Of course there are alternative ways to implement the same behavior. I would love to see some if you have a nicer solution. (@Bill, these are not really complex but in fact very simple solutions 😉).

 

I placed them in a file structure I can use for future stuff like this, it is possible to place it in the user.lib and add it to the template.

 

Just some screenshots... one I know for sure you just can't resist...

beuvink_0-1659435293880.pngbeuvink_1-1659435340540.png

beuvink_2-1659435598176.png

 

 

0 Kudos
Message 9 of 11
(155 Views)

@altenbach wrote:

Occurrences are a leftovers from the stone age of LabVIEW and probably just retained for backwards compatibility. They were sometimes useful before we had the event structure!

 

Don't use them for new designs and use notifiers as the help correctly states.

 

altenbach_0-1659368775880.png


Occurrences are indeed objects from the beginning of LabVIEW. They work well if you know their particularities. Some of the behaviour around ignore previous triggers and initialization are rather peculiar and could have been considered bugs in the initial LabVIEW versions. They are definitely not intuitive. But changing that behaviour now is an impossibility as there is quite a lot of code out there that was written with them and worked around the peculiarities they had. In fact I know that at least the initial implementation of Notifiers, Semaphores and Queues was written with them at the core and it may still be the mechanism used for the asynchronous waiting operation for these nodes.

 

They do not solve anything that you could not do with either Notifiers or Semaphores except if you want to have asynchronous signaling from external code, but the according manager API to do so was never officially documented so this is not a very viable option for shipping code anyways outside of NI products. And Queues, Events and Notifiers offer the additional option to have an associated data channel that lets you do things that you would have to use various involved workarounds when you try to do the same with Occurrences.

 

And yes the Generate Occurrence node is not really a "Generate" or create. The according occurrence refnum is created on load time of the VI for the actual instance of that node. Calling it umptien times in a loop will always return the SAME occurrence. If you want to have multiple different occurrences you will have to place as many "Generate Occurrence" nodes on the diagram as you want occurrences. And even if you place it in a reentrant VI, the occurrence "generated" will be always the same, independent of the reentrant instance of the VI.

 

There is an according manager API that really generates/creates a new occurrence every time it is called but I never tested how long that could go well. Occurrences can't be used in external code to wait asynchronously as that requires calling functions that need access to the current diagram context (more correctly DS heap for data space heap) to manage the scheduling, but they can be triggered from external code. The only other option to trigger asynchronous events from external code are user events through the LVPostUserEvent() call or using OS native events.

 

It's unfortunate that NI never added manager calls to work with queues and notifiers from external code. They may be there but are undocumented and for NI internal use only.

Rolf Kalbermatter
Averna BV
Message 10 of 11
(145 Views)