Changeset 713905fd


Ignore:
Timestamp:
Jul 10, 2023, 11:14:13 AM (2 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
master
Children:
c3f7dd9
Parents:
e6e1a12 (diff), b29a1e8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Files:
4 added
10 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/coroutine.cfa

    re6e1a12 r713905fd  
    121121        last = 0p;
    122122        cancellation = 0p;
     123    ehm_state.ehm_buffer{};
     124    ehm_state.buffer_lock{};
     125    ehm_state.ehm_enabled = false;
    123126}
    124127
     
    283286}
    284287
     288
     289////////////////////////////////////////////////////////////////////////////////////////////////////
     290// non local ehm routines
     291
     292// helper for popping from coroutine's ehm buffer
     293inline nonlocal_exception * pop_ehm_head( coroutine$ * this ) {
     294    lock( this->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
     295    nonlocal_exception * nl_ex = pop_head( this->ehm_state.ehm_buffer );
     296    unlock( this->ehm_state.buffer_lock );
     297    return nl_ex;
     298}
     299
     300// user facing ehm operations
     301forall(T & | is_coroutine(T)) {
     302    // enable/disable non-local exceptions
     303    void enable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = true; }
     304    void disable_ehm( T & cor ) libcfa_public { get_coroutine( cor )->ehm_state.ehm_enabled = false; }
     305
     306    // poll for non-local exceptions
     307    bool poll( T & cor ) libcfa_public {
     308        coroutine$ * base_cor = get_coroutine( cor );
     309        nonlocal_exception * nl_ex = pop_ehm_head( base_cor );
     310
     311        // if no exceptions return false
     312        if ( nl_ex == 0p ) return false;
     313       
     314        // otherwise loop and throwResume all pending exceptions
     315        while ( nl_ex != 0p ){
     316            exception_t * ex = nl_ex->the_exception;
     317            free( nl_ex );
     318            throwResume *ex;
     319            nl_ex = pop_ehm_head( base_cor );
     320        }
     321       
     322        return true;
     323    }
     324
     325    // poll iff nonlocal ehm is enabled
     326    bool checked_poll( T & cor ) libcfa_public { return get_coroutine( cor )->ehm_state.ehm_enabled ? poll( cor ) : false; }
     327}
     328
     329// resume non local exception at receiver (i.e. enqueue in ehm buffer)
     330forall(exceptT &, T & | ehm_resume_at( exceptT, T ))
     331void resumeAt( T & receiver, exceptT & ex )  libcfa_public {
     332    coroutine$ * cor = get_coroutine( receiver );
     333    nonlocal_exception * nl_ex = alloc();
     334    (*nl_ex){ (exception_t *)&ex };
     335    lock( cor->ehm_state.buffer_lock __cfaabi_dbg_ctx2 );
     336    append( cor->ehm_state.ehm_buffer, nl_ex );
     337    unlock( cor->ehm_state.buffer_lock );
     338}
     339
    285340// Local Variables: //
    286341// mode: c //
  • libcfa/src/concurrency/coroutine.hfa

    re6e1a12 r713905fd  
    1919#include "invoke.h"
    2020#include "../exception.hfa"
     21
     22//-----------------------------------------------------------------------------
     23// Type used to store and queue nonlocal exceptions on coroutines
     24struct nonlocal_exception {
     25    exception_t * the_exception;
     26    nonlocal_exception * next;
     27};
     28static inline void ?{} ( nonlocal_exception & this, exception_t * ex ) with(this) {
     29    the_exception = ex;
     30    next = 0p;
     31}
     32
     33static inline nonlocal_exception *& get_next( nonlocal_exception & this ) __attribute__((const)) {
     34    return this.next;
     35}
    2136
    2237//-----------------------------------------------------------------------------
     
    203218}
    204219
     220// non local ehm routines
     221forall(T & | is_coroutine(T)) {
     222    void enable_ehm( T & cor );
     223    void disable_ehm( T & cor );
     224    bool poll( T & cor );
     225    bool checked_poll( T & cor );
     226}
     227
     228// trait for exceptions able to be resumed at another coroutine
     229forall(exceptT &, T & | is_coroutine(T))
     230trait ehm_resume_at { void $throwResume(exceptT &); };
     231
     232forall(exceptT &, T & | ehm_resume_at( exceptT, T ))
     233void resumeAt( T & receiver, exceptT & ex );
     234
    205235// Local Variables: //
    206236// mode: c //
  • libcfa/src/concurrency/invoke.h

    re6e1a12 r713905fd  
    7474        };
    7575
     76    struct nonlocal_ehm {
     77        // list of pending nonlocal exceptions
     78        __queue_t(struct nonlocal_exception) ehm_buffer;
     79
     80        // lock to protect the buffer
     81        struct __spinlock_t buffer_lock;
     82
     83        // enable/disabled flag
     84        bool ehm_enabled;
     85    };
     86
    7687        enum __Coroutine_State { Halted, Start, Primed, Blocked, Ready, Active, Cancelled, Halting };
    7788
     
    98109                struct _Unwind_Exception * cancellation;
    99110
     111        // Non-local exception handling information
     112        struct nonlocal_ehm ehm_state;
    100113        };
    101114        // Wrapper for gdb
  • src/AST/Decl.hpp

    re6e1a12 r713905fd  
    6969public:
    7070        /// Represents the type with all types and typedefs expanded.
    71         /// This field is generated by SymTab::Validate::Pass2
    7271        std::string mangleName;
    7372        /// Stores the scope level at which the variable was declared.
  • src/AST/SymbolTable.cpp

    re6e1a12 r713905fd  
    1919
    2020#include "Copy.hpp"
    21 #include <iostream>
    22 #include <algorithm>
    23 
    2421#include "Decl.hpp"
    2522#include "Expr.hpp"
     
    206203                        out.push_back(decl.second);
    207204                }
    208 
    209                 // std::cerr << otypeKey << ' ' << out.size() << std::endl;
    210205        }
    211206
  • src/GenPoly/SpecializeNew.cpp

    re6e1a12 r713905fd  
    104104
    105105bool needsPolySpecialization(
    106                 const ast::Type * formalType,
     106                const ast::Type * /*formalType*/,
    107107                const ast::Type * actualType,
    108108                const ast::TypeSubstitution * subs ) {
     
    126126                        if ( closedVars.find( *inst ) == closedVars.end() ) {
    127127                                return true;
    128                         }
    129                         else {
     128                        } else {
    130129                                assertf(false, "closed: %s", inst->name.c_str());
    131130                        }
  • src/InitTweak/FixInitNew.cpp

    re6e1a12 r713905fd  
    2222#include "AST/SymbolTable.hpp"
    2323#include "AST/Type.hpp"
    24 #include "CodeGen/GenType.h"           // for genPrettyType
    25 #include "CodeGen/OperatorTable.h"
    26 #include "Common/PassVisitor.h"        // for PassVisitor, WithStmtsToAdd
     24#include "CodeGen/OperatorTable.h"     // for isConstructor, isCtorDtor, isD...
    2725#include "Common/SemanticError.h"      // for SemanticError
    2826#include "Common/ToString.hpp"         // for toCString
     
    3331#include "ResolvExpr/Resolver.h"       // for findVoidExpression
    3432#include "ResolvExpr/Unify.h"          // for typesCompatible
    35 #include "SymTab/Autogen.h"            // for genImplicitCall
    3633#include "SymTab/GenImplicitCall.hpp"  // for genImplicitCall
    37 #include "SymTab/Indexer.h"            // for Indexer
    38 #include "SymTab/Mangler.h"            // for Mangler
    39 #include "SynTree/LinkageSpec.h"       // for C, Spec, Cforall, isBuiltin
    40 #include "SynTree/Attribute.h"         // for Attribute
    41 #include "SynTree/Constant.h"          // for Constant
    42 #include "SynTree/Declaration.h"       // for ObjectDecl, FunctionDecl, Decl...
    43 #include "SynTree/Expression.h"        // for UniqueExpr, VariableExpr, Unty...
    44 #include "SynTree/Initializer.h"       // for ConstructorInit, SingleInit
    45 #include "SynTree/Label.h"             // for Label, operator<
    46 #include "SynTree/Mutator.h"           // for mutateAll, Mutator, maybeMutate
    47 #include "SynTree/Statement.h"         // for ExprStmt, CompoundStmt, Branch...
    48 #include "SynTree/Type.h"              // for Type, Type::StorageClasses
    49 #include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
    50 #include "SynTree/DeclReplacer.h"      // for DeclReplacer
    51 #include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
    52 #include "Validate/FindSpecialDecls.h" // for dtorStmt, dtorStructDestroy
    5334
    5435extern bool ctordtorp; // print all debug
  • src/ResolvExpr/CommonType.cc

    re6e1a12 r713905fd  
    696696                void postvisit( const ast::BasicType * basic ) {
    697697                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
    698                                 #warning remove casts when `commonTypes` moved to new AST
    699                                
    700                                 /*
    701                                 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
    702                                 if (
    703                                         ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
    704                                                 || widen.first )
    705                                         && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
    706                                                 || widen.second )
    707                                 ) {
    708                                         result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    709                                 }
    710                                 */
    711698                                ast::BasicType::Kind kind;
    712699                                if (basic->kind != basic2->kind && !widen.first && !widen.second) return;
     
    719706                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    720707                                }
    721                                
    722708                        } else if (
    723709                                dynamic_cast< const ast::ZeroType * >( type2 )
    724710                                || dynamic_cast< const ast::OneType * >( type2 )
    725711                        ) {
    726                                 #warning remove casts when `commonTypes` moved to new AST
    727                                 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    728                                 /*
    729                                 if ( // xxx - what does qualifier even do here??
    730                                         ( ( basic->qualifiers >= type2->qualifiers )
    731                                                 || widen.first )
    732                                          && ( ( /* kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    733                                                 || widen.second )
    734                                 )
    735                                 */
    736712                                if (widen.second) {
    737713                                        result = new ast::BasicType{ basic->kind, basic->qualifiers | type2->qualifiers };
    738714                                }
    739715                        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    740                                 #warning remove casts when `commonTypes` moved to new AST
    741716                                const ast::EnumDecl* enumDecl = enumInst->base;
    742717                                if ( enumDecl->base ) {
    743718                                        result = enumDecl->base.get();
    744719                                } else {
     720                                        #warning remove casts when `commonTypes` moved to new AST
    745721                                        ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    746722                                        if (
     
    763739                                auto entry = open.find( *var );
    764740                                if ( entry != open.end() ) {
    765                                 // if (tenv.lookup(*var)) {
    766741                                        ast::AssertionSet need, have;
    767742                                        if ( ! tenv.bindVar(
  • src/ResolvExpr/Unify.cc

    re6e1a12 r713905fd  
    12981298                auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
    12991299                auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
    1300                 ast::OpenVarSet::const_iterator
    1301                         entry1 = var1 ? open.find( *var1 ) : open.end(),
    1302                         entry2 = var2 ? open.find( *var2 ) : open.end();
    1303                 // bool isopen1 = entry1 != open.end();
    1304                 // bool isopen2 = entry2 != open.end();
    13051300                bool isopen1 = var1 && env.lookup(*var1);
    13061301                bool isopen2 = var2 && env.lookup(*var2);
    13071302
    1308                 /*
    1309                 if ( isopen1 && isopen2 ) {
    1310                         if ( entry1->second.kind != entry2->second.kind ) return false;
    1311                         return env.bindVarToVar(
    1312                                 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    1313                                 open, widen );
    1314                 } else if ( isopen1 ) {
    1315                         return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
    1316                 } else if ( isopen2 ) {
    1317                         return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
    1318                 } */
    13191303                if ( isopen1 && isopen2 ) {
    13201304                        if ( var1->base->kind != var2->base->kind ) return false;
     
    13261310                } else if ( isopen2 ) {
    13271311                        return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen );
    1328                 }else {
     1312                } else {
    13291313                        return ast::Pass<Unify_new>::read(
    13301314                                type1, type2, env, need, have, open, widen );
    13311315                }
    1332                
    13331316        }
    13341317
  • src/Validate/LinkReferenceToTypes.cpp

    re6e1a12 r713905fd  
    8080ast::EnumInstType const * LinkTypesCore::postvisit( ast::EnumInstType const * type ) {
    8181        ast::EnumDecl const * decl = symtab.lookupEnum( type->name );
     82        ast::EnumInstType * mut = ast::mutate( type );
    8283        // It's not a semantic error if the enum is not found, just an implicit forward declaration.
    8384        if ( decl ) {
    8485                // Just linking in the node.
    85                 auto mut = ast::mutate( type );
    8686                mut->base = decl;
    87                 type = mut;
    8887        }
    8988        if ( !decl || !decl->body ) {
    90                 auto mut = ast::mutate( type );
    9189                forwardEnums[ mut->name ].push_back( mut );
    92                 type = mut;
    93         }
    94         return type;
     90        }
     91        return mut;
    9592}
    9693
    9794ast::StructInstType const * LinkTypesCore::postvisit( ast::StructInstType const * type ) {
    9895        ast::StructDecl const * decl = symtab.lookupStruct( type->name );
     96        ast::StructInstType * mut = ast::mutate( type );
    9997        // It's not a semantic error if the struct is not found, just an implicit forward declaration.
    10098        if ( decl ) {
    10199                // Just linking in the node.
    102                 auto mut = ast::mutate( type );
    103100                mut->base = decl;
    104                 type = mut;
    105101        }
    106102        if ( !decl || !decl->body ) {
    107                 auto mut = ast::mutate( type );
    108103                forwardStructs[ mut->name ].push_back( mut );
    109                 type = mut;
    110         }
    111         return type;
     104        }
     105        return mut;
    112106}
    113107
    114108ast::UnionInstType const * LinkTypesCore::postvisit( ast::UnionInstType const * type ) {
    115109        ast::UnionDecl const * decl = symtab.lookupUnion( type->name );
     110        ast::UnionInstType * mut = ast::mutate( type );
    116111        // It's not a semantic error if the union is not found, just an implicit forward declaration.
    117112        if ( decl ) {
    118113                // Just linking in the node.
    119                 auto mut = ast::mutate( type );
    120114                mut->base = decl;
    121                 type = mut;
    122115        }
    123116        if ( !decl || !decl->body ) {
    124                 auto mut = ast::mutate( type );
    125117                forwardUnions[ mut->name ].push_back( mut );
    126                 type = mut;
    127         }
    128         return type;
     118        }
     119        return mut;
    129120}
    130121
Note: See TracChangeset for help on using the changeset viewer.