Changes in / [7a052e34:1dcd52a3]
- Files:
-
- 3 deleted
- 16 edited
-
doc/papers/general/Makefile (modified) (1 diff)
-
doc/papers/general/Paper.tex (modified) (40 diffs)
-
doc/papers/general/figures/Cdecl.fig (deleted)
-
src/libcfa/Makefile.am (modified) (2 diffs)
-
src/libcfa/Makefile.in (modified) (2 diffs)
-
src/libcfa/concurrency/alarm.c (modified) (2 diffs)
-
src/libcfa/concurrency/alarm.h (modified) (1 diff)
-
src/libcfa/concurrency/coroutine.c (modified) (4 diffs)
-
src/libcfa/concurrency/invoke.c (modified) (4 diffs)
-
src/libcfa/concurrency/invoke.h (modified) (3 diffs)
-
src/libcfa/concurrency/kernel.c (modified) (3 diffs)
-
src/libcfa/concurrency/monitor (modified) (1 diff)
-
src/libcfa/concurrency/monitor.c (modified) (3 diffs)
-
src/libcfa/concurrency/preemption.c (modified) (3 diffs)
-
src/libcfa/exception.c (modified) (3 diffs)
-
src/libcfa/stdhdr/sys/ucontext.h (deleted)
-
src/tests/preempt_longrun/Makefile.am (modified) (2 diffs)
-
src/tests/preempt_longrun/Makefile.in (modified) (3 diffs)
-
src/tests/preempt_longrun/coroutine.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Makefile
r7a052e34 r1dcd52a3 18 18 19 19 FIGURES = ${addsuffix .tex, \ 20 Cdecl \21 20 } 22 21 -
doc/papers/general/Paper.tex
r7a052e34 r1dcd52a3 102 102 \makeatother 103 103 104 \newenvironment{cquote}{%105 \list{}{\lstset{resetmargins=true,aboveskip=0pt,belowskip=0pt}\topsep=4pt\parsep=0pt\leftmargin=\parindent\rightmargin\leftmargin}%106 \item\relax107 }{%108 \endlist109 }% cquote110 111 104 % CFA programming language, based on ANSI C (with some gcc additions) 112 105 \lstdefinelanguage{CFA}[ANSI]{C}{ … … 234 227 int forty_two = identity( 42 ); $\C{// T is bound to int, forty\_two == 42}$ 235 228 \end{lstlisting} 236 The @identity@ function above can be applied to any complete \ newterm{object type} (or @otype@).229 The @identity@ function above can be applied to any complete \emph{object type} (or @otype@). 237 230 The type variable @T@ is transformed into a set of additional implicit parameters encoding sufficient information about @T@ to create and return a variable of that type. 238 231 The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor and destructor. 239 If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \ newterm{data type} (or @dtype@).232 If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \emph{data type} (or @dtype@). 240 233 241 234 In \CFA, the polymorphism runtime-cost is spread over each polymorphic call, due to passing more arguments to polymorphic functions; … … 243 236 A design advantage is that, unlike \CC template-functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat. 244 237 245 Since bare polymorphic-types provide a restricted set of available operations, \CFA provides a \ newterm{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable.238 Since bare polymorphic-types provide a restricted set of available operations, \CFA provides a \emph{type assertion}~\cite[pp.~37-44]{Alphard} mechanism to provide further type information, where type assertions may be variable or function declarations that depend on a polymorphic type-variable. 246 239 For example, the function @twice@ can be defined using the \CFA syntax for operator overloading: 247 240 \begin{lstlisting} … … 310 303 \end{lstlisting} 311 304 Here, the single name @MAX@ replaces all the C type-specific names: @SHRT_MAX@, @INT_MAX@, @DBL_MAX@. 305 As well, restricted constant overloading is allowed for the values @0@ and @1@, which have special status in C, \eg the value @0@ is both an integer and a pointer literal, so its meaning depends on context. 306 In addition, several operations are defined in terms values @0@ and @1@, \eg: 307 \begin{lstlisting} 308 int x; 309 if (x) x++ $\C{// if (x != 0) x += 1;}$ 310 \end{lstlisting} 311 Every @if@ and iteration statement in C compares the condition with @0@, and every increment and decrement operator is semantically equivalent to adding or subtracting the value @1@ and storing the result. 312 Due to these rewrite rules, the values @0@ and @1@ have the types @zero_t@ and @one_t@ in \CFA, which allows overloading various operations for new types that seamlessly connect to all special @0@ and @1@ contexts. 313 The types @zero_t@ and @one_t@ have special built in implicit conversions to the various integral types, and a conversion to pointer types for @0@, which allows standard C code involving @0@ and @1@ to work as normal. 314 312 315 313 316 \subsection{Traits} 314 317 315 \CFA provides \ newterm{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration:318 \CFA provides \emph{traits} to name a group of type assertions, where the trait name allows specifying the same set of assertions in multiple locations, preventing repetition mistakes at each function declaration: 316 319 \begin{lstlisting} 317 320 trait summable( otype T ) { … … 337 340 Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack-allocatable, default or copy-initialized, assigned, and deleted. 338 341 339 In summation, the \CFA type-system uses \ newterm{nominal typing} for concrete types, matching with the C type-system, and \newterm{structural typing} for polymorphic types.342 In summation, the \CFA type-system uses \emph{nominal typing} for concrete types, matching with the C type-system, and \emph{structural typing} for polymorphic types. 340 343 Hence, trait names play no part in type equivalence; 341 344 the names are simply macros for a list of polymorphic assertions, which are expanded at usage sites. … … 382 385 Furthermore, writing and using preprocessor macros can be unnatural and inflexible. 383 386 384 \CC, Java, and other languages use \ newterm{generic types} to produce type-safe abstract data-types.387 \CC, Java, and other languages use \emph{generic types} to produce type-safe abstract data-types. 385 388 \CFA also implements generic types that integrate efficiently and naturally with the existing polymorphic functions, while retaining backwards compatibility with C and providing separate compilation. 386 389 However, for known concrete parameters, the generic-type definition can be inlined, like \CC templates. … … 403 406 \end{lstlisting} 404 407 405 \CFA classifies generic types as either \ newterm{concrete} or \newterm{dynamic}.408 \CFA classifies generic types as either \emph{concrete} or \emph{dynamic}. 406 409 Concrete types have a fixed memory layout regardless of type parameters, while dynamic types vary in memory layout depending on their type parameters. 407 A type may have polymorphic parameters but still be concrete, called \ newterm{dtype-static}.410 A type may have polymorphic parameters but still be concrete, called \emph{dtype-static}. 408 411 Polymorphic pointers are an example of dtype-static types, \eg @forall(dtype T) T *@ is a polymorphic type, but for any @T@, @T *@ is a fixed-sized pointer, and therefore, can be represented by a @void *@ in code generation. 409 412 … … 442 445 Though \CFA implements concrete generic-types efficiently, it also has a fully general system for dynamic generic types. 443 446 As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller. 444 Dynamic generic-types also have an \ newterm{offset array} containing structure-member offsets.447 Dynamic generic-types also have an \emph{offset array} containing structure-member offsets. 445 448 A dynamic generic-union needs no such offset array, as all members are at offset 0, but size and alignment are still necessary. 446 449 Access to members of a dynamic structure is provided at runtime via base-displacement addressing with the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime. … … 455 458 For instance, modularity is generally provided in C by including an opaque forward-declaration of a structure and associated accessor and mutator functions in a header file, with the actual implementations in a separately-compiled @.c@ file. 456 459 \CFA supports this pattern for generic types, but the caller does not know the actual layout or size of the dynamic generic-type, and only holds it by a pointer. 457 The \CFA translator automatically generates \ newterm{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller.460 The \CFA translator automatically generates \emph{layout functions} for cases where the size, alignment, and offset array of a generic struct cannot be passed into a function from that function's caller. 458 461 These layout functions take as arguments pointers to size and alignment variables and a caller-allocated array of member offsets, as well as the size and alignment of all @sized@ parameters to the generic structure (un@sized@ parameters are forbidden from being used in a context that affects layout). 459 462 Results of these layout functions are cached so that they are only computed once per type per function. %, as in the example below for @pair@. … … 479 482 Since @pair(T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the fields of both pairs and the arguments to the comparison function match in type. 480 483 481 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \ newterm{tag-structures}.484 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \emph{tag-structures}. 482 485 Sometimes information is only used for type-checking and can be omitted at runtime, \eg: 483 486 \begin{lstlisting} … … 535 538 The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site. 536 539 The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly. 537 As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \ newterm{tuple}.538 539 However, functions also use \ newterm{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg:540 As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \emph{tuple}. 541 542 However, functions also use \emph{composition} (nested calls), with the direct consequence that MRVFs must also support composition to be orthogonal with single-returning-value functions (SRVF), \eg: 540 543 \begin{lstlisting} 541 544 printf( "%d %d\n", div( 13, 5 ) ); $\C{// return values seperated into arguments}$ … … 570 573 printf( "%d %d\n", qr ); 571 574 \end{lstlisting} 572 \CFA also supports \ newterm{tuple indexing} to access single components of a tuple expression:575 \CFA also supports \emph{tuple indexing} to access single components of a tuple expression: 573 576 \begin{lstlisting} 574 577 [int, int] * p = &qr; $\C{// tuple pointer}$ … … 613 616 \subsection{Tuple Assignment} 614 617 615 An assignment where the left side is a tuple type is called \ newterm{tuple assignment}.616 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called \ newterm{multiple} and \newterm{mass assignment}, respectively.618 An assignment where the left side is a tuple type is called \emph{tuple assignment}. 619 There are two kinds of tuple assignment depending on whether the right side of the assignment operator has a tuple type or a non-tuple type, called \emph{multiple} and \emph{mass assignment}, respectively. 617 620 %\lstDeleteShortInline@% 618 621 %\par\smallskip … … 648 651 \subsection{Member Access} 649 652 650 It is also possible to access multiple fields from a single expression using a \ newterm{member-access}.653 It is also possible to access multiple fields from a single expression using a \emph{member-access}. 651 654 The result is a single tuple-valued expression whose type is the tuple of the types of the members, \eg: 652 655 \begin{lstlisting} … … 778 781 Matching against a @ttype@ parameter consumes all remaining argument components and packages them into a tuple, binding to the resulting tuple of types. 779 782 In a given parameter list, there must be at most one @ttype@ parameter that occurs last, which matches normal variadic semantics, with a strong feeling of similarity to \CCeleven variadic templates. 780 As such, @ttype@ variables are also called \ newterm{argument packs}.783 As such, @ttype@ variables are also called \emph{argument packs}. 781 784 782 785 Like variadic templates, the main way to manipulate @ttype@ polymorphic functions is via recursion. … … 850 853 \subsection{Implementation} 851 854 852 Tuples are implemented in the \CFA translator via a transformation into \ newterm{generic types}.855 Tuples are implemented in the \CFA translator via a transformation into \emph{generic types}. 853 856 For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg: 854 857 \begin{lstlisting} … … 901 904 Similarly, tuple member expressions are recursively expanded into a list of member access expressions. 902 905 903 Expressions that may contain side effects are made into \ newterm{unique expressions} before being expanded by the flattening conversion.906 Expressions that may contain side effects are made into \emph{unique expressions} before being expanded by the flattening conversion. 904 907 Each unique expression is assigned an identifier and is guaranteed to be executed exactly once: 905 908 \begin{lstlisting} … … 1044 1047 The implicit targets of the current @continue@ and @break@, \ie the closest enclosing loop or @switch@, change as certain constructs are added or removed. 1045 1048 1046 \subsection{\texorpdfstring{Enhanced \LstKeywordStyle{switch} Statement}{Enhanced switch Statement}} 1047 1048 \CFA also fixes a number of ergonomic defecits in the @switch@ statements of standard C. 1049 C can specify a number of equivalent cases by using the default ``fall-through'' semantics of @case@ clauses, \eg @case 1: case 2: case 3:@ -- this syntax is cluttered, however, so \CFA includes a more concise list syntax, @case 1, 2, 3:@. 1050 For contiguous ranges, \CFA provides an even more concise range syntax as well, @case 1~3:@; lists of ranges are also allowed in case selectors. 1051 1052 Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter. 1053 \CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases. 1054 Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword. 1055 Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below: 1056 1057 \begin{cfa} 1058 choose( i ) { 1059 case 2: 1060 printf("even "); 1061 fallthrough; 1062 case 3: case 5: case 7: 1063 printf("small prime\n"); 1064 case 4,6,8,9: 1065 printf("small composite\n"); 1066 case 13~19: 1067 printf("teen\n"); 1068 default: 1069 printf("something else\n"); 1070 } 1071 \end{cfa} 1049 \TODO{choose and fallthrough here as well?} 1050 1072 1051 1073 1052 \subsection{\texorpdfstring{\LstKeywordStyle{with} Clause / Statement}{with Clause / Statement}} … … 1112 1091 % In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided. 1113 1092 % In any programming language, some functions have a naturally close relationship with a particular data type. 1114 % Object-oriented programming allows this close relationship to be codified in the language by making such functions \ newterm{class methods} of their related data type.1093 % Object-oriented programming allows this close relationship to be codified in the language by making such functions \emph{class methods} of their related data type. 1115 1094 % Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type. 1116 1095 % When writing C functions in an object-oriented style, this un-prefixed access is swiftly missed, as access to fields of a @Foo* f@ requires an extra three characters @f->@ every time, which disrupts coding flow and clutters the produced code. … … 1226 1205 C declaration syntax is notoriously confusing and error prone. 1227 1206 For example, many C programmers are confused by a declaration as simple as: 1228 \begin{ cquote}1207 \begin{flushleft} 1229 1208 \lstDeleteShortInline@% 1230 1209 \begin{tabular}{@{}ll@{}} … … 1236 1215 \end{tabular} 1237 1216 \lstMakeShortInline@% 1238 \end{ cquote}1217 \end{flushleft} 1239 1218 Is this an array of 5 pointers to integers or a pointer to an array of 5 integers? 1240 If there is any doubt, it impliesproductivity and safety issues even for basic programs.1219 The fact this declaration is unclear to many C programmers means there are productivity and safety issues even for basic programs. 1241 1220 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site. 1242 1221 For example, a routine returning a pointer to an array of integers is defined and used in the following way: … … 1252 1231 In the following example, \R{red} is the base type and \B{blue} is qualifiers. 1253 1232 The \CFA declarations move the qualifiers to the left of the base type, \ie move the blue to the left of the red, while the qualifiers have the same meaning but are ordered left to right to specify a variable's type. 1254 \begin{ cquote}1233 \begin{quote} 1255 1234 \lstDeleteShortInline@% 1256 1235 \lstset{moredelim=**[is][\color{blue}]{+}{+}} … … 1270 1249 \end{tabular} 1271 1250 \lstMakeShortInline@% 1272 \end{ cquote}1251 \end{quote} 1273 1252 The only exception is bit field specification, which always appear to the right of the base type. 1274 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@are used to indicate a routine parameter.1253 % Specifically, the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array or function return value, and parentheses ©()© are used to indicate a routine parameter. 1275 1254 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list. 1276 For instance, variables @x@ and @y@of type pointer to integer are defined in \CFA as follows:1277 \begin{ cquote}1255 For instance, variables ©x© and ©y© of type pointer to integer are defined in \CFA as follows: 1256 \begin{quote} 1278 1257 \lstDeleteShortInline@% 1279 1258 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 1288 1267 \end{tabular} 1289 1268 \lstMakeShortInline@% 1290 \end{ cquote}1269 \end{quote} 1291 1270 The downside of this semantics is the need to separate regular and pointer declarations: 1292 \begin{ cquote}1271 \begin{quote} 1293 1272 \lstDeleteShortInline@% 1294 1273 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} … … 1305 1284 \end{tabular} 1306 1285 \lstMakeShortInline@% 1307 \end{ cquote}1286 \end{quote} 1308 1287 which is prescribing a safety benefit. 1309 1288 Other examples are: 1310 \begin{ cquote}1289 \begin{quote} 1311 1290 \lstDeleteShortInline@% 1312 1291 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} … … 1346 1325 \end{tabular} 1347 1326 \lstMakeShortInline@% 1348 \end{ cquote}1349 1350 All type qualifiers, \eg @const@, @volatile@, etc., are used in the normal way with the new declarations and also appear left to right, \eg:1351 \begin{ cquote}1327 \end{quote} 1328 1329 All type qualifiers, \eg ©const©, ©volatile©, etc., are used in the normal way with the new declarations and also appear left to right, \eg: 1330 \begin{quote} 1352 1331 \lstDeleteShortInline@% 1353 1332 \begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}} … … 1369 1348 \end{tabular} 1370 1349 \lstMakeShortInline@% 1371 \end{ cquote}1372 All declaration qualifiers, \eg @extern@, @static@, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}1350 \end{quote} 1351 All declaration qualifiers, \eg ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1373 1352 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} \eg: 1374 \begin{ cquote}1353 \begin{quote} 1375 1354 \lstDeleteShortInline@% 1376 1355 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}} … … 1392 1371 \end{tabular} 1393 1372 \lstMakeShortInline@% 1394 \end{ cquote}1395 1396 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:1397 \begin{ cquote}1373 \end{quote} 1374 1375 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine ©sizeof©: 1376 \begin{quote} 1398 1377 \lstDeleteShortInline@% 1399 1378 \begin{tabular}{@{}l@{\hspace{3em}}l@{}} 1400 1379 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1401 1380 \begin{cfa} 1402 y = ( * int)x;1403 i = sizeof( [ 5 ] * int);1381 y = (`* int`)x; 1382 i = sizeof(`[ 5 ] * int`); 1404 1383 \end{cfa} 1405 1384 & 1406 1385 \begin{cfa} 1407 y = ( int *)x;1408 i = sizeof( int * [ 5 ]);1386 y = (`int *`)x; 1387 i = sizeof(`int * [ 5 ]`); 1409 1388 \end{cfa} 1410 1389 \end{tabular} 1411 1390 \lstMakeShortInline@% 1412 \end{ cquote}1391 \end{quote} 1413 1392 1414 1393 Finally, new \CFA declarations may appear together with C declarations in the same program block, but cannot be mixed within a specific declaration. 1415 1394 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 1416 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX -likesystems.1395 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems. 1417 1396 1418 1397 1419 1398 \subsection{References} 1420 1399 1421 All variables in C have an \newterm{address}, a \newterm{value}, and a \newterm{type}; 1422 at the position in the program's memory denoted by the address, there exists a sequence of bits (the value), with the length and semantic meaning of this bit sequence defined by the type. 1423 The C type-system does not always track the relationship between a value and its address; 1424 a value that does not have a corresponding address is called a \newterm{rvalue} (for ``right-hand value''), while a value that does have an address is called a \newterm{lvalue} (for ``left-hand value''). 1425 For example, in @int x; x = 42;@ the variable expression @x@ on the left-hand-side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is a rvalue. 1426 Despite the nomenclature of ``left-hand'' and ``right-hand'', an expression's classification as lvalue or rvalue is entirely dependent on whether it has an address or not; in imperative programming, the address of a value is used for both reading and writing (mutating) a value, and as such lvalues can be converted to rvalues and read from, but rvalues cannot be mutated because they lack a location to store the updated value. 1427 1428 Within a lexical scope, lvalue expressions have an \newterm{address interpretation} for writing a value or a \newterm{value interpretation} to read a value. 1429 For example, in @x = y@, @x@ has an address interpretation, while @y@ has a value interpretation. 1430 Though this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \newterm{pointer types} to serve a similar purpose. 1431 In C, for any type @T@ there is a pointer type @T *@, the value of which is the address of a value of type @T@. 1432 A pointer rvalue can be explicitly \newterm{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@. 1400 All variables in C have an \emph{address}, a \emph{value}, and a \emph{type}; at the position in the program's memory denoted by the address, there exists a sequence of bits (the value), with the length and semantic meaning of this bit sequence defined by the type. 1401 The C type system does not always track the relationship between a value and its address; a value that does not have a corresponding address is called a \emph{rvalue} (for ``right-hand value''), while a value that does have an address is called a \emph{lvalue} (for ``left-hand value''); in @int x; x = 42;@ the variable expression @x@ on the left-hand-side of the assignment is a lvalue, while the constant expression @42@ on the right-hand-side of the assignment is a rvalue. 1402 Which address a value is located at is sometimes significant; the imperative programming paradigm of C relies on the mutation of values at specific addresses. 1403 Within a lexical scope, lvalue exressions can be used in either their \emph{address interpretation} to determine where a mutated value should be stored or in their \emph{value interpretation} to refer to their stored value; in @x = y;@ in @{ int x, y = 7; x = y; }@, @x@ is used in its address interpretation, while y is used in its value interpretation. 1404 Though this duality of interpretation is useful, C lacks a direct mechanism to pass lvalues between contexts, instead relying on \emph{pointer types} to serve a similar purpose. 1405 In C, for any type @T@ there is a pointer type @T*@, the value of which is the address of a value of type @T@; a pointer rvalue can be explicitly \emph{dereferenced} to the pointed-to lvalue with the dereference operator @*?@, while the rvalue representing the address of a lvalue can be obtained with the address-of operator @&?@. 1433 1406 1434 1407 \begin{cfa} 1435 1408 int x = 1, y = 2, * p1, * p2, ** p3; 1436 p1 = &x; $\C{// p1 points to x}$1437 p2 = &y; $\C{// p2 points to y}$1438 p3 = &p1; $\C{// p3 points to p1}$1409 p1 = &x; $\C{// p1 points to x}$ 1410 p2 = &y; $\C{// p2 points to y}$ 1411 p3 = &p1; $\C{// p3 points to p1}$ 1439 1412 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15); 1440 1413 \end{cfa} … … 1442 1415 Unfortunately, the dereference and address-of operators introduce a great deal of syntactic noise when dealing with pointed-to values rather than pointers, as well as the potential for subtle bugs. 1443 1416 For both brevity and clarity, it would be desirable to have the compiler figure out how to elide the dereference operators in a complex expression such as the assignment to @*p2@ above. 1444 However, since C defines a number of forms of \ newterm{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a user programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators.1417 However, since C defines a number of forms of \emph{pointer arithmetic}, two similar expressions involving pointers to arithmetic types (\eg @*p1 + x@ and @p1 + x@) may each have well-defined but distinct semantics, introducing the possibility that a user programmer may write one when they mean the other, and precluding any simple algorithm for elision of dereference operators. 1445 1418 To solve these problems, \CFA introduces reference types @T&@; a @T&@ has exactly the same value as a @T*@, but where the @T*@ takes the address interpretation by default, a @T&@ takes the value interpretation by default, as below: 1446 1419 1447 1420 \begin{cfa} 1448 in tx = 1, y = 2, & r1, & r2, && r3;1421 inx x = 1, y = 2, & r1, & r2, && r3; 1449 1422 &r1 = &x; $\C{// r1 points to x}$ 1450 1423 &r2 = &y; $\C{// r2 points to y}$ … … 1468 1441 This allows \CFA references to be default-initialized (\eg to a null pointer), and also to point to different addresses throughout their lifetime. 1469 1442 This rebinding is accomplished without adding any new syntax to \CFA, but simply by extending the existing semantics of the address-of operator in C. 1470 1471 1443 In C, the address of a lvalue is always a rvalue, as in general that address is not stored anywhere in memory, and does not itself have an address. 1472 1444 In \CFA, the address of a @T&@ is a lvalue @T*@, as the address of the underlying @T@ is stored in the reference, and can thus be mutated there. … … 1482 1454 if @L@ is an lvalue of type {@T &@$_1 \cdots$@ &@$_l$} where $l \ge 0$ references (@&@ symbols) then @&L@ has type {@T `*`&@$_{\color{red}1} \cdots$@ &@$_{\color{red}l}$}, \\ \ie @T@ pointer with $l$ references (@&@ symbols). 1483 1455 \end{itemize} 1456 1484 1457 Since pointers and references share the same internal representation, code using either is equally performant; in fact the \CFA compiler converts references to pointers internally, and the choice between them in user code can be made based solely on convenience. 1485 1486 By analogy to pointers, \CFA references also allow cv-qualifiers such as @const@: 1458 By analogy to pointers, \CFA references also allow cv-qualifiers: 1487 1459 1488 1460 \begin{cfa} … … 1502 1474 1503 1475 More generally, this initialization of references from lvalues rather than pointers is an instance of a ``lvalue-to-reference'' conversion rather than an elision of the address-of operator; this conversion can actually be used in any context in \CFA an implicit conversion would be allowed. 1504 Similarly, use of a the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, anal ogous to the @T *@ to @const T *@ conversion in standard C.1476 Similarly, use of a the value pointed to by a reference in an rvalue context can be thought of as a ``reference-to-rvalue'' conversion, and \CFA also includes a qualifier-adding ``reference-to-reference'' conversion, analagous to the @T *@ to @const T *@ conversion in standard C. 1505 1477 The final reference conversion included in \CFA is ``rvalue-to-reference'' conversion, implemented by means of an implicit temporary. 1506 1478 When an rvalue is used to initialize a reference, it is instead used to initialize a hidden temporary value with the same lexical scope as the reference, and the reference is initialized to the address of this temporary. 1507 1479 This allows complex values to be succinctly and efficiently passed to functions, without the syntactic overhead of explicit definition of a temporary variable or the runtime cost of pass-by-value. 1508 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \newterm{const hell} problem, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1509 1480 \CC allows a similar binding, but only for @const@ references; the more general semantics of \CFA are an attempt to avoid the \emph{const hell} problem, in which addition of a @const@ qualifier to one reference requires a cascading chain of added qualifiers. 1510 1481 1511 1482 \subsection{Constructors and Destructors} … … 1513 1484 One of the strengths of C is the control over memory management it gives programmers, allowing resource release to be more consistent and precisely timed than is possible with garbage-collected memory management. 1514 1485 However, this manual approach to memory management is often verbose, and it is useful to manage resources other than memory (\eg file handles) using the same mechanism as memory. 1515 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Aquisition Is Initialization (RAII), implemented by means of special \ newterm{constructor} and \newterm{destructor} functions; we have implemented a similar feature in \CFA.1486 \CC is well-known for an approach to manual memory management that addresses both these issues, Resource Aquisition Is Initialization (RAII), implemented by means of special \emph{constructor} and \emph{destructor} functions; we have implemented a similar feature in \CFA. 1516 1487 While RAII is a common feature of object-oriented programming languages, its inclusion in \CFA does not violate the design principle that \CFA retain the same procedural paradigm as C. 1517 1488 In particular, \CFA does not implement class-based encapsulation: neither the constructor nor any other function has privileged access to the implementation details of a type, except through the translation-unit-scope method of opaque structs provided by C. … … 1545 1516 \end{cfa} 1546 1517 1547 In the example above, a \ newterm{default constructor} (\ie one with no parameters besides the @this@ parameter) and destructor are defined for the @Array@ struct, a dynamic array of @int@.1548 @Array@ is an example of a \ newterm{managed type} in \CFA, a type with a non-trivial constructor or destructor, or with a field of a managed type.1518 In the example above, a \emph{default constructor} (\ie one with no parameters besides the @this@ parameter) and destructor are defined for the @Array@ struct, a dynamic array of @int@. 1519 @Array@ is an example of a \emph{managed type} in \CFA, a type with a non-trivial constructor or destructor, or with a field of a managed type. 1549 1520 As in the example, all instances of managed types are implicitly constructed upon allocation, and destructed upon deallocation; this ensures proper initialization and cleanup of resources contained in managed types, in this case the @data@ array on the heap. 1550 1521 The exact details of the placement of these implicit constructor and destructor calls are omitted here for brevity, the interested reader should consult \cite{Schluntz17}. 1551 1522 1552 1523 Constructor calls are intended to seamlessly integrate with existing C initialization syntax, providing a simple and familiar syntax to veteran C programmers and allowing constructor calls to be inserted into legacy C code with minimal code changes. 1553 As such, \CFA also provides syntax for \ newterm{copy initialization} and \newterm{initialization parameters}:1524 As such, \CFA also provides syntax for \emph{copy initialization} and \emph{initialization parameters}: 1554 1525 1555 1526 \begin{cfa} … … 1566 1537 In addition to initialization syntax, \CFA provides two ways to explicitly call constructors and destructors. 1567 1538 Explicit calls to constructors double as a placement syntax, useful for construction of member fields in user-defined constructors and reuse of large storage allocations. 1568 While the existing function-call syntax works for explicit calls to constructors and destructors, \CFA also provides a more concise \ newterm{operator syntax} for both:1539 While the existing function-call syntax works for explicit calls to constructors and destructors, \CFA also provides a more concise \emph{operator syntax} for both: 1569 1540 1570 1541 \begin{cfa} … … 1583 1554 For compatibility with C, a copy constructor from the first union member type is also defined. 1584 1555 For @struct@ types, each of the four functions are implicitly defined to call their corresponding functions on each member of the struct. 1585 To better simulate the behaviour of C initializers, a set of \ newterm{field constructors} is also generated for structures.1556 To better simulate the behaviour of C initializers, a set of \emph{field constructors} is also generated for structures. 1586 1557 A constructor is generated for each non-empty prefix of a structure's member-list which copy-constructs the members passed as parameters and default-constructs the remaining members. 1587 1558 To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all field constructors for that type are hidden from expression resolution; similarly, the generated default constructor is hidden upon declaration of any constructor. … … 1589 1560 1590 1561 In rare situations user programmers may not wish to have constructors and destructors called; in these cases, \CFA provides an ``escape hatch'' to not call them. 1591 If a variable is initialized using the syntax \lstinline|S x @= {}| it will be an \ newterm{unmanaged object}, and will not have constructors or destructors called.1562 If a variable is initialized using the syntax \lstinline|S x @= {}| it will be an \emph{unmanaged object}, and will not have constructors or destructors called. 1592 1563 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|Array a @= { 0, 0x0 }|, with the usual C initialization semantics. 1593 1564 In addition to the expressive power, \lstinline|@=| provides a simple path for migrating legacy C code to \CFA, by providing a mechanism to incrementally convert initializers; the \CFA design team decided to introduce a new syntax for this escape hatch because we believe that our RAII implementation will handle the vast majority of code in a desirable way, and we wished to maintain familiar syntax for this common case. … … 1598 1569 \section{Literals} 1599 1570 1600 C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, while the syntactic forms of literals of the various integer and floating-point types are very similar, differing from each other only in suffix.1601 In keeping with the general \CFA approach of adding features while respecting ``the C way'' of doing things, we have extended both C's polymorphic zero and typed literal syntax to interoperate with user-defined types, while maintaining a backwards-compatible semantics.1602 1571 1603 1572 \subsection{0/1} 1604 1573 1605 In C, @0@ has the special property that it is the only ``false'' value; by the standard, any value which compares equal to @0@ is false, while any value that compares unequal to @0@ is true. 1606 As such, an expression @x@ in any boolean context (such as the condition of an @if@ or @while@ statement, or the arguments to an @&&@, @||@, or ternary operator) can be rewritten as @x != 0@ without changing its semantics. 1607 The operator overloading feature of \CFA provides a natural means to implement this truth value comparison for arbitrary types, but the C type system is not precise enough to distinguish an equality comparison with @0@ from an equality comparison with an arbitrary integer or pointer. 1608 To provide this precision, \CFA introduces a new type @zero_t@ as type type of literal @0@ (somewhat analagous to @nullptr_t@ and @nullptr@ in \CCeleven); @zero_t@ can only take the value @0@, but has implicit conversions to the integer and pointer types so that standard C code involving @0@ continues to work properly. 1609 With this addition, the \CFA compiler rewrites @if (x)@ and similar expressions to @if ((x) != 0)@ or the appropriate analogue, and any type @T@ can be made ``truthy'' by defining an operator overload @int ?!=?(T, zero_t)@. 1610 \CC makes types truthy by adding a conversion to @bool@; prior to the addition of explicit cast operators in \CCeleven this approach had the pitfall of making truthy types transitively convertable to any numeric type; our design for \CFA avoids this issue. 1611 1612 \CFA also includes a special type for @1@, @one_t@; like @zero_t@, @one_t@ has built-in implicit conversions to the various integral types so that @1@ maintains its expected semantics in legacy code. 1613 The addition of @one_t@ allows generic algorithms to handle the unit value uniformly for types where that is meaningful. 1614 \TODO{Make this sentence true} In particular, polymorphic functions in the \CFA prelude define @++x@ and @x++@ in terms of @x += 1@, allowing users to idiomatically define all forms of increment for a type @T@ by defining the single function @T& ?+=(T&, one_t)@; analogous overloads for the decrement operators are present as well. 1574 \TODO{Some text already at the end of Section~\ref{sec:poly-fns}} 1575 1615 1576 1616 1577 \subsection{Units} … … 1641 1602 \end{cfa} 1642 1603 }% 1604 1643 1605 1644 1606 \section{Evaluation} … … 1816 1778 Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable. 1817 1779 1818 There is ongoing work on a wide range of \CFA feature extensions, including arrays with size, exceptions, concurrent primitives, modules, and user-defined conversions.1780 There is ongoing work on a wide range of \CFA feature extensions, including reference types, arrays with size, exceptions, concurrent primitives and modules. 1819 1781 (While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these additional extensions.) 1820 1782 In addition, there are interesting future directions for the polymorphism design. -
src/libcfa/Makefile.am
r7a052e34 r1dcd52a3 10 10 ## Author : Peter A. Buhr 11 11 ## Created On : Sun May 31 08:54:01 2015 12 ## Last Modified By : Peter A. Buhr13 ## Last Modified On : Fri Feb 9 15:51:24 201814 ## Update Count : 22 312 ## Last Modified By : Andrew Beach 13 ## Last Modified On : Wed Jul 26 14:15:00 2017 14 ## Update Count : 221 15 15 ############################################################################### 16 16 … … 92 92 libcfa_d_a_CFLAGS = -debug -O0 #No need for __CFA_DEBUG__ since we pass -debug 93 93 94 stdhdr = ${shell find stdhdr -type f -printf "%p "}94 stdhdr = ${shell echo stdhdr/*} 95 95 96 96 cfa_includedir = $(CFA_INCDIR) -
src/libcfa/Makefile.in
r7a052e34 r1dcd52a3 263 263 containers/result containers/vector concurrency/coroutine \ 264 264 concurrency/thread concurrency/kernel concurrency/monitor \ 265 ${shell find stdhdr -type f -printf "%p "} math gmp \ 266 bits/align.h bits/containers.h bits/defs.h bits/debug.h \ 267 bits/locks.h concurrency/invoke.h 265 ${shell echo stdhdr/*} math gmp bits/align.h bits/containers.h \ 266 bits/defs.h bits/debug.h bits/locks.h concurrency/invoke.h 268 267 HEADERS = $(nobase_cfa_include_HEADERS) 269 268 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 429 428 libcfa_d_a_SOURCES = ${libsrc} 430 429 libcfa_d_a_CFLAGS = -debug -O0 #No need for __CFA_DEBUG__ since we pass -debug 431 stdhdr = ${shell find stdhdr -type f -printf "%p "}430 stdhdr = ${shell echo stdhdr/*} 432 431 cfa_includedir = $(CFA_INCDIR) 433 432 nobase_cfa_include_HEADERS = \ -
src/libcfa/concurrency/alarm.c
r7a052e34 r1dcd52a3 41 41 void ?{}( __cfa_time_t & this, zero_t zero ) { this.val = 0; } 42 42 43 void ?{}( itimerval & this, __cfa_time_t * alarm ) with( this ){44 it_value.tv_sec = alarm->val / one_second; // seconds45 it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds46 it_interval.tv_sec = 0;47 it_interval.tv_usec = 0;43 void ?{}( itimerval & this, __cfa_time_t * alarm ) { 44 this.it_value.tv_sec = alarm->val / one_second; // seconds 45 this.it_value.tv_usec = max( (alarm->val % one_second) / one_microsecond, 1000 ); // microseconds 46 this.it_interval.tv_sec = 0; 47 this.it_interval.tv_usec = 0; 48 48 } 49 49 … … 84 84 //============================================================================================= 85 85 86 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) with( this ){86 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 87 87 this.thrd = thrd; 88 88 this.alarm = alarm; 89 89 this.period = period; 90 next = 0;91 set = false;92 kernel_alarm = false;93 } 94 95 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) with( this ){90 this.next = 0; 91 this.set = false; 92 this.kernel_alarm = false; 93 } 94 95 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = zero_time, __cfa_time_t period = zero_time ) { 96 96 this.proc = proc; 97 97 this.alarm = alarm; 98 98 this.period = period; 99 next = 0;100 set = false;101 kernel_alarm = true;99 this.next = 0; 100 this.set = false; 101 this.kernel_alarm = true; 102 102 } 103 103 -
src/libcfa/concurrency/alarm.h
r7a052e34 r1dcd52a3 114 114 }; 115 115 116 static inline void ?{}( alarm_list_t & this ) with( this ){117 head = 0;118 t ail = &head;116 static inline void ?{}( alarm_list_t & this ) { 117 this.head = 0; 118 this.tail = &this.head; 119 119 } 120 120 -
src/libcfa/concurrency/coroutine.c
r7a052e34 r1dcd52a3 39 39 //----------------------------------------------------------------------------- 40 40 // Coroutine ctors and dtors 41 void ?{}(coStack_t& this) with( this ){42 size = 65000; // size of stack43 storage = NULL; // pointer to stack44 limit = NULL; // stack grows towards stack limit45 base = NULL; // base of stack46 context = NULL; // address of cfa_context_t47 t op = NULL; // address of top of storage48 userStack = false;41 void ?{}(coStack_t& this) { 42 this.size = 65000; // size of stack 43 this.storage = NULL; // pointer to stack 44 this.limit = NULL; // stack grows towards stack limit 45 this.base = NULL; // base of stack 46 this.context = NULL; // address of cfa_context_t 47 this.top = NULL; // address of top of storage 48 this.userStack = false; 49 49 } 50 50 … … 60 60 } 61 61 62 void ?{}(coroutine_desc& this, const char * name) with( this ){62 void ?{}(coroutine_desc& this, const char * name) { 63 63 this.name = name; 64 errno_ = 0;65 state = Start;66 starter = NULL;67 last = NULL;64 this.errno_ = 0; 65 this.state = Start; 66 this.starter = NULL; 67 this.last = NULL; 68 68 } 69 69 … … 99 99 // Wrapper for co 100 100 void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 101 disable_interrupts();101 // THREAD_GETMEM( This )->disableInterrupts(); 102 102 103 103 // set state of current coroutine to inactive … … 115 115 src->state = Active; 116 116 117 enable_interrupts( __cfaabi_dbg_ctx);117 // THREAD_GETMEM( This )->enableInterrupts(); 118 118 } //ctxSwitchDirect 119 119 -
src/libcfa/concurrency/invoke.c
r7a052e34 r1dcd52a3 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 16:37:42201813 // Update Count : 512 // Last Modified On : Thu Feb 8 16:18:11 2018 13 // Update Count : 4 14 14 // 15 15 … … 93 93 struct coStack_t* stack = &get_coroutine( this )->stack; 94 94 95 #if defined( __i386 )95 #if defined( __i386__ ) 96 96 97 97 struct FakeStack { … … 114 114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7 115 115 116 #elif defined( __x86_64 )116 #elif defined( __x86_64__ ) 117 117 118 118 struct FakeStack { … … 150 150 fs->arg[0] = this; 151 151 fs->arg[1] = invoke; 152 153 152 #else 154 #error uknown hardware architecture153 #error Only __i386__ and __x86_64__ is supported for threads in cfa 155 154 #endif 156 155 } -
src/libcfa/concurrency/invoke.h
r7a052e34 r1dcd52a3 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 14:41:55201813 // Update Count : 612 // Last Modified On : Tue Jan 23 14:55:46 2018 13 // Update Count : 3 14 14 // 15 15 … … 202 202 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 203 203 204 #if defined( __i386 ) 204 #if defined( __x86_64__ ) 205 #define CtxGet( ctx ) __asm__ ( \ 206 "movq %%rsp,%0\n" \ 207 "movq %%rbp,%1\n" \ 208 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 209 #elif defined( __i386__ ) 205 210 #define CtxGet( ctx ) __asm__ ( \ 206 211 "movl %%esp,%0\n" \ 207 212 "movl %%ebp,%1\n" \ 208 : "=rm" (ctx.SP), "=rm" (ctx.FP) )209 #elif defined( __x86_64 )210 #define CtxGet( ctx ) __asm__ ( \211 "movq %%rsp,%0\n" \212 "movq %%rbp,%1\n" \213 213 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 214 214 #elif defined( __ARM_ARCH ) … … 217 217 "mov %1,%%r11\n" \ 218 218 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 219 #else220 #error unknown hardware architecture221 219 #endif 222 220 -
src/libcfa/concurrency/kernel.c
r7a052e34 r1dcd52a3 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Feb 8 23:52:19201813 // Update Count : 512 // Last Modified On : Tue Feb 6 21:51:26 2018 13 // Update Count : 4 14 14 // 15 15 16 16 //C Includes 17 17 #include <stddef.h> 18 #define ftype `ftype` 18 19 extern "C" { 19 20 #include <stdio.h> … … 23 24 #include <unistd.h> 24 25 } 26 #undef ftype 25 27 26 28 //CFA Includes … … 142 144 } 143 145 144 void ?{}(processor & this, cluster * cltr) with( this ){146 void ?{}(processor & this, cluster * cltr) { 145 147 this.cltr = cltr; 146 t erminated{ 0 };147 do_terminate = false;148 preemption_alarm = NULL;149 pending_preemption = false;148 this.terminated{ 0 }; 149 this.do_terminate = false; 150 this.preemption_alarm = NULL; 151 this.pending_preemption = false; 150 152 151 153 start( &this ); 152 154 } 153 155 154 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) with( this ){156 void ?{}(processor & this, cluster * cltr, processorCtx_t & runner) { 155 157 this.cltr = cltr; 156 t erminated{ 0 };157 do_terminate = false;158 preemption_alarm = NULL;159 pending_preemption = false;160 kernel_thread = pthread_self();158 this.terminated{ 0 }; 159 this.do_terminate = false; 160 this.preemption_alarm = NULL; 161 this.pending_preemption = false; 162 this.kernel_thread = pthread_self(); 161 163 162 164 this.runner = &runner; -
src/libcfa/concurrency/monitor
r7a052e34 r1dcd52a3 27 27 }; 28 28 29 static inline void ?{}(monitor_desc & this) with( this ){30 lock{};31 entry_queue{};32 signal_stack{};33 owner = NULL;34 recursion = 0;35 mask.accepted = NULL;36 mask.data = NULL;37 mask.size = 0;38 dtor_node = NULL;29 static inline void ?{}(monitor_desc & this) { 30 (this.lock){}; 31 (this.entry_queue){}; 32 (this.signal_stack){}; 33 this.owner = NULL; 34 this.recursion = 0; 35 this.mask.accepted = NULL; 36 this.mask.data = NULL; 37 this.mask.size = 0; 38 this.dtor_node = NULL; 39 39 } 40 40 -
src/libcfa/concurrency/monitor.c
r7a052e34 r1dcd52a3 151 151 // We already have the monitor... but where about to destroy it so the nesting will fail 152 152 // Abort! 153 abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex." , this, thrd->self_cor.name, thrd);153 abort( "Attempt to destroy monitor %p by thread \"%.256s\" (%p) in nested mutex." ); 154 154 } 155 155 … … 358 358 } 359 359 360 void ?{}(__condition_criterion_t & this ) with( this ){361 ready = false;362 t arget = NULL;363 owner = NULL;364 next = NULL;360 void ?{}(__condition_criterion_t & this ) { 361 this.ready = false; 362 this.target = NULL; 363 this.owner = NULL; 364 this.next = NULL; 365 365 } 366 366 … … 427 427 thread_desc * this_thrd = this_thread; 428 428 if ( this.monitor_count != this_thrd->monitors.size ) { 429 abort( "Signal on condition %p made with different number of monitor(s), expected % li got %li", &this, this.monitor_count, this_thrd->monitors.size );429 abort( "Signal on condition %p made with different number of monitor(s), expected %i got %i", &this, this.monitor_count, this_thrd->monitors.size ); 430 430 } 431 431 432 432 for(int i = 0; i < this.monitor_count; i++) { 433 433 if ( this.monitors[i] != this_thrd->monitors[i] ) { 434 abort( "Signal on condition %p made with different monitor, expected %p got % p", &this, this.monitors[i], this_thrd->monitors[i] );434 abort( "Signal on condition %p made with different monitor, expected %p got %i", &this, this.monitors[i], this_thrd->monitors[i] ); 435 435 } 436 436 } -
src/libcfa/concurrency/preemption.c
r7a052e34 r1dcd52a3 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 16:38:13201813 // Update Count : 1 412 // Last Modified On : Thu Feb 8 17:01:56 2018 13 // Update Count : 13 14 14 // 15 15 16 16 #include "preemption.h" 17 17 18 #define ftype `ftype` 18 19 extern "C" { 19 20 #include <errno.h> … … 22 23 #include <unistd.h> 23 24 } 25 #undef ftype 24 26 25 27 #include "bits/signal.h" … … 48 50 49 51 // Machine specific register name 50 #if defined( __i386 ) 52 #if defined(__x86_64__) 53 #define CFA_REG_IP gregs[REG_RIP] 54 #elif defined(__i386__) 51 55 #define CFA_REG_IP gregs[REG_EIP] 52 #elif defined( __x86_64 ) 53 #define CFA_REG_IP gregs[REG_RIP] 54 #elif defined( __ARM_ARCH ) 56 #elif defined(__ARM_ARCH__) 55 57 #define CFA_REG_IP arm_pc 56 #else57 #error unknown hardware architecture58 58 #endif 59 59 -
src/libcfa/exception.c
r7a052e34 r1dcd52a3 9 9 // Author : Andrew Beach 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Feb 9 14:41:55 201813 // Update Count : 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Aug 17 15:45:00 2017 13 // Update Count : 7 14 14 // 15 15 … … 453 453 // match, which is no way generic. Some more works need to be done if we want to have a single call to the try routine. 454 454 455 #if defined( __ i386 ) || defined( __x86_64)455 #if defined( __x86_64__ ) || defined( __i386__ ) 456 456 asm ( 457 457 //HEADER … … 476 476 // " .section .note.GNU-stack,\"x\",@progbits\n" 477 477 ); 478 #endif // __ i386 || __x86_64478 #endif // __x86_64__ || __i386__ -
src/tests/preempt_longrun/Makefile.am
r7a052e34 r1dcd52a3 18 18 max_time=600 19 19 preempt=1_000ul 20 debug=-debug21 20 22 21 REPEAT = ${abs_top_srcdir}/tools/repeat 23 22 TIME = /usr/bin/time -f "%E" 24 23 25 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ - O2 -DPREEMPTION_RATE=${preempt}24 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt} 26 25 CFLAGS = ${BUILD_FLAGS} 27 26 CC = @CFA_BINDIR@/@CFA_NAME@ 28 27 29 TESTS = block c oroutine create disjoint enter enter3 processor stack wait yield28 TESTS = block create disjoint enter enter3 processor stack wait yield 30 29 31 30 .INTERMEDIATE: ${TESTS} … … 37 36 38 37 % : %.c ${CC} 39 ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug)-o ${@}38 ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@} 40 39 41 40 %.run : % ${REPEAT} -
src/tests/preempt_longrun/Makefile.in
r7a052e34 r1dcd52a3 451 451 max_time = 600 452 452 preempt = 1_000ul 453 debug = -debug454 453 REPEAT = ${abs_top_srcdir}/tools/repeat 455 454 TIME = /usr/bin/time -f "%E" 456 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ - O2 -DPREEMPTION_RATE=${preempt}457 TESTS = block c oroutine create disjoint enter enter3 processor stack wait yield455 BUILD_FLAGS = -g -Wall -Wno-unused-function -quiet @CFA_FLAGS@ -debug -O2 -DPREEMPTION_RATE=${preempt} 456 TESTS = block create disjoint enter enter3 processor stack wait yield 458 457 all: all-am 459 458 … … 644 643 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ 645 644 "$$tst" $(AM_TESTS_FD_REDIRECT) 646 coroutine.log: coroutine647 @p='coroutine'; \648 b='coroutine'; \649 $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \650 --log-file $$b.log --trs-file $$b.trs \651 $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \652 "$$tst" $(AM_TESTS_FD_REDIRECT)653 645 create.log: create 654 646 @p='create'; \ … … 881 873 882 874 % : %.c ${CC} 883 ${AM_V_GEN}${CC} ${CFLAGS} ${<} $(debug)-o ${@}875 ${AM_V_GEN}${CC} ${CFLAGS} ${<} -o ${@} 884 876 885 877 %.run : % ${REPEAT}
Note:
See TracChangeset
for help on using the changeset viewer.