Ignore:
Timestamp:
Mar 17, 2021, 1:56:12 PM (9 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
c407434
Parents:
e0c072c
Message:

C interface now runs worker init routine in dedicated thread.
Also added test for this case.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/clib/cfathread.cfa

    re0c072c ra5e7233  
    2121
    2222#include "cfathread.h"
     23
     24extern void ?{}(processor &, const char[], cluster &, $thread *);
     25extern "C" {
     26      extern void __cfactx_invoke_thread(void (*main)(void *), void * this);
     27}
     28
     29//================================================================================
     30// Thread run y the C Interface
    2331
    2432struct cfathread_object {
     
    6573}
    6674
    67 processor * procs = 0p;
    68 int proc_cnt = 1;
    69 
     75//================================================================================
     76// Special Init Thread responsible for the initialization or processors
     77struct __cfainit {
     78        $thread self;
     79        void (*init)( void * );
     80        void * arg;
     81};
     82void main(__cfainit & this);
     83void ^?{}(__cfainit & mutex this);
     84
     85static inline $thread * get_thread( __cfainit & this ) { return &this.self; }
     86
     87typedef ThreadCancelled(__cfainit) __cfainit_exception;
     88typedef ThreadCancelled_vtable(__cfainit) __cfainit_vtable;
     89
     90void defaultResumptionHandler(ThreadCancelled(__cfainit) & except) {
     91        abort | "The init thread was cancelled";
     92}
     93
     94__cfainit_vtable ___cfainit_vtable_instance;
     95
     96__cfainit_vtable const & get_exception_vtable(__cfainit_exception *) {
     97        return ___cfainit_vtable_instance;
     98}
     99
     100static void ?{}( __cfainit & this, void (*init)( void * ), void * arg ) {
     101        this.init = init;
     102        this.arg = arg;
     103        ((thread&)this){"Processir Init"};
     104
     105        // Don't use __thrd_start! just prep the context manually
     106        $thread * this_thrd = get_thread(this);
     107        void (*main_p)(__cfainit &) = main;
     108
     109        disable_interrupts();
     110        __cfactx_start(main_p, get_coroutine(this), this, __cfactx_invoke_thread);
     111
     112        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
     113        /* paranoid */ verify( this_thrd->context.SP );
     114
     115        this_thrd->state = Ready;
     116        enable_interrupts( __cfaabi_dbg_ctx );
     117}
     118
     119void ^?{}(__cfainit & mutex this) {
     120        ^(this.self){};
     121}
     122
     123void main( __cfainit & this ) {
     124        __attribute__((unused)) void * const thrd_obj = (void*)&this;
     125        __attribute__((unused)) void * const thrd_hdl = (void*)active_thread();
     126        /* paranoid */ verify( thrd_obj == thrd_hdl );
     127
     128        this.init( this.arg );
     129}
     130
     131//================================================================================
     132// Main Api
    70133extern "C" {
    71134        int cfathread_cluster_create(cfathread_cluster_t * cl) __attribute__((nonnull(1))) {
     
    79142
    80143        int cfathread_cluster_add_worker(cfathread_cluster_t cl, pthread_t* tid, void (*init_routine) (void *), void * arg) {
    81                 // processor * proc = new("C-processor", *cl, init_routine, arg);
     144                __cfainit * it = 0p;
     145                if(init_routine) {
     146                        it = alloc();
     147                        (*it){init_routine, arg};
     148                }
    82149                processor * proc = alloc();
    83                 (*proc){ "C-processor", *cl, init_routine, arg };
     150                (*proc){ "C-processor", *cl, get_thread(*it) };
     151
     152                // Wait for the init thread to return before continuing
     153                if(it) {
     154                        ^(*it){};
     155                        free(it);
     156                }
     157
    84158                if(tid) *tid = proc->kernel_thread;
    85159                return 0;
Note: See TracChangeset for help on using the changeset viewer.