source: doc/proposals/concurrency/text/together.tex@ 6ba16fa

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 6ba16fa was 6090518, checked in by Thierry Delisle <tdelisle@…>, 8 years ago

Ran Antidoe 9 spell checker on my thesis

  • 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.