source: doc/theses/thierry_delisle_MMath/text/together.tex @ 437b8b5

ADTast-experimentalenumpthread-emulationqualifiedEnum
Last change on this file since 437b8b5 was 67982887, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

specialize thesis directory-names

  • Property mode set to 100644
File size: 4.3 KB
Line 
1% ======================================================================
2% ======================================================================
3\chapter{Putting It All Together}
4% ======================================================================
5% ======================================================================
6
7
8\section{Threads As Monitors}
9As it was subtly alluded in section \ref{threads}, \code{thread}s in \CFA are in fact monitors, which means that all monitor features are available when using threads. For example, here is a very simple two thread pipeline that could be used for a simulator of a game engine:
10\begin{figure}[H]
11\begin{cfacode}[caption={Toy simulator using \code{thread}s and \code{monitor}s.},label={lst:engine-v1}]
12// Visualization declaration
13thread Renderer {} renderer;
14Frame * simulate( Simulator & this );
15
16// Simulation declaration
17thread Simulator{} simulator;
18void render( Renderer & this );
19
20// Blocking call used as communication
21void draw( Renderer & mutex this, Frame * frame );
22
23// Simulation loop
24void main( Simulator & this ) {
25        while( true ) {
26                Frame * frame = simulate( this );
27                draw( renderer, frame );
28        }
29}
30
31// Rendering loop
32void main( Renderer & this ) {
33        while( true ) {
34                waitfor( draw, this );
35                render( this );
36        }
37}
38\end{cfacode}
39\end{figure}
40One of the obvious complaints of the previous code snippet (other than its toy-like simplicity) is that it does not handle exit conditions and just goes on forever. Luckily, the monitor semantics can also be used to clearly enforce a shutdown order in a concise manner:
41\begin{figure}[H]
42\begin{cfacode}[caption={Same toy simulator with proper termination condition.},label={lst:engine-v2}]
43// Visualization declaration
44thread Renderer {} renderer;
45Frame * simulate( Simulator & this );
46
47// Simulation declaration
48thread Simulator{} simulator;
49void render( Renderer & this );
50
51// Blocking call used as communication
52void draw( Renderer & mutex this, Frame * frame );
53
54// Simulation loop
55void main( Simulator & this ) {
56        while( true ) {
57                Frame * frame = simulate( this );
58                draw( renderer, frame );
59
60                // Exit main loop after the last frame
61                if( frame->is_last ) break;
62        }
63}
64
65// Rendering loop
66void main( Renderer & this ) {
67        while( true ) {
68                   waitfor( draw, this );
69                or waitfor( ^?{}, this ) {
70                        // Add an exit condition
71                        break;
72                }
73
74                render( this );
75        }
76}
77
78// Call destructor for simulator once simulator finishes
79// Call destructor for renderer to signify shutdown
80\end{cfacode}
81\end{figure}
82
83\section{Fibers \& Threads}
84As mentioned in section \ref{preemption}, \CFA uses preemptive threads by default but can use fibers on demand. Currently, using fibers is done by adding the following line of code to the program~:
85\begin{cfacode}
86unsigned int default_preemption() {
87        return 0;
88}
89\end{cfacode}
90This function is called by the kernel to fetch the default preemption rate, where 0 signifies an infinite time-slice, i.e., no preemption. However, once clusters are fully implemented, it will be possible to create fibers and \glspl{uthread} in the same system, as in listing \ref{lst:fiber-uthread}
91\begin{figure}
92\begin{cfacode}[caption={Using fibers and \glspl{uthread} side-by-side in \CFA},label={lst:fiber-uthread}]
93//Cluster forward declaration
94struct cluster;
95
96//Processor forward declaration
97struct processor;
98
99//Construct clusters with a preemption rate
100void ?{}(cluster& this, unsigned int rate);
101//Construct processor and add it to cluster
102void ?{}(processor& this, cluster& cluster);
103//Construct thread and schedule it on cluster
104void ?{}(thread& this, cluster& cluster);
105
106//Declare two clusters
107cluster thread_cluster = { 10`ms };                     //Preempt every 10 ms
108cluster fibers_cluster = { 0 };                         //Never preempt
109
110//Construct 4 processors
111processor processors[4] = {
112        //2 for the thread cluster
113        thread_cluster;
114        thread_cluster;
115        //2 for the fibers cluster
116        fibers_cluster;
117        fibers_cluster;
118};
119
120//Declares thread
121thread UThread {};
122void ?{}(UThread& this) {
123        //Construct underlying thread to automatically
124        //be scheduled on the thread cluster
125        (this){ thread_cluster }
126}
127
128void main(UThread & this);
129
130//Declares fibers
131thread Fiber {};
132void ?{}(Fiber& this) {
133        //Construct underlying thread to automatically
134        //be scheduled on the fiber cluster
135        (this.__thread){ fibers_cluster }
136}
137
138void main(Fiber & this);
139\end{cfacode}
140\end{figure}
Note: See TracBrowser for help on using the repository browser.