Changeset 358cba0 for src


Ignore:
Timestamp:
May 15, 2018, 4:17:15 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
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, with_gc
Children:
2e5fa345
Parents:
7d0a3ba (diff), a61fa0bb (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:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
2 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r7d0a3ba r358cba0  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 20:42:52 2017
    13 // Update Count     : 490
     12// Last Modified On : Sat May  5 09:08:32 2018
     13// Update Count     : 494
    1414//
    1515#include "CodeGenerator.h"
     
    370370
    371371        void CodeGenerator::postvisit( Constant * constant ) {
    372                 output << constant->get_value() ;
     372                output << constant->get_value();
    373373        }
    374374
     
    587587                output << "(";
    588588                if ( castExpr->get_result()->isVoid() ) {
    589                         output << "(void)" ;
     589                        output << "(void)";
    590590                } else {
    591591                        // at least one result type of cast.
     
    878878                        } // for
    879879                } // if
    880                 output << " );" ;
     880                output << " );";
    881881        }
    882882
     
    886886                output << "( ";
    887887                if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor );
    888                 output << " )" ;
     888                output << " )";
    889889        }
    890890
    891891        void CodeGenerator::postvisit( DirectiveStmt * dirStmt ) {
    892                 output << dirStmt->directive;
     892                output << endl << dirStmt->directive;                   // endl prevents spaces before directive
    893893        }
    894894
     
    907907
    908908        void CodeGenerator::postvisit( SwitchStmt * switchStmt ) {
    909                 output << "switch ( " ;
     909                output << "switch ( ";
    910910                switchStmt->get_condition()->accept( *visitor );
    911911                output << " ) ";
     
    933933                ++indent;
    934934                for ( std::list<Statement *>::iterator i = sts.begin(); i != sts.end();  i++) {
    935                         output << indent << printLabels( (*i)->get_labels() )  ;
     935                        output << indent << printLabels( (*i)->get_labels() ) ;
    936936                        (*i)->accept( *visitor );
    937937                        output << endl;
     
    10701070        void CodeGenerator::postvisit( WhileStmt * whileStmt ) {
    10711071                if ( whileStmt->get_isDoWhile() ) {
    1072                         output << "do" ;
    1073                 } else {
    1074                         output << "while (" ;
     1072                        output << "do";
     1073                } else {
     1074                        output << "while (";
    10751075                        whileStmt->get_condition()->accept( *visitor );
    10761076                        output << ")";
     
    10841084
    10851085                if ( whileStmt->get_isDoWhile() ) {
    1086                         output << " while (" ;
     1086                        output << " while (";
    10871087                        whileStmt->get_condition()->accept( *visitor );
    10881088                        output << ");";
  • src/CodeGen/FixNames.cc

    r7d0a3ba r358cba0  
    5656                auto && name = SymTab::Mangler::mangle( mainDecl.get() );
    5757                // std::cerr << name << std::endl;
    58                 return name;
     58                return std::move(name);
    5959        }
    6060        std::string mangle_main_args() {
     
    7979                auto&& name = SymTab::Mangler::mangle( mainDecl.get() );
    8080                // std::cerr << name << std::endl;
    81                 return name;
     81                return std::move(name);
    8282        }
    8383
  • src/Common/Heap.cc

    r7d0a3ba r358cba0  
    77// Heap.cc --
    88//
    9 // Author           : Peter A. Buhr
    10 // Created On       :
     9// Author           : Thierry Delisle
     10// Created On       : Thu May  3 16:16:10 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May  3 16:16:10 2018
    13 // Update Count     : 2
     12// Last Modified On : Fri May  4 17:27:31 2018
     13// Update Count     : 28
    1414//
    1515
    16 namespace HeapStats{
    17   void newPass( const char * const name ) {}
    18   void printStats() {}
     16#include <cassert>
     17#include <cmath>
     18#include <cstddef>
     19#include <cstring>
     20#include <iomanip>
     21#include <iostream>
     22
     23//#define WITH_HEAP_STATISTICS
     24
     25namespace HeapStats {
     26#if !defined( WITH_HEAP_STATISTICS )
     27        void newPass( const char * const ) {}
     28
     29        void printStats() {}
     30#else
     31        struct StatBlock {
     32                const char * name = nullptr;
     33                size_t mallocs    = 0;
     34                size_t frees      = 0;
     35        };
     36
     37        StatBlock    passes[100] = {{ "Pre-Parse", 0, 0 }};
     38        const size_t passes_size = sizeof(passes) / sizeof(passes[0]);
     39        size_t       passes_cnt = 1;
     40
     41        void newPass( const char * const name ) {
     42                passes[passes_cnt].name    = name;
     43                passes[passes_cnt].mallocs = 0;
     44                passes[passes_cnt].frees   = 0;
     45                passes_cnt++;
     46
     47                assertf(passes_cnt < passes_size, "Too many passes for HeapStats, increase the size of the array in Heap.h");
     48        }
     49
     50        void print(size_t value, size_t total) {
     51                std::cerr << std::setw(12) << value;
     52                std::cerr << "(" << std::setw(3);
     53                std::cerr << (value == 0 ? 0 : value * 100 / total);
     54                std::cerr << "%) | ";
     55        }
     56
     57        void print(const StatBlock& stat, size_t nc, size_t total_mallocs, size_t total_frees) {
     58                std::cerr << std::setw(nc) << stat.name;
     59                std::cerr << " | ";
     60
     61                print(stat.mallocs, total_mallocs);
     62                print(stat.frees  , total_frees  );
     63                std::cerr << "\n";
     64        }
     65
     66        void print(char c, size_t nc) {
     67                for(size_t i = 0; i < nc; i++) {
     68                        std::cerr << c;
     69                }
     70                std::cerr << '\n';
     71        }
     72
     73        void printStats() {
     74                size_t nc = 0;
     75                size_t total_mallocs = 0;
     76                size_t total_frees   = 0;
     77                for(size_t i = 0; i < passes_cnt; i++) {
     78                        nc = std::max(nc, std::strlen(passes[i].name));
     79                        total_mallocs += passes[i].mallocs;
     80                        total_frees   += passes[i].frees;
     81                }
     82                size_t nct = nc + 44;
     83
     84                const char * const title = "Heap Usage Statistic";
     85                print('=', nct);
     86                for(size_t i = 0; i < (nct - std::strlen(title)) / 2; i++) std::cerr << ' ';
     87                std::cerr << title << std::endl;
     88                print('-', nct);
     89                std::cerr << std::setw(nc) << "Pass";
     90                std::cerr << " |       Malloc Count |         Free Count |" << std::endl;
     91
     92                print('-', nct);
     93                for(size_t i = 0; i < passes_cnt; i++) {
     94                        print(passes[i], nc, total_mallocs, total_frees);
     95                }
     96                print('-', nct);
     97                print({"Sum", total_mallocs, total_frees}, nc, total_mallocs, total_frees);
     98
     99        }
     100
     101#include <stdarg.h>
     102#include <stddef.h>
     103#include <stdio.h>
     104#include <string.h>
     105#include <unistd.h>
     106#include <signal.h>
     107        extern "C" {
     108#include <dlfcn.h>
     109#include <execinfo.h>
     110        }
     111
     112//=============================================================================================
     113// Interposing helpers
     114//=============================================================================================
     115
     116        typedef void (* generic_fptr_t)(void);
     117        generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
     118                const char * error;
     119
     120                static void * library;
     121                if ( ! library ) {
     122#if defined( RTLD_NEXT )
     123                        library = RTLD_NEXT;
     124#else
     125                        // missing RTLD_NEXT => must hard-code library name, assuming libstdc++
     126                        library = dlopen( "libc.so.6", RTLD_LAZY );
     127                        error = dlerror();
     128                        if ( error ) {
     129                                std::cerr << "interpose_symbol : failed to open libc, " << error << std::endl;
     130                                abort();
     131                        }
     132#endif // RTLD_NEXT
     133                } // if
     134
     135                generic_fptr_t fptr;
     136
     137#if defined( _GNU_SOURCE )
     138                if ( version ) {
     139                        fptr = (generic_fptr_t)dlvsym( library, symbol, version );
     140                } else {
     141                        fptr = (generic_fptr_t)dlsym( library, symbol );
     142                }
     143#else
     144                fptr = (generic_fptr_t)dlsym( library, symbol );
     145#endif // _GNU_SOURCE
     146
     147                error = dlerror();
     148                if ( error ) {
     149                        std::cerr << "interpose_symbol : internal error, " << error << std::endl;
     150                        abort();
     151                }
     152
     153                return fptr;
     154        }
     155
     156        extern "C" {
     157                void * malloc( size_t size ) __attribute__((malloc));
     158                void * malloc( size_t size ) {
     159                        static auto __malloc = reinterpret_cast<void * (*)(size_t)>(interpose_symbol( "malloc", nullptr ));
     160                        if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++;
     161                        return __malloc( size );
     162                }
     163
     164                void free( void * ptr ) {
     165                        static auto __free = reinterpret_cast<void   (*)(void *)>(interpose_symbol( "free", nullptr ));
     166                        if( passes_cnt > 0 ) passes[passes_cnt - 1].frees++;
     167                        return __free( ptr );
     168                }
     169
     170                void * calloc( size_t nelem, size_t size ) {
     171                        static auto __calloc = reinterpret_cast<void * (*)(size_t, size_t)>(interpose_symbol( "calloc", nullptr ));
     172                        if( passes_cnt > 0 ) passes[passes_cnt - 1].mallocs++;
     173                        return __calloc( nelem, size );
     174                }
     175
     176                void * realloc( void * ptr, size_t size ) {
     177                        static auto __realloc = reinterpret_cast<void * (*)(void *, size_t)>(interpose_symbol( "realloc", nullptr ));
     178                        void * s = __realloc( ptr, size );
     179                        if ( s != ptr && passes_cnt > 0 ) {                     // did realloc get new storage ?
     180                                passes[passes_cnt - 1].mallocs++;
     181                                passes[passes_cnt - 1].frees++;
     182                        } // if
     183                        return s;
     184                }
     185        }
     186#endif
    19187}
    20 
  • src/Common/Heap.h

    r7d0a3ba r358cba0  
    77// Heap.h --
    88//
    9 // Author           : Peter A. Buhr
    10 // Created On       :
     9// Author           : Thierry Delisle
     10// Created On       : Thu May  3 16:16:10 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May  3 16:16:10 2018
    13 // Update Count     : 2
     12// Last Modified On : Fri May  4 14:34:08 2018
     13// Update Count     : 3
    1414//
    1515
     
    1717
    1818namespace HeapStats {
    19   void newPass( const char * const name );
    20   void printStats();
     19        void newPass( const char * const name );
     20        void printStats();
    2121}
  • src/Common/PassVisitor.proto.h

    r7d0a3ba r358cba0  
    4747
    4848        operator bool() { return m_ref ? *m_ref : true; }
    49         bool operator=( bool val ) { return *m_ref = val; }
     49        bool operator=( bool val ) { assert(m_ref); return *m_ref = val; }
    5050
    5151private:
     
    5353        friend class ChildrenGuard;
    5454
    55         bool * set( bool & val ) {
     55        bool * set( bool * val ) {
    5656                bool * prev = m_ref;
    57                 m_ref = &val;
     57                m_ref = val;
    5858                return prev;
    5959        }
     
    6767        ChildrenGuard( bool_ref * ref )
    6868                : m_val ( true )
    69                 , m_prev( ref ? ref->set( m_val ) : nullptr )
     69                , m_prev( ref ? ref->set( &m_val ) : nullptr )
    7070                , m_ref ( ref )
    7171        {}
     
    7373        ~ChildrenGuard() {
    7474                if( m_ref ) {
    75                         m_ref->set( *m_prev );
     75                        m_ref->set( m_prev );
    7676                }
    7777        }
  • src/Common/utility.h

    r7d0a3ba r358cba0  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May  3 12:18:31 2018
    13 // Update Count     : 39
     12// Last Modified On : Sun May  6 22:24:16 2018
     13// Update Count     : 40
    1414//
    1515
     
    442442template<typename T>
    443443inline
    444 #if __GNUC__ > 4
     444#if defined(__GNUC__) && __GNUC__ > 4
    445445constexpr
    446446#endif
  • src/Parser/parser.yy

    r7d0a3ba r358cba0  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May  3 08:20:09 2018
    13 // Update Count     : 3225
     12// Last Modified On : Fri May 11 17:51:38 2018
     13// Update Count     : 3261
    1414//
    1515
     
    302302
    303303%type<decl> field_declaration field_declaration_list field_declarator field_declaring_list
    304 %type<en> field field_list field_name fraction_constants
     304%type<en> field field_list field_name fraction_constants_opt
    305305
    306306%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    499499        | type_name '.' no_attr_identifier                                      // CFA, nested type
    500500                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
     501//              { $$ = nullptr; }
    501502        | type_name '.' '[' push field_list pop ']'                     // CFA, nested type / tuple field selector
    502503                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
     504//              { $$ = nullptr; }
    503505        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    504506                { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     
    533535        | postfix_expression '.' no_attr_identifier
    534536                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     537        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
     538                { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     539        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
     540                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    535541        | postfix_expression '.' '[' push field_list pop ']' // CFA, tuple field selector
    536542                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $5 ) ) ); }
    537         | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    538                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    539543        | postfix_expression ARROW no_attr_identifier
    540544                {
    541545                        $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) );
    542546                }
    543         | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
    544                         { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
    545547        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    546548                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     549        | postfix_expression ARROW '[' push field_list pop ']' // CFA, tuple field selector
     550                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $5 ) ) ); }
    547551        | postfix_expression ICR
    548552                { $$ = new ExpressionNode( build_unary_ptr( OperKinds::IncrPost, $1 ) ); }
     
    597601
    598602field_name:
    599         INTEGERconstant fraction_constants
     603        INTEGERconstant fraction_constants_opt
    600604                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
    601         | FLOATINGconstant fraction_constants
     605        | FLOATINGconstant fraction_constants_opt
    602606                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
    603         | no_attr_identifier fraction_constants
     607        | no_attr_identifier fraction_constants_opt
    604608                {
    605609                        $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     
    607611        ;
    608612
    609 fraction_constants:
     613fraction_constants_opt:
    610614        // empty
    611615                { $$ = nullptr; }
    612         | fraction_constants FLOATING_FRACTIONconstant
     616        | fraction_constants_opt FLOATING_FRACTIONconstant
    613617                {
    614618                        Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
     
    23902394external_definition_list:
    23912395        external_definition
    2392         | external_definition_list { forall = xxx; } push external_definition
     2396        | external_definition_list
     2397                { forall = xxx; }
     2398          push external_definition
    23932399                { $$ = $1 ? $1->appendList( $4 ) : $4; }
    23942400        ;
     
    24302436                {
    24312437                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2432                                 iter->addQualifiers( $1->clone() );
     2438                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
     2439                                        iter->addQualifiers( $1->clone() );
     2440                                } // if
    24332441                        } // for
    24342442                        xxx = false;
     
    24432451                {
    24442452                        for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2445                                 iter->addQualifiers( $1->clone() );
     2453                                if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
     2454                                        iter->addQualifiers( $1->clone() );
     2455                                } // if
    24462456                        } // for
    24472457                        xxx = false;
     
    24572467                {
    24582468                        for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2459                                 iter->addQualifiers( $1->clone() );
    2460                                 iter->addQualifiers( $2->clone() );
     2469                                if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C"
     2470                                        iter->addQualifiers( $1->clone() );
     2471                                        iter->addQualifiers( $2->clone() );
     2472                                } // if
    24612473                        } // for
    24622474                        xxx = false;
  • src/benchmark/Makefile.am

    r7d0a3ba r358cba0  
    4343
    4444%.runquiet :
    45         @+make $(basename $@)
     45        @+make $(basename $@) CFLAGS="-w"
    4646        @taskset -c 1 ./a.out
    4747        @rm -f a.out
  • src/benchmark/Makefile.in

    r7d0a3ba r358cba0  
    459459
    460460%.runquiet :
    461         @+make $(basename $@)
     461        @+make $(basename $@) CFLAGS="-w"
    462462        @taskset -c 1 ./a.out
    463463        @rm -f a.out
  • src/driver/cc1.cc

    r7d0a3ba r358cba0  
    1010// Created On       : Fri Aug 26 14:23:51 2005
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 18 08:14:21 2017
    13 // Update Count     : 81
     12// Last Modified On : Sat May 12 16:11:53 2018
     13// Update Count     : 94
    1414//
    1515
     
    3232string compiler_name( CFA_BACKEND_CC );                                 // path/name of C compiler
    3333
     34string D__GCC_X__( "-D__GCC_X__=" );
    3435string D__GCC_BPREFIX__( "-D__GCC_BPREFIX__=" );
    3536string D__CFA_FLAGPREFIX__( "-D__CFA_FLAG__=" );
     
    162163                                cargs[ncargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
    163164                                ncargs += 1;
     165                                i += 1;                                                                 // and the argument
     166                        } else if ( prefix( arg, D__GCC_X__ ) ) {
     167                                args[nargs] = "-x";
     168                                nargs += 1;
     169                                args[nargs] = ( *new string( arg.substr( D__GCC_X__.size() ) ) ).c_str(); // pass the flag along
     170                                nargs += 1;
     171                        } else if ( arg == "-D" && prefix( argv[i + 1], D__GCC_X__.substr(2) ) ) {
     172                                args[nargs] = "-x";
     173                                nargs += 1;
     174                                args[nargs] = ( *new string( string( argv[i + 1] ).substr( D__GCC_X__.size() - 2 ) ) ).c_str(); // pass the flag along
     175                                nargs += 1;
    164176                                i += 1;                                                                 // and the argument
    165177                        } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
  • src/driver/cfa.cc

    r7d0a3ba r358cba0  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May  2 17:57:43 2018
    13 // Update Count     : 224
     12// Last Modified On : Mon May 14 07:52:50 2018
     13// Update Count     : 243
    1414//
    1515
     
    158158                                args[nargs] = argv[i];                                  // pass the argument along
    159159                                nargs += 1;
    160                         } else if ( prefix( arg, "-std=" ) ) {
     160                        } else if ( prefix( arg, "-std=" ) || prefix( arg, "--std=" ) ) {
    161161                                std_flag = true;                                                // -std=XX provided
    162162                                args[nargs] = argv[i];                                  // pass the argument along
     163                                nargs += 1;
     164                        } else if ( arg == "-x" ) {                                     // lost so force along
     165                                args[nargs] = argv[i];                                  // pass the argument along
     166                                nargs += 1;
     167                                i += 1;                                                                 // advance to argument
     168                                args[nargs] = argv[i];                                  // pass the argument along
     169                                nargs += 1;
     170                                args[nargs] = ( *new string( string("-D__GCC_X__=") + argv[i] ) ).c_str(); // add the argument for -x
     171                                nargs += 1;
     172                        } else if ( prefix( arg, "-x" ) ) {                     // lost so force along
     173                                args[nargs] = argv[i];                                  // pass the argument along
     174                                nargs += 1;
     175                                args[nargs] = ( *new string( string("-D__GCC_X__=") + arg.substr(2) ) ).c_str(); // add the argument for -x
    163176                                nargs += 1;
    164177                        } else if ( arg == "-w" ) {
     
    240253        } // for
    241254
     255#ifdef __x86_64__
     256        args[nargs] = "-mcx16";                                                         // allow double-wide CAA
     257        nargs += 1;
     258#endif // __x86_64__
     259
    242260#ifdef __DEBUG_H__
    243261        cerr << "args:";
     
    268286        if ( link ) {
    269287                #if ! defined(HAVE_LIBCFA_RELEASE)
    270                         if( !debug ) {
     288                        if ( ! debug ) {
    271289                                cerr << "error: Option -nodebug is unavailable, libcfa was not installed." << endl;
    272290                                exit( EXIT_FAILURE );
    273                                 }
     291                        } // if
    274292                #endif
    275293                #if ! defined(HAVE_LIBCFA_DEBUG)
    276                         if( debug ) {
     294                        if ( debug ) {
    277295                                cerr << "error: Option -debug is unavailable, libcfa-d was not installed." << endl;
    278296                                exit( EXIT_FAILURE );
    279                                 }
     297                        } // if
    280298                #endif
    281299
     
    292310                args[nargs] = "-L" CFA_LIBDIR;
    293311                nargs += 1;
    294                 if( debug ) {
     312                if ( debug ) {
    295313                        args[nargs] = "-lcfa-d";
    296314                } else {
    297315                        args[nargs] = "-lcfa";
    298                 }
     316                } // if
    299317                nargs += 1;
    300318                args[nargs] = "-lpthread";
  • src/libcfa/bits/containers.h

    r7d0a3ba r358cba0  
    186186#endif
    187187
     188
     189//-----------------------------------------------------------------------------
     190// Doubly Linked List
     191//-----------------------------------------------------------------------------
     192#ifdef __cforall
     193        forall(dtype TYPE | sized(TYPE))
     194        #define T TYPE
     195        #define __getter_t * [T * & next, T * & prev] ( T & )
     196#else
     197        typedef void (*__generit_c_getter_t)();
     198        #define T void
     199        #define __getter_t __generit_c_getter_t
     200#endif
     201struct __dllist {
     202        T * head;
     203        __getter_t __get;
     204};
     205#undef T
     206#undef __getter_t
     207
     208#ifdef __cforall
     209#define __dllist_t(T) __dllist(T)
     210#else
     211#define __dllist_t(T) struct __dllist
     212#endif
     213
     214#ifdef __cforall
     215
     216        forall(dtype T | sized(T))
     217        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
     218                this.head{ NULL };
     219                this.__get = __get;
     220        }
     221
     222        #define _next .0
     223        #define _prev .1
     224        forall(dtype T | sized(T))
     225        static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
     226                if ( head ) {
     227                        __get( node )_next = head;
     228                        __get( node )_prev = __get( *head )_prev;
     229                        // inserted node must be consistent before it is seen
     230                        // prevent code movement across barrier
     231                        asm( "" : : : "memory" );
     232                        __get( *head )_prev = &node;
     233                        T & prev = *__get( node )_prev;
     234                        __get( prev )_next = &node;
     235                }
     236                else {
     237                        __get( node )_next = &node;
     238                        __get( node )_prev = &node;
     239                }
     240
     241                // prevent code movement across barrier
     242                asm( "" : : : "memory" );
     243                head = &node;
     244        }
     245
     246        forall(dtype T | sized(T))
     247        static inline void remove( __dllist(T) & this, T & node ) with( this ) {
     248                if ( &node == head ) {
     249                        if ( __get( *head )_next == head ) {
     250                                head = NULL;
     251                        }
     252                        else {
     253                                head = __get( *head )_next;
     254                        }
     255                }
     256                __get( *__get( node )_next )_prev = __get( node )_prev;
     257                __get( *__get( node )_prev )_next = __get( node )_next;
     258                __get( node )_next = NULL;
     259                __get( node )_prev = NULL;
     260        }
     261        #undef _next
     262        #undef _prev
     263#endif
     264
    188265//-----------------------------------------------------------------------------
    189266// Tools
  • src/libcfa/concurrency/coroutine

    r7d0a3ba r358cba0  
    7272// Suspend implementation inlined for performance
    7373static inline void suspend() {
    74         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     74        // optimization : read TLS once and reuse it
     75        // Safety note: this is preemption safe since if
     76        // preemption occurs after this line, the pointer
     77        // will also migrate which means this value will
     78        // stay in syn with the TLS
     79        coroutine_desc * src = TL_GET( this_coroutine );
    7580
    7681        assertf( src->last != 0,
     
    8994forall(dtype T | is_coroutine(T))
    9095static inline void resume(T & cor) {
    91         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     96        // optimization : read TLS once and reuse it
     97        // Safety note: this is preemption safe since if
     98        // preemption occurs after this line, the pointer
     99        // will also migrate which means this value will
     100        // stay in syn with the TLS
     101        coroutine_desc * src = TL_GET( this_coroutine );
    92102        coroutine_desc * dst = get_coroutine(cor);
    93103
     
    107117                dst->last = src;
    108118                dst->starter = dst->starter ? dst->starter : src;
    109         } // if
     119        }
    110120
    111121        // always done for performance testing
     
    114124
    115125static inline void resume(coroutine_desc * dst) {
    116         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     126        // optimization : read TLS once and reuse it
     127        // Safety note: this is preemption safe since if
     128        // preemption occurs after this line, the pointer
     129        // will also migrate which means this value will
     130        // stay in syn with the TLS
     131        coroutine_desc * src = TL_GET( this_coroutine );
    117132
    118133        // not resuming self ?
     
    125140                // set last resumer
    126141                dst->last = src;
    127         } // if
     142        }
    128143
    129144        // always done for performance testing
  • src/libcfa/concurrency/coroutine.c

    r7d0a3ba r358cba0  
    8484// Wrapper for co
    8585void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    86       verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     86      // Safety note : This could cause some false positives due to preemption
     87      verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
    8788      disable_interrupts();
    8889
     
    9192
    9293      // set new coroutine that task is executing
    93       TL_SET( this_coroutine, dst );
     94      kernelTLS.this_coroutine = dst;
    9495
    9596      // context switch to specified coroutine
     
    102103
    103104      enable_interrupts( __cfaabi_dbg_ctx );
    104       verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     105      // Safety note : This could cause some false positives due to preemption
     106      verify( TL_GET( preemption_state.enabled ) || TL_GET( this_processor )->do_terminate );
    105107} //ctxSwitchDirect
    106108
  • src/libcfa/concurrency/invoke.c

    r7d0a3ba r358cba0  
    6969        // Fetch the thread handle from the user defined thread structure
    7070        struct thread_desc* thrd = get_thread( this );
     71        thrd->self_cor.last = NULL;
    7172
    7273        // Officially start the thread by enabling preemption
  • src/libcfa/concurrency/invoke.h

    r7d0a3ba r358cba0  
    1818#include "bits/locks.h"
    1919
    20 #define TL_GET( member ) kernelThreadData.member
    21 #define TL_SET( member, value ) kernelThreadData.member = value;
     20#define TL_GET( member ) kernelTLS.member
     21#define TL_SET( member, value ) kernelTLS.member = value;
    2222
    2323#ifdef __cforall
     
    4444                                volatile bool in_progress;
    4545                        } preemption_state;
    46                 } kernelThreadData;
     46                } kernelTLS;
    4747        }
    4848
    4949        static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_coroutine ); }
    50         static inline struct thread_desc * volatile active_thread() { return TL_GET( this_thread ); }
    51         static inline struct processor * volatile active_processor() { return TL_GET( this_processor ); }
     50        static inline struct thread_desc    * volatile active_thread   () { return TL_GET( this_thread    ); }
     51        static inline struct processor      * volatile active_processor() { return TL_GET( this_processor ); } // UNSAFE
    5252        #endif
    5353
     
    136136                struct thread_desc * next;
    137137
    138                 __cfaabi_dbg_debug_do(
    139                         // instrusive link field for debugging
    140                         struct thread_desc * dbg_next;
    141                         struct thread_desc * dbg_prev;
    142                 )
     138                struct {
     139                        struct thread_desc * next;
     140                        struct thread_desc * prev;
     141                } node;
    143142     };
    144143
     
    147146                static inline thread_desc * & get_next( thread_desc & this ) {
    148147                        return this.next;
     148                }
     149
     150                static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) {
     151                        return this.node.[next, prev];
    149152                }
    150153
  • src/libcfa/concurrency/kernel

    r7d0a3ba r358cba0  
    4040
    4141//-----------------------------------------------------------------------------
    42 // Cluster
    43 struct cluster {
    44         // Ready queue locks
    45         __spinlock_t ready_queue_lock;
     42// Processor
     43extern struct cluster * mainCluster;
    4644
    47         // Ready queue for threads
    48         __queue_t(thread_desc) ready_queue;
    49 
    50         // Name of the cluster
    51         const char * name;
    52 
    53         // Preemption rate on this cluster
    54         Duration preemption_rate;
    55 };
    56 
    57 extern struct cluster * mainCluster;
    58 extern Duration default_preemption();
    59 
    60 void ?{} (cluster & this, const char * name, Duration preemption_rate);
    61 void ^?{}(cluster & this);
    62 
    63 static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    64 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    65 static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
    66 
    67 //-----------------------------------------------------------------------------
    68 // Processor
    6945enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
    7046
     
    9874
    9975        // Cluster from which to get threads
    100         cluster * cltr;
     76        struct cluster * cltr;
    10177
    10278        // Name of the processor
     
    124100        bool pending_preemption;
    125101
     102        // Idle lock
     103
     104        // Link lists fields
     105        struct {
     106                struct processor * next;
     107                struct processor * prev;
     108        } node;
     109
    126110#ifdef __CFA_DEBUG__
    127111        // Last function to enable preemption on this processor
     
    130114};
    131115
    132 void  ?{}(processor & this, const char * name, cluster & cltr);
     116void  ?{}(processor & this, const char * name, struct cluster & cltr);
    133117void ^?{}(processor & this);
    134118
    135119static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    136 static inline void  ?{}(processor & this, cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
     120static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    137121static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
     122
     123static inline [processor *&, processor *& ] __get( processor & this ) {
     124        return this.node.[next, prev];
     125}
     126
     127//-----------------------------------------------------------------------------
     128// Cluster
     129struct cluster {
     130        // Ready queue locks
     131        __spinlock_t ready_queue_lock;
     132
     133        // Ready queue for threads
     134        __queue_t(thread_desc) ready_queue;
     135
     136        // Name of the cluster
     137        const char * name;
     138
     139        // Preemption rate on this cluster
     140        Duration preemption_rate;
     141
     142        // List of processors
     143        __spinlock_t proc_list_lock;
     144        __dllist_t(struct processor) procs;
     145        __dllist_t(struct processor) idles;
     146
     147        // Link lists fields
     148        struct {
     149                cluster * next;
     150                cluster * prev;
     151        } node;
     152};
     153extern Duration default_preemption();
     154
     155void ?{} (cluster & this, const char * name, Duration preemption_rate);
     156void ^?{}(cluster & this);
     157
     158static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
     159static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
     160static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
     161
     162static inline [cluster *&, cluster *& ] __get( cluster & this ) {
     163        return this.node.[next, prev];
     164}
    138165
    139166// Local Variables: //
  • src/libcfa/concurrency/kernel.c

    r7d0a3ba r358cba0  
    4949thread_desc * mainThread;
    5050
     51struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;
     52struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
     53
    5154//-----------------------------------------------------------------------------
    5255// Global state
     
    5659// volatile thread_local unsigned short disable_preempt_count = 1;
    5760
    58 thread_local struct KernelThreadData kernelThreadData = {
     61thread_local struct KernelThreadData kernelTLS = {
    5962        NULL,
    6063        NULL,
     
    117120        self_mon_p = &self_mon;
    118121        next = NULL;
    119         __cfaabi_dbg_debug_do(
    120                 dbg_next = NULL;
    121                 dbg_prev = NULL;
    122                 __cfaabi_dbg_thread_register(&this);
    123         )
     122
     123        node.next = NULL;
     124        node.prev = NULL;
     125        doregister(this);
    124126
    125127        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    155157                terminate(&this);
    156158                verify(this.do_terminate);
    157                 verify(TL_GET( this_processor ) != &this);
     159                verify( kernelTLS.this_processor != &this);
    158160                P( terminated );
    159                 verify(TL_GET( this_processor ) != &this);
     161                verify( kernelTLS.this_processor != &this);
    160162                pthread_join( kernel_thread, NULL );
    161163        }
     
    167169        ready_queue{};
    168170        ready_queue_lock{};
     171
     172        procs{ __get };
     173        idles{ __get };
     174
     175        doregister(this);
    169176}
    170177
    171178void ^?{}(cluster & this) {
    172 
     179        unregister(this);
    173180}
    174181
     
    183190        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
    184191
     192        doregister(this->cltr, this);
     193
    185194        {
    186195                // Setup preemption data
     
    196205                        if(readyThread)
    197206                        {
    198                                 verify( ! TL_GET( preemption_state ).enabled );
     207                                verify( ! kernelTLS.preemption_state.enabled );
    199208
    200209                                runThread(this, readyThread);
    201210
    202                                 verify( ! TL_GET( preemption_state ).enabled );
     211                                verify( ! kernelTLS.preemption_state.enabled );
    203212
    204213                                //Some actions need to be taken from the kernel
     
    216225        }
    217226
     227        unregister(this->cltr, this);
     228
    218229        V( this->terminated );
    219230
     
    221232}
    222233
     234// KERNEL ONLY
    223235// runThread runs a thread by context switching
    224236// from the processor coroutine to the target thread
     
    228240        coroutine_desc * thrd_cor = dst->curr_cor;
    229241
    230         //Reset the terminating actions here
     242        // Reset the terminating actions here
    231243        this->finish.action_code = No_Action;
    232244
    233         //Update global state
    234         TL_SET( this_thread, dst );
     245        // Update global state
     246        kernelTLS.this_thread = dst;
    235247
    236248        // Context Switch to the thread
     
    239251}
    240252
     253// KERNEL_ONLY
    241254void returnToKernel() {
    242         coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
    243         coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
     255        coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner);
     256        coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine;
    244257        ThreadCtxSwitch(thrd_cor, proc_cor);
    245258}
    246259
     260// KERNEL_ONLY
    247261// Once a thread has finished running, some of
    248262// its final actions must be executed from the kernel
    249263void finishRunning(processor * this) with( this->finish ) {
    250264        if( action_code == Release ) {
    251                 verify( ! TL_GET( preemption_state ).enabled );
     265                verify( ! kernelTLS.preemption_state.enabled );
    252266                unlock( *lock );
    253267        }
     
    256270        }
    257271        else if( action_code == Release_Schedule ) {
    258                 verify( ! TL_GET( preemption_state ).enabled );
     272                verify( ! kernelTLS.preemption_state.enabled );
    259273                unlock( *lock );
    260274                ScheduleThread( thrd );
    261275        }
    262276        else if( action_code == Release_Multi ) {
    263                 verify( ! TL_GET( preemption_state ).enabled );
     277                verify( ! kernelTLS.preemption_state.enabled );
    264278                for(int i = 0; i < lock_count; i++) {
    265279                        unlock( *locks[i] );
     
    285299}
    286300
     301// KERNEL_ONLY
    287302// Context invoker for processors
    288303// This is the entry point for processors (kernel threads)
     
    290305void * CtxInvokeProcessor(void * arg) {
    291306        processor * proc = (processor *) arg;
    292         TL_SET( this_processor, proc );
    293         TL_SET( this_coroutine, NULL );
    294         TL_SET( this_thread, NULL );
    295         TL_GET( preemption_state ).[enabled, disable_count] = [false, 1];
     307        kernelTLS.this_processor = proc;
     308        kernelTLS.this_coroutine = NULL;
     309        kernelTLS.this_thread    = NULL;
     310        kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
    296311        // SKULLDUGGERY: We want to create a context for the processor coroutine
    297312        // which is needed for the 2-step context switch. However, there is no reason
     
    305320
    306321        //Set global state
    307         TL_SET( this_coroutine, get_coroutine(proc->runner) );
    308         TL_SET( this_thread, NULL );
     322        kernelTLS.this_coroutine = get_coroutine(proc->runner);
     323        kernelTLS.this_thread    = NULL;
    309324
    310325        //We now have a proper context from which to schedule threads
     
    333348}
    334349
     350// KERNEL_ONLY
    335351void kernel_first_resume(processor * this) {
    336         coroutine_desc * src = TL_GET( this_coroutine );
     352        coroutine_desc * src = kernelTLS.this_coroutine;
    337353        coroutine_desc * dst = get_coroutine(this->runner);
    338354
    339         verify( ! TL_GET( preemption_state ).enabled );
     355        verify( ! kernelTLS.preemption_state.enabled );
    340356
    341357        create_stack(&dst->stack, dst->stack.size);
    342358        CtxStart(&this->runner, CtxInvokeCoroutine);
    343359
    344         verify( ! TL_GET( preemption_state ).enabled );
     360        verify( ! kernelTLS.preemption_state.enabled );
    345361
    346362        dst->last = src;
     
    351367
    352368        // set new coroutine that task is executing
    353         TL_SET( this_coroutine, dst );
     369        kernelTLS.this_coroutine = dst;
    354370
    355371        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    368384        src->state = Active;
    369385
    370         verify( ! TL_GET( preemption_state ).enabled );
     386        verify( ! kernelTLS.preemption_state.enabled );
    371387}
    372388
    373389//-----------------------------------------------------------------------------
    374390// Scheduler routines
     391
     392// KERNEL ONLY
    375393void ScheduleThread( thread_desc * thrd ) {
    376         // if( ! thrd ) return;
    377394        verify( thrd );
    378395        verify( thrd->self_cor.state != Halted );
    379396
    380         verify( ! TL_GET( preemption_state ).enabled );
     397        verify( ! kernelTLS.preemption_state.enabled );
    381398
    382399        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
     
    388405        }
    389406
    390         verify( ! TL_GET( preemption_state ).enabled );
    391 }
    392 
     407        verify( ! kernelTLS.preemption_state.enabled );
     408}
     409
     410// KERNEL ONLY
    393411thread_desc * nextThread(cluster * this) with( *this ) {
    394         verify( ! TL_GET( preemption_state ).enabled );
     412        verify( ! kernelTLS.preemption_state.enabled );
    395413        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    396414        thread_desc * head = pop_head( ready_queue );
    397415        unlock( ready_queue_lock );
    398         verify( ! TL_GET( preemption_state ).enabled );
     416        verify( ! kernelTLS.preemption_state.enabled );
    399417        return head;
    400418}
     
    402420void BlockInternal() {
    403421        disable_interrupts();
    404         verify( ! TL_GET( preemption_state ).enabled );
     422        verify( ! kernelTLS.preemption_state.enabled );
    405423        returnToKernel();
    406         verify( ! TL_GET( preemption_state ).enabled );
     424        verify( ! kernelTLS.preemption_state.enabled );
    407425        enable_interrupts( __cfaabi_dbg_ctx );
    408426}
     
    410428void BlockInternal( __spinlock_t * lock ) {
    411429        disable_interrupts();
    412         with( *TL_GET( this_processor ) ) {
     430        with( *kernelTLS.this_processor ) {
    413431                finish.action_code = Release;
    414432                finish.lock        = lock;
    415433        }
    416434
    417         verify( ! TL_GET( preemption_state ).enabled );
     435        verify( ! kernelTLS.preemption_state.enabled );
    418436        returnToKernel();
    419         verify( ! TL_GET( preemption_state ).enabled );
     437        verify( ! kernelTLS.preemption_state.enabled );
    420438
    421439        enable_interrupts( __cfaabi_dbg_ctx );
     
    424442void BlockInternal( thread_desc * thrd ) {
    425443        disable_interrupts();
    426         with( *TL_GET( this_processor ) ) {
     444        with( * kernelTLS.this_processor ) {
    427445                finish.action_code = Schedule;
    428446                finish.thrd        = thrd;
    429447        }
    430448
    431         verify( ! TL_GET( preemption_state ).enabled );
     449        verify( ! kernelTLS.preemption_state.enabled );
    432450        returnToKernel();
    433         verify( ! TL_GET( preemption_state ).enabled );
     451        verify( ! kernelTLS.preemption_state.enabled );
    434452
    435453        enable_interrupts( __cfaabi_dbg_ctx );
     
    439457        assert(thrd);
    440458        disable_interrupts();
    441         with( *TL_GET( this_processor ) ) {
     459        with( * kernelTLS.this_processor ) {
    442460                finish.action_code = Release_Schedule;
    443461                finish.lock        = lock;
     
    445463        }
    446464
    447         verify( ! TL_GET( preemption_state ).enabled );
     465        verify( ! kernelTLS.preemption_state.enabled );
    448466        returnToKernel();
    449         verify( ! TL_GET( preemption_state ).enabled );
     467        verify( ! kernelTLS.preemption_state.enabled );
    450468
    451469        enable_interrupts( __cfaabi_dbg_ctx );
     
    454472void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    455473        disable_interrupts();
    456         with( *TL_GET( this_processor ) ) {
     474        with( * kernelTLS.this_processor ) {
    457475                finish.action_code = Release_Multi;
    458476                finish.locks       = locks;
     
    460478        }
    461479
    462         verify( ! TL_GET( preemption_state ).enabled );
     480        verify( ! kernelTLS.preemption_state.enabled );
    463481        returnToKernel();
    464         verify( ! TL_GET( preemption_state ).enabled );
     482        verify( ! kernelTLS.preemption_state.enabled );
    465483
    466484        enable_interrupts( __cfaabi_dbg_ctx );
     
    469487void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    470488        disable_interrupts();
    471         with( *TL_GET( this_processor ) ) {
     489        with( *kernelTLS.this_processor ) {
    472490                finish.action_code = Release_Multi_Schedule;
    473491                finish.locks       = locks;
     
    477495        }
    478496
    479         verify( ! TL_GET( preemption_state ).enabled );
     497        verify( ! kernelTLS.preemption_state.enabled );
    480498        returnToKernel();
    481         verify( ! TL_GET( preemption_state ).enabled );
     499        verify( ! kernelTLS.preemption_state.enabled );
    482500
    483501        enable_interrupts( __cfaabi_dbg_ctx );
    484502}
    485503
     504// KERNEL ONLY
    486505void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    487         verify( ! TL_GET( preemption_state ).enabled );
    488         with( *TL_GET( this_processor ) ) {
     506        verify( ! kernelTLS.preemption_state.enabled );
     507        with( * kernelTLS.this_processor ) {
    489508                finish.action_code = thrd ? Release_Schedule : Release;
    490509                finish.lock        = lock;
     
    501520// Kernel boot procedures
    502521void kernel_startup(void) {
    503         verify( ! TL_GET( preemption_state ).enabled );
     522        verify( ! kernelTLS.preemption_state.enabled );
    504523        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     524
     525        global_threads. list{ __get };
     526        global_threads. lock{};
     527        global_clusters.list{ __get };
     528        global_clusters.lock{};
    505529
    506530        // Initialize the main cluster
     
    547571
    548572        //initialize the global state variables
    549         TL_SET( this_processor, mainProcessor );
    550         TL_SET( this_thread, mainThread );
    551         TL_SET( this_coroutine, &mainThread->self_cor );
     573        kernelTLS.this_processor = mainProcessor;
     574        kernelTLS.this_thread    = mainThread;
     575        kernelTLS.this_coroutine = &mainThread->self_cor;
    552576
    553577        // Enable preemption
     
    561585        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    562586        // mainThread is on the ready queue when this call is made.
    563         kernel_first_resume( TL_GET( this_processor ) );
     587        kernel_first_resume( kernelTLS.this_processor );
    564588
    565589
     
    568592        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    569593
    570         verify( ! TL_GET( preemption_state ).enabled );
     594        verify( ! kernelTLS.preemption_state.enabled );
    571595        enable_interrupts( __cfaabi_dbg_ctx );
    572         verify( TL_GET( preemption_state ).enabled );
     596        verify( TL_GET( preemption_state.enabled ) );
    573597}
    574598
     
    576600        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    577601
    578         verify( TL_GET( preemption_state ).enabled );
     602        verify( TL_GET( preemption_state.enabled ) );
    579603        disable_interrupts();
    580         verify( ! TL_GET( preemption_state ).enabled );
     604        verify( ! kernelTLS.preemption_state.enabled );
    581605
    582606        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    604628
    605629//=============================================================================================
     630// Kernel Quiescing
     631//=============================================================================================
     632
     633// void halt(processor * this) with( this ) {
     634//      pthread_mutex_lock( &idle.lock );
     635
     636
     637
     638//      // SKULLDUGGERY: Even if spurious wake-up is a thing
     639//      // spuriously waking up a kernel thread is not a big deal
     640//      // if it is very rare.
     641//      pthread_cond_wait( &idle.cond, &idle.lock);
     642//      pthread_mutex_unlock( &idle.lock );
     643// }
     644
     645// void wake(processor * this) with( this ) {
     646//      pthread_mutex_lock  (&idle.lock);
     647//      pthread_cond_signal (&idle.cond);
     648//      pthread_mutex_unlock(&idle.lock);
     649// }
     650
     651//=============================================================================================
    606652// Unexpected Terminating logic
    607653//=============================================================================================
     
    609655
    610656static __spinlock_t kernel_abort_lock;
    611 static __spinlock_t kernel_debug_lock;
    612657static bool kernel_abort_called = false;
    613658
    614 void * kernel_abort    (void) __attribute__ ((__nothrow__)) {
     659void * kernel_abort(void) __attribute__ ((__nothrow__)) {
    615660        // abort cannot be recursively entered by the same or different processors because all signal handlers return when
    616661        // the globalAbort flag is true.
     
    618663
    619664        // first task to abort ?
    620         if ( ! kernel_abort_called ) {                  // not first task to abort ?
     665        if ( kernel_abort_called ) {                    // not first task to abort ?
     666                unlock( kernel_abort_lock );
     667
     668                sigset_t mask;
     669                sigemptyset( &mask );
     670                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
     671                sigsuspend( &mask );                    // block the processor to prevent further damage during abort
     672                _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     673        }
     674        else {
    621675                kernel_abort_called = true;
    622676                unlock( kernel_abort_lock );
    623677        }
    624         else {
    625                 unlock( kernel_abort_lock );
    626 
    627                 sigset_t mask;
    628                 sigemptyset( &mask );
    629                 sigaddset( &mask, SIGALRM );                    // block SIGALRM signals
    630                 sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    631                 sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    632                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    633         }
    634 
    635         return TL_GET( this_thread );
     678
     679        return kernelTLS.this_thread;
    636680}
    637681
     
    639683        thread_desc * thrd = kernel_data;
    640684
    641         int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd );
    642         __cfaabi_dbg_bits_write( abort_text, len );
    643 
    644         if ( get_coroutine(thrd) != TL_GET( this_coroutine ) ) {
    645                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) );
     685        if(thrd) {
     686                int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
    646687                __cfaabi_dbg_bits_write( abort_text, len );
     688
     689                if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
     690                        len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     691                        __cfaabi_dbg_bits_write( abort_text, len );
     692                }
     693                else {
     694                        __cfaabi_dbg_bits_write( ".\n", 2 );
     695                }
    647696        }
    648697        else {
    649                 __cfaabi_dbg_bits_write( ".\n", 2 );
     698                int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
    650699        }
    651700}
    652701
    653702int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    654         return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    655 }
     703        return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
     704}
     705
     706static __spinlock_t kernel_debug_lock;
    656707
    657708extern "C" {
     
    682733        if ( count < 0 ) {
    683734                // queue current task
    684                 append( waiting, (thread_desc *)TL_GET( this_thread ) );
     735                append( waiting, kernelTLS.this_thread );
    685736
    686737                // atomically release spin lock and block
     
    708759
    709760//-----------------------------------------------------------------------------
     761// Global Queues
     762void doregister( thread_desc & thrd ) {
     763        // lock      ( global_thread.lock );
     764        // push_front( global_thread.list, thrd );
     765        // unlock    ( global_thread.lock );
     766}
     767
     768void unregister( thread_desc & thrd ) {
     769        // lock  ( global_thread.lock );
     770        // remove( global_thread.list, thrd );
     771        // unlock( global_thread.lock );
     772}
     773
     774void doregister( cluster     & cltr ) {
     775        // lock      ( global_cluster.lock );
     776        // push_front( global_cluster.list, cltr );
     777        // unlock    ( global_cluster.lock );
     778}
     779
     780void unregister( cluster     & cltr ) {
     781        // lock  ( global_cluster.lock );
     782        // remove( global_cluster.list, cltr );
     783        // unlock( global_cluster.lock );
     784}
     785
     786
     787void doregister( cluster * cltr, processor * proc ) {
     788        // lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     789        // push_front(cltr->procs, *proc);
     790        // unlock    (cltr->proc_list_lock);
     791}
     792
     793void unregister( cluster * cltr, processor * proc ) {
     794        // lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     795        // remove(cltr->procs, *proc );
     796        // unlock(cltr->proc_list_lock);
     797}
     798
     799//-----------------------------------------------------------------------------
    710800// Debug
    711801__cfaabi_dbg_debug_do(
    712         struct {
    713                 thread_desc * tail;
    714         } __cfaabi_dbg_thread_list = { NULL };
    715 
    716         void __cfaabi_dbg_thread_register( thread_desc * thrd ) {
    717                 if( !__cfaabi_dbg_thread_list.tail ) {
    718                         __cfaabi_dbg_thread_list.tail = thrd;
    719                         return;
    720                 }
    721                 __cfaabi_dbg_thread_list.tail->dbg_next = thrd;
    722                 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail;
    723                 __cfaabi_dbg_thread_list.tail = thrd;
    724         }
    725 
    726         void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) {
    727                 thread_desc * prev = thrd->dbg_prev;
    728                 thread_desc * next = thrd->dbg_next;
    729 
    730                 if( next ) { next->dbg_prev = prev; }
    731                 else       {
    732                         assert( __cfaabi_dbg_thread_list.tail == thrd );
    733                         __cfaabi_dbg_thread_list.tail = prev;
    734                 }
    735 
    736                 if( prev ) { prev->dbg_next = next; }
    737 
    738                 thrd->dbg_prev = NULL;
    739                 thrd->dbg_next = NULL;
    740         }
    741 
    742802        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    743803                this.prev_name = prev_name;
    744                 this.prev_thrd = TL_GET( this_thread );
     804                this.prev_thrd = kernelTLS.this_thread;
    745805        }
    746806)
  • src/libcfa/concurrency/kernel_private.h

    r7d0a3ba r358cba0  
    100100#define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)]
    101101
     102
     103void doregister( struct thread_desc & thrd );
     104void unregister( struct thread_desc & thrd );
     105
     106void doregister( struct cluster     & cltr );
     107void unregister( struct cluster     & cltr );
     108
     109void doregister( struct cluster * cltr, struct processor * proc );
     110void unregister( struct cluster * cltr, struct processor * proc );
     111
    102112// Local Variables: //
    103113// mode: c //
  • src/libcfa/concurrency/monitor.c

    r7d0a3ba r358cba0  
    8585                // Lock the monitor spinlock
    8686                lock( this->lock __cfaabi_dbg_ctx2 );
    87                 thread_desc * thrd = TL_GET( this_thread );
     87                // Interrupts disable inside critical section
     88                thread_desc * thrd = kernelTLS.this_thread;
    8889
    8990                __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    134135                // Lock the monitor spinlock
    135136                lock( this->lock __cfaabi_dbg_ctx2 );
    136                 thread_desc * thrd = TL_GET( this_thread );
     137                // Interrupts disable inside critical section
     138                thread_desc * thrd = kernelTLS.this_thread;
    137139
    138140                __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     
    168170
    169171                        // Create the node specific to this wait operation
    170                         wait_ctx_primed( TL_GET( this_thread ), 0 )
     172                        wait_ctx_primed( thrd, 0 )
    171173
    172174                        // Some one else has the monitor, wait for him to finish and then run
     
    179181                        __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    180182
    181                         wait_ctx( TL_GET( this_thread ), 0 )
     183                        wait_ctx( thrd, 0 )
    182184                        this->dtor_node = &waiter;
    183185
     
    199201                lock( this->lock __cfaabi_dbg_ctx2 );
    200202
    201                 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", TL_GET( this_thread ), this, this->owner);
    202 
    203                 verifyf( TL_GET( this_thread ) == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", TL_GET( this_thread ), this->owner, this->recursion, this );
     203                __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", kernelTLS.this_thread, this, this->owner);
     204
     205                verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this );
    204206
    205207                // Leaving a recursion level, decrement the counter
     
    289291// Sorts monitors before entering
    290292void ?{}( monitor_guard_t & this, monitor_desc * m [], __lock_size_t count, fptr_t func ) {
     293        thread_desc * thrd = TL_GET( this_thread );
     294
    291295        // Store current array
    292296        this.m = m;
     
    297301
    298302        // Save previous thread context
    299         this.prev = TL_GET( this_thread )->monitors;
     303        this.prev = thrd->monitors;
    300304
    301305        // Update thread context (needed for conditions)
    302         (TL_GET( this_thread )->monitors){m, count, func};
     306        (thrd->monitors){m, count, func};
    303307
    304308        // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count);
     
    328332// Sorts monitors before entering
    329333void ?{}( monitor_dtor_guard_t & this, monitor_desc * m [], fptr_t func ) {
     334        // optimization
     335        thread_desc * thrd = TL_GET( this_thread );
     336
    330337        // Store current array
    331338        this.m = *m;
    332339
    333340        // Save previous thread context
    334         this.prev = TL_GET( this_thread )->monitors;
     341        this.prev = thrd->monitors;
    335342
    336343        // Update thread context (needed for conditions)
    337         (TL_GET( this_thread )->monitors){m, 1, func};
     344        (thrd->monitors){m, 1, func};
    338345
    339346        __enter_monitor_dtor( this.m, func );
     
    473480
    474481        // Create the node specific to this wait operation
    475         wait_ctx_primed( TL_GET( this_thread ), 0 )
     482        wait_ctx_primed( kernelTLS.this_thread, 0 )
    476483
    477484        //save contexts
     
    566573
    567574                                // Create the node specific to this wait operation
    568                                 wait_ctx_primed( TL_GET( this_thread ), 0 );
     575                                wait_ctx_primed( kernelTLS.this_thread, 0 );
    569576
    570577                                // Save monitor states
     
    612619
    613620        // Create the node specific to this wait operation
    614         wait_ctx_primed( TL_GET( this_thread ), 0 );
     621        wait_ctx_primed( kernelTLS.this_thread, 0 );
    615622
    616623        monitor_save;
     
    618625
    619626        for( __lock_size_t i = 0; i < count; i++) {
    620                 verify( monitors[i]->owner == TL_GET( this_thread ) );
     627                verify( monitors[i]->owner == kernelTLS.this_thread );
    621628        }
    622629
  • src/libcfa/concurrency/preemption.c

    r7d0a3ba r358cba0  
    149149        // Disable interrupts by incrementing the counter
    150150        void disable_interrupts() {
    151                 with( TL_GET( preemption_state ) ) {
     151                with( kernelTLS.preemption_state ) {
    152152                        enabled = false;
    153153                        __attribute__((unused)) unsigned short new_val = disable_count + 1;
     
    160160        // If counter reaches 0, execute any pending CtxSwitch
    161161        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    162                 processor   * proc = TL_GET( this_processor ); // Cache the processor now since interrupts can start happening after the atomic add
    163                 thread_desc * thrd = TL_GET( this_thread );       // Cache the thread now since interrupts can start happening after the atomic add
    164 
    165                 with( TL_GET( preemption_state ) ){
     162                processor   * proc = kernelTLS.this_processor; // Cache the processor now since interrupts can start happening after the atomic add
     163                thread_desc * thrd = kernelTLS.this_thread;       // Cache the thread now since interrupts can start happening after the atomic add
     164
     165                with( kernelTLS.preemption_state ){
    166166                        unsigned short prev = disable_count;
    167167                        disable_count -= 1;
     
    185185        // Don't execute any pending CtxSwitch even if counter reaches 0
    186186        void enable_interrupts_noPoll() {
    187                 unsigned short prev = TL_GET( preemption_state ).disable_count;
    188                 TL_GET( preemption_state ).disable_count -= 1;
     187                unsigned short prev = kernelTLS.preemption_state.disable_count;
     188                kernelTLS.preemption_state.disable_count -= 1;
    189189                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    190190                if( prev == 1 ) {
    191                         TL_GET( preemption_state ).enabled = true;
     191                        kernelTLS.preemption_state.enabled = true;
    192192                }
    193193        }
     
    234234}
    235235
    236 
     236// KERNEL ONLY
    237237// Check if a CtxSwitch signal handler shoud defer
    238238// If true  : preemption is safe
    239239// If false : preemption is unsafe and marked as pending
    240240static inline bool preemption_ready() {
    241         bool ready = TL_GET( preemption_state ).enabled && !TL_GET( preemption_state ).in_progress; // Check if preemption is safe
    242         TL_GET( this_processor )->pending_preemption = !ready;                  // Adjust the pending flag accordingly
     241        // Check if preemption is safe
     242        bool ready = kernelTLS.preemption_state.enabled && ! kernelTLS.preemption_state.in_progress;
     243
     244        // Adjust the pending flag accordingly
     245        kernelTLS.this_processor->pending_preemption = !ready;
    243246        return ready;
    244247}
     
    254257
    255258        // Start with preemption disabled until ready
    256         TL_GET( preemption_state ).enabled = false;
    257         TL_GET( preemption_state ).disable_count = 1;
     259        kernelTLS.preemption_state.enabled = false;
     260        kernelTLS.preemption_state.disable_count = 1;
    258261
    259262        // Initialize the event kernel
     
    320323        // before the kernel thread has even started running. When that happens an iterrupt
    321324        // we a null 'this_processor' will be caught, just ignore it.
    322         if(!TL_GET( this_processor )) return;
     325        if(! kernelTLS.this_processor ) return;
    323326
    324327        choose(sfp->si_value.sival_int) {
    325328                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    326                 case PREEMPT_TERMINATE: verify(TL_GET( this_processor )->do_terminate);
     329                case PREEMPT_TERMINATE: verify( kernelTLS.this_processor->do_terminate);
    327330                default:
    328331                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    332335        if( !preemption_ready() ) { return; }
    333336
    334         __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", TL_GET( this_processor ), TL_GET( this_thread ) );
    335 
    336         TL_GET( preemption_state ).in_progress = true;  // Sync flag : prevent recursive calls to the signal handler
    337         signal_unblock( SIGUSR1 );                          // We are about to CtxSwitch out of the signal handler, let other handlers in
    338         TL_GET( preemption_state ).in_progress = false; // Clear the in progress flag
     337        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", kernelTLS.this_processor, kernelTLS.this_thread );
     338
     339        // Sync flag : prevent recursive calls to the signal handler
     340        kernelTLS.preemption_state.in_progress = true;
     341
     342        // We are about to CtxSwitch out of the signal handler, let other handlers in
     343        signal_unblock( SIGUSR1 );
     344
     345        // TODO: this should go in finish action
     346        // Clear the in progress flag
     347        kernelTLS.preemption_state.in_progress = false;
    339348
    340349        // Preemption can occur here
    341350
    342         BlockInternal( (thread_desc*)TL_GET( this_thread ) ); // Do the actual CtxSwitch
     351        BlockInternal( kernelTLS.this_thread ); // Do the actual CtxSwitch
    343352}
    344353
     
    348357        // Block sigalrms to control when they arrive
    349358        sigset_t mask;
     359        sigfillset(&mask);
     360        if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
     361            abort( "internal error, pthread_sigmask" );
     362        }
     363
    350364        sigemptyset( &mask );
    351365        sigaddset( &mask, SIGALRM );
    352 
    353         if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
    354             abort( "internal error, pthread_sigmask" );
    355         }
    356366
    357367        // Main loop
     
    409419
    410420void __cfaabi_check_preemption() {
    411         bool ready = TL_GET( preemption_state ).enabled;
     421        bool ready = kernelTLS.preemption_state.enabled;
    412422        if(!ready) { abort("Preemption should be ready"); }
    413423
  • src/libcfa/concurrency/thread.c

    r7d0a3ba r358cba0  
    3939        curr_cluster = &cl;
    4040        next = NULL;
    41         __cfaabi_dbg_debug_do(
    42                 dbg_next = NULL;
    43                 dbg_prev = NULL;
    44                 __cfaabi_dbg_thread_register(&this);
    45         )
     41
     42        node.next = NULL;
     43        node.prev = NULL;
     44        doregister(this);
    4645
    4746        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    4948
    5049void ^?{}(thread_desc& this) with( this ) {
     50        unregister(this);
    5151        ^self_cor{};
    5252}
     
    8181        disable_interrupts();
    8282        create_stack(&thrd_c->stack, thrd_c->stack.size);
    83         TL_SET( this_coroutine, thrd_c );
     83        kernelTLS.this_coroutine = thrd_c;
    8484        CtxStart(&this, CtxInvokeThread);
    8585        assert( thrd_c->last->stack.context );
     
    9191
    9292extern "C" {
     93        // KERNEL ONLY
    9394        void __finish_creation(void) {
    94                 coroutine_desc* thrd_c = TL_GET( this_coroutine );
     95                coroutine_desc* thrd_c = kernelTLS.this_coroutine;
    9596                ThreadCtxSwitch( thrd_c, thrd_c->last );
    9697        }
     
    9899
    99100void yield( void ) {
    100         verify( TL_GET( preemption_state ).enabled );
     101        // Safety note : This could cause some false positives due to preemption
     102      verify( TL_GET( preemption_state.enabled ) );
    101103        BlockInternal( TL_GET( this_thread ) );
    102         verify( TL_GET( preemption_state ).enabled );
     104        // Safety note : This could cause some false positives due to preemption
     105      verify( TL_GET( preemption_state.enabled ) );
    103106}
    104107
     
    109112}
    110113
     114// KERNEL ONLY
    111115void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    112116        // set state of current coroutine to inactive
     
    116120        // set new coroutine that the processor is executing
    117121        // and context switch to it
    118         TL_SET( this_coroutine, dst );
     122        kernelTLS.this_coroutine = dst;
    119123        assert( src->stack.context );
    120124        CtxSwitch( src->stack.context, dst->stack.context );
    121         TL_SET( this_coroutine, src );
     125        kernelTLS.this_coroutine = src;
    122126
    123127        // set state of new coroutine to active
  • src/libcfa/interpose.c

    r7d0a3ba r358cba0  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May  1 15:05:35 2018
    13 // Update Count     : 83
    14 //
    15 
    16 #include <stdarg.h>
    17 #include <stddef.h>
    18 
    19 extern "C" {
    20 #include <stdio.h>
    21 #include <string.h>
    22 #include <dlfcn.h>
    23 #include <unistd.h>
     12// Last Modified On : Sat May  5 11:37:35 2018
     13// Update Count     : 111
     14//
     15
     16#include <stdarg.h>                                                                             // va_start, va_end
     17#include <string.h>                                                                             // strlen
     18#include <unistd.h>                                                                             // _exit, getpid
    2419#define __USE_GNU
    2520#include <signal.h>
    2621#undef __USE_GNU
    27 #include <execinfo.h>
     22extern "C" {
     23#include <dlfcn.h>                                                                              // dlopen, dlsym
     24#include <execinfo.h>                                                                   // backtrace, messages
    2825}
    2926
    3027#include "bits/debug.h"
    3128#include "bits/defs.h"
    32 #include "bits/signal.h"
    33 #include "startup.h"
     29#include "bits/signal.h"                                                                // sigHandler_?
     30#include "startup.h"                                                                    // STARTUP_PRIORITY_CORE
    3431
    3532//=============================================================================================
     
    3734//=============================================================================================
    3835
    39 typedef void (*generic_fptr_t)(void);
    40 generic_fptr_t interpose_symbol( const char* symbol, const char *version ) {
     36typedef void (* generic_fptr_t)(void);
     37generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
    4138        const char * error;
    4239
     
    5552        } // if
    5653
    57         union { generic_fptr_t fptr; void* ptr; } originalFunc;
     54        union { generic_fptr_t fptr; void * ptr; } originalFunc;
    5855
    5956        #if defined( _GNU_SOURCE )
     
    7370}
    7471
    75 forall(dtype T)
    76 static inline void ptr_from_symbol( T** symbol_ptr, const char * symbol_name, const char * version) {
    77         union {
    78                 generic_fptr_t gp;
    79                 T* tp;
    80         } u;
    81 
    82         u.gp = interpose_symbol( symbol_name, version );
    83 
    84         *symbol_ptr = u.tp;
    85 }
    86 
    87 #define INTERPOSE_LIBC( x, ver ) ptr_from_symbol( (void**)&__cabi_libc.x, #x, ver)
    88 
    89 //=============================================================================================
    90 // Terminating Signals logic
     72#define INTERPOSE_LIBC( x, ver ) __cabi_libc.x = (typeof(__cabi_libc.x))interpose_symbol( #x, ver )
     73
     74//=============================================================================================
     75// Interposition Startup logic
    9176//=============================================================================================
    9277
     
    9883
    9984struct {
    100         void (* exit)( int ) __attribute__ (( __noreturn__ ));
    101         void (* abort)( void ) __attribute__ (( __noreturn__ ));
     85        void (* exit)( int ) __attribute__(( __noreturn__ ));
     86        void (* abort)( void ) __attribute__(( __noreturn__ ));
    10287} __cabi_libc;
    10388
     
    10792                const char *version = NULL;
    10893
     94#pragma GCC diagnostic push
     95#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
    10996                INTERPOSE_LIBC( abort, version );
    11097                INTERPOSE_LIBC( exit , version );
    111 
    112                 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler
    113                 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler
    114                 __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO ); // Failure handler
    115                 __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO ); // Failure handler
    116                 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO ); // Failure handler
    117                 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); // Failure handler
    118                 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); // Failure handler
     98#pragma GCC diagnostic pop
     99
     100                // Failure handler
     101                __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );
     102                __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );
     103                __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
     104                __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
     105                __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND);
     106                __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
     107                __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
    119108        }
    120109}
     
    125114
    126115// Forward declare abort after the __typeof__ call to avoid ambiguities
    127 void exit( int status, const char fmt[], ... ) __attribute__ (( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    128 void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     116void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
     117void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
    129118
    130119extern "C" {
    131         void abort( void ) __attribute__ (( __nothrow__, __leaf__, __noreturn__ )) {
     120        void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    132121                abort( NULL );
    133122        }
    134123
    135         void __cabi_abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
     124        void __cabi_abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
    136125                va_list argp;
    137126                va_start( argp, fmt );
     
    140129        }
    141130
    142         void exit( int status ) __attribute__ (( __nothrow__, __leaf__, __noreturn__ )) {
     131        void exit( int status ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    143132                __cabi_libc.exit( status );
    144133        }
    145134}
    146135
    147 void * kernel_abort    ( void ) __attribute__ (( __nothrow__, __leaf__, __weak__ )) { return NULL; }
    148 void   kernel_abort_msg( void * data, char * buffer, int size ) __attribute__ (( __nothrow__, __leaf__, __weak__ )) {}
    149 int kernel_abort_lastframe( void ) __attribute__ (( __nothrow__, __leaf__, __weak__ )) { return 4; }
     136void * kernel_abort    ( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return NULL; }
     137void   kernel_abort_msg( void * data, char * buffer, int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     138int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    150139
    151140enum { abort_text_size = 1024 };
     
    153142static int abort_lastframe;
    154143
    155 void exit( int status, const char fmt[], ... ) __attribute__ (( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ )) {
     144void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ )) {
    156145    va_list args;
    157146    va_start( args, fmt );
     
    161150}
    162151
    163 void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
     152void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
    164153        void * kernel_data = kernel_abort();                    // must be done here to lock down kernel
    165154        int len;
  • src/libcfa/stdlib

    r7d0a3ba r358cba0  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jan  2 12:21:04 2018
    13 // Update Count     : 292
     12// Last Modified On : Sun May 13 23:22:23 2018
     13// Update Count     : 299
    1414//
    1515
    1616#pragma once
    1717
    18 //#define _XOPEN_SOURCE 600                                                             // posix_memalign, *rand48
     18#define __USE_ISOC11                                                                    // aligned_alloc
    1919#include <stdlib.h>                                                                             // strto*, *abs
    2020
     
    2828//---------------------------------------
    2929
    30 // allocation, non-array types
    31 static inline forall( dtype T | sized(T) ) T * malloc( void ) {
    32         // printf( "* malloc\n" );
    33         return (T *)(void *)malloc( (size_t)sizeof(T) );        // C malloc
    34 } // malloc
    35 
    36 // static inline forall( dtype T | sized(T) ) T & malloc( void ) {
    37 //      int & p = *(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    38 //      printf( "& malloc %p\n", &p );
    39 //      return p;
    40 // //   return (T &)*(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
    41 // } // malloc
    42 
    43 extern "C" { void * calloc( size_t dim, size_t size ); } // default C routine
    44 static inline forall( dtype T | sized(T) ) T * calloc( size_t dim ) {
    45         //printf( "X2\n" );
    46         return (T *)(void *)calloc( dim, sizeof(T) );           // C cmalloc
    47 }
    48 
    49 extern "C" { void * realloc( void * ptr, size_t size ); } // default C routine for void *
    50 static inline forall( dtype T | sized(T) ) T * realloc( T * ptr, size_t size ) {
    51         //printf( "X3\n" );
    52         return (T *)(void *)realloc( (void *)ptr, size );
    53 }
    54 
    55 extern "C" { void * memalign( size_t align, size_t size ); } // use default C routine for void *
    56 static inline forall( dtype T | sized(T) ) T * memalign( size_t align ) {
    57         //printf( "X4\n" );
    58         return (T *)memalign( align, sizeof(T) );
    59 } // memalign
    60 
    61 static inline forall( dtype T | sized(T) ) T * aligned_alloc( size_t align ) {
    62         //printf( "X5\n" );
    63         return (T *)memalign( align, sizeof(T) );
    64 } // aligned_alloc
    65 
    66 extern "C" { int posix_memalign( void ** ptr, size_t align, size_t size ); } // use default C routine for void *
    67 static inline forall( dtype T | sized(T) ) int posix_memalign( T ** ptr, size_t align ) {
    68         //printf( "X6\n" );
    69         return posix_memalign( (void **)ptr, align, sizeof(T) );
    70 } // posix_memalign
    71 
    72 
    73 extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void *
    74 
    75 static inline forall( dtype T | sized(T) ) T * alloc( void ) {
    76         //printf( "X7\n" );
    77         return (T *)(void *)malloc( (size_t)sizeof(T) );        // C malloc
    78 } // alloc
    79 static inline forall( dtype T | sized(T) ) T * alloc( char fill ) {
    80         //printf( "X8\n" );
    81         T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) );     // C malloc
    82     return (T *)memset( ptr, (int)fill, sizeof(T) );    // initial with fill value
    83 } // alloc
    84 
    85 static inline forall( dtype T | sized(T) ) T * alloc( size_t dim ) {
    86         //printf( "X9\n" );
    87         return (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
    88 } // alloc
    89 static inline forall( dtype T | sized(T) ) T * alloc( size_t dim, char fill ) {
    90         //printf( "X10\n" );
    91         T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
    92     return (T *)memset( ptr, (int)fill, dim * sizeof(T) );
    93 } // alloc
    94 
    95 static inline forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim ) {
    96         //printf( "X11\n" );
    97         return (T *)(void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc
    98 } // alloc
     30// C dynamic allocation
     31static inline forall( dtype T | sized(T) ) {
     32        T * malloc( void ) {
     33                // printf( "* malloc\n" );
     34                return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     35        } // malloc
     36
     37        // T & malloc( void ) {
     38        //      int & p = *(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     39        //      printf( "& malloc %p\n", &p );
     40        //      return p;
     41        //      //      return (T &)*(T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     42        // } // malloc
     43
     44        T * calloc( size_t dim ) {
     45                //printf( "X2\n" );
     46                return (T *)(void *)calloc( dim, sizeof(T) );   // C calloc
     47        } // calloc
     48
     49        T * realloc( T * ptr, size_t size ) {
     50                //printf( "X3\n" );
     51                return (T *)(void *)realloc( (void *)ptr, size );
     52        } // realloc
     53
     54        extern "C" { void * memalign( size_t align, size_t size ); } // use default C routine for void *
     55        T * memalign( size_t align ) {
     56                //printf( "X4\n" );
     57                return (T *)memalign( align, sizeof(T) );
     58        } // memalign
     59
     60        extern "C" { void * aligned_alloc( size_t align, size_t size ); } // use default C routine for void *
     61        T * aligned_alloc( size_t align ) {
     62                //printf( "X5\n" );
     63                return (T *)aligned_alloc( align, sizeof(T) );
     64        } // aligned_alloc
     65
     66        int posix_memalign( T ** ptr, size_t align ) {
     67                //printf( "X6\n" );
     68                return posix_memalign( (void **)ptr, align, sizeof(T) ); // C posix_memalign
     69        } // posix_memalign
     70
     71
     72        // Cforall dynamic allocation
     73        extern "C" { void * memset( void * dest, int c, size_t size ); } // use default C routine for void *
     74
     75        T * alloc( void ) {
     76                //printf( "X7\n" );
     77                return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     78        } // alloc
     79
     80        T * alloc( char fill ) {
     81                //printf( "X8\n" );
     82                T * ptr = (T *)(void *)malloc( (size_t)sizeof(T) );     // C malloc
     83                return (T *)memset( ptr, (int)fill, sizeof(T) );        // initial with fill value
     84        } // alloc
     85
     86        T * alloc( size_t dim ) {
     87                //printf( "X9\n" );
     88                return (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
     89        } // alloc
     90
     91        T * alloc( size_t dim, char fill ) {
     92                //printf( "X10\n" );
     93                T * ptr = (T *)(void *)malloc( dim * (size_t)sizeof(T) ); // C malloc
     94                return (T *)memset( ptr, (int)fill, dim * sizeof(T) );    // initial with fill value
     95        } // alloc
     96
     97        T * alloc( T ptr[], size_t dim ) {
     98                //printf( "X11\n" );
     99                return (T *)(void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc
     100        } // alloc
     101} // distribution
     102
     103
    99104forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill );
    100105
  • src/libcfa/time.c

    r7d0a3ba r358cba0  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 12 14:41:00 2018
    13 // Update Count     : 22
     12// Last Modified On : Sun May  6 22:26:00 2018
     13// Update Count     : 37
    1414//
    1515
     
    1717#include "iostream"
    1818#include <stdio.h>                                                                              // snprintf
     19#include <assert.h>
    1920
    2021static char * nanomsd( long int ns, char * buf ) {              // most significant digits
     
    8788        time_t s = tv / TIMEGRAN;
    8889        tm tm;
    89         gmtime_r( &s, &tm );
     90        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     91#if defined(__GNUC__) && __GNUC__ >= 7
     92#pragma GCC diagnostic push
     93#pragma GCC diagnostic ignored "-Wformat-truncation"
     94#endif
    9095        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_year % 99, tm.tm_mon + 1, tm.tm_mday );
     96#if defined(__GNUC__) && __GNUC__ >= 7
     97#pragma GCC diagnostic pop
     98#endif
    9199        return buf;
    92100} // yy_mm_dd
     
    95103        time_t s = tv / TIMEGRAN;
    96104        tm tm;
    97         gmtime_r( &s, &tm );
     105        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     106#if defined(__GNUC__) && __GNUC__ >= 7
     107#pragma GCC diagnostic push
     108#pragma GCC diagnostic ignored "-Wformat-truncation"
     109#endif
    98110        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mon + 1, tm.tm_mday, tm.tm_year % 99 );
     111#if defined(__GNUC__) && __GNUC__ >= 7
     112#pragma GCC diagnostic pop
     113#endif
    99114        return buf;
    100115} // mm_dd_yy
     
    103118        time_t s = tv / TIMEGRAN;
    104119        tm tm;
    105         gmtime_r( &s, &tm );
     120        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     121#if defined(__GNUC__) && __GNUC__ >= 7
     122#pragma GCC diagnostic push
     123#pragma GCC diagnostic ignored "-Wformat-truncation"
     124#endif
    106125        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mday, tm.tm_mon + 1, tm.tm_year % 99 );
     126#if defined(__GNUC__) && __GNUC__ >= 7
     127#pragma GCC diagnostic pop
     128#endif
    107129        return buf;
    108130} // dd_mm_yy
  • src/main.cc

    r7d0a3ba r358cba0  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May  2 14:59:02 2018
    13 // Update Count     : 490
     12// Last Modified On : Mon May  7 14:35:57 2018
     13// Update Count     : 492
    1414//
    1515
     
    6464
    6565#define PASS(name, pass)                   \
    66         if ( errorp ) { cerr << #name << endl; } \
    67         HeapStats::newPass(#name);               \
     66        if ( errorp ) { cerr << name << endl; } \
     67        HeapStats::newPass(name);               \
    6868        pass;
    6969
     
    371371                } // if
    372372                return 1;
    373         } // try
     373        } catch(...) {
     374                std::exception_ptr eptr = std::current_exception();
     375                try {
     376                        if (eptr) {
     377                                std::rethrow_exception(eptr);
     378                        }
     379                        else {
     380                                std::cerr << "Exception Uncaught and Unkown" << std::endl;
     381                        }
     382                } catch(const std::exception& e) {
     383                        std::cerr << "Unaught Exception \"" << e.what() << "\"\n";
     384                }
     385                return 1;
     386        }// try
    374387
    375388        deleteAll( translationUnit );
    376         HeapStats::printStats();
     389        if(!libcfap && !treep) HeapStats::printStats();
    377390        return 0;
    378391} // main
     
    407420        opterr = 0;                                                                                     // (global) prevent getopt from printing error messages
    408421
    409         bool Werror = false;
     422        bool Wsuppress = false, Werror = false;
    410423        int c;
    411424        while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrstTvwW:yzZD:F:", long_opts, &long_index )) != -1 ) {
     
    495508                        break;
    496509                  case 'w':
    497                         SemanticWarning_SuppressAll();
     510                        Wsuppress = true;
    498511                        break;
    499512                  case 'W':
     
    534547                                assertf( false, "Unknown option: %s\n", argv[optind - 1] );
    535548                        } // if
    536                         #if __GNUC__ < 7
    537                         #else
     549                        #if defined(__GNUC__) && __GNUC__ >= 7
    538550                                __attribute__((fallthrough));
    539551                        #endif
     
    545557        if ( Werror ) {
    546558                SemanticWarning_WarningAsError();
     559        } // if
     560        if ( Wsuppress ) {
     561                SemanticWarning_SuppressAll();
    547562        } // if
    548563        // for ( const auto w : WarningFormats ) {
  • src/tests/coroutine/fmtLines.c

    r7d0a3ba r358cba0  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // fmtLines.cc --
     7// fmtLines.cc -- format characters into blocks of 4 and groups of 5 blocks per line
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sun Sep 17 21:56:15 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  5 21:56:35 2017
    13 // Update Count     : 38
     12// Last Modified On : Tue May 15 12:25:33 2018
     13// Update Count     : 42
    1414//
    1515
     
    2121        int g, b;                                                                                       // global because used in destructor
    2222};
    23 
    24 void ?{}( Format & fmt ) {
    25         resume( fmt );                                                                          // prime (start) coroutine
    26 }
    27 
    28 void ^?{}( Format & fmt ) with( fmt ) {
    29         if ( g != 0 || b != 0 ) sout | endl;
    30 }
    3123
    3224void main( Format & fmt ) with( fmt ) {
     
    4638} // main
    4739
    48 void prt( Format & fmt, char ch ) {
    49         fmt.ch = ch;
     40void ?{}( Format & fmt ) {
     41        resume( fmt );                                                                          // prime (start) coroutine
     42}
     43
     44void ^?{}( Format & fmt ) with( fmt ) {
     45        if ( g != 0 || b != 0 ) sout | endl;
     46}
     47
     48void format( Format & fmt ) {
    5049        resume( fmt );
    5150} // prt
    5251
    5352int main() {
    54         Format fmt;                                                                                     // format characters into blocks of 4 and groups of 5 blocks per line
    55         char ch;
     53        Format fmt;
    5654
    57         Eof: for ( ;; ) {                                                                       // read until end of file
    58                 sin | ch;                                                                               // read one character
    59           if ( eof( sin ) ) break Eof;                                          // eof ?
    60                 prt( fmt, ch );                                                                 // push character for formatting
     55        eof: for ( ;; ) {                                                                       // read until end of file
     56                sin | fmt.ch;                                                                   // read one character
     57          if ( eof( sin ) ) break eof;                                          // eof ?
     58                format( fmt );                                                                  // push character for formatting
    6159        } // for
    6260} // main
Note: See TracChangeset for help on using the changeset viewer.