Ignore:
Timestamp:
Jan 7, 2021, 2:55:57 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
58fe85a
Parents:
bdfc032 (diff), 44e37ef (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' into dkobets-vector

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/invoke.c

    rbdfc032 reef8dfb  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  9 16:37:42 2018
    13 // Update Count     : 5
     12// Last Modified On : Sat Oct 24 14:35:28 2020
     13// Update Count     : 32
    1414//
    1515
     
    2929// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    3030
    31 extern void __leave_coroutine ( struct coroutine_desc * );
    32 extern struct coroutine_desc * __finish_coroutine(void);
    33 extern void __leave_thread_monitor();
     31extern struct $coroutine * __cfactx_cor_finish(void);
     32extern void __cfactx_cor_leave ( struct $coroutine * );
     33extern void __cfactx_thrd_leave();
     34
    3435extern void disable_interrupts() OPTIONAL_THREAD;
    3536extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3637
    37 void CtxInvokeCoroutine(
     38void __cfactx_invoke_coroutine(
    3839        void (*main)(void *),
    3940        void *this
    4041) {
    4142        // Finish setting up the coroutine by setting its state
    42         struct coroutine_desc * cor = __finish_coroutine();
     43        struct $coroutine * cor = __cfactx_cor_finish();
    4344
    4445        // Call the main of the coroutine
     
    4647
    4748        //Final suspend, should never return
    48         __leave_coroutine( cor );
     49        __cfactx_cor_leave( cor );
    4950        __cabi_abort( "Resumed dead coroutine" );
    5051}
    5152
    52 static _Unwind_Reason_Code _CtxCoroutine_UnwindStop(
     53static _Unwind_Reason_Code __cfactx_coroutine_unwindstop(
    5354        __attribute((__unused__)) int version,
    5455        _Unwind_Action actions,
     
    6162                // We finished unwinding the coroutine,
    6263                // leave it
    63                 __leave_coroutine( param );
     64                __cfactx_cor_leave( param );
    6465                __cabi_abort( "Resumed dead coroutine" );
    6566        }
     
    6970}
    7071
    71 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__));
    72 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) {
    73         _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor );
     72void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine * cor) __attribute__ ((__noreturn__));
     73void __cfactx_coroutine_unwind(struct _Unwind_Exception * storage, struct $coroutine * cor) {
     74        _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, __cfactx_coroutine_unwindstop, cor );
    7475        printf("UNWIND ERROR %d after force unwind\n", ret);
    7576        abort();
    7677}
    7778
    78 void CtxInvokeThread(
     79void __cfactx_invoke_thread(
    7980        void (*main)(void *),
    8081        void *this
     
    9394        // The order of these 4 operations is very important
    9495        //Final suspend, should never return
    95         __leave_thread_monitor();
     96        __cfactx_thrd_leave();
    9697        __cabi_abort( "Resumed dead thread" );
    9798}
    9899
    99 void CtxStart(
     100void __cfactx_start(
    100101        void (*main)(void *),
    101         struct coroutine_desc * cor,
     102        struct $coroutine * cor,
    102103        void *this,
    103104        void (*invoke)(void *)
     
    108109
    109110        struct FakeStack {
    110             void *fixedRegisters[3];              // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
    111             void *rturn;                          // where to go on return from uSwitch
    112             void *dummyReturn;                    // fake return compiler would have pushed on call to uInvoke
    113             void *argument[3];                    // for 16-byte ABI, 16-byte alignment starts here
    114             void *padding;                        // padding to force 16-byte alignment, as "base" is 16-byte aligned
     111            void *fixedRegisters[3];                                            // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant)
     112            void *rturn;                                                                        // where to go on return from uSwitch
     113            void *dummyReturn;                                                          // fake return compiler would have pushed on call to uInvoke
     114            void *argument[3];                                                          // for 16-byte ABI, 16-byte alignment starts here
     115            void *padding;                                                                      // padding to force 16-byte alignment, as "base" is 16-byte aligned
    115116        };
    116117
     
    121122
    122123        fs->dummyReturn = NULL;
    123         fs->argument[0] = main;     // argument to invoke
    124         fs->argument[1] = this;     // argument to invoke
     124        fs->argument[0] = main;                                                         // argument to invoke
     125        fs->argument[1] = this;                                                         // argument to invoke
    125126        fs->rturn = invoke;
    126127
     
    128129
    129130        struct FakeStack {
    130                 void *fixedRegisters[5];            // fixed registers rbx, r12, r13, r14, r15
    131                 void *rturn;                        // where to go on return from uSwitch
    132                 void *dummyReturn;                  // NULL return address to provide proper alignment
     131                void *fixedRegisters[5];                                                // fixed registers rbx, r12, r13, r14, r15
     132                void *rturn;                                                                    // where to go on return from uSwitch
     133                void *dummyReturn;                                                              // NULL return address to provide proper alignment
    133134        };
    134135
    135136        cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );
    136         cor->context.FP = NULL;         // terminate stack with NULL fp
     137        cor->context.FP = NULL;                                                         // terminate stack with NULL fp
    137138
    138139        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
    139140
    140141        fs->dummyReturn = NULL;
    141         fs->rturn = CtxInvokeStub;
    142         fs->fixedRegisters[0] = main;
    143         fs->fixedRegisters[1] = this;
     142        fs->rturn = __cfactx_invoke_stub;
     143        fs->fixedRegisters[0] = main;                                           // argument to invoke
     144        fs->fixedRegisters[1] = this;                                           // argument to invoke
    144145        fs->fixedRegisters[2] = invoke;
    145146
    146 #elif defined( __ARM_ARCH )
    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)
     147#elif defined( __ARM_ARCH_32 )
     148#error ARM needs to be upgrade to use two parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it)
     149        // More details about the error:
     150        // To avoid the thunk problem, I changed the invoke routine to pass the main explicitly
     151        // instead of relying on an assertion. This effectively hoists any required thunk one level
     152        // which was enough to get to global scope in most cases.
     153        // This means that __cfactx_invoke_... now takes two parameters and the FakeStack needs
     154        // to be adjusted as a consequence of that.
     155        // I don't know how to do that for ARM, hence the #error
     156
    148157        struct FakeStack {
    149                 float fpRegs[16];                       // floating point registers
    150                 void *intRegs[9];                       // integer/pointer registers
    151                 void *arg[2];                           // placeholder for this pointer
     158                float fpRegs[16];                                                               // floating point registers
     159                void * intRegs[9];                                                              // integer/pointer registers
     160                void * arg[2];                                                                  // placeholder for this pointer
    152161        };
    153162
     
    157166        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
    158167
    159         fs->intRegs[8] = CtxInvokeStub;
     168        fs->intRegs[8] = __cfactx_invoke_stub;
    160169        fs->arg[0] = this;
    161170        fs->arg[1] = invoke;
    162171
     172#elif defined( __ARM_ARCH )
     173        struct FakeStack {
     174                void * intRegs[12];                                                             // x19-x30 integer registers
     175                double fpRegs[8];                                                               // v8-v15 floating point
     176        };
     177
     178        cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );
     179        cor->context.FP = NULL;
     180
     181        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
     182
     183        fs->intRegs[0] = main;                                                          // argument to invoke x19 => x0
     184        fs->intRegs[1] = this;                                                          // argument to invoke x20 => x1
     185        fs->intRegs[2] = invoke;
     186        fs->intRegs[11] = __cfactx_invoke_stub;                         // link register x30 => ret moves to pc
    163187#else
    164188        #error uknown hardware architecture
Note: See TracChangeset for help on using the changeset viewer.