Safe System-level Concurrency on Resource-Constrained Nodes
Accepted paper in SenSys’13 (preprint version)
Francisco Sant’Anna Noemi Rodriguez Roberto Ierusalimschy [email protected] [email protected] [email protected] Departamento de Informatica´ – PUC-Rio, Brazil
Olaf Landsiedel Philippas Tsigas olafl@chalmers.se [email protected] Computer Science and Engineering – Chalmers University of Technology, Sweden
Abstract as an alternative, providing traditional structured program- Despite the continuous research in facilitating program- ming for WSNs [12, 7]. However, the development pro- ming WSNs, most safety analysis and mitigation efforts in cess still requires manual synchronization and bookkeeping concurrency are still left to developers, who must manage of threads [24]. Synchronous languages [2] have also been synchronization and shared memory explicitly. In this paper, adapted to WSNs and offer higher-level compositions of ac- we present a system language that ensures safe concurrency tivities, considerably reducing programming efforts [21, 22]. by handling threats at compile time, rather than at runtime. Despite the increase in development productivity, WSN The synchronous and static foundation of our design allows system languages still fail to ensure static safety properties for a simple reasoning about concurrency enabling compile- for concurrent programs. However, given the difficulty in time analysis to ensure deterministic and memory-safe pro- debugging WSN applications, it is paramount to push as grams. As a trade-off, our design imposes limitations on many safety guarantees to compile time as possible [25]. As the language expressiveness, such as doing computationally- an example, shared memory is widely used as a low-level intensive operations and meeting hard real-time responsive- communication mechanism, but current languages do not ness. We implement widespread network protocols and the go beyond runtime atomic access guarantees, either through CC2420 radio driver to show that the achieved expressive- synchronization primitives [7, 27], or by adopting coopera- ness and responsiveness is sufficient for a wide range of tive scheduling [21, 17]. Requiring explicit synchronization WSN applications. The implementations show a reduction primitives lead to potential safety hazards [24]. Enforcing around 25% in code complexity, with a penalty of mem- cooperative scheduling is no less questionable, as it assumes ory increase below 10% in comparison to nesC. Overall, we that all accesses are dangerous. The bottom line is that exist- ensure safety properties for programs relying on high-level ing languages cannot detect and enforce atomicity only when control abstractions that also lead to concise and readable they are required. code. In this work, we present the design of CEU´ 1, a syn- 1 Introduction chronous system-level programming language that provides a reliable yet powerful set of abstractions for the develop- System-level development for WSNs commonly fol- ment of control-intensive WSN applications. CEU´ is based lows three major programming models: event-driven, multi- on a small set of control primitives similar to Esterel’s, lead- threaded, and synchronous models. In event-driven pro- ing to implementations that more closely reflect program gramming [19, 11], each external event can be associated specifications [8]. In addition, CEU´ provides a disciplined with a short-lived function callback to handle a reaction to policy for typical system-level functionality, such as low- the environment. This model is efficient, but is known to be level access to C and shared memory concurrency. It also difficult to program [1, 12]. Multi-threaded systems emerged introduces the following new safety mechanisms: first-class timers to ensure that timers in parallel remain synchronized (not depending on internal reaction timings); finalization blocks for local pointers going out of scope; and stack-based communication that avoids cyclic dependencies. We propose Permission to make digital or hard copies of all or part of this work for personal or a static analysis that considers all language mechanisms and classroom use is granted without fee provided that copies are not made or distributed detects safety threats at compile time, such as concurrent for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, to republish, to post on servers or to redistribute accesses to shared memory, and concurrent termination of to lists, requires prior specific permission and/or a fee. timers and threads. Our work focus on concurrency safety,
ACM 1Ceu´ is the Portuguese word for sky. /* nesC */ /* Protothreads */ /* CEU´ */ event void Boot.booted () { int main () { par/or do call T1.startOneShot(0) PT INIT(&blink); loop do call T2.startOneShot(60000) timer set(&timeout, 60000); Leds led0On(); } while ( await 2s; event void T1.fired () { PT SCHEDULE(blink()) && Leds led0Off(); static int on = 0; !timer expired(timeout) await 1s; if (on) { ); end call Leds.led0Off(); leds off(LEDS RED); with call T1.startOneShot(1000); <...> // CONTINUE await 1min; } else { } end call Leds.led0On(); PT THREAD blink () { Leds led0Off(); call T1.startOneShot(2000); while (1) { <...> // CONTINUE } leds on(LEDS RED); on = !on timer set(&timer, 2000); } PT WAIT UNTIL(expired(&timer)); event void T2.fired() { leds off(LEDS RED); call T1.cancel(); timer set(&timer, 1000); call Leds.led0Off(); PT WAIT UNTIL(expired(&timer)); <...> // CONTINUE } } }
Figure 1. “Blinking LED” in nesC [17], Protothreads [12], and CEU´ . The colors associate chunks of code with respective actions in the diagram. rather than type safety [9].2 tween sampling a sensor and broadcasting its readings has a In order to enable the static analysis, CEU´ programs must sequential pattern (with an enclosing loop); while including undergo some limitations. Computations that run in un- an 1-minute timeout to interrupt an activity denotes a parallel bounded time (e.g., compression, image processing) cannot pattern. be elegantly implemented [29], and dynamic support, such Figure 1 presents the three different programming mod- as dynamic loading is forbidden. However, we show that els commonly used in WSNs. It shows the implementations CEU´ is sufficiently expressive for the context of WSN ap- in nesC, Protothreads, and CEU´ for an application that con- plications. We successfully implemented the CC2420 radio tinuously lights on a LED for 2 seconds and off for 1 sec- driver, and the DRIP, SRP, and CTP network protocols [32] ond. After 1 minute of activity, the application turns off the in CEU´ . The implementations reduced code complexity by LED and proceeds to another activity (marked in the code as 25%, with an increase in ROM and RAM below 10% in com- <...>). The diagram on the right of Figure 1 describes the parison to nesC [17]. overall control behavior for the application. The sequential The rest of the paper is organized as follows: Section 2 programming pattern is represented by the LED alternating gives an overview on how different programming models between the two states, while the parallel pattern is repre- used in WSNs can express typical control patterns. Sec- sented by the 1-minute timeout. tion 3 details the design of CEU´ , motivating and discussing nesC the safety aspects of each relevant language feature. Sec- The first implementation in , which represents event-driven tion 4, evaluates the implementation of the network protocols the model, spawns two timers at boot time (Boot.booted): one to make the LED blink and another to wait in CEU´ and compares some aspects with nesC (e.g. memory usage and tokens count). We also evaluate the responsive- for 1 minute. The callback T1.fired continuously toggles the LED and resets the timer according to the state variable ness of the radio driver written in CEU´ . Section 5 discusses on. The callback T2.fired executes only once, canceling the related work to CEU´ . Section 6 concludes the paper and makes final remarks. blinking timer, and proceeds to <...>. Overall, we argue that this implementation has little structure: the blinking loop is 2 Overview of Programming Models not explicit, but instead, relies on a static state variable and WSN applications must handle a multitude of concurrent multiple invocations of the same callback. Furthermore, the events, such as timers and packet transmissions. Although timeout handler (T2.fired) requires specific knowledge about they may seem random and unrelated for an external ob- how to stop the blinking activity manually (T1.cancel()). server, a program must logically keep track of them accord- The second implementation in Protothreads, which rep- ing to its control specification. From a control perspective, resents the multi-threaded model [12, 7], uses a dedicated sequential programs are composed of two main patterns: , thread to make the LED blink in a loop. This brings more i.e., an activity with two or more states in sequence; and structure to the solution. The main thread also helps a reader parallel , i.e., unrelated activities that eventually need to syn- to identify the overall sequence of the program, which is not chronize. As an example, an application that alternates be- easily identifiable in the event-driven implementation with- 2We consider both safety aspects to be complimentary and orthogonal, out tracking the dependencies among callbacks. However, it i.e., type-safety techniques could also be applied to CEU´ . still requires much bookkeeping for initializing, scheduling and rejoining the blinking thread after the timeout (inside the 1 input void CC2420_START, CC2420_STOP; while condition). 2 loop do 3 await CC2420_START; The third implementation, in CEU´ , which represents the 4 par/or do synchronous model, uses a par/or construct to run the two 5 await CC2420_STOP; activities in parallel: an endless loop to blink the LED, and a 6 with single statement that waits for 1 minute before terminating. 7 // loop with other nested trails The par/or stands for parallel-or and rejoins automatically 8 // to receive radio packets when any of its trails terminates (CEU´ also supports par/and 9 <...> compositions, which rejoin when all spawned trails termi- 10 end end nate.). We argue that the hierarchical structure of CEU´ more 11 closely reflects the control diagram and ties the two activities together, implying that (a) they can only exist together; (b) Figure 2. Start/stop behavior for the radio driver. they always start together (c) they always terminate together. The occurrence of CC2420 STOP (line 5) seamlessly kills the receiv- Besides the arguably cleaner syntax, the additional control- ing loop (collapsed in line 9) and resets the driver to wait for the next flow information that can be inferred from the program is CC2420 START (line 3). the base for all features and safety guarantees introduced by CEU´ . 3.1 Deterministic and Bounded Execution 3 The Design of Ceu´ CEU´ is grounded on a precise definition of time as a discrete sequence of external input events: a sequence be- CEU´ is a concurrent language in which multiple lines cause only a single input event is handled at a time; dis- of execution—known as trails—continuously react to input crete because reactions to events are guaranteed to execute events from the environment. Waiting for an event halts the in bounded time (to be discussed further). The execution running trail until that event occurs. The environment broad- model for a CEU´ program is as follows: casts an occurring event to all active trails, which share a sin- 1. The program initiates the “boot reaction” in a single gle global time reference (the event itself). The fundamental trail. distinction between CEU´ and prevailing multi-threaded de- 2. Active trails execute until they await or terminate. This signs is the way threads are combined in programs. CEU´ pro- step is named a reaction chain, and always runs in vides Esterel-like syntactic hierarchical compositions, while bounded time. most multi-threaded systems typically only support top-level 3. The program goes idle and the environment takes con- definitions for threads. CEU´ distinguishes itself from Esterel trol. by its tight integration with C and support for shared mem- 4. On the occurrence of a new external input event, the en- ory, which also demands an effective safety analysis perme- vironment awakes all trails awaiting that event. It then ating (and affecting) all language features. goes to step 2. As an introductory example, the code in Figure 2 is The synchronous model is based on the hypothesis that extracted from our implementation of the CC2420 radio internal reactions run infinitely faster than the rate of events driver [32] and uses a par/or to control the start/stop behav- from the environment [29]. Conceptually, a program takes ior of the radio. The input events CC2420 START and CC2420 STOP no time on step 2 and is always idle on step 3. In practice, (line 1) represent the external interface of the driver with a if a new external input event occurs while a reaction chain is client application (e.g. a protocol). The driver enters the running (step 2), it is enqueued to run in the next reaction. top-level loop and awaits the starting event (line 3); upon re- When multiple trails are active at a time (i.e. awaking from quest, the driver spawns two other trails: one to await the the same event), CEU´ schedules them in the order they ap- stopping event (line 5), and another to actually receive radio pear in the program text. This policy is somewhat arbitrary, messages in a loop (collapsed in line 9). As compositions can but provides a priority scheme for trails, and also ensures a be nested, the receiving loop can be as complex as needed deterministic and reproducible execution for programs. and contain other loops and parallel constructs. However, The blinking LED in CEU´ of Figure 1 illustrates how the once the client requests to stop the driver, the trail in line 5 synchronous model leads to a simpler reasoning about con- awakes and terminates, making the par/or to also terminate currency aspects. As reaction times are assumed to be instan- and kill the receiving loop, proceeding to the statement in taneous, the blinking loop takes exactly 3 seconds. Hence, sequence. In this case, the top-level loop restarts, waiting for after 20 iterations, the accumulated time becomes 1 minute the next request to start. and the loop terminates concurrently with the 1-minute time- The par/or construct is regarded as an orthogonal pre- out in parallel. Given that the loop appears first, it will restart emption primitive [5] because the two sides in the compo- and turn on the LED for the last time. Then, the 1-minute sition need not to be tweaked with synchronization primi- timeout is scheduled, kills the whole par/or, and turns off the tives or state variables in order to affect each other. It is LED. This reasoning is actually reproducible in practice, and known that traditional multi-threaded languages cannot ex- the LED will light on exactly 21 times for every single execu- press thread termination safely [5, 28], thus being incompat- tion of this program. First-class timers are discussed in more ible with a par/or construct. depth in Section 3.5. Note that this static control inference cannot be easily extracted from the other implementations of segments can never execute during the same reaction chain: Figure 1, specially considering the presence of two different timers. var int x=1; input void A, B; The behavior for the LED timeout just described denotes par/and do var int y=0; x = x + 1; par/and do a weak abortion, because the blinking trail had the chance with await A; to execute for the last time. By inverting the two trails, the x = x * 2; y = y + 1; par/or would terminate immediately, and the blinking trail end with would not execute, denoting a strong abortion [5]. CEU´ await B; not only provides means to choose between weak and strong y = y * 2; abortion, but also detects the two conflicting possibilities and end issues a warning at compile time (to be discussed in Sec- Note that although the variable x is accessed concur- tion 3.2). rently in the first example, the assignments are both atomic Reaction chains should run in bounded time to guarantee and deterministic (due to the scheduling policy and run to that programs are responsive and can handle upcoming input completion semantics): the final value of x is always 4 (i.e. events from the environment. Similarly to Esterel [8], CEU´ (1 + 1) ∗ 2)). However, programs with concurrent accesses to requires that each possible path in a loop body contains at shared memory are suspicious, because an apparently in- least one await or break statement, thus ensuring that loops nocuous reordering of trails modifies the semantics of the never run in unbounded time. Consider the examples that program (e.g. the previous example would yield 3 with the follow: trails reordered, i.e., (1 ∗ 2 + 1)). We developed a compile-time temporal analysis for CEU´ in order to detect concurrent accesses to shared variables, as loop do loop do follows: if a variable is written in a trail segment, then a con- if
Figure 3. Automatic detection for concurrent accesses to sented in Section 3.1 and cannot appear in concurrent trails shared memory. segments, because CEU´ has no knowledge about their side The first example is suspicious because x and p can be accessed concur- effects. Also, passing variables as parameters counts as read rently (lines 11 and 14). The second example is safe because accesses accesses to them, while passing pointers counts as write ac- to y can only occur in sequence. The third example illustrates a false cesses to those types (because functions may dereference and positive in our algorithm. assign to them). This policy increases considerably the num- ber of false positives in the analysis, given that many func- tions can actually be safely called concurrently. Therefore, C do 1 CEU´ supports syntactic annotations to relax the policy ex- 2 #include
local first- max. Céu globals internal parallel Céu Céu vs data class number vs vs Component Application Language tokens events comp. ROM RAM nesC state data variables timers or trails nesC nesC nesC 383 4 5 18896 1295 CTP TestNetwork -23% 2;5;6 2 3 5 8 9% 2% Céu 295 - 2 20542 1319 nesC 418 2 8 12266 1252 SRP TestSrp -30% 2;2;2;- 1 - 1 3 5% -3% Céu 291 - 4 12836 1215 nesC 342 2 1 12708 393 DRIP TestDissemination -25% 4 1 - 1 5 8% 4% Céu 258 - - 13726 407 nesC 519 1 2 10546 283 CC2420 RadioCountToLeds -27% 3;3 1 - 2 4 2% 3% Céu 380 - - 10782 291 nesC 477 2 2 3504 72 Trickle TestTrickle -69% 2;5 - 2 3 6 22% 22% Céu 149 - - 4284 88
Figure 9. Comparison between CEU´ and nesC for the re-implemented applications. The column group Code complexity compares the number of language tokens and global variables in the sources; the group Ceu´ features shows the number of times each functionality is used in each application; the group Memory usage compares ROM and RAM consumption.
1 <...> do not represent control functionality and pose no challenges 2 event void next; regarding concurrency aspects (i.e. they are basically predi- 3 loop do cates, struct accessors, etc.). 4 await CC_RECV_FIFOP; We chose to use tokens instead of lines of code because 5 par/or do the code density is considerably lower in CEU´ , as most lines 6 await next; are composed of a single block delimiter from a structural 7 with 8 <...>//(contains awaits) composition. Note that the languages share the core syntax 9 if rxFrameLength > _MAC_PACKET_SIZE then for expressions, calls, and field accessors (based on C), and 10 emit next;// packet is too large we removed all verbose annotations from the nesC imple- 11 end mentations for a fair comparison (e.g. signal, call, command, 12 <...>//(contains awaits) etc.). The column Code complexity in Figure 9 shows a con- 13 if rxFrameLength == 0 then siderable decrease in the number of tokens for all implemen- 14 emit next;// packet is empty 15 end tations (from 23% up to 69%). 16 <...>//(contains awaits) Regarding the metric of number of globals, we catego- 17 end rized them in state and data variables. 18 end State variables are used as a mechanism to control the application flow (on the lack of a better primitive). Keep- Figure 8. Exception handling in CEU´ . ing track of them is often regarded as a difficult task, hence, The emit’s in lines 10 and 14 raise an exception to be caught by the reduction of state variables has already been proposed as a await in line 6. The emit continuations are discarded given that the metric of code complexity in a related work [12]. The im- surrounding par/or is killed. plementations in CEU´ completely eliminated state variables, given that all control patterns could be expressed with hier- archical compositions of activities assisted by internal events ure also details how many times each relevant feature of CEU´ communication. was used in the implementations. In Section 4.3, we evalu- Data variables in WSN programs usually hold message ate the performance of CEU´ with respect to responsiveness, buffers and protocol parameters (e.g. sequence numbers, i.e., its capacity to promptly acknowledge requests from the timer intervals, etc.). In event-driven systems, given that environment, such as radio packets arrivals. stacks are not retained across reactions to the environment, all data variables must be global5. Although the use of lo- 4.1 Code Complexity cal variables does not imply in reduction of lines of code We use two metrics to compare code complexity between (or tokens), the smallest the scope of a variable, the more the implementations in CEU´ and nesC: the number of tokens and the number of global variables used in the source code. 5In the case of nesC, we refer to globals as all variables defined in the Similarly to comparisons from related works [4, 12], we did top-level of a component implementation block (which are visible to all not consider code shared among the implementations, as they functions inside the component). readable and less susceptible to bugs the program becomes. Operation Duration In the CEU´ implementations, most variables could be nested Block cipher [20, 16] 1ms to a deeper scope. The column local data variables in Fig- MD5 hash [16] 3ms ure 9 shows the new depth of each global that became a local Wavelet decomposition [34] 6ms ´ variable in CEU (e.g. “2;5;6” represents globals that became SHA-1 hash [16] 8ms locals inside blocks in the 2nd, 5th, and 6th depth level). RLE compression [31] 70ms The columns below Ceu´ features in Figure 9 point out BWT compression [31] 300ms how many times each functionality has been used in the im- Image processing [30] 50–1000ms ´ plementations in CEU, helping on identifying where the re- Table 1. Durations for lengthy operations is WSNs. duction in complexity comes from. As an example, Trickle CEU´ can perform the operations in the green rows in real-time and uses 2 timers and 3 parallel compositions, resulting in at under high loads. most 6 trails active at the same time. Six coexisting trails for such a small application is justified by its highly control- intensive nature, and the almost 70% code reduction illus- 4.3 Responsiveness ´ trates the huge gains with CEU in this context. A known limitation of languages with synchronous and 4.2 Memory Usage cooperative execution is that they cannot guarantee to meet Memory is a scarce resource in WSN motes and it is im- hard real-time deadlines [10, 23]. For instance, the rigorous synchronous semantics of CEU´ forbids non-deterministic portant that CEU´ does not pose significant overheads in com- ´ parison to nesC. We evaluate ROM and RAM consumption preemption to serve high priority trails. Even though CEU by using the simplest available test applications, which were ensures bounded execution for reactions, this guarantee is C carefully tweaked to remove extra functionality, so that the not extended to function calls, which are usually preferred generated binary is dominated by the component of inter- for executing long computations (due to performance and ex- est. Then, we compiled each application twice: first with the isting code base). This way, the implementation of a radio ´ original component in nesC, and then with the ported compo- driver purely in CEU raises questions regarding its respon- siveness and we conducted two experiments in order to eval- nent in CEU´ . The column Memory usage in Figure 9 shows uate it. the consumption of ROM and RAM for the generated appli- 6 cations. With the exception of the Trickle timer, the results In the first experiment , we “stress-test” the radio driver to compare its performance in the CEU´ and nesC imple- in CEU´ remain below 10% in ROM and 5% in RAM in com- parison with the implementations in nesC. Our method and mentations. We use 10 motes that broadcast 100 consecu- results are similar to those for Protothreads [12], which is an tive packets of 20 bytes to a mote that runs a periodic time- actively supported system for Contiki [11], with a simple and consuming activity. The receiving handler simply adds the lightweight implementation based on a set of C macros. value of each received byte to a global counter. The send- ing rate of each mote is 200ms (leading to an average of 50 The results for Trickle illustrate the footprint of the run- packets per second considering the 10 motes), and the ac- time of CEU´ . The RAM overhead of 22% actually corre- tivity in the receiving mote runs every 140ms. We run the sponds to only 16 bytes: 1 byte for each of the maximum experiment varying the duration of the lengthy activity from 6 concurrent trails, and 10 bytes to handle synchronization 1 to 128 milliseconds. We assume that the lengthy operation among timers. As the complexity of the application grows, is implemented directly in C and cannot be easily split in this basic overhead tends to become irrelevant. The SRP im- smaller operations (e.g. recursive algorithms [10, 23]). This plementation shows a decrease in RAM, which comes from way, we simulated it with a simple busy wait that will keep the internal communication mechanism of CEU´ that could the driver in CEU´ unresponsive during that period. eliminate a queue. Note that both TinyOS and CEU´ de- Figure 10 shows the percentage of handled packets in fine functions to manipulate queues for timers and tasks (or CEU´ and nesC for each duration. Starting from the col- trails). Hence, as our implementations mix components in umn 8ms, the performance of CEU´ is 5% worse than the the two systems, we pay an extra overhead in ROM for all performance of nesC. Likewise, the nesC driver starts to be- applications. come unresponsive with operations that take 32ms, which We focused most of the language implementation efforts is a similar conclusion taken from TOSThreads experiments on RAM optimization, as it has been historically considered (25-bytes packets every 50ms, while running a 50-ms opera- more scarce then ROM [25]. Although we have achieved tion [23]). Table 1 shows the duration of some lengthy opera- competitive results, we expected more gains with memory tions specifically designed for WSNs found in the literature. reuse for blocks with locals in sequence, because it is some- The operations in the group with timings below 6ms could thing that cannot be done automatically by the nesC com- be used with real-time responsiveness in CEU´ (considering piler. However, we analyzed each ported application and it the proposed parameters). turned out that we had no gains at all from blocks in se- Although we did not perform specific tests to evaluate quence. Our conclusion is that sequential patterns in WSN CPU usage, the first experiment suggests that the overhead applications come either from split-phase operations, which of CEU´ over nesC is lower than 3%, based on the packet always require memory to be preserved; or from loops, which do reuse all memory, but in the same way event-driven 6The experiments use the COOJA simulator [13] running images com- systems do. piled to TelosB motes. more, WSNs are not subject to strict deadlines, being not classified as hard real-time systems [25]. 4.4 Discussion CEU´ targets control-intensive applications and provides abstractions that can express program flow specifications concisely. Our evaluation shows a considerable decrease in code complexity that comes from logical compositions of trails through the par/or and par/and constructs. They han- dle startup and termination for trails seamlessly without ex- Figure 10. Percentage of received packets depending on tra programming efforts. We believe that the small overhead the duration of the lengthy operation. in memory qualifies CEU´ as a realistic option for constrained Note the logarithmic scale on the x-axis. The packet arrival frequency devices. Furthermore, a broad safety analysis, encompassing is 20ms. The operation frequency is 140ms. In the green area, CEU´ per- all proposed concurrency mechanisms, ensures that the high forms similarly to nesC. The gray area represents the region in which degree of concurrency in WSNs does not pose safety threats nesC is still responsive. In the red area, both implementations become to applications. unresponsive (i.e. over 5% packet losses). As a summary, the following safety properties hold for all programs that successfully compile in CEU´ : • Time-bounded reactions to the environment (Sec- tions 3.1 and 3.6). • Reliable weak and strong abortion among activities (Sections 3.1 and 3.2). • No concurrency in accesses to shared variables (Sec- tion 3.2). • No concurrency in system calls sharing a resource (Sec- tion 3.3). • Finalization for blocks going out of scope (Section 3.4). Figure 11. Percentage of received packets depending on • Auto-adjustment for timers in sequence (Section 3.5). the sending frequency. • Synchronization for timers in parallel (Section 3.5). Each received packet is tied to a 8-ms operation. CEU´ is 95% responsive These properties are desirable in any application and are up to a frequency of 25ms per packet. guaranteed as preconditions in CEU´ by design. Ensuring or even extracting these properties from less restricted lan- guages requires significant manual analysis. losses for the CPU awake full time. (We performed an addi- tional test omitting the lengthy operation, yielding the same Even though the achieved expressiveness and overhead ´ result of column 1ms in Figure 10.) Note that for lengthy of CEU meet the requirements of WSNs, its design imposes operations implemented in C, there is no overhead, as the two inherent limitations: the lack of dynamic primitives that would forbid the static analysis, and the lack of hard real- generated code is the same for CEU´ and nesC. time guarantees. Regarding the first limitation, dynamic fea- In the second experiment, instead of running an activity tures are already discouraged due to resource constraints. in parallel, we use a 8-ms operation tied in sequence with For instance, even object-oriented languages targeting WSNs every packet arrival to simulate an activity such as encryp- forbid dynamic allocation [3, 33]. tion. We now run the experiment varying the rate in the To deal with the second limitation, which can be critical 10 sending motes from 600ms to 100ms. Figure 11 shows in the presence of lengthy computations, we can consider the the percentage of handled packets in CEU´ and nesC for each following approaches: (1) manually placing pause statements rate of message arrival. The results show that CEU´ is 95% in tight loops; (2) integrating CEU´ with a preemptive system. responsive up to frequency of 40 packets per second. The first option requires to rewrite the lengthy operations in The overall conclusion is that the radio driver in CEU´ per- CEU´ with pause statements so that other trails can be inter- forms as well as the original driver in nesC under high loads leaved with them. This option is the one recommended in for programs with lengthy operations of up to 4ms, which is a many related works that provide a similar cooperative prim- reasonable time for control execution and simple processing. itive (e.g. pause [6], PT YIELD [12], yield [21], post [17]). For- The range between 6ms and 16ms is a “gray area” that offers tunately, CEU´ and preemptive threads are not mutually ex- opportunities for performing more complex operations, but clusive. For instance, TOSThreads [23] proposes a message- that also requires careful analysis and testing. For instance, based integration with nesC that is safe and matches the se- the second experiment shows that the CEU´ driver can pro- mantics of CEU´ external events. cess in real time messages arriving every 35ms in sequence with a 8-ms operation. 5 Related Work Note that our experiments represent a “stress-test” sce- CEU´ is strongly influenced by Esterel [8] in its support nario that is atypical to WSNs. Protocols commonly use for compositions and reactivity to events. However, Esterel longer intervals between messages and mechanisms to avoid is focused only on control and delegates to programmers contention, such as randomized timers [26, 18]. Further- most efforts to deal with data and low-level access to the un- Language Complexity Safety 1: sequential 2: local 3: parallel 4: internal 5: deterministic 6: bounded 7: safe shared 8: finalization name year execution variables compositions events execution execution memory blocks Preemptive many ✔ ✔ ✔ rt
nesC [18] 2003 ✔ async ✔ OSM [23] 2005 ✔ ✔ ✔ Protothreads [13] 2006 ✔ ✔ TinyThreads [28] 2006 ✔ ✔ ✔ Sol [22] 2007 ✔ ✔ ✔ ✔ ✔ FlowTalk [4] 2011 ✔ ✔ Ocram [5] 2013 ✔ ✔ ✔
Céu ✔ ✔ ✔ ✔ ✔ ✔ ✔ ✔
Figure 12. Table of features found in related work to CEU´ . The languages are sorted by the date they first appeared in a publication. A gray background indicates where the feature first appeared (or a contribution if it appears in a CEU´ cell). derlying platform. For instance, read/write to shared mem- from multi-threaded languages by handling thread destruc- ory among threads is forbidden, and avoiding conflicts be- tion seamlessly [28, 5]. Compositions are fundamental for tween concurrent C calls is left to programmers [6]. CEU´ the simpler reasoning about control that made possible the deals with shared memory and C integration at its very core, safety analysis of CEU´ . Sol detects infinite loops at compile with additional support for finalization, conflict annotations, time to ensure that programs are responsive (column 6). CEU´ and a static analysis that permeates all languages aspects. adopts the same policy, which first appeared in Esterel. Inter- This way, CEU´ could not be designed easily as pure exten- nal events (column 4) can be used as a reactive alternative to sions to Esterel. shared-memory communication in synchronous languages, Figure 12 presents an overview of work related to as supported in OSM [22]. CEU´ introduces a stack-based CEU´ , pointing out supported features which are grouped by execution that also provides a restricted but safer form of those that reduce complexity and those that increase safety. subroutines. The line Preemptive represents languages with preemptive nesC provides a data-race detector for interrupt handlers scheduling [7, 23], which are summarized further. The re- (column 7), ensuring that “if a variable x is accessed by maining lines enumerate languages with goals similar to asynchronous code, then any access of x outside of an atomic those of CEU´ that follow a synchronous or cooperative ex- statement is a compile-time error” [17]. The analysis of CEU´ ecution semantics. is, instead, targeted at synchronous code and points more Many related approaches allow events to be handled in precisely when accesses can be concurrent, which is only sequence through a blocking primitive, overcoming the main possible given its restricted semantics. Furthermore, CEU´ limitation of event-driven systems (column 1 [12, 4, 27, 3, extends the analysis for system calls (commands in nesC) 21]). As a natural extension, most of them also keep the and control conflicts in trail termination. Although nesC state of local variables between reactions to the environment does not enforce bounded reactions, it promotes a cooper- (column 2). In addition, CEU´ introduces a reliable mecha- ative style among tasks, and provides asynchronous events nism to interface local pointers with the system through fi- that can preempt tasks (column 6), something that cannot be nalization blocks (column 8). Given that these approaches done in CEU´ . use cooperative scheduling, they can provide deterministic On the opposite side of concurrency models, lan- and reproducible execution (column 5). However, as far as guages with preemptive scheduling assume time indepen- we know, CEU´ is the first system to extend this guarantee for dence among processes and are more appropriate for applica- timers in parallel. tions involving algorithmic-intensive problems. Preemptive Synchronous languages first appeared in the context of scheduling is also employed in real-time operating systems WSNs through OSM [22] and Sol [21], which provide par- to provide response predictability, typically through priori- allel compositions (column 3) and distinguish themselves tized schedulers [7, 14, 15, 23]. The choice between the two models should take into account the nature of the application [11] Dunkels et al. Contiki - a lightweight and flexible operating system for and consider the trade-off between safe synchronization and tiny networked sensors. In Proceedings of LCN’04, pages 455–462, predictable responsiveness. Washington, DC, USA, 2004. IEEE Computer Society. [12] Dunkels et al. Protothreads: simplifying event-driven programming 6 Conclusion of memory-constrained embedded systems. In Proceedings of Sen- We present CEU´ , a system-level programming language Sys’06, pages 29–42. ACM, 2006. ´ [13] J. Eriksson et al. COOJA/MSPSim: interoperability testing for wire- targeting control-intensive WSN applications. CEU is based less sensor networks. In Proceedings of SIMUTools’09, page 27. on a synchronous core that combines parallel composi- ICST, 2009. tions with standard imperative primitives, such as sequences, [14] M. Farooq and T. Kunz. Operating systems for wireless sensor net- loops and assignments. Our work has two main contribu- works: A survey. Sensors, 11(6):5900–5930, 2011. [15] FreeRTOS. FreeRTOS homepage. http://www.freertos.org. tions: (1) a resource-efficient synchronous language that can [16] P. Ganesan et al. Analyzing and modeling encryption overhead for express control specifications concisely; (2) a wide set of sensor network nodes. In Proceedings of WSNA’03, pages 151–159. compile-time safety guarantees for programs with shared- ACM, 2003. memory concurrency and access to the underlying platform [17] D. Gay et al. The nesC language: A holistic approach to networked C embedded systems. In PLDI’03, pages 1–11, 2003. through . [18] O. Gnawali et al. Collection tree protocol. In Proceedings of Sen- We argue that the dictated safety mindset of our design Sys’09, pages 1–14. ACM, 2009. does not lead to a tedious and bureaucratic programming [19] Hill et al. System architecture directions for networked sensors. SIG- experience. In fact, the proposed safety analysis relies on PLAN Notices, 35:93–104, November 2000. control information that can only be inferred based on high- [20] C. Karlof et al. TinySec: a link layer security architecture for wireless sensor networks. In Proceedings of SenSys’04, pages 162–175. ACM, level control-flow mechanisms, which results in more com- 2004. pact implementations. Furthermore, CEU´ embraces practical [21] M. Karpinski and V. Cahill. High-level application development is aspects for the context WSNs, providing seamless integra- realistic for wireless sensor networks. In Proceedings of SECON’07, tion with C and a convenient syntax for timers. pages 610–619, 2007. [22] O. Kasten and K. Romer.¨ Beyond event handlers: Programming wire- EU´ The resource-efficient implementation of C is suitable less sensors with attributed state machines. In Proceedings of IPSN for constrained sensor nodes and imposes a small memory ’05, pages 45–52, April 2005. overhead in comparison to handcrafted event-driven code. [23] K. Klues et al. TOSThreads: thread-safe and non-invasive preemption in TinyOS. In Proceedings of SenSys’09, pages 127–140, New York, 7 References NY, USA, 2009. ACM. [1] A. Adya et al. Cooperative task management without manual stack [24] E. A. Lee. The problem with threads. Computer, 39(5):33–42, 2006. management. In ATEC’02, pages 289–302. USENIX Association, [25] P. Levis. Experiences from a decade of TinyOS development. In 2002. Proceedings of OSDI’12, pages 207–220, Berkeley, CA, USA, 2012. [2] A. Benveniste et al. The synchronous languages twelve years later. In USENIX Association. Proceedings of the IEEE, volume 91, pages 64–83, Jan 2003. [26] P. Levis et al. Trickle: A self-regulating mechanism for code prop- [3] Bergel et al. Flowtalk: language support for long-latency operations agation and maintenance in wireless networks. In Proceedings of in embedded devices. IEEE Transactions on Software Engineering, NSDI’04, volume 4, page 2, 2004. 37(4):526–543, 2011. [27] W. P. McCartney and N. Sridhar. Abstractions for safe concurrent pro- [4] A. Bernauer and K. Romer.¨ A comprehensive compiler-assisted gramming in networked embedded systems. In Proceedings of Sen- thread abstraction for resource-constrained systems. In Proceedings Sys’06, pages 167–180, New York, NY, USA, 2006. ACM. of IPSN’13, Philadelphia, USA, Apr. 2013. [28] ORACLE. Java thread primitive deprecation. http: [5] G. Berry. Preemption in concurrent systems. In FSTTCS, volume 761 //docs.oracle.com/javase/6/docs/technotes/guides/ of Lecture Notes in Computer Science, pages 72–93. Springer, 1993. concurrency/threadPrimitiveDeprecation.html, 2011. [6] G. Berry. The Esterel-V5 Language Primer. CMA and Inria, Sophia- [29] D. Potop-Butucaru et al. The synchronous hypothesis and syn- Antipolis, France, June 2000. Version 5.10, Release 2.0. chronous languages. In R. Zurawski, editor, Embedded Systems Hand- [7] S. Bhatti et al. MANTIS OS: an embedded multithreaded operat- book. 2005. ing system for wireless micro sensor platforms. Mob. Netw. Appl., [30] M. Rahimi et al. Cyclops: in situ image sensing and interpretation in 10:563–579, August 2005. wireless sensor networks. In Proceedings of SenSys’05, pages 192– [8] F. Boussinot and R. de Simone. The Esterel language. Proceedings of 204. ACM, 2005. the IEEE, 79(9):1293–1304, Sep 1991. [31] C. M. Sadler and M. Martonosi. Data compression algorithms for [9] N. Cooprider, W. Archer, E. Eide, D. Gay, and J. Regehr. Efficient energy-constrained devices in delay tolerant networks. In Proceedings memory safety for TinyOS. In Proceedings of SenSys’07, pages 205– of SenSys’06, pages 265–278. ACM, 2006. 218. ACM, 2007. [32] TinyOS TEPs. http://docs.tinyos.net/tinywiki/index.php/ [10] C. Duffy et al. A comprehensive experimental comparison of event TEPs, 2013. driven and multi-threaded sensor node operating systems. JNW, [33] B. L. Titzer. Virgil: Objects on the head of a pin. In ACM SIGPLAN 3(3):57–70, 2008. Notices, volume 41, pages 191–208. ACM, 2006. [34] N. Xu et al. A wireless sensor network for structural monitoring. In Proceedings of SenSys’04, pages 13–24. ACM, 2004.