Changeset 87d13cd


Ignore:
Timestamp:
Mar 21, 2017, 10:07:52 PM (5 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
cb91437
Parents:
829c907 (diff), a53e10a (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:

fix conflicit in iostream.c

Files:
6 added
34 edited

Legend:

Unmodified
Added
Removed
  • doc/proposals/concurrency/thePlan.md

    r829c907 r87d13cd  
    88_Phase 2_ : Minimum Viable Product
    99done - Monitor type and enter/leave mutex member routines
    10 Monitors as a language feature (not calling enter/leave by hand)
     10done - Multi monitors calls,
     11done - Monitors as a language feature (not calling enter/leave by hand)
    1112Internal scheduling
    1213
    1314_Phase 3_ : Kernel features
     15Preemption
    1416Detach thread
    1517Cluster migration
    16 Preemption
    1718
    1819_Phase 4_ : Monitor features
    19 Multi monitors calls,
    2020External scheduling
    2121
  • src/Concurrency/Keywords.cc

    r829c907 r87d13cd  
    1717#include "Concurrency/Keywords.h"
    1818
     19#include "SymTab/AddVisit.h"
    1920#include "SynTree/Declaration.h"
    2021#include "SynTree/Expression.h"
     
    2930        namespace {
    3031                const std::list<Label> noLabels;
     32                const std::list< Attribute * > noAttributes;
    3133                Type::StorageClasses noStorage;
    3234                Type::Qualifiers noQualifiers;
     
    6365        //                                           void main( MyCoroutine * this );
    6466        //
    65         class CoroutineKeyword final : public Mutator {
     67        class CoroutineKeyword final : public Visitor {
     68            template< typename Visitor >
     69            friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    6670          public:
    6771
    68                 static void implement( std::list< Declaration * > & translationUnit ) {}
     72                using Visitor::visit;
     73                virtual void visit( StructDecl * decl ) override final;
     74
     75                void handle( StructDecl * );
     76                Declaration * addField( StructDecl * );
     77                void addRoutines( StructDecl *, Declaration * );
     78
     79                static void implement( std::list< Declaration * > & translationUnit ) {
     80                        CoroutineKeyword impl;
     81                        SymTab::acceptAndAdd( translationUnit, impl );
     82                }
     83
     84          private:
     85                std::list< Declaration * > declsToAdd, declsToAddAfter;
     86                StructDecl* coroutine_decl = nullptr;
    6987        };
    7088
     
    97115
    98116                using Visitor::visit;
    99                 virtual void visit( FunctionDecl *functionDecl ) override final;
    100                 virtual void visit(   StructDecl *functionDecl ) override final;
     117                virtual void visit( FunctionDecl * decl ) override final;
     118                virtual void visit(   StructDecl * decl ) override final;
    101119
    102120                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     
    111129          private:
    112130                StructDecl* monitor_decl = nullptr;
     131                StructDecl* guard_decl = nullptr;
    113132        };
    114133
     
    124143
    125144        //=============================================================================================
     145        // Coroutine keyword implementation
     146        //=============================================================================================
     147        void CoroutineKeyword::visit(StructDecl * decl) {
     148                if( decl->get_name() == "coroutine_desc" ) {
     149                        assert( !coroutine_decl );
     150                        coroutine_decl = decl;
     151                }
     152                else if ( decl->is_coroutine() ) {
     153                        handle( decl );
     154                }
     155
     156        }
     157
     158        void CoroutineKeyword::handle( StructDecl * decl ) {
     159                if( ! decl->has_body() ) return;
     160
     161                if( !coroutine_decl ) throw SemanticError( "coroutine keyword requires coroutines to be in scope, add #include <coroutine>", decl );
     162
     163                Declaration * field = addField( decl );
     164                addRoutines( decl, field );
     165        }
     166
     167        Declaration * CoroutineKeyword::addField( StructDecl * decl ) {
     168                Declaration * cor = new ObjectDecl(
     169                        "__cor",
     170                        noStorage,
     171                        LinkageSpec::Cforall,
     172                        nullptr,
     173                        new StructInstType(
     174                                noQualifiers,
     175                                coroutine_decl
     176                        ),
     177                        nullptr
     178                );
     179
     180                decl->get_members().push_back( cor );
     181
     182                return cor;
     183        }
     184
     185        void CoroutineKeyword::addRoutines( StructDecl * decl, Declaration * field ) {
     186                FunctionType * type = new FunctionType( noQualifiers, false );
     187                type->get_parameters().push_back(
     188                        new ObjectDecl(
     189                                "this",
     190                                noStorage,
     191                                LinkageSpec::Cforall,
     192                                nullptr,
     193                                new PointerType(
     194                                        noQualifiers,
     195                                        new StructInstType(
     196                                                noQualifiers,
     197                                                decl
     198                                        )
     199                                ),
     200                                nullptr
     201                        )
     202                );
     203                type->get_returnVals().push_back(
     204                        new ObjectDecl(
     205                                "ret",
     206                                noStorage,
     207                                LinkageSpec::Cforall,
     208                                nullptr,
     209                                new PointerType(
     210                                        noQualifiers,
     211                                        new StructInstType(
     212                                                noQualifiers,
     213                                                coroutine_decl
     214                                        )
     215                                ),
     216                                nullptr
     217                        )
     218                );
     219
     220                CompoundStmt * statement = new CompoundStmt( noLabels );
     221                statement->push_back(
     222                        new ReturnStmt(
     223                                noLabels,
     224                                new AddressExpr(
     225                                        new UntypedMemberExpr(
     226                                                new NameExpr( "__cor" ),
     227                                                new UntypedExpr(
     228                                                        new NameExpr( "*?" ),
     229                                                        { new NameExpr( "this" ) }
     230                                                )
     231                                        )
     232                                )
     233                        )
     234                );
     235
     236                FunctionDecl * get_decl = new FunctionDecl(
     237                        "get_coroutine",
     238                        Type::Static,
     239                        LinkageSpec::Cforall,
     240                        type,
     241                        statement,
     242                        noAttributes,
     243                        Type::Inline
     244                );
     245
     246                declsToAddAfter.push_back( get_decl );
     247
     248                get_decl->fixUniqueId();
     249        }
     250       
     251
     252        //=============================================================================================
    126253        // Mutex keyword implementation
    127254        //=============================================================================================
     
    137264                if( ! body ) return;
    138265
    139                 assert(monitor_decl);
     266                if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
     267                if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
     268
    140269                addStatments( body, mutexArgs );
    141270        }
     
    146275                        monitor_decl = decl;
    147276                }
     277                else if( decl->get_name() == "monitor_guard_t" ) {
     278                        assert( !guard_decl );
     279                        guard_decl = decl;
     280                }
    148281        }
    149282
     
    175308
    176309                //Make sure that typed isn't mutex
    177                 if( ! base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     310                if( base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
    178311        }
    179312
    180313        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
    181 
    182314                ObjectDecl * monitors = new ObjectDecl(
    183315                        "__monitors",
     
    199331                        ),
    200332                        new ListInit(
    201                                 map_range < std::list<Initializer*> > ( args, [](DeclarationWithType * var ){
     333                                map_range < std::list<Initializer*> > ( args, [this](DeclarationWithType * var ){
     334                                        Type * type = var->get_type()->clone();
     335                                        type->set_mutex( false );
    202336                                        return new SingleInit( new UntypedExpr(
    203337                                                new NameExpr( "get_monitor" ),
    204                                                 {  new VariableExpr( var ) }
     338                                                {  new CastExpr( new VariableExpr( var ), type ) }
    205339                                        ) );
    206340                                })
     
    218352                                new StructInstType(
    219353                                        noQualifiers,
    220                                         "monitor_guard_t"
     354                                        guard_decl
    221355                                ),
    222356                                new ListInit(
     
    224358                                                new SingleInit( new VariableExpr( monitors ) ),
    225359                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
    226                                         }
     360                                        },
     361                                        noDesignators,
     362                                        true
    227363                                )
    228364                        ))
    229365                );
    230366
    231                 //monitor_desc * __monitors[] = { a, b };
     367                //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
    232368                body->push_front( new DeclStmt( noLabels, monitors) );
    233369        }
  • src/InitTweak/FixInit.cc

    r829c907 r87d13cd  
    534534                        } else {
    535535                                // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    536                                 unqExpr->set_object( new ObjectDecl( toString("_unq_expr_", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
     536                                unqExpr->set_object( new ObjectDecl( toString("_unq", unqExpr->get_id()), Type::StorageClasses(), LinkageSpec::C, nullptr, unqExpr->get_result()->clone(), nullptr ) );
    537537                                unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    538538                        }
     
    764764                                                }
    765765                                        } else {
    766                                                 stmtsToAddAfter.push_back( ctor );
     766                                                ImplicitCtorDtorStmt * implicit = safe_dynamic_cast< ImplicitCtorDtorStmt * > ( ctor );
     767                                                ExprStmt * ctorStmt = dynamic_cast< ExprStmt * >( implicit->get_callStmt() );
     768                                                ApplicationExpr * ctorCall = nullptr;
     769                                                if ( ctorStmt && (ctorCall = isIntrinsicCallExpr( ctorStmt->get_expr() )) && ctorCall->get_args().size() == 2 ) {
     770                                                        // clean up intrinsic copy constructor calls by making them into SingleInits
     771                                                        objDecl->set_init( new SingleInit( ctorCall->get_args().back() ) );
     772                                                        ctorCall->get_args().pop_back();
     773                                                } else {
     774                                                        stmtsToAddAfter.push_back( ctor );
     775                                                        objDecl->set_init( NULL );
     776                                                        ctorInit->set_ctor( NULL );
     777                                                }
    767778                                        } // if
    768                                         objDecl->set_init( NULL );
    769                                         ctorInit->set_ctor( NULL );
    770779                                } else if ( Initializer * init = ctorInit->get_init() ) {
    771780                                        objDecl->set_init( init );
  • src/Parser/ExpressionNode.cc

    r829c907 r87d13cd  
    163163ConstantExpr *build_constantStr( const std::string & str ) {
    164164        // string should probably be a primitive type
    165         ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
     165        ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
    166166                                new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
    167167                                                                                        toString( str.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
  • src/Parser/lex.ll

    r829c907 r87d13cd  
    202202__const__               { KEYWORD_RETURN(CONST); }                              // GCC
    203203continue                { KEYWORD_RETURN(CONTINUE); }
    204 _Coroutine              { KEYWORD_RETURN(COROUTINE); }                  // CFA
     204coroutine               { KEYWORD_RETURN(COROUTINE); }                  // CFA
    205205default                 { KEYWORD_RETURN(DEFAULT); }
    206206disable                 { KEYWORD_RETURN(DISABLE); }                    // CFA
  • src/SynTree/Type.h

    r829c907 r87d13cd  
    117117                bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); }
    118118                bool operator<=( Qualifiers other ) const {
    119                         return is_const <= other.is_const && is_volatile <= other.is_volatile &&
    120                                 is_mutex >= other.is_mutex && is_atomic == other.is_atomic;
     119                        return is_const    <= other.is_const        //Any non-const converts to const without cost
     120                                        && is_volatile <= other.is_volatile     //Any non-volatile converts to volatile without cost
     121                                        && is_mutex    >= other.is_mutex        //Any mutex converts to non-mutex without cost
     122                                        && is_atomic   == other.is_atomic;      //No conversion from atomic to non atomic is free
    121123                }
    122124                bool operator<( Qualifiers other ) const { return *this != other && *this <= other; }
     
    155157        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
    156158
     159        /// return type without outer pointers and arrays
    157160        Type *stripDeclarator();
    158161
  • src/Tuples/TupleExpansion.cc

    r829c907 r87d13cd  
    194194                        }
    195195                        BasicType * boolType = new BasicType( Type::Qualifiers(), BasicType::Bool );
    196                         ObjectDecl * finished = new ObjectDecl( toString( "_unq_expr_finished_", id ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ), new SingleInit( new ConstantExpr( Constant( boolType->clone(), "0" ) ), noDesignators ) );
     196                        ObjectDecl * finished = new ObjectDecl( toString( "_unq", id, "_finished_" ), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::Bool ), new SingleInit( new ConstantExpr( Constant( boolType->clone(), "0" ) ), noDesignators ) );
    197197                        addDeclaration( finished );
    198198                        // (finished ? _unq_expr_N : (_unq_expr_N = <unqExpr->get_expr()>, finished = 1, _unq_expr_N))
     
    225225                if ( ! typeMap.count( tupleSize ) ) {
    226226                        // generate struct type to replace tuple type based on the number of components in the tuple
    227                         StructDecl * decl = new StructDecl( toString( "_tuple_type_", tupleSize ) );
     227                        StructDecl * decl = new StructDecl( toString( "_tuple", tupleSize, "_" ) );
    228228                        decl->set_body( true );
    229229                        for ( size_t i = 0; i < tupleSize; ++i ) {
  • src/benchmark/CorCtxSwitch.c

    r829c907 r87d13cd  
    2424
    2525struct GreatSuspender {
    26         coroutine_desc c;
     26        coroutine_desc __cor;
    2727};
    2828
  • src/benchmark/bench.c

    r829c907 r87d13cd  
    8686//=======================================
    8787
    88 struct CoroutineDummy { coroutine_desc c; };
     88struct CoroutineDummy { coroutine_desc __cor; };
    8989DECL_COROUTINE(CoroutineDummy);
    9090void main(CoroutineDummy * this) {}
     
    119119struct CoroutineResume {
    120120    int N;
    121     coroutine_desc c;
     121    coroutine_desc __cor;
    122122};
    123123
     
    150150//=======================================
    151151
    152 struct ThreadDummy { thread_desc t; };
     152struct ThreadDummy { thread_desc __thrd; };
    153153DECL_THREAD(ThreadDummy);
    154154void main(ThreadDummy * this) {}
     
    180180    int N;
    181181    long long result;
    182     thread_desc t;
     182    thread_desc __thrd;
    183183};
    184184
  • src/benchmark/csv-data.c

    r829c907 r87d13cd  
    2626
    2727struct GreatSuspender {
    28         coroutine_desc c;
     28        coroutine_desc __cor;
    2929};
    3030
  • src/driver/Makefile.am

    r829c907 r87d13cd  
    3232
    3333install-exec-hook:
     34        @test -z "$(CFA_BINDIR)" || $(MKDIR_P) "$(CFA_BINDIR)"
    3435        @echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa '$(CFA_BINDIR)/$(CFA_NAME)'"; \
    3536        $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa $(CFA_BINDIR)/$(CFA_NAME) || exit $$?
  • src/driver/Makefile.in

    r829c907 r87d13cd  
    530530
    531531install-exec-hook:
     532        @test -z "$(CFA_BINDIR)" || $(MKDIR_P) "$(CFA_BINDIR)"
    532533        @echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa '$(CFA_BINDIR)/$(CFA_NAME)'"; \
    533534        $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) cfa $(CFA_BINDIR)/$(CFA_NAME) || exit $$?
  • src/examples/multicore.c

    r829c907 r87d13cd  
    22#include <thread>
    33
    4 struct MyThread { thread_desc t; };
     4struct MyThread { thread_desc __thrd; };
    55
    66DECL_THREAD(MyThread);
  • src/libcfa/concurrency/coroutine

    r829c907 r87d13cd  
    3030};
    3131
    32 #define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X* this) { return &this->c; } void main(X* this)
     32#define DECL_COROUTINE(X) static inline coroutine_desc* get_coroutine(X* this) { return &this->__cor; } void main(X* this)
    3333
    3434//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/invoke.c

    r829c907 r87d13cd  
    2929
    3030extern void __suspend_internal(void);
    31 extern void __thread_signal_termination(struct thread_desc*);
     31extern void __leave_monitor_desc( struct monitor_desc * this );
    3232
    3333void CtxInvokeCoroutine(
     
    5656
    5757void CtxInvokeThread(
     58      void (*dtor)(void *),
    5859      void (*main)(void *),
    5960      struct thread_desc *(*get_thread)(void *),
     
    6364
    6465      struct thread_desc* thrd = get_thread( this );
    65       struct coroutine_desc* cor = &thrd->c;
     66      struct coroutine_desc* cor = &thrd->cor;
     67      struct monitor_desc* mon = &thrd->mon;
    6668      cor->state = Active;
    6769
     
    6971      main( this );
    7072
    71       __thread_signal_termination(thrd);
     73      __leave_monitor_desc( mon );
    7274
    7375      //Final suspend, should never return
     
    9193        struct FakeStack {
    9294            void *fixedRegisters[3];                    // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
    93             uint32_t mxcr;                              // SSE Status and Control bits (control bits are preserved across function calls)
    94             uint16_t fcw;                               // X97 FPU control word (preserved across function calls)
    95             void *rturn;                                // where to go on return from uSwitch
     95            uint32_t mxcr;                        // SSE Status and Control bits (control bits are preserved across function calls)
     96          uint16_t fcw;                         // X97 FPU control word (preserved across function calls)
     97            void *rturn;                          // where to go on return from uSwitch
    9698            void *dummyReturn;                          // fake return compiler would have pushed on call to uInvoke
    9799            void *argument[3];                          // for 16-byte ABI, 16-byte alignment starts here
     
    105107        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this;     // argument to invoke
    106108        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
     109      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
     110      ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    107111
    108112#elif defined( __x86_64__ )
    109113
    110114      struct FakeStack {
    111             void *fixedRegisters[5];                    // fixed registers rbx, r12, r13, r14, r15
    112             uint32_t mxcr;                              // SSE Status and Control bits (control bits are preserved across function calls)
    113             uint16_t fcw;                               // X97 FPU control word (preserved across function calls)
    114             void *rturn;                                // where to go on return from uSwitch
    115             void *dummyReturn;                          // NULL return address to provide proper alignment
     115            void *fixedRegisters[5];            // fixed registers rbx, r12, r13, r14, r15
     116            uint32_t mxcr;                      // SSE Status and Control bits (control bits are preserved across function calls)
     117            uint16_t fcw;                       // X97 FPU control word (preserved across function calls)
     118            void *rturn;                        // where to go on return from uSwitch
     119            void *dummyReturn;                  // NULL return address to provide proper alignment
    116120      };
    117121
  • src/libcfa/concurrency/invoke.h

    r829c907 r87d13cd  
    2828      #define unlikely(x)    __builtin_expect(!!(x), 0)
    2929      #define thread_local _Thread_local
    30       #define SCHEDULER_CAPACITY 10
    3130
    3231      struct spinlock {
     
    3938      };
    4039
    41       struct signal_once {
    42             volatile bool condition;
    43             struct spinlock lock;
    44             struct simple_thread_list blocked;
    45       };
    46 
    4740      #ifdef __CFORALL__
    4841      extern "Cforall" {
     
    5346            void ?{}(spinlock * this);
    5447            void ^?{}(spinlock * this);
    55 
    56             void ?{}(signal_once * this);
    57             void ^?{}(signal_once * this);
    5848      }
    5949      #endif
    6050
    6151      struct coStack_t {
    62             unsigned int size;                // size of stack
    63             void *storage;                            // pointer to stack
    64             void *limit;                              // stack grows towards stack limit
    65             void *base;                               // base of stack
    66             void *context;                            // address of cfa_context_t
    67             void *top;                                // address of top of storage
    68             bool userStack;     
     52            unsigned int size;                  // size of stack
     53            void *storage;                      // pointer to stack
     54            void *limit;                        // stack grows towards stack limit
     55            void *base;                         // base of stack
     56            void *context;                      // address of cfa_context_t
     57            void *top;                          // address of top of storage
     58            bool userStack;                     // whether or not the user allocated the stack
    6959      };
    7060
     
    7262
    7363      struct coroutine_desc {
    74             struct coStack_t stack;
    75             const char *name;                         // textual name for coroutine/task, initialized by uC++ generated code
    76             int errno_;                               // copy of global UNIX variable errno
    77             enum coroutine_state state;       // current execution status for coroutine
    78             struct coroutine_desc *starter;           // first coroutine to resume this one
    79             struct coroutine_desc *last;                      // last coroutine to resume this one
     64            struct coStack_t stack;             // stack information of the coroutine
     65            const char *name;                   // textual name for coroutine/task, initialized by uC++ generated code
     66            int errno_;                         // copy of global UNIX variable errno
     67            enum coroutine_state state;         // current execution status for coroutine
     68            struct coroutine_desc *starter;     // first coroutine to resume this one
     69            struct coroutine_desc *last;              // last coroutine to resume this one
     70      };
     71
     72      struct monitor_desc {
     73            struct spinlock lock;
     74            struct thread_desc * owner;
     75            struct simple_thread_list entry_queue;
     76            unsigned int recursion;
    8077      };
    8178
    8279      struct thread_desc {
    83             struct coroutine_desc c;                 // coroutine body used to store context
    84             struct signal_once terminated;      // indicate if execuation state is not halted
    85             struct thread_desc * next;               // instrusive link field for threads
     80            struct coroutine_desc cor;          // coroutine body used to store context
     81            struct monitor_desc mon;            // monitor body used for mutual exclusion
     82            struct thread_desc * next;          // instrusive link field for threads
    8683      };
    8784
  • src/libcfa/concurrency/kernel

    r829c907 r87d13cd  
    3030void lock( spinlock * );
    3131void unlock( spinlock * );
     32
     33struct signal_once {
     34        volatile bool condition;
     35        struct spinlock lock;
     36        struct simple_thread_list blocked;
     37};
     38
     39void ?{}(signal_once * this);
     40void ^?{}(signal_once * this);
    3241
    3342void wait( signal_once * );
  • src/libcfa/concurrency/kernel.c

    r829c907 r87d13cd  
    107107
    108108void ?{}( thread_desc * this, current_stack_info_t * info) {
    109         (&this->c){ info };
     109        (&this->cor){ info };
    110110}
    111111
     
    113113// Processor coroutine
    114114void ?{}(processorCtx_t * this, processor * proc) {
    115         (&this->c){};
     115        (&this->__cor){};
    116116        this->proc = proc;
    117117        proc->runner = this;
     
    119119
    120120void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) {
    121         (&this->c){ info };
     121        (&this->__cor){ info };
    122122        this->proc = proc;
    123123        proc->runner = this;
     
    255255        processorCtx_t proc_cor_storage = { proc, &info };
    256256
    257         LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.c.stack.base);
     257        LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base);
    258258
    259259        //Set global state
    260         proc->current_coroutine = &proc->runner->c;
     260        proc->current_coroutine = &proc->runner->__cor;
    261261        proc->current_thread = NULL;
    262262
     
    268268        // back to here. Instead directly call the main since we already are on the
    269269        // appropriate stack.
    270         proc_cor_storage.c.state = Active;
     270        proc_cor_storage.__cor.state = Active;
    271271      main( &proc_cor_storage );
    272       proc_cor_storage.c.state = Halted;
     272      proc_cor_storage.__cor.state = Halted;
    273273
    274274        // Main routine of the core returned, the core is now fully terminated
     
    359359        this_processor = systemProcessor;
    360360        this_processor->current_thread = mainThread;
    361         this_processor->current_coroutine = &mainThread->c;
     361        this_processor->current_coroutine = &mainThread->cor;
    362362
    363363        // SKULLDUGGERY: Force a context switch to the system processor to set the main thread's context to the current UNIX
  • src/libcfa/concurrency/kernel_private.h

    r829c907 r87d13cd  
    3535struct processorCtx_t {
    3636        processor * proc;
    37         coroutine_desc c;
     37        coroutine_desc __cor;
    3838};
    3939
  • src/libcfa/concurrency/monitor

    r829c907 r87d13cd  
    2222#include "stdlib"
    2323
    24 struct monitor_desc {
    25         spinlock lock;
    26         thread_desc * owner;
    27         simple_thread_list entry_queue;
    28         unsigned int recursion;
    29 };
    30 
    3124static inline void ?{}(monitor_desc * this) {
    3225        this->owner = 0;
    3326        this->recursion = 0;
    3427}
    35 
    36 //Basic entering routine
    37 void enter(monitor_desc *);
    38 void leave(monitor_desc *);
    3928
    4029//Array entering routine
     
    4938static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
    5039        return ((intptr_t)lhs) < ((intptr_t)rhs);
    51 }
    52 
    53 static inline void ?{}( monitor_guard_t * this, monitor_desc ** m ) {
    54         this->m = m;
    55         this->count = 1;
    56         enter( *this->m );
    5740}
    5841
  • src/libcfa/concurrency/monitor.c

    r829c907 r87d13cd  
    1919#include "kernel_private.h"
    2020
    21 void enter(monitor_desc * this) {
    22         lock( &this->lock );
    23         thread_desc * thrd = this_thread();
     21extern "C" {
     22        void __enter_monitor_desc(monitor_desc * this) {
     23                lock( &this->lock );
     24                thread_desc * thrd = this_thread();
    2425
    25         if( !this->owner ) {
    26                 //No one has the monitor, just take it
    27                 this->owner = thrd;
    28                 this->recursion = 1;
    29         }
    30         else if( this->owner == thrd) {
    31                 //We already have the monitor, just not how many times we took it
    32                 assert( this->recursion > 0 );
    33                 this->recursion += 1;
    34         }
    35         else {
    36                 //Some one else has the monitor, wait in line for it
    37                 append( &this->entry_queue, thrd );
    38                 ScheduleInternal( &this->lock );
     26                if( !this->owner ) {
     27                        //No one has the monitor, just take it
     28                        this->owner = thrd;
     29                        this->recursion = 1;
     30                }
     31                else if( this->owner == thrd) {
     32                        //We already have the monitor, just not how many times we took it
     33                        assert( this->recursion > 0 );
     34                        this->recursion += 1;
     35                }
     36                else {
     37                        //Some one else has the monitor, wait in line for it
     38                        append( &this->entry_queue, thrd );
     39                        ScheduleInternal( &this->lock );
    3940
    40                 //ScheduleInternal will unlock spinlock, no need to unlock ourselves
    41                 return;
     41                        //ScheduleInternal will unlock spinlock, no need to unlock ourselves
     42                        return;
     43                }
     44
     45                unlock( &this->lock );
    4246        }
    4347
    44         unlock( &this->lock );
    45 }
     48        void __leave_monitor_desc(monitor_desc * this) {
     49                lock( &this->lock );
    4650
    47 void leave(monitor_desc * this) {
    48         lock( &this->lock );
     51                thread_desc * thrd = this_thread();
     52                assert( thrd == this->owner );
    4953
    50         thread_desc * thrd = this_thread();
    51         assert( thrd == this->owner );
     54                //Leaving a recursion level, decrement the counter
     55                this->recursion -= 1;
    5256
    53         //Leaving a recursion level, decrement the counter
    54         this->recursion -= 1;
     57                //If we left the last level of recursion it means we are changing who owns the monitor
     58                thread_desc * new_owner = 0;
     59                if( this->recursion == 0) {
     60                        //Get the next thread in the list
     61                        new_owner = this->owner = pop_head( &this->entry_queue );
    5562
    56         //If we left the last level of recursion it means we are changing who owns the monitor
    57         thread_desc * new_owner = 0;
    58         if( this->recursion == 0) {
    59                 //Get the next thread in the list
    60                 new_owner = this->owner = pop_head( &this->entry_queue );
     63                        //We are passing the monitor to someone else, which means recursion level is not 0
     64                        this->recursion = new_owner ? 1 : 0;
     65                }       
    6166
    62                 //We are passing the monitor to someone else, which means recursion level is not 0
    63                 this->recursion = new_owner ? 1 : 0;
    64         }       
     67                unlock( &this->lock );
    6568
    66         unlock( &this->lock );
    67 
    68         //If we have a new owner, we need to wake-up the thread
    69         if( new_owner ) {
    70                 ScheduleThread( new_owner );
     69                //If we have a new owner, we need to wake-up the thread
     70                if( new_owner ) {
     71                        ScheduleThread( new_owner );
     72                }
    7173        }
    7274}
     
    7476void enter(monitor_desc ** monitors, int count) {
    7577        for(int i = 0; i < count; i++) {
    76                 // printf("%d\n", i);
    77                 enter( monitors[i] );
     78                __enter_monitor_desc( monitors[i] );
    7879        }
    7980}
     
    8182void leave(monitor_desc ** monitors, int count) {
    8283        for(int i = count - 1; i >= 0; i--) {
    83                 // printf("%d\n", i);
    84                 leave( monitors[i] );
     84                __leave_monitor_desc( monitors[i] );
    8585        }
    8686}
  • src/libcfa/concurrency/thread

    r829c907 r87d13cd  
    2222
    2323#include "coroutine"
     24#include "monitor"
    2425
    2526//-----------------------------------------------------------------------------
     
    2829// Anything that is resumed is a coroutine.
    2930trait is_thread(dtype T) {
     31      void ^?{}(T* mutex this);
    3032      void main(T* this);
    3133      thread_desc* get_thread(T* this);
    3234};
    3335
    34 #define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->t; } void main(X* this)
     36#define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->__thrd; } void main(X* this)
    3537
    3638forall( dtype T | is_thread(T) )
    3739static inline coroutine_desc* get_coroutine(T* this) {
    38         return &get_thread(this)->c;
     40        return &get_thread(this)->cor;
    3941}
    4042
    41 static inline coroutine_desc* get_coroutine(thread_desc* this) {
    42         return &this->c;
     43forall( dtype T | is_thread(T) )
     44static inline monitor_desc* get_monitor(T * this) {
     45        return &get_thread(this)->mon;
     46}
     47
     48static inline coroutine_desc* get_coroutine(thread_desc * this) {
     49        return &this->cor;
     50}
     51
     52static inline monitor_desc* get_monitor(thread_desc * this) {
     53        return &this->mon;
    4354}
    4455
     
    6475void ?{}( scoped(T)* this, P params );
    6576
    66 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
     77forall( dtype T | sized(T) | is_thread(T) )
    6778void ^?{}( scoped(T)* this );
    6879
  • src/libcfa/concurrency/thread.c

    r829c907 r87d13cd  
    3535void start( T* this );
    3636
    37 forall( dtype T | is_thread(T) )
    38 void stop( T* this );
    39 
    4037//-----------------------------------------------------------------------------
    4138// Thread ctors and dtors
    4239
    4340void ?{}(thread_desc* this) {
    44         (&this->c){};
    45         this->c.name = "Anonymous Coroutine";
    46         (&this->terminated){};
     41        (&this->cor){};
     42        this->cor.name = "Anonymous Coroutine";
     43        this->mon.owner = this;
     44        this->mon.recursion = 1;
    4745        this->next = NULL;
    4846}
    4947
    5048void ^?{}(thread_desc* this) {
    51         ^(&this->c){};
     49        ^(&this->cor){};
    5250}
    5351
     
    6462}
    6563
    66 forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
     64forall( dtype T | sized(T) | is_thread(T) )
    6765void ^?{}( scoped(T)* this ) {
    68         stop(&this->handle);
    6966        ^(&this->handle){};
    7067}
     
    8683
    8784        ScheduleThread(thrd_h);
    88 }
    89 
    90 forall( dtype T | is_thread(T) )
    91 void stop( T* this ) {
    92         wait( & get_thread(this)->terminated );
    9385}
    9486
     
    116108}
    117109
    118 // C Helper to signal the termination of a thread_desc
    119 // Used in invoke.c
    120 extern "C" {
    121         void __thread_signal_termination( thread_desc * this ) {
    122                 this->c.state = Halted;
    123                 LIB_DEBUG_PRINTF("Thread end : %p\n", this);
    124                 signal( &this->terminated );   
    125         }
    126 }
    127 
    128110// Local Variables: //
    129111// mode: c //
  • src/libcfa/iostream.c

    r829c907 r87d13cd  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 21 20:58:48 2017
    13 // Update Count     : 347
     12// Last Modified On : Tue Mar 21 22:05:57 2017
     13// Update Count     : 348
    1414//
    1515
  • src/main.cc

    r829c907 r87d13cd  
    241241                OPTPRINT( "fixNames" )
    242242                CodeGen::fixNames( translationUnit );
    243                 OPTPRINT( "tweakInit" )
     243                OPTPRINT( "genInit" )
    244244                InitTweak::genInit( translationUnit );
    245245                OPTPRINT( "expandMemberTuples" );
  • src/tests/avltree/avl.h

    r829c907 r87d13cd  
    6161void ?{}(tree(K, V) *t, K key, V value);
    6262
    63 forall(otype K | Comparable(K), otype V)
     63forall(otype K, otype V)
    6464void ^?{}(tree(K, V) * t);
    6565
  • src/tests/avltree/avl1.c

    r829c907 r87d13cd  
    1212}
    1313
    14 forall(otype K | Comparable(K), otype V)
     14forall(otype K, otype V)
    1515void ^?{}(tree(K, V) * t){
    1616  delete(t->left);
  • src/tests/avltree/avl_test.c

    r829c907 r87d13cd  
    2525
    2626  // int -> char *
    27   tree(int, char *) * smap = create(-1, "baz");
     27  tree(int, const char *) * smap = create(-1, "baz");
    2828  insert(&smap, 12, "bar");
    2929  insert(&smap, 2, "foo");
     
    3535  delete(smap);
    3636
    37   // char* -> char*
    38   struct c_str { char *str; };  // wraps a C string
    39   int ?<?(c_str a, c_str b) {
    40     return strcmp(a.str,b.str) < 0;
     37  // const char* -> const char*
     38  int ?<?(const char * a, const char * b) {
     39    return strcmp(a, b) < 0;
    4140  }
    42   tree(c_str, char *) * ssmap = create((c_str){"queso"}, "cheese");
    43   insert(&ssmap, (c_str){"foo"}, "bar");
    44   insert(&ssmap, (c_str){"hello"}, "world");
     41
     42  tree(const char *, const char *) * ssmap = create("queso", "cheese");
     43  insert(&ssmap, "foo", "bar");
     44  insert(&ssmap, "hello", "world");
    4545  assert( height(ssmap) == 2 );
    4646
    47   printf("%s %s %s\n", *find(ssmap, (c_str){"hello"}), *find(ssmap, (c_str){"foo"}), *find(ssmap, (c_str){"queso"}));
     47  printf("%s %s %s\n", *find(ssmap, "hello"), *find(ssmap, "foo"), *find(ssmap, "queso"));
    4848
    49   remove(&ssmap, (c_str){"foo"});
     49  remove(&ssmap, "foo");
    5050  delete(ssmap);
    5151}
  • src/tests/completeTypeError.c

    r829c907 r87d13cd  
    6262
    6363forall(dtype T | sized(T))
    64 void qux(T * z) {
     64void quux(T * z) {
    6565        // okay
    6666        bar(z);
  • src/tests/coroutine.c

    r829c907 r87d13cd  
    22#include <coroutine>
    33
    4 struct Fibonacci {
     4coroutine Fibonacci {
    55      int fn; // used for communication
    6       coroutine_desc c;
    76};
    87
     
    1110}
    1211
    13 coroutine_desc* get_coroutine(Fibonacci* this) {
    14       return &this->c;
    15 }
    16 
    1712void main(Fibonacci* this) {
    18 #ifdef MORE_DEBUG
    19       sout | "Starting main of coroutine " | this | endl;
    20       sout | "Started from " | this->c.last | endl;
    21 #endif
    2213      int fn1, fn2;             // retained between resumes
    2314      this->fn = 0;
     
    4536int main() {
    4637      Fibonacci f1, f2;
    47 #ifdef MORE_DEBUG     
    48       Fibonacci *pf1 = &f1, *pf2 = &f2;
    49       coroutine_desc *cf1 = &f1.c, *cf2 = &f2.c;
    50       covptr_t  *vf1 = vtable(pf1), *vf2 = vtable(pf2);
    51       coroutine_desc *cv1 = get_coroutine(vf1), *cv2 = get_coroutine(vf2);
    52       Fibonacci *ov1 = (Fibonacci *)get_object(vf1), *ov2 = (Fibonacci *)get_object(vf2);
    53 
    54       sout | "User coroutines : " | pf1 | ' ' | pf2 | endl;
    55       sout | "Coroutine data  : " | cf1 | ' ' | cf2 | endl;
    56       sout | "Vptr address    : " | vf1 | ' ' | vf2 | endl;
    57       sout | "Vptr obj data   : " | ov1 | ' ' | ov2 | endl;
    58       sout | "Vptr cor data   : " | cv1 | ' ' | cv2 | endl;
    59 #endif
    6038      for ( int i = 1; i <= 10; i += 1 ) {
    6139            sout | next(&f1) | ' ' | next(&f2) | endl;
  • src/tests/dtor-early-exit.c

    r829c907 r87d13cd  
    2828// don't want these called
    2929void ?{}(A * a) { assert( false ); }
    30 void ?{}(A * a, char * name) { a->name = name; sout | "construct " | name | endl; a->x = (int*)malloc(); }
    31 void ?{}(A * a, char * name, int * ptr) { assert( false ); }
     30void ?{}(A * a, const char * name) { a->name = name; sout | "construct " | name | endl; a->x = (int*)malloc(); }
     31void ?{}(A * a, const char * name, int * ptr) { assert( false ); }
    3232
    3333A ?=?(A * a, A a) {  sout | "assign " | a->name | " " | a.name; return a; }
  • src/tests/monitor.c

    r829c907 r87d13cd  
    1313}
    1414
     15monitor_desc * get_monitor( global_t * this ) {
     16        return &this->m;
     17}
     18
    1519static global_t global;
    1620
    17 void increment( /*mutex*/ global_t * this ) {
    18         monitor_desc * mon = &this->m;
    19         monitor_guard_t g1 = { &mon };
    20         {
    21                 monitor_guard_t g2 = { &mon };
    22                 {
    23                         monitor_guard_t g3 = { &mon };
    24                         this->value += 1;
    25                 }
    26         }
     21void increment3( global_t * mutex this ) {
     22        this->value += 1;
    2723}
    2824
    29 struct MyThread { thread_desc t; };
     25void increment2( global_t * mutex this ) {
     26        increment3( this );
     27}
     28
     29void increment( global_t * mutex this ) {
     30        increment2( this );
     31}
     32
     33struct MyThread { thread_desc __thrd; };
    3034
    3135DECL_THREAD(MyThread);
    3236
    3337void ?{}( MyThread * this ) {}
     38void ^?{}( MyThread * mutex this ) {}
    3439
    3540void main( MyThread* this ) {
    36         for(int i = 0; i < 1000000; i++) {
     41        for(int i = 0; i < 1_000_000; i++) {
    3742                increment( &global );
    3843        }
  • src/tests/multi-monitor.c

    r829c907 r87d13cd  
    66static int global12, global23, global13;
    77
    8 static monitor_desc m1, m2, m3;
     8struct monitor_t {
     9        monitor_desc m;
     10};
    911
    10 void increment( /*mutex*/ monitor_desc * p1, /*mutex*/ monitor_desc * p2, int * value ) {
    11         monitor_desc * mons[] = { p1, p2 };
    12         monitor_guard_t g = { mons, 2 };
     12monitor_desc * get_monitor( monitor_t * this ) {
     13        return &this->m;
     14}
     15
     16static monitor_t m1, m2, m3;
     17
     18void increment( monitor_t * mutex p1, monitor_t * mutex p2, int * value ) {
    1319        *value += 1;
    1420}
    1521
    1622struct MyThread {
    17         thread_desc t;
     23        thread_desc __thrd;
    1824        int target;
    1925};
     
    2430        this->target = target;
    2531}
     32
     33void ^?{}( MyThread * mutex this ) {}
    2634
    2735void main( MyThread* this ) {
  • src/tests/thread.c

    r829c907 r87d13cd  
    44#include <thread>
    55
    6 struct First { thread_desc t; signal_once* lock; };
    7 struct Second { thread_desc t; signal_once* lock; };
     6struct First { thread_desc __thrd; signal_once* lock; };
     7struct Second { thread_desc __thrd; signal_once* lock; };
    88
    99DECL_THREAD(First);
     
    1212void ?{}( First * this, signal_once* lock ) { this->lock = lock; }
    1313void ?{}( Second * this, signal_once* lock ) { this->lock = lock; }
     14
     15void ^?{}( First  * mutex this ) {}
     16void ^?{}( Second * mutex this ) {}
    1417
    1518void main(First* this) {
Note: See TracChangeset for help on using the changeset viewer.