Ignore:
Timestamp:
May 11, 2018, 10:42:09 AM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
Children:
78af962
Parents:
afd550c
Message:

some more work on kernel doubly linked lists and fixed segfault in abort message

Location:
src/libcfa/concurrency
Files:
5 edited

Legend:

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

    rafd550c rde94a60  
    136136                struct thread_desc * next;
    137137
    138                 __cfaabi_dbg_debug_do(
    139                         // instrusive link field for debugging
    140                         struct thread_desc * dbg_next;
    141                         struct thread_desc * dbg_prev;
    142                 )
     138                struct {
     139                        struct thread_desc * next;
     140                        struct thread_desc * prev;
     141                } node;
    143142     };
    144143
     
    147146                static inline thread_desc * & get_next( thread_desc & this ) {
    148147                        return this.next;
     148                }
     149
     150                static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) {
     151                        return this.node.[next, prev];
    149152                }
    150153
  • src/libcfa/concurrency/kernel

    rafd550c rde94a60  
    4040
    4141//-----------------------------------------------------------------------------
    42 // Cluster
    43 struct cluster {
    44         // Ready queue locks
    45         __spinlock_t ready_queue_lock;
     42// Processor
     43extern struct cluster * mainCluster;
    4644
    47         // Ready queue for threads
    48         __queue_t(thread_desc) ready_queue;
    49 
    50         // Name of the cluster
    51         const char * name;
    52 
    53         // Preemption rate on this cluster
    54         Duration preemption_rate;
    55 
    56         // List of idle processors
    57         // __dllist_t(struct processor) idles;
    58 };
    59 
    60 extern struct cluster * mainCluster;
    61 extern Duration default_preemption();
    62 
    63 void ?{} (cluster & this, const char * name, Duration preemption_rate);
    64 void ^?{}(cluster & this);
    65 
    66 static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    67 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    68 static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
    69 
    70 //-----------------------------------------------------------------------------
    71 // Processor
    7245enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
    7346
     
    10174
    10275        // Cluster from which to get threads
    103         cluster * cltr;
     76        struct cluster * cltr;
    10477
    10578        // Name of the processor
     
    127100        bool pending_preemption;
    128101
     102        // Idle lock
     103
     104        // Link lists fields
    129105        struct {
    130                 pthread_mutex_t lock;
    131                 pthread_cond_t  cond;
    132         } idle;
     106                struct processor * next;
     107                struct processor * prev;
     108        } node;
    133109
    134110#ifdef __CFA_DEBUG__
     
    138114};
    139115
    140 void  ?{}(processor & this, const char * name, cluster & cltr);
     116void  ?{}(processor & this, const char * name, struct cluster & cltr);
    141117void ^?{}(processor & this);
    142118
    143119static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    144 static inline void  ?{}(processor & this, cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
     120static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    145121static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
     122
     123static inline [processor *&, processor *& ] __get( processor & this ) {
     124        return this.node.[next, prev];
     125}
     126
     127//-----------------------------------------------------------------------------
     128// Cluster
     129struct cluster {
     130        // Ready queue locks
     131        __spinlock_t ready_queue_lock;
     132
     133        // Ready queue for threads
     134        __queue_t(thread_desc) ready_queue;
     135
     136        // Name of the cluster
     137        const char * name;
     138
     139        // Preemption rate on this cluster
     140        Duration preemption_rate;
     141
     142        // List of processors
     143        __spinlock_t proc_list_lock;
     144        __dllist_t(struct processor) procs;
     145        __dllist_t(struct processor) idles;
     146
     147        // Link lists fields
     148        struct {
     149                cluster * next;
     150                cluster * prev;
     151        } node;
     152};
     153extern Duration default_preemption();
     154
     155void ?{} (cluster & this, const char * name, Duration preemption_rate);
     156void ^?{}(cluster & this);
     157
     158static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
     159static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
     160static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
     161
     162static inline [cluster *&, cluster *& ] __get( cluster & this ) {
     163        return this.node.[next, prev];
     164}
    146165
    147166// Local Variables: //
  • src/libcfa/concurrency/kernel.c

    rafd550c rde94a60  
    4949thread_desc * mainThread;
    5050
     51struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;
     52struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
     53
    5154//-----------------------------------------------------------------------------
    5255// Global state
     
    117120        self_mon_p = &self_mon;
    118121        next = NULL;
    119         __cfaabi_dbg_debug_do(
    120                 dbg_next = NULL;
    121                 dbg_prev = NULL;
    122                 __cfaabi_dbg_thread_register(&this);
    123         )
     122
     123        node.next = NULL;
     124        node.prev = NULL;
     125        doregister(this);
    124126
    125127        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    167169        ready_queue{};
    168170        ready_queue_lock{};
     171
     172        procs{ __get };
     173        idles{ __get };
     174
     175        doregister(this);
    169176}
    170177
    171178void ^?{}(cluster & this) {
    172 
     179        unregister(this);
    173180}
    174181
     
    182189
    183190        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
     191
     192        doregister(this->cltr, this);
    184193
    185194        {
     
    215224                __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this);
    216225        }
     226
     227        unregister(this->cltr, this);
    217228
    218229        V( this->terminated );
     
    512523        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    513524
     525        global_threads. list{ __get };
     526        global_threads. lock{};
     527        global_clusters.list{ __get };
     528        global_clusters.lock{};
     529
    514530        // Initialize the main cluster
    515531        mainCluster = (cluster *)&storage_mainCluster;
     
    639655
    640656static __spinlock_t kernel_abort_lock;
    641 static __spinlock_t kernel_debug_lock;
    642657static bool kernel_abort_called = false;
    643658
     
    648663
    649664        // first task to abort ?
    650         if ( ! kernel_abort_called ) {                  // not first task to abort ?
     665        if ( kernel_abort_called ) {                    // not first task to abort ?
     666                unlock( kernel_abort_lock );
     667
     668                sigset_t mask;
     669                sigemptyset( &mask );
     670                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
     671                sigsuspend( &mask );                    // block the processor to prevent further damage during abort
     672                _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     673        }
     674        else {
    651675                kernel_abort_called = true;
    652676                unlock( kernel_abort_lock );
    653677        }
    654         else {
    655                 unlock( kernel_abort_lock );
    656 
    657                 sigset_t mask;
    658                 sigemptyset( &mask );
    659                 sigaddset( &mask, SIGALRM );                    // block SIGALRM signals
    660                 sigaddset( &mask, SIGUSR1 );                    // block SIGUSR1 signals
    661                 sigsuspend( &mask );                            // block the processor to prevent further damage during abort
    662                 _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    663         }
    664678
    665679        return kernelTLS.this_thread;
     
    669683        thread_desc * thrd = kernel_data;
    670684
    671         int len = snprintf( abort_text, abort_text_size, "Error occurred while executing task %.256s (%p)", thrd->self_cor.name, thrd );
    672         __cfaabi_dbg_bits_write( abort_text, len );
    673 
    674         if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
    675                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     685        if(thrd) {
     686                int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
    676687                __cfaabi_dbg_bits_write( abort_text, len );
     688
     689                if ( get_coroutine(thrd) != kernelTLS.this_coroutine ) {
     690                        len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine );
     691                        __cfaabi_dbg_bits_write( abort_text, len );
     692                }
     693                else {
     694                        __cfaabi_dbg_bits_write( ".\n", 2 );
     695                }
    677696        }
    678697        else {
    679                 __cfaabi_dbg_bits_write( ".\n", 2 );
     698                int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
    680699        }
    681700}
     
    684703        return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
    685704}
     705
     706static __spinlock_t kernel_debug_lock;
    686707
    687708extern "C" {
     
    738759
    739760//-----------------------------------------------------------------------------
     761// Global Queues
     762void doregister( thread_desc & thrd ) {
     763        // lock      ( global_thread.lock );
     764        // push_front( global_thread.list, thrd );
     765        // unlock    ( global_thread.lock );
     766}
     767
     768void unregister( thread_desc & thrd ) {
     769        // lock  ( global_thread.lock );
     770        // remove( global_thread.list, thrd );
     771        // unlock( global_thread.lock );
     772}
     773
     774void doregister( cluster     & cltr ) {
     775        // lock      ( global_cluster.lock );
     776        // push_front( global_cluster.list, cltr );
     777        // unlock    ( global_cluster.lock );
     778}
     779
     780void unregister( cluster     & cltr ) {
     781        // lock  ( global_cluster.lock );
     782        // remove( global_cluster.list, cltr );
     783        // unlock( global_cluster.lock );
     784}
     785
     786
     787void doregister( cluster * cltr, processor * proc ) {
     788        // lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     789        // push_front(cltr->procs, *proc);
     790        // unlock    (cltr->proc_list_lock);
     791}
     792
     793void unregister( cluster * cltr, processor * proc ) {
     794        // lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     795        // remove(cltr->procs, *proc );
     796        // unlock(cltr->proc_list_lock);
     797}
     798
     799//-----------------------------------------------------------------------------
    740800// Debug
    741801__cfaabi_dbg_debug_do(
    742         struct {
    743                 thread_desc * tail;
    744         } __cfaabi_dbg_thread_list = { NULL };
    745 
    746         void __cfaabi_dbg_thread_register( thread_desc * thrd ) {
    747                 if( !__cfaabi_dbg_thread_list.tail ) {
    748                         __cfaabi_dbg_thread_list.tail = thrd;
    749                         return;
    750                 }
    751                 __cfaabi_dbg_thread_list.tail->dbg_next = thrd;
    752                 thrd->dbg_prev = __cfaabi_dbg_thread_list.tail;
    753                 __cfaabi_dbg_thread_list.tail = thrd;
    754         }
    755 
    756         void __cfaabi_dbg_thread_unregister( thread_desc * thrd ) {
    757                 thread_desc * prev = thrd->dbg_prev;
    758                 thread_desc * next = thrd->dbg_next;
    759 
    760                 if( next ) { next->dbg_prev = prev; }
    761                 else       {
    762                         assert( __cfaabi_dbg_thread_list.tail == thrd );
    763                         __cfaabi_dbg_thread_list.tail = prev;
    764                 }
    765 
    766                 if( prev ) { prev->dbg_next = next; }
    767 
    768                 thrd->dbg_prev = NULL;
    769                 thrd->dbg_next = NULL;
    770         }
    771 
    772802        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    773803                this.prev_name = prev_name;
  • src/libcfa/concurrency/kernel_private.h

    rafd550c rde94a60  
    100100#define KERNEL_STORAGE(T,X) static char storage_##X[sizeof(T)]
    101101
     102
     103void doregister( struct thread_desc & thrd );
     104void unregister( struct thread_desc & thrd );
     105
     106void doregister( struct cluster     & cltr );
     107void unregister( struct cluster     & cltr );
     108
     109void doregister( struct cluster * cltr, struct processor * proc );
     110void unregister( struct cluster * cltr, struct processor * proc );
     111
    102112// Local Variables: //
    103113// mode: c //
  • src/libcfa/concurrency/thread.c

    rafd550c rde94a60  
    3939        curr_cluster = &cl;
    4040        next = NULL;
    41         __cfaabi_dbg_debug_do(
    42                 dbg_next = NULL;
    43                 dbg_prev = NULL;
    44                 __cfaabi_dbg_thread_register(&this);
    45         )
     41
     42        node.next = NULL;
     43        node.prev = NULL;
     44        doregister(this);
    4645
    4746        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    4948
    5049void ^?{}(thread_desc& this) with( this ) {
     50        unregister(this);
    5151        ^self_cor{};
    5252}
Note: See TracChangeset for help on using the changeset viewer.