reactor-c
C Runtime for Lingua Franca
|
#include "pythontarget.h"
#include "modal_models/definitions.h"
#include "platform.h"
#include "python_action.h"
#include "python_port.h"
#include "python_tag.h"
#include "python_time.h"
#include "reactor.h"
#include "tag.h"
#include "util.h"
#include "environment.h"
#include "api/schedule.h"
Functions | |
PyObject * | py_schedule (PyObject *self, PyObject *args) |
PyObject * | py_schedule_copy (PyObject *self, PyObject *args) |
int | lf_reactor_c_main (int argc, const char *argv[]) |
void | lf_request_stop (void) |
Request a stop to execution as soon as possible. | |
PyObject * | py_request_stop (PyObject *self, PyObject *args) |
PyObject * | py_source_directory (PyObject *self, PyObject *args) |
Return the source directory path (where the main .lf file is) as a string. | |
PyObject * | py_package_directory (PyObject *self, PyObject *args) |
Return the root project directory path as a string. | |
const char ** | _lf_py_parse_argv_impl (PyObject *py_argv, size_t *argc) |
void | py_initialize_interpreter (void) |
Initialize the Python interpreter if it hasn't already been. | |
PyObject * | py_main (PyObject *self, PyObject *py_args) |
PyMODINIT_FUNC | GEN_NAME (PyInit_, MODULE_NAME) |
void | destroy_action_capsule (PyObject *capsule) |
PyObject * | convert_C_port_to_py (void *port, int width) |
PyObject * | convert_C_action_to_py (void *action) |
PyObject * | get_python_function (string module, string class, int instance_id, string func) |
PyObject * | load_serializer (string package_name) |
PyObject * | custom_serialize (PyObject *obj, PyObject *custom_serializer) |
PyObject * | custom_deserialize (PyObject *serialized_pyobject, PyObject *custom_serializer) |
Variables | |
PyObject * | globalPythonModule = NULL |
PyObject * | globalPythonModuleDict = NULL |
PyObject * | global_pickler = NULL |
environment_t * | top_level_environment = NULL |
Copyright (c) 2022, The University of California at Berkeley. Copyright (c) 2021, The University of Texas at Dallas.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Implementation of functions defined in
const char ** _lf_py_parse_argv_impl | ( | PyObject * | py_argv, |
size_t * | argc ) |
Parse Python's 'argv' (from sys.argv()) into a pair of C-style 'argc' (the size of command-line parameters array) and 'argv' (an array of char* containing the command-line parameters).
This function assumes that argc is already allocated, and will fail if it isn't.
py_argv | The returned value by 'sys.argv()' |
argc | Will contain an integer which is the number of arguments passed on the command line. |
PyObject * convert_C_action_to_py | ( | void * | action | ) |
A helper function to convert C actions to Python action capsules
The input to this function is a pointer to a C action, which might or might not contain a value and an is_present field. To simplify the assumptions made by this function, the "value" and "is_present" are passed to the function instead of expecting them to exist.
The void* pointer to the C action instance is encapsulated in a PyCapsule instead of passing an exposed pointer through Python.
PyObject * convert_C_port_to_py | ( | void * | port, |
int | width ) |
A function that is called any time a Python reaction is called with ports as inputs and outputs. This function converts ports that are either a multiport or a non-multiport into a port_capsule.
First, the void* pointer is stored in a PyCapsule. If the port is not a multiport, the value and is_present fields are copied verbatim. These feilds then can be accessed from the Python code as port.value and port.is_present. If the value is absent, it will be set to None.
For multiports, the value of the port_capsule (i.e., port.value) is always set to None and is_present is set to false. Individual ports can then later be accessed in Python code as port[idx].
PyObject * custom_deserialize | ( | PyObject * | serialized_pyobject, |
PyObject * | custom_serializer ) |
Deserialize Python object from a bytes object using external serializer
serialized_pyobject | The serialized bytes Python object |
custom_serializer | The custom Serializer class |
PyObject * custom_serialize | ( | PyObject * | obj, |
PyObject * | custom_serializer ) |
Serialize Python object to a bytes object using external serializer
obj | The Python object to serialize |
custom_serializer | The custom Serializer class |
void destroy_action_capsule | ( | PyObject * | capsule | ) |
Python Helper Functions These functions are called in generated C code for various reasons. Their main purpose is to facilitate C runtime's communication with Python code. A function that destroys action capsules
PyMODINIT_FUNC GEN_NAME | ( | PyInit_ | , |
MODULE_NAME | ) |
Invoke a Python func in class[instance_id] from module. Class instances in generated Python code are always instantiated in a list of template classs[_class(params), _class(params), ...] (note the extra s) regardless of whether a bank is used or not. If there is no bank, or a bank of width 1, the list will be instantiated as classs[_class(params)].
This function would thus call classs[0] to access the first instance in a bank and so on.
Possible optimizations include: - Not loading the module each time (by storing it in global memory),
module | The Python module to load the function from. In embedded mode, it should be set to "__main__" |
class | The name of the list of classes in the generated Python code |
instance_id | The element number in the list of classes. class[instance_id] points to a class instance |
func | The reaction functino to be called |
pArgs | the PyList of arguments to be sent to function func() |
int lf_reactor_c_main | ( | int | argc, |
const char * | argv[] ) |
Prototype for the main function.
The main loop of the LF program.
An unambiguous function name that can be called by external libraries.
Note: In target languages that use the C core library, there should be an unambiguous way to execute the LF program's main function that will not conflict with other main functions that might get resolved and linked at compile time.
void lf_request_stop | ( | void | ) |
Request a stop to execution as soon as possible.
Prototype for lf_request_stop().
In a non-federated execution with only a single enclave, this will occur one microstep later than the current tag. In a federated execution or when there is more than one enclave, it will likely occur at a later tag determined by the RTI so that all federates and enclaves stop at the same tag.
PyObject * load_serializer | ( | string | package_name | ) |
Load the Serializer class from package name
package_name | Name of the python package to load |
void py_initialize_interpreter | ( | void | ) |
Initialize the Python interpreter if it hasn't already been.
PyObject * py_main | ( | PyObject * | self, |
PyObject * | py_args ) |
The main function of this Python module.
py_args | A single object, which should be a list of arguments taken from sys.argv(). |
PyObject * py_package_directory | ( | PyObject * | self, |
PyObject * | args ) |
Return the root project directory path as a string.
self | The lf object. |
args | Empty. |
PyObject * py_request_stop | ( | PyObject * | self, |
PyObject * | args ) |
Stop execution at the conclusion of the current logical time.
PyObject * py_schedule | ( | PyObject * | self, |
PyObject * | args ) |
Schedule an action to occur with the specified time offset with no payload (no value conveyed). This function is callable in Python by calling action_name.schedule(offset). Some examples include: action_name.schedule(5) action_name.schedule(NSEC(5)) See schedule_token(), which this uses, for details.
self | Pointer to the calling object. |
args | contains:
|
PyObject * py_schedule_copy | ( | PyObject * | self, |
PyObject * | args ) |
Schedule an action to occur with the specified value and time offset with a copy of the specified value. See reactor.h for documentation.
PyObject * py_source_directory | ( | PyObject * | self, |
PyObject * | args ) |
Return the source directory path (where the main .lf file is) as a string.
self | The lf object. |
args | Empty. |
PyObject* global_pickler = NULL |
PyObject* globalPythonModule = NULL |
PyObject* globalPythonModuleDict = NULL |
environment_t* top_level_environment = NULL |