Shared memory
The shmem node-type can be used to quickly exchange samples with a process on the same host using a POSIX shared memory object.
Prerequisites
This node-type does not have any special library dependencies. It is always available.
Implementation
The source code of the node-type is available here: https://github.com/VILLASframework/node/blob/master/lib/nodes/shmem.cpp
Configuration
| queuelen | integer Default: "<DEFAULT_SHMEM_QUEUELEN>" Length of the input and output queues in elements. |
| samplelen | integer Default: "<DEFAULT_SHMEM_SAMPLELEN>" Maximum number of data elements in a single `struct Sample`` for the samples handled by this node. |
| mode | string Default: "pthread" Enum: "pthread" "polling" If set to |
| exec | Array of strings Optional name and command-line arguments (as passed to |
object (Input configuration (received by VILLASnode)) | |
object (Output configuration (sent out by VILLASnode)) | |
| vectorize | integer Default: 1 This setting allows to send multiple samples in a single message to the destination nodes. The value of this setting determines how many samples will be combined into one packet. |
Array of Hook Object (object) or Hook Name (string) (hook_list) | |
| builtin | boolean (Builtin hook functions) Default: true By default, each node and paths has a couple of default hooks attached to them. With this setting the attachment of built-in hooks can be disabled. |
{- "queuelen": "<DEFAULT_SHMEM_QUEUELEN>",
- "samplelen": "<DEFAULT_SHMEM_SAMPLELEN>",
- "mode": "pthread",
- "exec": [
- "string"
], - "in": {
- "name": "string",
- "signals": [
- {
- "name": "tap_position",
- "type": "integer",
- "init": 0
}, - {
- "name": "voltage",
- "type": "float",
- "unit": "V",
- "init": 230
}
], - "vectorize": 1,
- "hooks": [
- "print",
- {
- "type": "limit_rate",
- "rate": 1000
}
]
}, - "out": {
- "name": "string",
- "vectorize": 0,
- "hooks": [
- "print",
- {
- "type": "limit_rate",
- "rate": 1000
}
]
}, - "vectorize": 1,
- "hooks": [
- "print",
- {
- "type": "limit_rate",
- "rate": 1000
}
], - "builtin": true
}Example
nodes = {
shmem_node = {
type = "shmem"
in = {
# Name of shared memory segment for receiving side
name = "sn1_in"
}
out = {
# Name of shared memory segment for sending side
name = "sn1_in"
}
# Length of the queues
queuelen = 1024
# We can busy-wait or use pthread condition variables for synchronizations
mode = "pthread"
# Execute an external process when starting the node which
# then starts the other side of this shared memory channel
# Usually we also pass the shmem names as parameters
exec = [ "villas-shmem", "sn1_in", "sn1_out" ]
}
}
API for external programs
The actual sharing of data is implemented by putting two shared struct queues
(one per direction) and an associated struct pool in the shared memory region.
Samples can be exchanged by simply writing to and reading from these queues.
External programs that want to use this interface must link against
libvillas.so.
The interface for external programs is very simple: after opening the shared
memory object with shmem_shared_open (passing the object name from the
configuration file), samples can be read from and written to VILLASNode using
shmem_shared_read and shmem_shared_write, respectively. Samples written to
the node must be allocated by sample_alloc from the shared pool; samples read
from the node should be freed with sample_put after they have been processed.
See the example client and the API for more details.