source: doc/proposals/concurrency/text/together.tex @ 07c1e595

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 07c1e595 was 07c1e595, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Ran ispell on the thesis

  • Property mode set to 100644
File size: 3.9 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{threads} 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{cfacode}
11// Visualization declaration
12thread Renderer {} renderer;
13Frame * simulate( Simulator & this );
14
15// Simulation declaration
16thread Simulator{} simulator;
17void render( Renderer & this );
18
19// Blocking call used as communication
20void draw( Renderer & mutex this, Frame * frame );
21
22// Simulation loop
23void main( Simulator & this ) {
24        while( true ) {
25                Frame * frame = simulate( this );
26                draw( renderer, frame );
27        }
28}
29
30// Rendering loop
31void main( Renderer & this ) {
32        while( true ) {
33                waitfor( draw, this );
34                render( this );
35        }
36}
37\end{cfacode}
38One 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 :
39\begin{cfacode}
40// Visualization declaration
41thread Renderer {} renderer;
42Frame * simulate( Simulator & this );
43
44// Simulation declaration
45thread Simulator{} simulator;
46void render( Renderer & this );
47
48// Blocking call used as communication
49void draw( Renderer & mutex this, Frame * frame );
50
51// Simulation loop
52void main( Simulator & this ) {
53        while( true ) {
54                Frame * frame = simulate( this );
55                draw( renderer, frame );
56
57                // Exit main loop after the last frame
58                if( frame->is_last ) break;
59        }
60}
61
62// Rendering loop
63void main( Renderer & this ) {
64        while( true ) {
65                   waitfor( draw, this );
66                or waitfor( ^?{}, this ) {
67                        // Add an exit condition
68                        break;
69                }
70
71                render( this );
72        }
73}
74
75// Call destructor for simulator once simulator finishes
76// Call destructor for renderer to signify shutdown
77\end{cfacode}
78
79\section{Fibers \& Threads}
80As 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~:
81\begin{cfacode}
82unsigned int default_preemption() {
83        return 0;
84}
85\end{cfacode}
86This 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 uthreads in on the same system :
87\begin{figure}
88\begin{cfacode}
89//Cluster forward declaration
90struct cluster;
91
92//Processor forward declaration
93struct processor;
94
95//Construct clusters with a preemption rate
96void ?{}(cluster& this, unsigned int rate);
97//Construct processor and add it to cluster
98void ?{}(processor& this, cluster& cluster);
99//Construct thread and schedule it on cluster
100void ?{}(thread& this, cluster& cluster);
101
102//Declare two clusters
103cluster thread_cluster = { 10`ms };                     //Preempt every 10 ms
104cluster fibers_cluster = { 0 };                         //Never preempt
105
106//Construct 4 processors
107processor processors[4] = {
108        //2 for the thread cluster
109        thread_cluster;
110        thread_cluster;
111        //2 for the fibers cluster
112        fibers_cluster;
113        fibers_cluster;
114};
115
116//Declares thread
117thread UThread {};
118void ?{}(UThread& this) {
119        //Construct underlying thread to automatically
120        //be scheduled on the thread cluster
121        (this){ thread_cluster }
122}
123
124void main(UThread & this);
125
126//Declares fibers
127thread Fiber {};
128void ?{}(Fiber& this) {
129        //Construct underlying thread to automatically
130        //be scheduled on the fiber cluster
131        (this.__thread){ fibers_cluster }
132}
133
134void main(Fiber & this);
135\end{cfacode}
136\end{figure}
Note: See TracBrowser for help on using the repository browser.