source: doc/theses/andrew_beach_MMath/existing.tex @ 12b4ab4

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 12b4ab4 was f28fdee, checked in by Peter A. Buhr <pabuhr@…>, 3 years ago

incorporate uw-thesis macros and CFA common macros

  • Property mode set to 100644
File size: 9.4 KB
Line 
1\chapter{\CFA Existing Features}
2
3\CFA (C-for-all)~\cite{Cforall} is an open-source project extending ISO C with modern safety and productivity features, while still ensuring backwards compatibility with C and its programmers.
4\CFA is designed to have an orthogonal feature-set based closely on the C programming paradigm (non-object-oriented) and these features can be added incrementally to an existing C code-base allowing programmers to learn \CFA on an as-needed basis.
5
6\section{Overloading and extern}
7Cforall has overloading, allowing multiple definitions of the same name to
8be defined.~\cite{Moss18}
9
10This also adds name mangling so that the assembly symbols are unique for
11different overloads. For compatability with names in C there is also a
12syntax to diable the name mangling. These unmangled names cannot be overloaded
13but act as the interface between C and \CFA code.
14
15The syntax for disabling mangling is:
16\begin{cfa}
17extern "C" {
18    ...
19}
20\end{cfa}
21
22To re-enable mangling once it is disabled the syntax is:
23\begin{cfa}
24extern "Cforall" {
25    ...
26}
27\end{cfa}
28
29Both should occur at the declaration level and effect all the declarations
30in @...@. Neither care about the state of mangling when they begin
31and will return to that state after the group is finished. So re-enabling
32is only used to nest areas of mangled and unmangled declarations.
33
34\section{References}
35\CFA adds references to C. These are auto-dereferencing pointers and use the
36same syntax as pointers except they use ampersand (@&@) instead of
37the asterisk (@*@). They can also be constaint or mutable, if they
38are mutable they may be assigned to by using the address-of operator
39(@&@) which converts them into a pointer.
40
41\section{Constructors and Destructors}
42
43Both constructors and destructors are operators, which means they are just
44functions with special names. The special names are used to define them and
45may be used to call the functions expicately. The \CFA special names are
46constructed by taking the tokens in the operators and putting @?@ where
47the arguments would go. So multiplication is @?*?@ while dereference
48is @*?@. This also make it easy to tell the difference between
49pre-fix operations (such as @++?@) and post-fix operations
50(@?++@).
51
52The special name for contructors is @?{}@, which comes from the
53initialization syntax in C. The special name for destructors is
54@^{}@. % I don't like the \^{} symbol but $^\wedge$ isn't better.
55
56Any time a type T goes out of scope the destructor matching
57@void ^?{}(T &);@ is called. In theory this is also true of
58primitive types such as @int@, but in practice those are no-ops and
59are usually omitted for optimization.
60
61\section{Polymorphism}
62\CFA uses polymorphism to create functions and types that are defined over
63different types. \CFA polymorphic declarations serve the same role as \CC
64templates or Java generics.
65
66Polymorphic declaractions start with a forall clause that goes before the
67standard (monomorphic) declaration. These declarations have the same syntax
68except that you may use the names introduced by the forall clause in them.
69
70Forall clauses are written @forall( ... )@ where @...@ becomes
71the list of polymorphic variables (local type names) and assertions, which
72repersent required operations on those types.
73
74\begin{cfa}
75forall(dtype T | { void do_once(T &); })
76void do_twice(T & value) {
77    do_once(value);
78    do_once(value);
79}
80\end{cfa}
81
82A polymorphic function can be used in the same way normal functions are.
83The polymorphics variables are filled in with concrete types and the
84assertions are checked. An assertion checked by seeing if that name of that
85type (with all the variables replaced with the concrete types) is defined at
86the the call site.
87
88As an example, even if no function named @do_once@ is not defined
89near the definition of @do_twice@ the following code will work.
90\begin{cfa}
91int quadruple(int x) {
92    void do_once(int & y) {
93        y = y * 2;
94    }
95    do_twice(x);
96    return x;
97}
98\end{cfa}
99This is not the recommended way to implement a quadruple function but it
100does work. The complier will deduce that @do_twice@'s T is an
101integer from the argument. It will then look for a definition matching the
102assertion which is the @do_once@ defined within the function. That
103function will be passed in as a function pointer to @do_twice@ and
104called within it.
105
106To avoid typing out long lists of assertions again and again there are also
107traits which collect assertions into convenent packages that can then be used
108in assertion lists instead of all of their components.
109\begin{cfa}
110trait done_once(dtype T) {
111    void do_once(T &);
112}
113\end{cfa}
114
115After this the forall list in the previous example could instead be written
116with the trait instead of the assertion itself.
117\begin{cfa}
118forall(dtype T | done_once(T))
119\end{cfa}
120
121Traits can have arbitrary number of assertions in them and are usually used to
122create short hands for, and give descriptive names to, commond groupings of
123assertions.
124
125Polymorphic structures and unions may also be defined by putting a forall
126clause before the declaration. The type variables work the same way except
127are now used in field declaractions instead of parameters and local variables.
128
129\begin{cfa}
130forall(dtype T)
131struct node {
132    node(T) * next;
133    T * data;
134}
135\end{cfa}
136
137The @node(T)@ is a use of a polymorphic structure. Polymorphic types
138must be provided their polymorphic parameters.
139
140There are many other features of polymorphism that have not given here but
141these are the ones used by the exception system.
142
143\section{Concurrency}
144
145\CFA has a number of concurrency features, @thread@s,
146@monitor@s and @mutex@ parameters, @coroutine@s and
147@generator@s. The two features that interact with the exception system
148are @thread@s and @coroutine@s; they and their supporting
149constructs will be described here.
150
151\subsection{Coroutines}
152Coroutines are routines that do not have to finish execution to hand control
153back to their caller, instead they may suspend their execution at any time
154and resume it later.
155Coroutines are not true concurrency but share some similarities and many of
156the same underpinnings and so are included as part of the \CFA threading
157library.
158
159In \CFA coroutines are created using the @coroutine@ keyword which
160works just like @struct@ except that the created structure will be
161modified by the compiler to satify the @is_coroutine@ trait.
162
163These structures act as the interface between callers and the coroutine,
164the fields are used to pass information in and out. Here is a simple example
165where the single field is used to pass the next number in a sequence out.
166\begin{cfa}
167coroutine CountUp {
168    unsigned int next;
169}
170\end{cfa}
171
172The routine part of the coroutine is a main function for the coroutine. It
173takes a reference to a coroutine object and returns nothing. In this function,
174and any functions called by this function, the suspend statement may be used
175to return execution to the coroutine's caller. When control returns to the
176function it continue from that same suspend statement instead of at the top
177of the function.
178\begin{cfa}
179void main(CountUp & this) {
180    unsigned int next = 0;
181    while (true) {
182        this.next = next;
183        suspend;
184        next = next + 1;
185    }
186}
187\end{cfa}
188
189Control is passed to the coroutine with the resume function. This includes the
190first time when the coroutine is starting up. The resume function takes a
191reference to the coroutine structure and returns the same reference. The
192return value is for easy access to communication variables. For example the
193next value from a count-up can be generated and collected in a single
194expression: @resume(count).next@.
195
196\subsection{Monitors and Mutex}
197
198True concurrency does not garrenty ordering. To get some of that ordering back
199\CFA uses monitors and mutex (mutual exclution) parameters. A monitor is
200another special declaration that contains a lock and is compatable with mutex
201parameters.
202
203Function parameters can have the @mutex@ qualifiers on reference
204arguments, for example @void example(a_monitor & mutex arg);@. When the
205function is called it will acquire the lock on all of the mutex parameters.
206
207This means that all functions that mutex on a type are part of a critical
208section and only one will ever run at a time.
209
210\subsection{Threads}
211While coroutines allow new things to be done with a single execution path
212threads actually introduce new paths of execution that continue independently.
213Now for threads to work together their must be some communication between them
214and that means the timing of certain operations does have to be known. There
215or various means of syncronization and mutual exclution provided by \CFA but
216for exceptions only the basic two -- fork and join -- are needed.
217
218Threads are created like coroutines except the keyword is changed:
219\begin{cfa}
220thread StringWorker {
221    const char * input;
222    int result;
223};
224
225void main(StringWorker & this) {
226    const char * localCopy = this.input;
227    // ... do some work, perhaps hashing the string ...
228    this.result = result;
229}
230\end{cfa}
231The main function will start executing after the fork operation and continue
232executing until it is finished. If another thread joins with this one it will
233wait until main has completed execution. In other words everything the thread
234does is between fork and join.
235
236From the outside this is the creation and destruction of the thread object.
237Fork happens after the constructor is run and join happens before the
238destructor runs. Join also happens during the @join@ function which
239can be used to join a thread earlier. If it is used the destructor does not
240join as that has already been completed.
Note: See TracBrowser for help on using the repository browser.