This paper presents an integration of the Actor model in Emfrp, a functional reactive programming language designed for resource constrained embedded systems. In this integration, actors not only express nodes that represent time-varying values, but also present communication mechanism. The integration provides a higher-level view of the internal representation of nodes, representations of time-varying values, as well as an actor-based inter-device communication mechanism.
Towards an Integration of the Actor Model in an FRP Language for Small-Scale Embedded Systems
1. Towards an Integration of the Actor
Model in an FRP Language for
Small-Scale Embedded Systems
Takuo Watanabe & Kensuke Sawada
Department of Computer Science, Tokyo Institute of Technology
Oct. 30, 2016
AGERE!@SPLASH 2016
1
2. About This Work
• An actor-based execution model of a pure FRP
languages for small-scale embedded systems
• Objective
- flexible execution models
- open/customizable interface with higher-level abstraction
• Talk Outline
- EmFRP
- Runtime System
- Actor-Based Runtime Implementation
- Future Work
2
3. "Small-Scale" Embedded Systems
• Resource-Constrained Systems
- Processor: 8–32bit
- Clock: ≤ 100MHz
- Program Storage: ≤ 1M words
- RAM: ≤ 1M bytes
- No MMU
• w/o full-fledged OS (e.g., Linux)
- embedded in special purpose devices
• ex) Microcontrollers
- PIC, AVR, H8, ARM Cortex-M, etc.
3
4. Emfrp [Sawada & Watanabe, CROW2016]
• An FRP language for small-scale embedded systems
- Strongly-typed, Purely functional
• parametric polymorphism & type inference
• algebraic data types & pattern matching
- Simple abstraction for time-varying values (aka signals)
• node: named, non-first-class representation
• lifting-free
- Bounded & predictable amount of runtime memory
• syntactic restrictions & type system
• github.com/sawaken/emfrp
- Compiler & Interpreter (written in Ruby)
• The compiler generates platform-independent ANSI-C code
runnable several microcontrollers (AVR, ARM Cortex-M)
4
5. Ex1: Air-Conditioner Controller in Emfrp
5
01: module ACController # module name
02: in tmp : Float, # temperature sensor
03: hmd : Float # humidity sensor
04: out ac : Bool # air-conditioner
05: use Std # standard library
06:
07: # discomfort (temperature-humidity) index
08: node di = 0.81 * tmp + 0.01 * hmd
09: * (0.99 * tmp - 14.3) + 46.3
10:
11: # air-conditioner status
12: node init[False] ac = di >= 75.0 + ho
13:
14: # hysteresis offset
15: node ho = if ac@last then -0.5 else 0.5
6. History-Sensitive Behavior with @last
6
# air-conditioner status
node ac = di >= 75.0
# air-conditioner status
node init[False] ac =
di >= 75.0 + ho
# hysteresis offset
node ho = if ac@last
then -0.5 else 0.5
75.0
di
ac
75.0
di
ac
Emfrp syntax for referring to the previous value of an
arbitrary node (cf. foldp in Elm)
7. Case Study: Digital Clock [CROW2016]
• Target: mbed LPC1768
- ARM Cortex M3, 96MHz
- RAM 32K, Flash 512K
- LCD, 3 Buttons
• Code
- Emfrp: 80 loc
- Glue code in C++: 45 loc
- External Libraries
• Compiled Code
- Generated C code: 592 loc
- Binary (ARM RVDS4.1)
• w/o library : 2.3 KB
• w/ library: 30.1 KB
7
9. DAG Representation of Ex1
9
tmp
(Float)
hmd
(Float)
di
(Float)
ac
(Bool)
ho
(Float)
temperature
sensor
humidity
sensor
discomfort index
air-
conditioner
air-conditioner
status
hysteresis offset
node dependency
past-value dependencynode
device connection
10. Push-Based Execution Model of Emfrp
10
tmp
(Float)
hmd
(Float)
di
(Float)
ac
(Bool)
ho
(Float)
tmp hmd di ho ac
iteration
The runtime system
updates the values of the
nodes by repeatedly
evaluating them in an order
compatible to the DAG.
11. module ACController # module name
in tmp : Float, # temperature sensor
hmd : Float # humidity sensor
pulse10ms : Bool # hardware interval timer (10ms)
out ac : Bool, # air-conditioner
led : Bool # LED
use Std # standard library
# discomfort (temperature-humidity) index
node di = 0.81 * tmp + 0.01 * hmd * (0.99 * tmp - 14.3) + 46.3
# timer counter (resets to 0 every 1 minute)
node init[0] timer =
if !pulse10ms@last && pulse10ms
then (timer@last + 1) % 6000 else timer@last
# air-conditioner switch
node ac = if timer@last != timer && timer == 0
then di >= 75.0 else ac@last
# LED blinks at 1Hz
node led = (timer % 100) < 50
Ex2: A Timer-Based Air-Conditioner Controller
11
12. Actor-Based Execution Model
• With the push-based execution model, tmp, hmd and di
are evaluated in every iteration. However, the value of
them required only once per minute.
• In this work, we adopt an actor representation of
nodes to provide flexible runtime strategies and good
abstractions runtime access
- one actor (implemented as a C++ object) per node
- message-based dependency propagation
• single dispatch queue model
• transmission order preservation (a la ABCL)
- customizable scheduling via reflection (GWR)
• GWR = Reflection on Actor-Groups [Watanabe, AGERE2013]
12
13. DAG Representation of Ex2
13
tmp
(Float)
hmd
(Float)
di
(Float)
ac
(Bool)
timer
(Int)
temperature
sensor
humidity
sensor
air-
conditioner
led
(Bool)
hardware
timer
pulse
10ms
(Bool)
LED
14. class TMPNode : public Actor {
public:
TMPNode(Actor2 *di, TMPSensor *tmp);
virtual ~TMPNode() {}
virtual void activate(Message *m);
private:
Actor2 *di;
TMPSensor *tmp;
}
void TMPNode::activate(Message *m) {
di->send1(Message::floatMessage(tmp->read(), m->cust));
}
class DINode : public Actor2 {
public:
DINode(Actor *ac) ac(ac) { ... }
virtual ~DINode() {}
virtual void activate(Message *m);
private:
Actor *ac;
}
void DINode::activate(Message *mt, Message *mh) {
assert(mt->cust == mh->cust);
float t = mt->getFloat(), h = mh->getFloat();
float di = 0.81 * t + 0.01 * h * (0.99 * t - 14.3) + 46.3;
ac->send(Message::floatMessage(di, mt->cust));
}
Actor-Based
Representation of
Nodes in Ex2
14
15. Ex: Delayed (Lazy/Pull) Blocks
• An expression suffixed with @delay indicates that the
expression is evaluated only when it is required.
• Nodes in a delayed block and their dependent nodes
are evaluated in a separate actor group that is
activated only when it is needed.
15
# air-conditioner switch
node ac = if timer@last != timer && timer == 0
then (di >= 75.0)@delay else ac@last
16. The Actor-Group for the Delayed Block
• Actors in the group
for the delayed block
is detached from the
main iteration path.
- They have separate
message queue.
• The detached actor
group is activated by
sending an activation
message from ac
when they are
needed.
16
tmp
(Float)
hmd
(Float)
di
(Float)
ac
(Bool)
timer
(Int)
led
(Bool)
pulse
10ms
(Bool)
17. class DINode : public Actor2 { ... }
void DINode::activate(Message *mt, Message *mh) {
float t = mt->getFloat(), h = mh->getFloat();
float di = 0.81 * t + 0.01 * h * (0.99 * t - 14.3) + 46.3;
mt->cust->send(mkFloatMessage(di, mt->cust));
}
class ACNode : public Actor { ... }
void ACNode::activate(Message *m) {
if (m->prevInt() != m->getInt() &&
m->getInt() == 0) {
acDelayedBlockGroup->send(Message::unitMessage(&acDelayedBlock));
}
}
class ACDelayedBlock : public Actor { ...}
void ACDelayedBlock::activate(Message *m) {
m->cust->send(
Message::booleanMessage(m->getFloat() > 75.0, m->cust));
}
17
18. Summary & Future Work
• Proposed an actor-based execution model of Emfrp.
- actor representation of nodes (time-varying values)
- GWR for flexible execution strategies
• Future Work
- Possible Applications
• Asynchronous (Future) Node
- heavy node / slow peripheral devices / inter-device communication
• Group-Wide Iteration Control
- periodical iteration / deep sleep mode / interrupts from devices
• Actors as signal values
- Relationship to other concurrent / event models
- Better (meta-level) interface
- Implementation
18