Description
Arbitrated stores (ASTs) are used as repositories for persistent (state) data, and reads are therefore non-destructive. Arbitrated store buffers can be exclusively accessed by any number of readers, or a single writer, or a single updater. AST data provides an equivalent to object member data and/or static data. These objects also provide an alternative to conventional data locks.
Creation Attributes
Name
Instance name (see Object Names)
Dimensions
Instance dimensionality (see Object Dimensionality)
Presence
Instance presence flag (see Object Presence)
Buffer Depth
This attribute determines the number of buffers owned by the store. If the store is single buffered then it can only be opened simultaneously by one updater, or one writer, or multiple readers. If the store has two buffers, then one buffer could be opened for update or write, whilst the other is opened for read. When a buffer is closed for write or update, then subsequent reads will be directed to it. It is possible therefore for any number of buffers to be opened for read and the more buffers that are available, the less likely it is that the readers will block. Typically, stores are created with two buffers. The default value buffer depth is 1.
Buffer Allocation
This attribute determines the buffer storage mode used by the store. Arbitrated stores support three modes. In 'static' mode, buffers are created when the store is created and their size cannot change. In 'extendible' mode, buffers are re-allocated if their constructed size is greater then their existing size. In 'conforming' mode, buffers are re-allocated if their constructed size differs from their existing size. If the data is fixed size then 'static' mode is preferable. If the data is variable sized then extendible mode will have less CPU overhead but require more memory to be allocated. The default allocation mode is 'conforming'.
Buffer Size
This attribute determines the initial buffer size at creation time. If the store uses 'static' buffer allocation, then this size will be fixed. By default, buffers are creted with size 0.
Record Type
This attributes identifies the record type that the store holds (see store records)
Connection Attributes
Arbitrated store connections require the following attributes;
Timeout
This attribute determines whether the connection will poll or block (see Connection Timeout). Since arbitrated stores are only usually held open for short periods this attribute is usually set to 'block'.
Signature
This attribute is a string that describes the mapping from elements in the consumer, to elements in the arbitrated store. See Connection Mappings.
Dimensions
This attribute determines the dimensionality of the connection array owned by each consuming element. By default, this will provide the consuming element with one connection for each provider element. Collector, Multiplexor and Manual connection consumers can have multi-dimensional connection arrays, but in all other cases, this attribute will be '1'. See Connection Mappings.
Repeat Count
This attribute determines the number of times that each 'provider element to consumer element' connection is repeated. If the repeat count is greater then one, then the Dimensions attribute (above), and the resulting connection access functions, will both have an 'extra' dimension. Only Collector, Multiplexor and Manual connection consumers can have repeat counts that are greater than '1'. See Connection Mappings.
Name
This attribute determines the connection's 'name' which is used to construct access function names (see Connection Names).
Access
This attribute determines whether the consumer is requesting read, write or update access to the store's data.
Key
This attribute can be used as a means of filtering reads and updates. If a writer and/or updater specifies a key then it is associated with the buffer instance. Readers and/or updaters that specify a key and a rule will only be granted access to data that satisfies their specified constraint. See Store Keys and Rules.
Rule
This attribute can be used by readers and updaters as a means of filtering out data of interest (see Store Keys and Rules).
Additional attributes may also be required that are specific to the connection's consuming object. These are documented in their respective sections.
Manual Connections
Manual connections provide a means of directly accessing target objects. These are created automatically from CDL diagrams and accessed using their access function names (see Manual Connections).
Arbitrated store connections provide the following member functions;
OpenWrite()
This member function opens the store for exclusive write access (see AST OpenWrite function).
OpenRead()
This member function opens the store for shareable read access (see AST OpenRead function).
OpenUpdate()
This member function opens the store for exclusive update access (see AST OpenUpdate function).
Close()
This member function closes a store that was successfully opened for write, read, or update (see AST Close function).
Automatic and Manual Connections
The following member functions can be used for both automatic and manual connections;
Record()
If the connection has been successfully opened, and not yet closed, then this member function returns a reference to the store's record object. If the buffer mode (see above) is not 'static', and the store has been opened for write or update access, then the data object will need to be constructed before it can be referenced (see access functions and store records).
IsOpen()
This member function returns TRUE if the connection is 'Open' or FALSE otherwise.
Key()
This member function returns the key that is associated with the currently 'Open' buffer (see key attribute above).
Update Notification
In addition to automatic and manual connections, ASTs also support 'notifications'. Any consumer can request an update notification from an AST, and events are generated if the store's latest readable buffer is 'newer' than the last buffer update notification. This means that consumers can subscribe to 'latest' data (see AST Update Notifications). Notification events do not 'Open' stores for access and so a separate 'manual' connection is usually required in order to access the 'latest' data.
Notes
There are a number of points to bear in mind when using arbitrated stores;
Firstly, they are transparently arbitrated using read/write/update locks and so deadly embraces are possible if two or more subscribers access multiple stores in different sequence order. The best way to avoid this is to use sequential collectors to ensure that consumers always access stores in the same order.
If stores have multiple buffers then there is no guarantee that two apparently simultaneous reads from adjacent functions will be directed to the same buffer instance. If multiple readers need to read the same buffer for consistency then a distributor can be used to ensure that all accessors see the same buffer instance.
AST notifications are received by subscribers if the latest data in the store 'differs' from the data in the last update. This means that some intermediate updates may not necessarily be seen. If a store receives two updates in quick succession then the reader may only receive an event for one of them. If this is an issue then the circuit designer probably needs to consider using a transient store in place of the arbitrated store.
All read and update accesses will block until the store has been initialized by a 'write'. Typically, stores are initialized from circuit/method initialization code during startup and prior to execution (see Entering Harness Code).
Writers and updaters take precedence over readers. If a write or update request is issued to a store, and there are no free buffers then the oldest buffer (earliest written to or updated) becomes the target buffer for writes/updates. If there are no uncontended buffers and writers/updaters waiting, then subsequent read requests will block.
When writing to a data record, only the fields that are written-to will be defined. In most cases therefore, data records need to be 'updated' rather than 'written'. Updating does however carry the overhead that the current data object needs to be referenced. In practice this overhead is generally small because updates to the store are broadcast to all accessing processes. This means that updates occur locally, but on 'close', the updated buffer is flushed back to the process that owns the definitive store object. On arrival, the update is broadcast to all connecting processes (except the one that initiated the update). This minimizes bandwidth for the typical case where data is 'read' many more times than it is written.
Store data object alignment is 32 byte. This can be important for some high performance math libraries that require data to be aligned. It is sometimes beneficial therefore to 'pad' data objects.
Examples
The example below shows a store named 'Ast', with data type 'Dtype', and dimensionality 'NxM'.