Changeset 69ce455


Ignore:
Timestamp:
Feb 6, 2018, 11:42:52 AM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
7d94d805
Parents:
7ad6b6d (diff), 5f95b5f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/general/Paper.tex

    r7ad6b6d r69ce455  
    6161\newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}}
    6262\newcommand{\CRT}{\global\columnposn=\gcolumnposn}
     63
     64% Denote newterms in particular font and index them without particular font and in lowercase, e.g., \newterm{abc}.
     65% The option parameter provides an index term different from the new term, e.g., \newterm[\texttt{abc}]{abc}
     66% The star version does not lowercase the index information, e.g., \newterm*{IBM}.
     67\newcommand{\newtermFontInline}{\emph}
     68\newcommand{\newterm}{\@ifstar\@snewterm\@newterm}
     69\newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi}
     70\newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}
    6371
    6472% Latin abbreviation
     
    10401048\TODO{choose and fallthrough here as well?}
    10411049
     1050
    10421051\subsection{\texorpdfstring{\LstKeywordStyle{with} Clause / Statement}{with Clause / Statement}}
    10431052\label{s:WithClauseStatement}
    10441053
    1045 In any programming language, some functions have a naturally close relationship with a particular data type.
    1046 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.
    1047 Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type.
    1048 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.
    1049 
    1050 \TODO{Fill out section. Be sure to mention arbitrary expressions in with-blocks, recent change driven by Thierry to prioritize field name over parameters.}
    1051 
    1052 
    1053 In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided.
     1054Grouping heterogenous data into \newterm{aggregate}s is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
     1055\begin{cfa}
     1056struct S {                                                              $\C{// aggregate}$
     1057        char c;                                                         $\C{// fields}$
     1058        int i;
     1059        double d;
     1060};
     1061S s, as[10];
     1062\end{cfa}
     1063However, routines manipulating aggregates have repeition of the aggregate name to access its containing fields:
     1064\begin{cfa}
     1065void f( S s ) {
     1066        `s.`c; `s.`i; `s.`d;                            $\C{// access containing fields}$
     1067}
     1068\end{cfa}
     1069A similar situation occurs in object-oriented programming, \eg \CC:
    10541070\begin{C++}
    10551071class C {
    1056         int i, j;
    1057         int mem() {                                     $\C{\color{red}// implicit "this" parameter}$
    1058                 i = 1;                                  $\C{\color{red}// this-{\textgreater}i}$
    1059                 j = 2;                                  $\C{\color{red}// this-{\textgreater}j}$
     1072        char c;                                                         $\C{// fields}$
     1073        int i;
     1074        double d;
     1075        int mem() {                                                     $\C{// implicit "this" parameter}$
     1076                `this->`c; `this->`i; `this->`d;$\C{// access containing fields}$
    10601077        }
    10611078}
    10621079\end{C++}
    1063 Since \CFA is non-object-oriented, the equivalent object-oriented program looks like:
     1080Nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of nested lexical-scoping.
     1081
     1082% In object-oriented programming, there is an implicit first parameter, often names @self@ or @this@, which is elided.
     1083% In any programming language, some functions have a naturally close relationship with a particular data type.
     1084% 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.
     1085% Class methods have certain privileges with respect to their associated data type, notably un-prefixed access to the fields of that data type.
     1086% 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.
     1087%
     1088% \TODO{Fill out section. Be sure to mention arbitrary expressions in with-blocks, recent change driven by Thierry to prioritize field name over parameters.}
     1089
     1090\CFA provides a @with@ clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided aggregate qualification to fields by opening a scope containing field identifiers.
     1091Hence, the qualified fields become variables, and making it easier to optimizing field references in a block.
    10641092\begin{cfa}
    1065 struct S { int i, j; };
    1066 int mem( S & `this` ) {                 $\C{// explicit "this" parameter}$
    1067         `this.`i = 1;                           $\C{// "this" is not elided}$
    1068         `this.`j = 2;
     1093void f( S s ) `with s` {                                $\C{// with clause}$
     1094        c; i; d;                                                        $\C{\color{red}// s.c, s.i, s.d}$
    10691095}
    10701096\end{cfa}
    1071 but it is cumbersome having to write "this." many times in a member.
    1072 
    1073 \CFA provides a @with@ clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "@this.@" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references.
     1097and the equivalence for object-style programming is:
    10741098\begin{cfa}
    1075 int mem( S &this ) `with this` { $\C{// with clause}$
    1076         i = 1;                                          $\C{\color{red}// this.i}$
    1077         j = 2;                                          $\C{\color{red}// this.j}$
     1099int mem( S & this ) `with this` {               $\C{// with clause}$
     1100        c; i; d;                                                        $\C{\color{red}// this.c, this.i, this.d}$
    10781101}
    10791102\end{cfa}
    1080 which extends to multiple routine parameters:
     1103The key generality over the object-oriented approach is that one aggregate parameter \lstinline[language=C++]@this@ is not treated specially over other aggregate parameters:
    10811104\begin{cfa}
    10821105struct T { double m, n; };
    1083 int mem2( S & this1, T & this2 ) `with this1, this2` {
    1084         i = 1; j = 2;
    1085         m = 1.0; n = 2.0;
     1106int mem( S & s, T & t ) `with s, t` {   $\C{// multiple aggregate parameters}$
     1107        c; i; d;                                                        $\C{\color{red}// s.c, s.i, s.d}$
     1108        m; n;                                                           $\C{\color{red}// t.m, t.n}$
     1109}
     1110\end{cfa}
     1111The equivalent object-oriented style is:
     1112\begin{cfa}
     1113int S::mem( T & t ) {                                   $\C{// multiple aggregate parameters}$
     1114        c; i; d;                                                        $\C{\color{red}// this-\textgreater.c, this-\textgreater.i, this-\textgreater.d}$
     1115        `t.`m; `t.`n;
    10861116}
    10871117\end{cfa}
     
    10921122        struct S1 { ... } s1;
    10931123        struct S2 { ... } s2;
    1094         `with s1` {                                     $\C{// with statement}$
     1124        `with s1` {                                             $\C{// with statement}$
    10951125                // access fields of s1 without qualification
    1096                 `with s2` {                             $\C{// nesting}$
     1126                `with s2` {                                     $\C{// nesting}$
    10971127                        // access fields of s1 and s2 without qualification
    10981128                }
     
    11101140struct T { int i; int k; int m } b, c;
    11111141`with a, b` {
    1112         j + k;                                          $\C{// unambiguous, unique names define unique types}$
    1113         i;                                                      $\C{// ambiguous, same name and type}$
    1114         a.i + b.i;                                      $\C{// unambiguous, qualification defines unique names}$
    1115         m;                                                      $\C{// ambiguous, same name and no context to define unique type}$
    1116         m = 5.0;                                        $\C{// unambiguous, same name and context defines unique type}$
    1117         m = 1;                                          $\C{// unambiguous, same name and context defines unique type}$
    1118 }
    1119 `with c` { ... }                                $\C{// ambiguous, same name and no context}$
    1120 `with (S)c` { ... }                             $\C{// unambiguous, same name and cast defines unique type}$
     1142        j + k;                                                  $\C{// unambiguous, unique names define unique types}$
     1143        i;                                                              $\C{// ambiguous, same name and type}$
     1144        a.i + b.i;                                              $\C{// unambiguous, qualification defines unique names}$
     1145        m;                                                              $\C{// ambiguous, same name and no context to define unique type}$
     1146        m = 5.0;                                                $\C{// unambiguous, same name and context defines unique type}$
     1147        m = 1;                                                  $\C{// unambiguous, same name and context defines unique type}$
     1148}
     1149`with c` { ... }                                        $\C{// ambiguous, same name and no context}$
     1150`with (S)c` { ... }                                     $\C{// unambiguous, same name and cast defines unique type}$
    11211151\end{cfa}
    11221152
     
    12341264\TODO{finish reference conversions; look at user manual}
    12351265
     1266
    12361267\subsection{Constructors and Destructors}
    12371268
     
    12521283
    12531284\TODO{Some text already at the end of Section~\ref{sec:poly-fns}}
     1285
    12541286
    12551287\subsection{Units}
  • src/driver/cfa.cc

    r7ad6b6d r69ce455  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  1 22:26:10 2018
    13 // Update Count     : 163
     12// Last Modified On : Mon Feb  5 22:05:28 2018
     13// Update Count     : 166
    1414//
    1515
     
    258258                #endif
    259259
     260                args[nargs] = "-Xlinker";
     261                nargs += 1;
     262                args[nargs] = "--undefined=__cfaabi_dbg_bits_write";
     263                nargs += 1;
     264                args[nargs] = "-Xlinker";
     265                nargs += 1;
     266                args[nargs] = "--undefined=__cfaabi_interpose_startup";
     267                nargs += 1;
     268
    260269                // include the cfa library in case it's needed
    261270                args[nargs] = "-L" CFA_LIBDIR;
     
    273282                args[nargs] = "-lrt";
    274283                nargs += 1;
    275                 args[nargs] = "-Xlinker";
    276                 nargs += 1;
    277                 args[nargs] = "--undefined=__cfaabi_dbg_bits_write";
    278                 nargs += 1;
    279                 args[nargs] = "-Xlinker";
    280                 nargs += 1;
    281                 args[nargs] = "--undefined=__cfaabi_interpose_startup";
    282                 nargs += 1;
    283 
    284         } // if
    285 #endif //HAVE_LIBCFA
     284        } // if
     285#endif // HAVE_LIBCFA
    286286
    287287        // Add exception flags (unconditionally)
     
    333333                nargs += 1;
    334334        } // if
     335
     336    args[nargs] = "-Xlinker";                                                   // used by backtrace
     337    nargs += 1;
     338    args[nargs] = "-export-dynamic";
     339    nargs += 1;
    335340
    336341        // execute the compilation command
  • src/libcfa/concurrency/invoke.h

    r7ad6b6d r69ce455  
    121121                // coroutine body used to store context
    122122                struct coroutine_desc  self_cor;
     123
     124                // current active context
     125                struct coroutine_desc * curr_cor;
    123126
    124127                // monitor body used for mutual exclusion
  • src/libcfa/concurrency/kernel.c

    r7ad6b6d r69ce455  
    108108void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) {
    109109        self_cor{ info };
     110        curr_cor = &self_cor;
     111        self_mon.owner = &this;
     112        self_mon.recursion = 1;
     113        self_mon_p = &self_mon;
     114        next = NULL;
     115        __cfaabi_dbg_debug_do(
     116                dbg_next = NULL;
     117                dbg_prev = NULL;
     118                __cfaabi_dbg_thread_register(&this);
     119        )
     120
     121        monitors{ &self_mon_p, 1, (fptr_t)0 };
    110122}
    111123
     
    225237// from the processor coroutine to the target thread
    226238void runThread(processor * this, thread_desc * dst) {
     239        assert(dst->curr_cor);
    227240        coroutine_desc * proc_cor = get_coroutine(*this->runner);
    228         coroutine_desc * thrd_cor = get_coroutine(dst);
     241        coroutine_desc * thrd_cor = dst->curr_cor;
    229242
    230243        //Reset the terminating actions here
     
    237250        ThreadCtxSwitch(proc_cor, thrd_cor);
    238251        // when ThreadCtxSwitch returns we are back in the processor coroutine
     252}
     253
     254void returnToKernel() {
     255        coroutine_desc * proc_cor = get_coroutine(*this_processor->runner);
     256        coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
     257        ThreadCtxSwitch(thrd_cor, proc_cor);
    239258}
    240259
     
    360379        disable_interrupts();
    361380        verify( !preemption_enabled );
    362         suspend();
     381        returnToKernel();
    363382        verify( !preemption_enabled );
    364383        enable_interrupts( __cfaabi_dbg_ctx );
     
    371390
    372391        verify( !preemption_enabled );
    373         suspend();
     392        returnToKernel();
    374393        verify( !preemption_enabled );
    375394
     
    383402
    384403        verify( !preemption_enabled );
    385         suspend();
     404        returnToKernel();
    386405        verify( !preemption_enabled );
    387406
     
    397416
    398417        verify( !preemption_enabled );
    399         suspend();
     418        returnToKernel();
    400419        verify( !preemption_enabled );
    401420
     
    410429
    411430        verify( !preemption_enabled );
    412         suspend();
     431        returnToKernel();
    413432        verify( !preemption_enabled );
    414433
     
    425444
    426445        verify( !preemption_enabled );
    427         suspend();
     446        returnToKernel();
    428447        verify( !preemption_enabled );
    429448
     
    437456        this_processor->finish.thrd        = thrd;
    438457
    439         suspend();
     458        returnToKernel();
    440459}
    441460
     
    502521        // which is currently here
    503522        mainProcessor->do_terminate = true;
    504         suspend();
     523        returnToKernel();
    505524
    506525        // THE SYSTEM IS NOW COMPLETELY STOPPED
  • src/libcfa/concurrency/thread.c

    r7ad6b6d r69ce455  
    3434        self_cor{};
    3535        self_cor.name = "Anonymous Coroutine";
     36        curr_cor = &self_cor;
    3637        self_mon.owner = &this;
    3738        self_mon.recursion = 1;
     
    104105        dst->state = Active;
    105106
    106         //update the last resumer
    107         dst->last = src;
    108 
    109107        // set new coroutine that the processor is executing
    110108        // and context switch to it
  • src/libcfa/interpose.c

    r7ad6b6d r69ce455  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:27:33 2017
    13 // Update Count     : 1
     12// Last Modified On : Mon Feb  5 23:40:04 2018
     13// Update Count     : 17
    1414//
    1515
     
    3232#include "bits/signal.h"
    3333#include "startup.h"
    34 
    35 void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    3634
    3735typedef void (*generic_fptr_t)(void);
     
    9290void sigHandler_abort( __CFA_SIGPARMS__ );
    9391
    94 void __cfaabi_interpose_startup() {
    95         const char *version = NULL;
    96 
    97         INIT_REALRTN( abort, version );
    98         INIT_REALRTN( exit, version );
    99 
    100         __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );      // Failure handler
    101         __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );      // Failure handler
    102         __kernel_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO );      // Failure handler
     92extern "C" {
     93        void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
     94        void __cfaabi_interpose_startup( void ) {
     95                const char *version = NULL;
     96
     97                INIT_REALRTN( abort, version );
     98                INIT_REALRTN( exit, version );
     99
     100                __kernel_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler
     101                __kernel_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler
     102                __kernel_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO ); // Failure handler
     103        }
    103104}
    104105
     
    108109
    109110extern "C" {
    110         void abort (void) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
     111        void abort( void ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
    111112                abortf( NULL );
    112113        }
    113114
    114         void exit (int __status) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
     115        void exit( int __status ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
    115116                libc_exit(__status);
    116117        }
     
    121122}
    122123
    123 void * kernel_abort    (void) __attribute__ ((__nothrow__, __leaf__, __weak__)) { return NULL; }
    124 void   kernel_abort_msg(void * data, char * buffer, int size) __attribute__ ((__nothrow__, __leaf__, __weak__)) {}
     124void * kernel_abort    ( void ) __attribute__ ((__nothrow__, __leaf__, __weak__)) { return NULL; }
     125void   kernel_abort_msg( void * data, char * buffer, int size ) __attribute__ ((__nothrow__, __leaf__, __weak__)) {}
    125126
    126127enum { abort_text_size = 1024 };
     
    133134                int len;
    134135
    135                 if( fmt ) {
     136                if ( fmt ) {
    136137                        va_list args;
    137138                        va_start( args, fmt );
     
    142143
    143144                        __cfaabi_dbg_bits_write( abort_text, len );
    144                         __cfaabi_dbg_bits_write( "\n", 1 );
     145                        //__cfaabi_dbg_bits_write( "\n", 1 );
    145146                }
    146147
     
    162163        enum { Frames = 50 };
    163164        void * array[Frames];
    164         int size = backtrace( array, Frames );
     165        size_t size = backtrace( array, Frames );
    165166        char ** messages = backtrace_symbols( array, size );
    166167
     
    176177
    177178                for ( char *p = messages[i]; *p; ++p ) {
     179                        //__cfaabi_dbg_bits_print_nolock( "X %s\n", p);
    178180                        // find parantheses and +offset
    179181                        if ( *p == '(' ) {
Note: See TracChangeset for help on using the changeset viewer.