Jump to content

Functional global variable

From LabVIEW Wiki
Revision as of 22:39, 17 March 2007 by MichaelAivaliotis (talk | contribs) (New page: Functional globals (LabVIEW 2 style globals) refer to the same code construct in LV. Most people in the mailing list refer to these structures as LV2 globals because this was the version o...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Functional globals (LabVIEW 2 style globals) refer to the same code construct in LV. Most people in the mailing list refer to these structures as LV2 globals because this was the version of LV when they were introduced. Functional globals is how NI refer to these structures because they can be more than just global variables in that they can contain code and data. Uninitialised shift registers (USR's) are the LV code primitives used in making these functional global variables work.

A functional global is created by placing a shift register upon a while loop and wiring a boolean constant to the condition terminal such that the loop executes a single time. When the shift register is not wired with an input from the left hand side (ie it is uninitialised) LV retains the memory in use for that vi between calls. This means the the vi stores the value of the shift register variable between calls (executions) in the code. Extensions can be done by adding cases within the loop, eg one for read and one for write with a 'mode' enumerated type selecting which case is executed when the vi is called (see attached image). These globals can contain as many cases as needed and because these are very similar to state machines, they can be made to execute several cases at each call to add increased functionality.

Of course all recent versions of LV have global variables, accessed from the structures palette, so why do people still refer to them or even use them? Well, there are a couple of good reasons: 1. More efficient memory storage. Because the vi retains the same data space regardless of it use in the code, only a single call to the memory manager is made. If arrays are stored in the USR, and replace array element primitives used, then the memory space is efficiently used/accessed wherever the vi is called. 2. Built in data space protection. One problem that can happen with normal globals in LV, occurs if you try to write a value to the global in several places in your code, updates to the value are unpredictable with respect to time. This means that changes to the global can be subject to race conditions. This is especially true if you read/write to the global where a race condition could occur between the read and the write of the variable.

So how does it work? In the LV execution system, a single vi, even if called from multiple places in the LV code, can only be executed exclusively in each place. In other words, the vi will not execute until a previous execution is complete. With a functional global, because it is a vi, LV determines that the functional global can only be executed once. Therefore updating of the shift registers is protected by the LV execution system. This mechanism of a vi 'protects' the data preventing any race condition. It should also be noted that USR's only retain this ability to share data across the code when they are not reentrant. If the vi is reentrant then the USR still stores the data, but this is only stored between calls of the vi in that place in the code - another call to the vi in another section of the code would have its own dataspace and its own saved USR values. It should be stressed that the reentrant vi would not transfer data from one section of the code to another and by definition not be a functional global.