Changeset 09f357ec


Ignore:
Timestamp:
Feb 4, 2020, 11:29:11 AM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
4f7b418
Parents:
5cdeecd
Message:

Optim : coroutine and thread creation no-longer uses polymorphic call, leading to significant speedup. Breaks Arm support

Files:
10 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/CtxSwitch-x86_64.S

    r5cdeecd r09f357ec  
    8787CtxInvokeStub:
    8888        movq %rbx, %rdi
    89         jmp *%r12
     89        movq %r12, %rsi
     90        jmp *%r13
    9091        .size  CtxInvokeStub, .-CtxInvokeStub
    9192
  • libcfa/src/concurrency/coroutine.cfa

    r5cdeecd r09f357ec  
    187187// is not inline (We can't inline Cforall in C)
    188188extern "C" {
    189         void __suspend_internal(void) {
    190                 suspend();
    191         }
    192 
    193         void __leave_coroutine( coroutine_desc * src ) {
     189        void __leave_coroutine( struct coroutine_desc * src ) {
    194190                coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter;
    195191
     
    207203                CoroutineCtxSwitch( src, starter );
    208204        }
     205
     206        struct coroutine_desc * __finish_coroutine(void) {
     207                struct coroutine_desc * cor = kernelTLS.this_thread->curr_cor;
     208
     209                if(cor->state == Primed) {
     210                        suspend();
     211                }
     212
     213                cor->state = Active;
     214
     215                return cor;
     216        }
    209217}
    210218
  • libcfa/src/concurrency/coroutine.hfa

    r5cdeecd r09f357ec  
    6161// Start coroutine routines
    6262extern "C" {
    63       forall(dtype T | is_coroutine(T))
    64       void CtxInvokeCoroutine(T * this);
     63        void CtxInvokeCoroutine(void (*main)(void *), void * this);
    6564
    66       forall(dtype T | is_coroutine(T))
    67       void CtxStart(T * this, void ( *invoke)(T *));
     65        forall(dtype T)
     66        void CtxStart(void (*main)(T &), struct coroutine_desc * cor, T & this, void (*invoke)(void (*main)(void *), void *));
    6867
    6968        extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
     
    129128
    130129        if( unlikely(dst->context.SP == 0p) ) {
     130                TL_GET( this_thread )->curr_cor = dst;
    131131                __stack_prepare(&dst->stack, 65000);
    132                 CtxStart(&cor, CtxInvokeCoroutine);
     132                CtxStart(main, dst, cor, CtxInvokeCoroutine);
     133                TL_GET( this_thread )->curr_cor = src;
    133134        }
    134135
  • libcfa/src/concurrency/invoke.c

    r5cdeecd r09f357ec  
    2929// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    3030
    31 extern void __suspend_internal(void);
    32 extern void __leave_coroutine( struct coroutine_desc * );
    33 extern void __finish_creation( struct thread_desc * );
    34 extern void __leave_thread_monitor( struct thread_desc * this );
     31extern void __leave_coroutine ( struct coroutine_desc * );
     32extern struct coroutine_desc * __finish_coroutine(void);
     33extern void __leave_thread_monitor();
    3534extern void disable_interrupts() OPTIONAL_THREAD;
    3635extern void enable_interrupts( __cfaabi_dbg_ctx_param );
     
    3837void CtxInvokeCoroutine(
    3938        void (*main)(void *),
    40         struct coroutine_desc *(*get_coroutine)(void *),
    4139        void *this
    4240) {
    43         struct coroutine_desc* cor = get_coroutine( this );
     41        // Finish setting up the coroutine by setting its state
     42        struct coroutine_desc * cor = __finish_coroutine();
    4443
    45         if(cor->state == Primed) {
    46                 __suspend_internal();
    47         }
    48 
    49         cor->state = Active;
    50 
     44        // Call the main of the coroutine
    5145        main( this );
    5246
     
    8377
    8478void CtxInvokeThread(
    85         void (*dtor)(void *),
    8679        void (*main)(void *),
    87         struct thread_desc *(*get_thread)(void *),
    8880        void *this
    8981) {
    90         // Fetch the thread handle from the user defined thread structure
    91         struct thread_desc* thrd = get_thread( this );
    92 
    93         // First suspend, once the thread arrives here,
    94         // the function pointer to main can be invalidated without risk
    95         __finish_creation( thrd );
    96 
    9782        // Officially start the thread by enabling preemption
    9883        enable_interrupts( __cfaabi_dbg_ctx );
     
    10893        // The order of these 4 operations is very important
    10994        //Final suspend, should never return
    110         __leave_thread_monitor( thrd );
     95        __leave_thread_monitor();
    11196        __cabi_abort( "Resumed dead thread" );
    11297}
    11398
    114 
    11599void CtxStart(
    116100        void (*main)(void *),
    117         struct coroutine_desc *(*get_coroutine)(void *),
     101        struct coroutine_desc * cor,
    118102        void *this,
    119103        void (*invoke)(void *)
    120104) {
    121         struct coroutine_desc * cor = get_coroutine( this );
    122105        struct __stack_t * stack = cor->stack.storage;
    123106
     
    138121
    139122        fs->dummyReturn = NULL;
    140         fs->argument[0] = this;     // argument to invoke
     123        fs->argument[0] = main;     // argument to invoke
     124        fs->argument[1] = this;     // argument to invoke
    141125        fs->rturn = invoke;
    142126
     
    156140        fs->dummyReturn = NULL;
    157141        fs->rturn = CtxInvokeStub;
    158         fs->fixedRegisters[0] = this;
    159         fs->fixedRegisters[1] = invoke;
     142        fs->fixedRegisters[0] = main;
     143        fs->fixedRegisters[1] = this;
     144        fs->fixedRegisters[2] = invoke;
    160145
    161146#elif defined( __ARM_ARCH )
    162 
     147#error ARM needs to be upgrade to use to parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it)
    163148        struct FakeStack {
    164149                float fpRegs[16];                       // floating point registers
  • libcfa/src/concurrency/kernel.cfa

    r5cdeecd r09f357ec  
    469469        );
    470470
    471         Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 
     471        Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
    472472
    473473        Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" );
     
    490490        verify( ! kernelTLS.preemption_state.enabled );
    491491
     492        kernelTLS.this_thread->curr_cor = dst;
    492493        __stack_prepare( &dst->stack, 65000 );
    493         CtxStart(&this->runner, CtxInvokeCoroutine);
     494        CtxStart(main, dst, this->runner, CtxInvokeCoroutine);
    494495
    495496        verify( ! kernelTLS.preemption_state.enabled );
     
    505506        CtxSwitch( &src->context, &dst->context );
    506507        // when CtxSwitch returns we are back in the src coroutine
     508
     509        mainThread->curr_cor = &mainThread->self_cor;
    507510
    508511        // set state of new coroutine to active
  • libcfa/src/concurrency/kernel_private.hfa

    r5cdeecd r09f357ec  
    8888// Threads
    8989extern "C" {
    90       forall(dtype T | is_thread(T))
    91       void CtxInvokeThread(T * this);
     90      void CtxInvokeThread(void (*main)(void *), void * this);
    9291}
    9392
  • libcfa/src/concurrency/monitor.cfa

    r5cdeecd r09f357ec  
    243243        // last routine called by a thread.
    244244        // Should never return
    245         void __leave_thread_monitor( thread_desc * thrd ) {
     245        void __leave_thread_monitor() {
     246                thread_desc * thrd = TL_GET( this_thread );
    246247                monitor_desc * this = &thrd->self_mon;
    247248
  • libcfa/src/concurrency/thread.cfa

    r5cdeecd r09f357ec  
    5858void ?{}( scoped(T)& this ) with( this ) {
    5959        handle{};
    60         __thrd_start(handle);
     60        __thrd_start(handle, main);
    6161}
    6262
     
    6464void ?{}( scoped(T)& this, P params ) with( this ) {
    6565        handle{ params };
    66         __thrd_start(handle);
     66        __thrd_start(handle, main);
    6767}
    6868
     
    7575// Starting and stopping threads
    7676forall( dtype T | is_thread(T) )
    77 void __thrd_start( T& this ) {
     77void __thrd_start( T & this, void (*main_p)(T &) ) {
    7878        thread_desc * this_thrd = get_thread(this);
    7979        thread_desc * curr_thrd = TL_GET( this_thread );
    8080
    8181        disable_interrupts();
    82         CtxStart(&this, CtxInvokeThread);
     82        CtxStart(main_p, get_coroutine(this), this, CtxInvokeThread);
     83
    8384        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
    8485        verify( this_thrd->context.SP );
    85         CtxSwitch( &curr_thrd->context, &this_thrd->context );
     86        // CtxSwitch( &curr_thrd->context, &this_thrd->context );
    8687
    8788        ScheduleThread(this_thrd);
    8889        enable_interrupts( __cfaabi_dbg_ctx );
    89 }
    90 
    91 extern "C" {
    92         // KERNEL ONLY
    93         void __finish_creation(thread_desc * this) {
    94                 // set new coroutine that the processor is executing
    95                 // and context switch to it
    96                 verify( kernelTLS.this_thread != this );
    97                 verify( kernelTLS.this_thread->context.SP );
    98                 CtxSwitch( &this->context, &kernelTLS.this_thread->context );
    99         }
    10090}
    10191
  • libcfa/src/concurrency/thread.hfa

    r5cdeecd r09f357ec  
    5454
    5555forall( dtype T | is_thread(T) )
    56 void __thrd_start( T & this );
     56void __thrd_start( T & this, void (*)(T &) );
    5757
    5858//-----------------------------------------------------------------------------
  • src/Concurrency/Keywords.cc

    r5cdeecd r09f357ec  
    716716                                new UntypedExpr(
    717717                                        new NameExpr( "__thrd_start" ),
    718                                         { new VariableExpr( param ) }
     718                                        { new VariableExpr( param ), new NameExpr("main") }
    719719                                )
    720720                        )
Note: See TracChangeset for help on using the changeset viewer.