[382edbe] | 1 | \chapter{\CFA{} Existing Features}
|
---|
[553f8abe] | 2 | \label{c:existing}
|
---|
[f28fdee] | 3 |
|
---|
[382edbe] | 4 | \CFA is an open-source project extending ISO C with
|
---|
[6c79bef] | 5 | modern safety and productivity features, while still ensuring backwards
|
---|
| 6 | compatibility with C and its programmers. \CFA is designed to have an
|
---|
| 7 | orthogonal feature-set based closely on the C programming paradigm
|
---|
| 8 | (non-object-oriented) and these features can be added incrementally to an
|
---|
| 9 | existing C code-base allowing programmers to learn \CFA on an as-needed basis.
|
---|
| 10 |
|
---|
[382edbe] | 11 | Only those \CFA features pertaining to this thesis are discussed.
|
---|
[be497c6] | 12 | A familiarity with
|
---|
[382edbe] | 13 | C or C-like languages is assumed.
|
---|
[6c79bef] | 14 |
|
---|
[9af0fe2d] | 15 | \section{Overloading and \lstinline{extern}}
|
---|
[6c79bef] | 16 | \CFA has extensive overloading, allowing multiple definitions of the same name
|
---|
[67c6a47] | 17 | to be defined~\cite{Moss18}.
|
---|
[f42a6b8] | 18 | \begin{cfa}
|
---|
| 19 | char i; int i; double i;
|
---|
| 20 | int f(); double f();
|
---|
| 21 | void g( int ); void g( double );
|
---|
| 22 | \end{cfa}
|
---|
[6c79bef] | 23 | This feature requires name mangling so the assembly symbols are unique for
|
---|
| 24 | different overloads. For compatibility with names in C, there is also a syntax
|
---|
| 25 | to disable name mangling. These unmangled names cannot be overloaded but act as
|
---|
| 26 | the interface between C and \CFA code. The syntax for disabling/enabling
|
---|
| 27 | mangling is:
|
---|
[f28fdee] | 28 | \begin{cfa}
|
---|
[edc6ea2] | 29 | // name mangling on by default
|
---|
[6c79bef] | 30 | int i; // _X1ii_1
|
---|
[21f2e92] | 31 | extern "C" { // disables name mangling
|
---|
[6c79bef] | 32 | int j; // j
|
---|
[21f2e92] | 33 | extern "Cforall" { // enables name mangling
|
---|
[6c79bef] | 34 | int k; // _X1ki_1
|
---|
| 35 | }
|
---|
[edc6ea2] | 36 | // revert to no name mangling
|
---|
[6e7b969] | 37 | }
|
---|
[edc6ea2] | 38 | // revert to name mangling
|
---|
[6c79bef] | 39 | \end{cfa}
|
---|
| 40 | Both forms of @extern@ affect all the declarations within their nested lexical
|
---|
| 41 | scope and transition back to the previous mangling state when the lexical scope
|
---|
| 42 | ends.
|
---|
| 43 |
|
---|
| 44 | \section{Reference Type}
|
---|
[03c0e44] | 45 | \CFA adds a reference type to C as an auto-dereferencing pointer.
|
---|
| 46 | They work very similarly to pointers.
|
---|
[382edbe] | 47 | Reference-types are written the same way as a pointer-type but each
|
---|
[03c0e44] | 48 | asterisk (@*@) is replaced with a ampersand (@&@);
|
---|
[21f2e92] | 49 | this includes cv-qualifiers and multiple levels of reference.
|
---|
[03c0e44] | 50 |
|
---|
[382edbe] | 51 | Generally, references act like pointers with an implicate dereferencing
|
---|
| 52 | operation added to each use of the variable.
|
---|
| 53 | These automatic dereferences may be disabled with the address-of operator
|
---|
| 54 | (@&@).
|
---|
[21f2e92] | 55 |
|
---|
[382edbe] | 56 | % Check to see if these are generating errors.
|
---|
| 57 | \begin{minipage}{0,5\textwidth}
|
---|
[03c0e44] | 58 | With references:
|
---|
| 59 | \begin{cfa}
|
---|
| 60 | int i, j;
|
---|
| 61 | int & ri = i;
|
---|
| 62 | int && rri = ri;
|
---|
| 63 | rri = 3;
|
---|
[f42a6b8] | 64 | &ri = &j;
|
---|
[03c0e44] | 65 | ri = 5;
|
---|
| 66 | \end{cfa}
|
---|
| 67 | \end{minipage}
|
---|
[382edbe] | 68 | \begin{minipage}{0,5\textwidth}
|
---|
[03c0e44] | 69 | With pointers:
|
---|
[6c79bef] | 70 | \begin{cfa}
|
---|
| 71 | int i, j;
|
---|
[03c0e44] | 72 | int * pi = &i
|
---|
| 73 | int ** ppi = π
|
---|
| 74 | **ppi = 3;
|
---|
[21f2e92] | 75 | pi = &j;
|
---|
[03c0e44] | 76 | *pi = 5;
|
---|
[f28fdee] | 77 | \end{cfa}
|
---|
[03c0e44] | 78 | \end{minipage}
|
---|
[6e7b969] | 79 |
|
---|
[be497c6] | 80 | References are intended to be used when the indirection of a pointer is
|
---|
| 81 | required, but the address is not as important as the value and dereferencing
|
---|
| 82 | is the common usage.
|
---|
[382edbe] | 83 | Mutable references may be assigned to by converting them to a pointer
|
---|
[be497c6] | 84 | with a @&@ and then assigning a pointer to them, as in @&ri = &j;@ above.
|
---|
| 85 | % ???
|
---|
[6e7b969] | 86 |
|
---|
[382edbe] | 87 | \section{Operators}
|
---|
[6c79bef] | 88 |
|
---|
[be497c6] | 89 | \CFA implements operator overloading by providing special names, where
|
---|
| 90 | operator expressions are translated into function calls using these names.
|
---|
| 91 | An operator name is created by taking the operator symbols and joining them with
|
---|
[1e567ab] | 92 | @?@s to show where the arguments go.
|
---|
[382edbe] | 93 | For example,
|
---|
[be497c6] | 94 | infixed multiplication is @?*?@, while prefix dereference is @*?@.
|
---|
[edc6ea2] | 95 | This syntax make it easy to tell the difference between prefix operations
|
---|
| 96 | (such as @++?@) and post-fix operations (@?++@).
|
---|
[f42a6b8] | 97 |
|
---|
[be497c6] | 98 | As an example, here are the addition and equality operators for a point type.
|
---|
[382edbe] | 99 | \begin{cfa}
|
---|
[6071efc] | 100 | point ?+?(point a, point b) { return point{a.x + b.x, a.y + b.y}; }
|
---|
[be497c6] | 101 | int ?==?(point a, point b) { return a.x == b.x && a.y == b.y; }
|
---|
[382edbe] | 102 | {
|
---|
| 103 | assert(point{1, 2} + point{3, 4} == point{4, 6});
|
---|
| 104 | }
|
---|
| 105 | \end{cfa}
|
---|
[be497c6] | 106 | Note that this syntax works effectively but a textual transformation,
|
---|
| 107 | the compiler converts all operators into functions and then resolves them
|
---|
| 108 | normally. This means any combination of types may be used,
|
---|
| 109 | although nonsensical ones (like @double ?==?(point, int);@) are discouraged.
|
---|
| 110 | This feature is also used for all builtin operators as well,
|
---|
| 111 | although those are implicitly provided by the language.
|
---|
[382edbe] | 112 |
|
---|
| 113 | %\subsection{Constructors and Destructors}
|
---|
[be497c6] | 114 | In \CFA, constructors and destructors are operators, which means they are
|
---|
| 115 | functions with special operator names rather than type names in \Cpp.
|
---|
| 116 | Both constructors and destructors can be implicity called by the compiler,
|
---|
| 117 | however the operator names allow explicit calls.
|
---|
[f42a6b8] | 118 | % Placement new means that this is actually equivant to C++.
|
---|
[382edbe] | 119 |
|
---|
[21f2e92] | 120 | The special name for a constructor is @?{}@, which comes from the
|
---|
[382edbe] | 121 | initialization syntax in C, \eg @Example e = { ... }@.
|
---|
[be497c6] | 122 | \CFA generates a constructor call each time a variable is declared,
|
---|
| 123 | passing the initialization arguments to the constructor.
|
---|
[edc6ea2] | 124 | \begin{cfa}
|
---|
[21f2e92] | 125 | struct Example { ... };
|
---|
| 126 | void ?{}(Example & this) { ... }
|
---|
[f42a6b8] | 127 | {
|
---|
| 128 | Example a;
|
---|
| 129 | Example b = {};
|
---|
| 130 | }
|
---|
[21f2e92] | 131 | void ?{}(Example & this, char first, int num) { ... }
|
---|
[f42a6b8] | 132 | {
|
---|
| 133 | Example c = {'a', 2};
|
---|
| 134 | }
|
---|
[edc6ea2] | 135 | \end{cfa}
|
---|
[f42a6b8] | 136 | Both @a@ and @b@ will be initalized with the first constructor,
|
---|
[be497c6] | 137 | @b@ because of the explicit call and @a@ implicitly.
|
---|
| 138 | @c@ will be initalized with the second constructor.
|
---|
[f42a6b8] | 139 | Currently, there is no general way to skip initialation.
|
---|
[be497c6] | 140 | % I don't use @= anywhere in the thesis.
|
---|
[f42a6b8] | 141 |
|
---|
[6c79bef] | 142 | % I don't like the \^{} symbol but $^\wedge$ isn't better.
|
---|
[be497c6] | 143 | Similarly, destructors use the special name @^?{}@ (the @^@ has no special
|
---|
[382edbe] | 144 | meaning).
|
---|
[6c79bef] | 145 | \begin{cfa}
|
---|
[21f2e92] | 146 | void ^?{}(Example & this) { ... }
|
---|
[6c79bef] | 147 | {
|
---|
[f42a6b8] | 148 | Example d;
|
---|
[be497c6] | 149 | ^?{}(d);
|
---|
| 150 |
|
---|
| 151 | Example e;
|
---|
| 152 | } // Implicit call of ^?{}(e);
|
---|
[6c79bef] | 153 | \end{cfa}
|
---|
[edc6ea2] | 154 |
|
---|
[be497c6] | 155 | Whenever a type is defined, \CFA creates a default zero-argument
|
---|
[edc6ea2] | 156 | constructor, a copy constructor, a series of argument-per-field constructors
|
---|
| 157 | and a destructor. All user constructors are defined after this.
|
---|
[6e7b969] | 158 |
|
---|
| 159 | \section{Polymorphism}
|
---|
[6c79bef] | 160 | \CFA uses parametric polymorphism to create functions and types that are
|
---|
| 161 | defined over multiple types. \CFA polymorphic declarations serve the same role
|
---|
[29c9b23] | 162 | as \Cpp templates or Java generics. The ``parametric'' means the polymorphism is
|
---|
[6c79bef] | 163 | accomplished by passing argument operations to associate \emph{parameters} at
|
---|
| 164 | the call site, and these parameters are used in the function to differentiate
|
---|
| 165 | among the types the function operates on.
|
---|
| 166 |
|
---|
| 167 | Polymorphic declarations start with a universal @forall@ clause that goes
|
---|
| 168 | before the standard (monomorphic) declaration. These declarations have the same
|
---|
| 169 | syntax except they may use the universal type names introduced by the @forall@
|
---|
| 170 | clause. For example, the following is a polymorphic identity function that
|
---|
| 171 | works on any type @T@:
|
---|
| 172 | \begin{cfa}
|
---|
[edc6ea2] | 173 | forall( T ) T identity( T val ) { return val; }
|
---|
| 174 | int forty_two = identity( 42 );
|
---|
| 175 | char capital_a = identity( 'A' );
|
---|
[6c79bef] | 176 | \end{cfa}
|
---|
[382edbe] | 177 | Each use of a polymorphic declaration resolves its polymorphic parameters
|
---|
[edc6ea2] | 178 | (in this case, just @T@) to concrete types (@int@ in the first use and @char@
|
---|
| 179 | in the second).
|
---|
[6e7b969] | 180 |
|
---|
[6c79bef] | 181 | To allow a polymorphic function to be separately compiled, the type @T@ must be
|
---|
| 182 | constrained by the operations used on @T@ in the function body. The @forall@
|
---|
[382edbe] | 183 | clause is augmented with a list of polymorphic variables (local type names)
|
---|
[6c79bef] | 184 | and assertions (constraints), which represent the required operations on those
|
---|
| 185 | types used in a function, \eg:
|
---|
[f28fdee] | 186 | \begin{cfa}
|
---|
[382edbe] | 187 | forall( T | { void do_once(T); } )
|
---|
[6c79bef] | 188 | void do_twice(T value) {
|
---|
| 189 | do_once(value);
|
---|
| 190 | do_once(value);
|
---|
[6e7b969] | 191 | }
|
---|
[f28fdee] | 192 | \end{cfa}
|
---|
[6c79bef] | 193 |
|
---|
| 194 | A polymorphic function can be used in the same way as a normal function. The
|
---|
| 195 | polymorphic variables are filled in with concrete types and the assertions are
|
---|
| 196 | checked. An assertion is checked by verifying each assertion operation (with
|
---|
| 197 | all the variables replaced with the concrete types from the arguments) is
|
---|
| 198 | defined at a call site.
|
---|
[edc6ea2] | 199 | \begin{cfa}
|
---|
| 200 | void do_once(int i) { ... }
|
---|
| 201 | int i;
|
---|
| 202 | do_twice(i);
|
---|
| 203 | \end{cfa}
|
---|
| 204 | Any object with a type fulfilling the assertion may be passed as an argument to
|
---|
| 205 | a @do_twice@ call.
|
---|
[6c79bef] | 206 |
|
---|
| 207 | Note, a function named @do_once@ is not required in the scope of @do_twice@ to
|
---|
[29c9b23] | 208 | compile it, unlike \Cpp template expansion. Furthermore, call-site inferencing
|
---|
[be497c6] | 209 | allows local replacement of the specific parametric functions needs for a
|
---|
[6c79bef] | 210 | call.
|
---|
[f28fdee] | 211 | \begin{cfa}
|
---|
[edc6ea2] | 212 | void do_once(double y) { ... }
|
---|
[6e7b969] | 213 | int quadruple(int x) {
|
---|
[382edbe] | 214 | void do_once(int & y) { y = y * 2; }
|
---|
[21f2e92] | 215 | do_twice(x);
|
---|
[6c79bef] | 216 | return x;
|
---|
[6e7b969] | 217 | }
|
---|
[f28fdee] | 218 | \end{cfa}
|
---|
[6c79bef] | 219 | Specifically, the complier deduces that @do_twice@'s T is an integer from the
|
---|
[21f2e92] | 220 | argument @x@. It then looks for the most specific definition matching the
|
---|
[6c79bef] | 221 | assertion, which is the nested integral @do_once@ defined within the
|
---|
| 222 | function. The matched assertion function is then passed as a function pointer
|
---|
[21f2e92] | 223 | to @do_twice@ and called within it.
|
---|
[382edbe] | 224 | The global definition of @do_once@ is ignored, however if quadruple took a
|
---|
[be497c6] | 225 | @double@ argument, then the global definition would be used instead as it
|
---|
| 226 | would then be a better match.
|
---|
| 227 | \todo{cite Aaron's thesis (maybe)}
|
---|
[6c79bef] | 228 |
|
---|
[be497c6] | 229 | To avoid typing long lists of assertions, constraints can be collected into
|
---|
| 230 | convenient a package called a @trait@, which can then be used in an assertion
|
---|
[6c79bef] | 231 | instead of the individual constraints.
|
---|
[f28fdee] | 232 | \begin{cfa}
|
---|
[6c79bef] | 233 | trait done_once(T) {
|
---|
| 234 | void do_once(T);
|
---|
[6e7b969] | 235 | }
|
---|
[f28fdee] | 236 | \end{cfa}
|
---|
[6c79bef] | 237 | and the @forall@ list in the previous example is replaced with the trait.
|
---|
[f28fdee] | 238 | \begin{cfa}
|
---|
[edc6ea2] | 239 | forall(dtype T | done_once(T))
|
---|
[f28fdee] | 240 | \end{cfa}
|
---|
[6c79bef] | 241 | In general, a trait can contain an arbitrary number of assertions, both
|
---|
| 242 | functions and variables, and are usually used to create a shorthand for, and
|
---|
| 243 | give descriptive names to, common groupings of assertions describing a certain
|
---|
| 244 | functionality, like @sumable@, @listable@, \etc.
|
---|
| 245 |
|
---|
[be497c6] | 246 | Polymorphic structures and unions are defined by qualifying an aggregate type
|
---|
[6c79bef] | 247 | with @forall@. The type variables work the same except they are used in field
|
---|
| 248 | declarations instead of parameters, returns, and local variable declarations.
|
---|
[f28fdee] | 249 | \begin{cfa}
|
---|
[edc6ea2] | 250 | forall(dtype T)
|
---|
[6e7b969] | 251 | struct node {
|
---|
[9b0bb79] | 252 | node(T) * next;
|
---|
[edc6ea2] | 253 | T * data;
|
---|
[be497c6] | 254 | };
|
---|
[edc6ea2] | 255 | node(int) inode;
|
---|
[f28fdee] | 256 | \end{cfa}
|
---|
[edc6ea2] | 257 | The generic type @node(T)@ is an example of a polymorphic type usage. Like \Cpp
|
---|
| 258 | template usage, a polymorphic type usage must specify a type parameter.
|
---|
[6e7b969] | 259 |
|
---|
[6c79bef] | 260 | There are many other polymorphism features in \CFA but these are the ones used
|
---|
| 261 | by the exception system.
|
---|
[6e7b969] | 262 |
|
---|
[67c6a47] | 263 | \section{Control Flow}
|
---|
| 264 | \CFA has a number of advanced control-flow features: @generator@, @coroutine@, @monitor@, @mutex@ parameters, and @thread@.
|
---|
| 265 | The two features that interact with
|
---|
| 266 | the exception system are @coroutine@ and @thread@; they and their supporting
|
---|
[6c79bef] | 267 | constructs are described here.
|
---|
| 268 |
|
---|
| 269 | \subsection{Coroutine}
|
---|
| 270 | A coroutine is a type with associated functions, where the functions are not
|
---|
| 271 | required to finish execution when control is handed back to the caller. Instead
|
---|
| 272 | they may suspend execution at any time and be resumed later at the point of
|
---|
| 273 | last suspension. (Generators are stackless and coroutines are stackful.) These
|
---|
| 274 | types are not concurrent but share some similarities along with common
|
---|
| 275 | underpinnings, so they are combined with the \CFA threading library. Further
|
---|
| 276 | discussion in this section only refers to the coroutine because generators are
|
---|
| 277 | similar.
|
---|
| 278 |
|
---|
| 279 | In \CFA, a coroutine is created using the @coroutine@ keyword, which is an
|
---|
| 280 | aggregate type like @struct,@ except the structure is implicitly modified by
|
---|
| 281 | the compiler to satisfy the @is_coroutine@ trait; hence, a coroutine is
|
---|
| 282 | restricted by the type system to types that provide this special trait. The
|
---|
| 283 | coroutine structure acts as the interface between callers and the coroutine,
|
---|
| 284 | and its fields are used to pass information in and out of coroutine interface
|
---|
| 285 | functions.
|
---|
| 286 |
|
---|
| 287 | Here is a simple example where a single field is used to pass (communicate) the
|
---|
| 288 | next number in a sequence.
|
---|
[f28fdee] | 289 | \begin{cfa}
|
---|
[6e7b969] | 290 | coroutine CountUp {
|
---|
[9b0bb79] | 291 | unsigned int next;
|
---|
[be497c6] | 292 | };
|
---|
[6c79bef] | 293 | CountUp countup;
|
---|
[f28fdee] | 294 | \end{cfa}
|
---|
[67c6a47] | 295 | Each coroutine has a @main@ function, which takes a reference to a coroutine
|
---|
[6c79bef] | 296 | object and returns @void@.
|
---|
[382edbe] | 297 | %[numbers=left] Why numbers on this one?
|
---|
[f42a6b8] | 298 | \begin{cfa}
|
---|
[edc6ea2] | 299 | void main(CountUp & this) {
|
---|
[f42a6b8] | 300 | for (unsigned int next = 0 ; true ; ++next) {
|
---|
[be497c6] | 301 | this.next = next;
|
---|
[edc6ea2] | 302 | suspend;$\label{suspend}$
|
---|
[6c79bef] | 303 | }
|
---|
[6e7b969] | 304 | }
|
---|
[f28fdee] | 305 | \end{cfa}
|
---|
[6c79bef] | 306 | In this function, or functions called by this function (helper functions), the
|
---|
[f42a6b8] | 307 | @suspend@ statement is used to return execution to the coroutine's caller
|
---|
| 308 | without terminating the coroutine's function.
|
---|
[6c79bef] | 309 |
|
---|
| 310 | A coroutine is resumed by calling the @resume@ function, \eg @resume(countup)@.
|
---|
| 311 | The first resume calls the @main@ function at the top. Thereafter, resume calls
|
---|
| 312 | continue a coroutine in the last suspended function after the @suspend@
|
---|
[be497c6] | 313 | statement. In this case there is only one and, hence, the difference between
|
---|
| 314 | subsequent calls is the state of variables inside the function and the
|
---|
| 315 | coroutine object.
|
---|
| 316 | The return value of @resume@ is a reference to the coroutine, to make it
|
---|
| 317 | convent to access fields of the coroutine in the same expression.
|
---|
| 318 | Here is a simple example in a helper function:
|
---|
| 319 | \begin{cfa}
|
---|
| 320 | unsigned int get_next(CountUp & this) {
|
---|
| 321 | return resume(this).next;
|
---|
| 322 | }
|
---|
| 323 | \end{cfa}
|
---|
| 324 |
|
---|
| 325 | When the main function returns the coroutine halts and can no longer be
|
---|
| 326 | resumed.
|
---|
[6e7b969] | 327 |
|
---|
[67c6a47] | 328 | \subsection{Monitor and Mutex Parameter}
|
---|
[6c79bef] | 329 | Concurrency does not guarantee ordering; without ordering results are
|
---|
| 330 | non-deterministic. To claw back ordering, \CFA uses monitors and @mutex@
|
---|
| 331 | (mutual exclusion) parameters. A monitor is another kind of aggregate, where
|
---|
| 332 | the compiler implicitly inserts a lock and instances are compatible with
|
---|
| 333 | @mutex@ parameters.
|
---|
| 334 |
|
---|
| 335 | A function that requires deterministic (ordered) execution, acquires mutual
|
---|
| 336 | exclusion on a monitor object by qualifying an object reference parameter with
|
---|
| 337 | @mutex@.
|
---|
[f42a6b8] | 338 | \begin{cfa}
|
---|
| 339 | void example(MonitorA & mutex argA, MonitorB & mutex argB);
|
---|
| 340 | \end{cfa}
|
---|
[6c79bef] | 341 | When the function is called, it implicitly acquires the monitor lock for all of
|
---|
| 342 | the mutex parameters without deadlock. This semantics means all functions with
|
---|
| 343 | the same mutex type(s) are part of a critical section for objects of that type
|
---|
| 344 | and only one runs at a time.
|
---|
[6e7b969] | 345 |
|
---|
[67c6a47] | 346 | \subsection{Thread}
|
---|
[6c79bef] | 347 | Functions, generators, and coroutines are sequential so there is only a single
|
---|
| 348 | (but potentially sophisticated) execution path in a program. Threads introduce
|
---|
| 349 | multiple execution paths that continue independently.
|
---|
[6e7b969] | 350 |
|
---|
[6c79bef] | 351 | For threads to work safely with objects requires mutual exclusion using
|
---|
| 352 | monitors and mutex parameters. For threads to work safely with other threads,
|
---|
| 353 | also requires mutual exclusion in the form of a communication rendezvous, which
|
---|
[67c6a47] | 354 | also supports internal synchronization as for mutex objects. For exceptions,
|
---|
| 355 | only two basic thread operations are important: fork and join.
|
---|
[6e7b969] | 356 |
|
---|
[6c79bef] | 357 | Threads are created like coroutines with an associated @main@ function:
|
---|
[f28fdee] | 358 | \begin{cfa}
|
---|
[6e7b969] | 359 | thread StringWorker {
|
---|
[6c79bef] | 360 | const char * input;
|
---|
| 361 | int result;
|
---|
[6e7b969] | 362 | };
|
---|
| 363 | void main(StringWorker & this) {
|
---|
[6c79bef] | 364 | const char * localCopy = this.input;
|
---|
| 365 | // ... do some work, perhaps hashing the string ...
|
---|
| 366 | this.result = result;
|
---|
[6e7b969] | 367 | }
|
---|
[6c79bef] | 368 | {
|
---|
| 369 | StringWorker stringworker; // fork thread running in "main"
|
---|
[be497c6] | 370 | } // Implicit call to join(stringworker), waits for completion.
|
---|
[f28fdee] | 371 | \end{cfa}
|
---|
[6c79bef] | 372 | The thread main is where a new thread starts execution after a fork operation
|
---|
| 373 | and then the thread continues executing until it is finished. If another thread
|
---|
| 374 | joins with an executing thread, it waits until the executing main completes
|
---|
| 375 | execution. In other words, everything a thread does is between a fork and join.
|
---|
| 376 |
|
---|
| 377 | From the outside, this behaviour is accomplished through creation and
|
---|
| 378 | destruction of a thread object. Implicitly, fork happens after a thread
|
---|
| 379 | object's constructor is run and join happens before the destructor runs. Join
|
---|
| 380 | can also be specified explicitly using the @join@ function to wait for a
|
---|
| 381 | thread's completion independently from its deallocation (\ie destructor
|
---|
| 382 | call). If @join@ is called explicitly, the destructor does not implicitly join.
|
---|