Changeset a5e7233


Ignore:
Timestamp:
Mar 17, 2021, 1:56:12 PM (4 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:
c407434e
Parents:
e0c072c
Message:

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

Files:
2 added
5 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;
  • libcfa/src/concurrency/kernel.cfa

    re0c072c ra5e7233  
    149149        #endif
    150150
    151         // if we need to run some special setup, now is the time to do it.
    152         if(this->init.fnc) {
    153                 this->init.fnc(this->init.arg);
    154         }
    155 
    156151        {
    157152                // Setup preemption data
     
    162157                #endif
    163158
     159                // if we need to run some special setup, now is the time to do it.
     160                if(this->init.thrd) {
     161                        this->init.thrd->curr_cluster = this->cltr;
     162                        __run_thread(this, this->init.thrd);
     163                }
    164164
    165165                __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this);
  • libcfa/src/concurrency/kernel.hfa

    re0c072c ra5e7233  
    112112        // it is not a particularly safe scheme as it can make processors less homogeneous
    113113        struct {
    114                 void (*fnc) (void *);
    115                 void * arg;
     114                $thread * thrd;
    116115        } init;
    117116
     
    127126};
    128127
    129 void  ?{}(processor & this, const char name[], struct cluster & cltr, void (*init) (void *), void * arg);
     128void  ?{}(processor & this, const char name[], struct cluster & cltr);
    130129void ^?{}(processor & this);
    131130
    132 static inline void  ?{}(processor & this)                        { this{ "Anonymous Processor", *mainCluster, 0p, 0p}; }
    133 static inline void  ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr, 0p, 0p}; }
    134 static inline void  ?{}(processor & this, const char name[])     { this{name, *mainCluster, 0p, 0p }; }
     131static inline void  ?{}(processor & this)                        { this{ "Anonymous Processor", *mainCluster}; }
     132static inline void  ?{}(processor & this, struct cluster & cltr) { this{ "Anonymous Processor", cltr}; }
     133static inline void  ?{}(processor & this, const char name[])     { this{name, *mainCluster}; }
    135134
    136135DLISTED_MGD_IMPL_OUT(processor)
  • libcfa/src/concurrency/kernel/startup.cfa

    re0c072c ra5e7233  
    7373static void __kernel_first_resume( processor * this );
    7474static void __kernel_last_resume ( processor * this );
    75 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg);
     75static void init(processor & this, const char name[], cluster & _cltr, $thread * initT);
    7676static void deinit(processor & this);
    7777static void doregister( struct cluster & cltr );
     
    198198                ( this.terminated ){};
    199199                ( this.runner ){};
    200                 init( this, "Main Processor", *mainCluster, 0p, 0p );
     200                init( this, "Main Processor", *mainCluster, 0p );
    201201                kernel_thread = pthread_self();
    202202
     
    452452}
    453453
    454 static void init(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) with( this ) {
     454static void init(processor & this, const char name[], cluster & _cltr, $thread * initT) with( this ) {
    455455        this.name = name;
    456456        this.cltr = &_cltr;
     
    464464        this.io.dirty   = false;
    465465
    466         this.init.fnc = fnc;
    467         this.init.arg = arg;
     466        this.init.thrd = initT;
    468467
    469468        this.idle = eventfd(0, 0);
     
    516515}
    517516
    518 void ?{}(processor & this, const char name[], cluster & _cltr, void (*fnc) (void *), void * arg) {
     517void ?{}(processor & this, const char name[], cluster & _cltr, $thread * initT) {
    519518        ( this.terminated ){};
    520519        ( this.runner ){};
    521520
    522521        disable_interrupts();
    523                 init( this, name, _cltr, fnc, arg );
     522                init( this, name, _cltr, initT );
    524523        enable_interrupts( __cfaabi_dbg_ctx );
    525524
     
    527526
    528527        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    529 
     528}
     529
     530void ?{}(processor & this, const char name[], cluster & _cltr) {
     531        (this){name, _cltr, 0p};
    530532}
    531533
  • tests/concurrent/clib.c

    re0c072c ra5e7233  
    6262        cfathread_cluster_add_worker( cl, NULL, NULL, NULL );
    6363        cfathread_cluster_add_worker( cl, NULL, NULL, NULL );
     64
     65        cfathread_attr_t attr;
     66        cfathread_attr_init(&attr);
     67        cfathread_attr_setcluster(&attr, cl);
     68
    6469        cfathread_t u;
    65         cfathread_create( &u, NULL, Unparker, NULL );
     70        cfathread_create( &u, &attr, Unparker, NULL );
    6671        {
    6772                cfathread_t t[20];
    6873                for(int i = 0; i < 20; i++) {
    69                         cfathread_create( &t[i], NULL, Worker, NULL );
     74                        cfathread_create( &t[i], &attr, Worker, NULL );
    7075                }
    7176                for(int i = 0; i < 20; i++) {
     
    7580        stop = true;
    7681        cfathread_join(u, NULL);
     82        cfathread_attr_destroy(&attr);
    7783        fflush(stdout);
    7884        _exit(0);
Note: See TracChangeset for help on using the changeset viewer.