reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
lf_token.c File Reference

Functions supporting token types. See lf_token.h for docs. More...

#include <stdbool.h>
#include <assert.h>
#include <string.h>
#include "lf_token.h"
#include "environment.h"
#include "lf_types.h"
#include "hashset/hashset_itr.h"
#include "util.h"
#include "platform.h"
#include "port.h"

Macros

#define _LF_TOKEN_RECYCLING_BIN_SIZE_LIMIT   512
 

Functions

lf_token_tlf_new_token (void *port_or_action, void *val, size_t len)
 Return a new disassociated token with type matching the specified port or action and containing the specified value and length. The value is assumed to point to dynamically allocated memory that will be automatically freed. The length is 1 unless the type of the port is an array, in which case the value points to an array of the specified length. The token must then be sent to the port using lf_set_token or scheduled with the action using lf_schedule_token. The token can also be safely sent to any other port or scheduled with any other action that has the same type. If it is not scheduled or sent, then it is up to the user to free the memory allocated for the token and its value.
 
lf_token_tlf_writable_copy (lf_port_base_t *port)
 
token_freed _lf_free_token (lf_token_t *token)
 Free the specified token, if appropriate. If the reference count is greater than 0, then do not free anything. Otherwise, the token value (payload) will be freed, if there is one. Then the token itself will be freed. The freed token will be put on the recycling bin unless that bin has reached the designated capacity, in which case free() will be used.
 
lf_token_t_lf_new_token (token_type_t *type, void *value, size_t length)
 Return a new token with the specified type, value, and length. This will attempt to get one from the recyling bin, and, if the recycling bin is empty, will allocate a new token using calloc and set its type to point to the specified type. The returned token will indicate that it is not a template token, and its reference count will be 0.
 
lf_token_t_lf_get_token (token_template_t *tmplt)
 
void _lf_initialize_template (token_template_t *tmplt, size_t element_size)
 
lf_token_t_lf_initialize_token_with_value (token_template_t *tmplt, void *value, size_t length)
 
lf_token_t_lf_initialize_token (token_template_t *tmplt, size_t length)
 
void _lf_free_all_tokens ()
 Free all tokens. Free tokens on the _lf_token_recycling_bin hashset and all template tokens.
 
void _lf_replace_template_token (token_template_t *tmplt, lf_token_t *newtoken)
 Replace the token in the specified template, if there is one, with a new one. If the new token is the same as the token in the template, then this does nothing. Otherwise, it frees the previous template token.
 
token_freed _lf_done_using (lf_token_t *token)
 
void _lf_free_token_copies ()
 Free token copies made for mutable inputs. This function should be called at the beginning of each time step to avoid memory leaks.
 

Variables

int _lf_count_payload_allocations
 
int _lf_count_token_allocations
 

Detailed Description

Functions supporting token types. See lf_token.h for docs.

Author
Edward A. Lee (eal@b.nosp@m.erke.nosp@m.ley.e.nosp@m.du)

Macro Definition Documentation

◆ _LF_TOKEN_RECYCLING_BIN_SIZE_LIMIT

#define _LF_TOKEN_RECYCLING_BIN_SIZE_LIMIT   512

To allow a system to recover from burst of activity, the token recycling bin has a limited size. When it becomes full, token are freed using free().

Function Documentation

◆ _lf_done_using()

token_freed _lf_done_using ( lf_token_t * token)

Decrement the reference count of the specified token. If the reference count hits 0, free the memory for the value carried by the token, and, if the token is not also the template token of its trigger, free the token.

Parameters
tokenPointer to a token.
Returns
NOT_FREED if nothing was freed, VALUE_FREED if the value was freed, TOKEN_FREED if only the token was freed, and TOKEN_AND_VALUE_FREED if both the value and the token were freed.

◆ _lf_free_all_tokens()

void _lf_free_all_tokens ( )

Free all tokens. Free tokens on the _lf_token_recycling_bin hashset and all template tokens.

◆ _lf_free_token()

token_freed _lf_free_token ( lf_token_t * token)

Free the specified token, if appropriate. If the reference count is greater than 0, then do not free anything. Otherwise, the token value (payload) will be freed, if there is one. Then the token itself will be freed. The freed token will be put on the recycling bin unless that bin has reached the designated capacity, in which case free() will be used.

Parameters
tokenPointer to a token.
Returns
NOT_FREED if nothing was freed, VALUE_FREED if the value was freed, TOKEN_FREED if only the token was freed, and TOKEN_AND_VALUE_FREED if both the value and the token were freed.

◆ _lf_free_token_copies()

void _lf_free_token_copies ( void )

Free token copies made for mutable inputs. This function should be called at the beginning of each time step to avoid memory leaks.

Parameters
envEnvironment in which we are executing.

◆ _lf_get_token()

lf_token_t * _lf_get_token ( token_template_t * tmplt)

Get a token for the specified template. If the template already has a token and the reference count is 1, then return that token. Otherwise, create a new token, make it the new template, and dissociate or free the previous template token.

Parameters
tmpltThe template. // template is a C++ keyword.
Returns
A new or recycled lf_token_t struct.

◆ _lf_initialize_template()

void _lf_initialize_template ( token_template_t * tmplt,
size_t element_size )

Initialize the specified template to contain a token that is an array with the specified element size. If the template already has a token with a reference count greater than 1 or a non-matching type, it will be replaced and that token will be freed. The length of the returned token will be 0, its value will be NULL, and its reference count will be 1.

Parameters
tmpltThe template. // template is a C++ keyword.
element_sizeThe element size.

◆ _lf_initialize_token()

lf_token_t * _lf_initialize_token ( token_template_t * tmplt,
size_t length )

Return a token for storing an array of the specified length with new memory allocated (using calloc, so initialize to zero) for storing that array. If the template's token is available (it is non-null and its reference count is 1), then reuse it. Otherwise, create a new token and replace the template token with the new one, freeing the previous token from its template association. The element_size for elements of the array is specified by the specified template. The caller should populate the value and ref_count field of the returned token after this returns.

Parameters
tmpltThe token template (must not be NULL). // template is a C++ keyword.
lengthThe length of the array, or 1 if it is not an array.
Returns
Either the template's token or a new one, in each case with a value field pointing to newly allocated memory.

◆ _lf_initialize_token_with_value()

lf_token_t * _lf_initialize_token_with_value ( token_template_t * tmplt,
void * value,
size_t length )

Return a token storing the specified value, which is assumed to be either a scalar (if length is 1) or an array of the specified length. If the token in the specified template is available (it non-null and its reference count is 1), then return it. Otherwise, create a new token and replace the template token with the new one, freeing the previous token from its template association. The element_size for elements of the array is specified by the specified template.

Parameters
tmpltA template for the token. // template is a C++ keyword.
valueThe value of the array.
lengthThe length of the array, or 1 if it is not an array.
Returns
Either the specified token or a new one, in each case with a value field pointing to newly allocated memory.

◆ _lf_new_token()

lf_token_t * _lf_new_token ( token_type_t * type,
void * value,
size_t length )

Return a new token with the specified type, value, and length. This will attempt to get one from the recyling bin, and, if the recycling bin is empty, will allocate a new token using calloc and set its type to point to the specified type. The returned token will indicate that it is not a template token, and its reference count will be 0.

Parameters
typeThe type of the token.
valueThe value, or NULL to have no value.
lengthThe array length of the value, 1 to not be an array, or 0 to have no value.
Returns
lf_token_t*

◆ _lf_replace_template_token()

void _lf_replace_template_token ( token_template_t * tmplt,
lf_token_t * newtoken )

Replace the token in the specified template, if there is one, with a new one. If the new token is the same as the token in the template, then this does nothing. Otherwise, it frees the previous template token.

Parameters
tmpltPointer to a template. // template is a C++ keyword.
newtokenThe replacement token.

◆ lf_new_token()

lf_token_t * lf_new_token ( void * port_or_action,
void * val,
size_t len )

Return a new disassociated token with type matching the specified port or action and containing the specified value and length. The value is assumed to point to dynamically allocated memory that will be automatically freed. The length is 1 unless the type of the port is an array, in which case the value points to an array of the specified length. The token must then be sent to the port using lf_set_token or scheduled with the action using lf_schedule_token. The token can also be safely sent to any other port or scheduled with any other action that has the same type. If it is not scheduled or sent, then it is up to the user to free the memory allocated for the token and its value.

Parameters
port_or_actionA port or action.
valThe value.
lenThe length, or 1 if it not an array.
Returns
A pointer to a lf_token_t struct.

◆ lf_writable_copy()

lf_token_t * lf_writable_copy ( lf_port_base_t * port)

Return a writable copy of the token in the specified template. If the reference count is 1, this returns the template's token rather than a copy. The reference count will be 1. Otherwise, if the size of the token payload is zero, this also returns the original token, again with reference count of 1. Otherwise, this returns a new token with a reference count of 1. The new token is added to a list of tokens whose reference counts will be decremented at the start of the next tag. If the template has no token (it has a primitive type), then there is no need for a writable copy. Return NULL.

Parameters
portAn input port, cast to (lf_port_base_t*).
Returns
A pointer to a writable copy of the token, or NULL if the type is primitive.

Variable Documentation

◆ _lf_count_payload_allocations

int _lf_count_payload_allocations

Counter used to issue a warning if memory is allocated for message payloads and never freed.

◆ _lf_count_token_allocations

int _lf_count_token_allocations

Counter used to issue a warning if memory is allocated for tokens and never freed. Note that every trigger will have one token allocated for it. That token is not counted because it is not expected to be freed.