PaperReading: Events Can Make Sense
Paper: Events can make sense | Frans Kaashoek and Maxwell Krohn - Academia.edu
1 Introduction
How to manage concurrency in network applications? There is much controversy about this issue. Event based system is a kind of method, it’s flexible and robust to load. But it has the problem called “stack ripping” which will complicate the code. As a result, it’s not easy to solve concurrency problems in events because of the property of being unreadable. To free events from the stack-ripping problem and retain the benefit of event-based, Tame is proposed. Tame is an event-based system, but it can be unified with thread in the same program. And it’s friendly to develop, read and debug just like the thread-based project. What’s more, Tame has excellent use of memory and great practical performance.
2 Using Tame
The core thought in Tame is to make the event-based project readable as the thread-based project by using a powerful abstraction. Tame introduces four important abstractions to implement this idea: Events Wait points、Rendezvous、Safe local variables
Events is a class which represents the abstraction of future occurrence. To create an event, using the function as:
Wait points are written as
Just using
specifies a set of expected events relevant to a wait point. Such as:
1 | { |
The
The last one is safe local variables. The variables who need to keep safe should be enclosed in a block. Then tame will preserve their values in a heap-allocated closure. Closure is a concept that is related to the control of the tamed function. Its lifetime is from the start of the tamed function to the exit of the function.
Besides, Tame can be unified with Thread in a program. It allows a simple transition between thread based code and event-based code. The basic idea of this feature is using event call to implement a thread call, and in turn, using thread call to implement an event call. An example of the former implementation is one event-based call that has
There is an example of using Tame to solve the problem about “stack ripping”:
3 Implementing Tame
Tame is implemented as a source-to-source translator. The whole procedure to translate a tamed function could be looked at as four parts. First, the Tame will generate a new opaque C++ structure for each tamed function, and this structure couldn’t be accessed by programmers. Second, Tame will rewrite the variables in closure as references. Such as:
Third, Tame rewrites points as return with different labels. Tame will add to the function one new entry and exit point per statement. Last, Tame will totally reconstruct the whole function. The preprocessor uses an extra “closure pointer” to indicate whether the function is called normally (the first time the function is called) or is reentered at a later wait point (the function may be called again when corresponding event trigger). In this process, Tame tries to avoid as much C++ parsing as possible at the cost of compiler integration. In addition, Tame also builds with the libraries and so it can be backwards compatible with legacy event code.
Tame provides a safe and automated memory management scheme, so the programmer does not need to worry about garbage collection. For the basic usage of
4 Limitation of Tame
Even though Tame provides many powerful features, more work still needs to be done. Needing some
changes for Tame so that it can support true simultaneous threading. And Tame cannot interact well with
C++ exceptions. Moreover, there may be some cost about signature changes of a tamed function all the
way up the call stack in some situations, and it will influence the interfaces of export libraries.
5 Summary
In terms of practical effects in development, Tame is not just a source-to-source translator that can simplify the codes of event-based programs, but a powerful tool to integrate event-based and thread-based. More precisely, Tame provides a simple way to interchange the event-based codes and thread-based codes. If the assignment fits the event-based method better, but it was implemented by thread because of worrying about stack ripple. It costs very little to change it to event-based with the help of Tame now. And Tame will help programmers to do the memory management and debug which reduces the workload further.
However, Tame just unifies event and thread in terms of expressivity. It does not really solve the problem of thread. When there are too many requests to a thread-based system, the overhead of thread switching may be so high that it is unacceptable. Fortunately, there are some methods that can improve the performance of thread. Capriccio is a scalable thread package, and it uses sophisticated stack management to make one stack appear as many to provide superior performance in high concurrency. SEDA uses threads and events in concert to achieve flexible scheduling and intra-process concurrency. And all these techniques can cooperate with Tame to extend Tame from uniformity in expressivity to performance. Besides, Tame needs to refine the interaction with C++ exceptions, because exceptions can not be completely avoided.
Overall, with the use of Tame, programmers can be somehow liberated from complicated code development, memory management and program maintenance, especially in high concurrency scenarios. Programmers can focus on providing efficient and robust codes without the indecision about thread-based method or event-based method.