Changes in / [31ce3d6:6e8f1df]


Ignore:
Files:
20 edited

Legend:

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

    r31ce3d6 r6e8f1df  
    88_Phase 2_ : Minimum Viable Product
    99done - Monitor type and enter/leave mutex member routines
    10 done - Multi monitors calls,
    11 done - Monitors as a language feature (not calling enter/leave by hand)
     10Monitors as a language feature (not calling enter/leave by hand)
    1211Internal scheduling
    1312
    1413_Phase 3_ : Kernel features
    15 Preemption
    1614Detach thread
    1715Cluster migration
     16Preemption
    1817
    1918_Phase 4_ : Monitor features
     19Multi monitors calls,
    2020External scheduling
    2121
  • src/Concurrency/Keywords.cc

    r31ce3d6 r6e8f1df  
    1717#include "Concurrency/Keywords.h"
    1818
    19 #include "SymTab/AddVisit.h"
    2019#include "SynTree/Declaration.h"
    2120#include "SynTree/Expression.h"
     
    3029        namespace {
    3130                const std::list<Label> noLabels;
    32                 const std::list< Attribute * > noAttributes;
    3331                Type::StorageClasses noStorage;
    3432                Type::Qualifiers noQualifiers;
     
    6563        //                                           void main( MyCoroutine * this );
    6664        //
    67         class CoroutineKeyword final : public Visitor {
    68             template< typename Visitor >
    69             friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
    70           public:
    71 
    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;
     65        class CoroutineKeyword final : public Mutator {
     66          public:
     67
     68                static void implement( std::list< Declaration * > & translationUnit ) {}
    8769        };
    8870
     
    11597
    11698                using Visitor::visit;
    117                 virtual void visit( FunctionDecl * decl ) override final;
    118                 virtual void visit(   StructDecl * decl ) override final;
     99                virtual void visit( FunctionDecl *functionDecl ) override final;
     100                virtual void visit(   StructDecl *functionDecl ) override final;
    119101
    120102                std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
     
    129111          private:
    130112                StructDecl* monitor_decl = nullptr;
    131                 StructDecl* guard_decl = nullptr;
    132113        };
    133114
     
    143124
    144125        //=============================================================================================
    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 ( false ) {
    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_front( 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 
    204                 CompoundStmt * statement = new CompoundStmt( noLabels );
    205                 statement->push_back(
    206                         new ReturnStmt(
    207                                 noLabels,
    208                                 new UntypedMemberExpr(
    209                                         new NameExpr( "__cor" ),
    210                                         new NameExpr( "this" )
    211                                 )
    212                         )
    213                 );
    214 
    215                 declsToAddAfter.push_back(
    216                         new FunctionDecl(
    217                                 "get_coroutine",
    218                                 Type::Static,
    219                                 LinkageSpec::Cforall,
    220                                 type,
    221                                 statement,
    222                                 noAttributes,
    223                                 Type::Inline
    224                         )
    225                 );
    226         }
    227        
    228 
    229         //=============================================================================================
    230126        // Mutex keyword implementation
    231127        //=============================================================================================
     
    241137                if( ! body ) return;
    242138
    243                 if( !monitor_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    244                 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl );
    245 
     139                assert(monitor_decl);
    246140                addStatments( body, mutexArgs );
    247141        }
     
    252146                        monitor_decl = decl;
    253147                }
    254                 else if( decl->get_name() == "monitor_guard_t" ) {
    255                         assert( !guard_decl );
    256                         guard_decl = decl;
    257                 }
    258148        }
    259149
     
    289179
    290180        void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {
     181
    291182                ObjectDecl * monitors = new ObjectDecl(
    292183                        "__monitors",
     
    327218                                new StructInstType(
    328219                                        noQualifiers,
    329                                         guard_decl
     220                                        "monitor_guard_t"
    330221                                ),
    331222                                new ListInit(
     
    333224                                                new SingleInit( new VariableExpr( monitors ) ),
    334225                                                new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) )
    335                                         },
    336                                         noDesignators,
    337                                         true
     226                                        }
    338227                                )
    339228                        ))
    340229                );
    341230
    342                 //monitor_desc * __monitors[] = { get_monitor(a), get_monitor(b) };
     231                //monitor_desc * __monitors[] = { a, b };
    343232                body->push_front( new DeclStmt( noLabels, monitors) );
    344233        }
  • src/benchmark/CorCtxSwitch.c

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

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

    r31ce3d6 r6e8f1df  
    2626
    2727struct GreatSuspender {
    28         coroutine_desc __cor;
     28        coroutine_desc c;
    2929};
    3030
  • src/examples/multicore.c

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

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

    r31ce3d6 r6e8f1df  
    5656
    5757void CtxInvokeThread(
    58       void (*dtor)(void *),
    5958      void (*main)(void *),
    6059      struct thread_desc *(*get_thread)(void *),
     
    6463
    6564      struct thread_desc* thrd = get_thread( this );
    66       struct coroutine_desc* cor = &thrd->cor;
     65      struct coroutine_desc* cor = &thrd->c;
    6766      cor->state = Active;
    6867
     
    9291        struct FakeStack {
    9392            void *fixedRegisters[3];                    // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
    94             uint32_t mxcr;                        // SSE Status and Control bits (control bits are preserved across function calls)
    95           uint16_t fcw;                         // X97 FPU control word (preserved across function calls)
    96             void *rturn;                          // where to go on return from uSwitch
     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
    9796            void *dummyReturn;                          // fake return compiler would have pushed on call to uInvoke
    9897            void *argument[3];                          // for 16-byte ABI, 16-byte alignment starts here
     
    106105        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this;     // argument to invoke
    107106        ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;
    108       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520
    109       ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
    110107
    111108#elif defined( __x86_64__ )
    112109
    113110      struct FakeStack {
    114             void *fixedRegisters[5];            // fixed registers rbx, r12, r13, r14, r15
    115             uint32_t mxcr;                      // SSE Status and Control bits (control bits are preserved across function calls)
    116             uint16_t fcw;                       // X97 FPU control word (preserved across function calls)
    117             void *rturn;                        // where to go on return from uSwitch
    118             void *dummyReturn;                  // NULL return address to provide proper alignment
     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
    119116      };
    120117
  • src/libcfa/concurrency/invoke.h

    r31ce3d6 r6e8f1df  
    2828      #define unlikely(x)    __builtin_expect(!!(x), 0)
    2929      #define thread_local _Thread_local
     30      #define SCHEDULER_CAPACITY 10
    3031
    3132      struct spinlock {
     
    5960
    6061      struct coStack_t {
    61             unsigned int size;                  // size of stack
    62             void *storage;                      // pointer to stack
    63             void *limit;                        // stack grows towards stack limit
    64             void *base;                         // base of stack
    65             void *context;                      // address of cfa_context_t
    66             void *top;                          // address of top of storage
    67             bool userStack;                     // whether or not the user allocated the stack
     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;     
    6869      };
    6970
     
    7172
    7273      struct coroutine_desc {
    73             struct coStack_t stack;             // stack information of the coroutine
    74             const char *name;                   // textual name for coroutine/task, initialized by uC++ generated code
    75             int errno_;                         // copy of global UNIX variable errno
    76             enum coroutine_state state;         // current execution status for coroutine
    77             struct coroutine_desc *starter;     // first coroutine to resume this one
    78             struct coroutine_desc *last;              // last coroutine to resume this one
     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
    7980      };
    8081
    8182      struct thread_desc {
    82             struct coroutine_desc cor;            // coroutine body used to store context
     83            struct coroutine_desc c;                 // coroutine body used to store context
    8384            struct signal_once terminated;      // indicate if execuation state is not halted
    84             struct thread_desc * next;          // instrusive link field for threads
     85            struct thread_desc * next;               // instrusive link field for threads
    8586      };
    8687
  • src/libcfa/concurrency/kernel.c

    r31ce3d6 r6e8f1df  
    107107
    108108void ?{}( thread_desc * this, current_stack_info_t * info) {
    109         (&this->cor){ info };
     109        (&this->c){ info };
    110110}
    111111
     
    113113// Processor coroutine
    114114void ?{}(processorCtx_t * this, processor * proc) {
    115         (&this->__cor){};
     115        (&this->c){};
    116116        this->proc = proc;
    117117        proc->runner = this;
     
    119119
    120120void ?{}(processorCtx_t * this, processor * proc, current_stack_info_t * info) {
    121         (&this->__cor){ info };
     121        (&this->c){ 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.__cor.stack.base);
     257        LIB_DEBUG_PRINTF("Coroutine : created stack %p\n", proc_cor_storage.c.stack.base);
    258258
    259259        //Set global state
    260         proc->current_coroutine = &proc->runner->__cor;
     260        proc->current_coroutine = &proc->runner->c;
    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.__cor.state = Active;
     270        proc_cor_storage.c.state = Active;
    271271      main( &proc_cor_storage );
    272       proc_cor_storage.__cor.state = Halted;
     272      proc_cor_storage.c.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->cor;
     361        this_processor->current_coroutine = &mainThread->c;
    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

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

    r31ce3d6 r6e8f1df  
    3434}
    3535
     36//Basic entering routine
     37void enter(monitor_desc *);
     38void leave(monitor_desc *);
     39
    3640//Array entering routine
    3741void enter(monitor_desc **, int count);
     
    4549static inline int ?<?(monitor_desc* lhs, monitor_desc* rhs) {
    4650        return ((intptr_t)lhs) < ((intptr_t)rhs);
     51}
     52
     53static inline void ?{}( monitor_guard_t * this, monitor_desc ** m ) {
     54        this->m = m;
     55        this->count = 1;
     56        enter( *this->m );
    4757}
    4858
  • src/libcfa/concurrency/monitor.c

    r31ce3d6 r6e8f1df  
    7474void enter(monitor_desc ** monitors, int count) {
    7575        for(int i = 0; i < count; i++) {
     76                // printf("%d\n", i);
    7677                enter( monitors[i] );
    7778        }
     
    8081void leave(monitor_desc ** monitors, int count) {
    8182        for(int i = count - 1; i >= 0; i--) {
     83                // printf("%d\n", i);
    8284                leave( monitors[i] );
    8385        }
  • src/libcfa/concurrency/thread

    r31ce3d6 r6e8f1df  
    2828// Anything that is resumed is a coroutine.
    2929trait is_thread(dtype T) {
    30       void ^?{}(T* this);
    3130      void main(T* this);
    3231      thread_desc* get_thread(T* this);
    3332};
    3433
    35 #define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->__thrd; } void main(X* this)
     34#define DECL_THREAD(X) thread_desc* get_thread(X* this) { return &this->t; } void main(X* this)
    3635
    3736forall( dtype T | is_thread(T) )
    3837static inline coroutine_desc* get_coroutine(T* this) {
    39         return &get_thread(this)->cor;
     38        return &get_thread(this)->c;
    4039}
    4140
    4241static inline coroutine_desc* get_coroutine(thread_desc* this) {
    43         return &this->cor;
     42        return &this->c;
    4443}
    4544
     
    6564void ?{}( scoped(T)* this, P params );
    6665
    67 forall( dtype T | sized(T) | is_thread(T) )
     66forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
    6867void ^?{}( scoped(T)* this );
    6968
  • src/libcfa/concurrency/thread.c

    r31ce3d6 r6e8f1df  
    4242
    4343void ?{}(thread_desc* this) {
    44         (&this->cor){};
    45         this->cor.name = "Anonymous Coroutine";
     44        (&this->c){};
     45        this->c.name = "Anonymous Coroutine";
    4646        (&this->terminated){};
    4747        this->next = NULL;
     
    4949
    5050void ^?{}(thread_desc* this) {
    51         ^(&this->cor){};
     51        ^(&this->c){};
    5252}
    5353
     
    6464}
    6565
    66 forall( dtype T | sized(T) | is_thread(T) )
     66forall( dtype T | sized(T) | is_thread(T) | { void ^?{}(T*); } )
    6767void ^?{}( scoped(T)* this ) {
    6868        stop(&this->handle);
     
    120120extern "C" {
    121121        void __thread_signal_termination( thread_desc * this ) {
    122                 this->cor.state = Halted;
     122                this->c.state = Halted;
    123123                LIB_DEBUG_PRINTF("Thread end : %p\n", this);
    124124                signal( &this->terminated );   
  • src/main.cc

    r31ce3d6 r6e8f1df  
    241241                OPTPRINT( "fixNames" )
    242242                CodeGen::fixNames( translationUnit );
    243                 OPTPRINT( "genInit" )
     243                OPTPRINT( "tweakInit" )
    244244                InitTweak::genInit( translationUnit );
    245245                OPTPRINT( "expandMemberTuples" );
  • src/tests/coroutine.c

    r31ce3d6 r6e8f1df  
    44struct Fibonacci {
    55      int fn; // used for communication
    6       coroutine_desc __cor;
     6      coroutine_desc c;
    77};
    88
     
    1212
    1313coroutine_desc* get_coroutine(Fibonacci* this) {
    14       return &this->__cor;
     14      return &this->c;
    1515}
    1616
     
    1818#ifdef MORE_DEBUG
    1919      sout | "Starting main of coroutine " | this | endl;
    20       sout | "Started from " | this->__cor.last | endl;
     20      sout | "Started from " | this->c.last | endl;
    2121#endif
    2222      int fn1, fn2;             // retained between resumes
  • src/tests/monitor.c

    r31ce3d6 r6e8f1df  
    1313}
    1414
    15 monitor_desc * get_monitor( global_t * this ) {
    16         return &this->m;
     15static global_t global;
     16
     17void 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        }
    1727}
    1828
    19 static global_t global;
    20 
    21 void increment3( global_t * mutex this ) {
    22         this->value += 1;
    23 }
    24 
    25 void increment2( global_t * mutex this ) {
    26         increment3( this );
    27 }
    28 
    29 void increment( global_t * mutex this ) {
    30         increment2( this );
    31 }
    32 
    33 struct MyThread { thread_desc __thrd; };
     29struct MyThread { thread_desc t; };
    3430
    3531DECL_THREAD(MyThread);
  • src/tests/multi-monitor.c

    r31ce3d6 r6e8f1df  
    66static int global12, global23, global13;
    77
    8 struct monitor_t {
    9         monitor_desc m;
    10 };
     8static monitor_desc m1, m2, m3;
    119
    12 monitor_desc * get_monitor( monitor_t * this ) {
    13         return &this->m;
    14 }
    15 
    16 static monitor_t m1, m2, m3;
    17 
    18 void increment( monitor_t * mutex p1, monitor_t * mutex p2, int * value ) {
     10void increment( /*mutex*/ monitor_desc * p1, /*mutex*/ monitor_desc * p2, int * value ) {
     11        monitor_desc * mons[] = { p1, p2 };
     12        monitor_guard_t g = { mons, 2 };
    1913        *value += 1;
    2014}
    2115
    2216struct MyThread {
    23         thread_desc __thrd;
     17        thread_desc t;
    2418        int target;
    2519};
  • src/tests/thread.c

    r31ce3d6 r6e8f1df  
    44#include <thread>
    55
    6 struct First { thread_desc __thrd; signal_once* lock; };
    7 struct Second { thread_desc __thrd; signal_once* lock; };
     6struct First { thread_desc t; signal_once* lock; };
     7struct Second { thread_desc t; signal_once* lock; };
    88
    99DECL_THREAD(First);
Note: See TracChangeset for help on using the changeset viewer.