Changes in / [2b22e050:1dbc8590]


Ignore:
Location:
src
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • src/benchmark/Makefile.am

    r2b22e050 r1dbc8590  
    4343
    4444%.runquiet :
    45         @+make $(basename $@) CFLAGS="-w"
     45        @+make $(basename $@)
    4646        @taskset -c 1 ./a.out
    4747        @rm -f a.out
  • src/benchmark/Makefile.in

    r2b22e050 r1dbc8590  
    459459
    460460%.runquiet :
    461         @+make $(basename $@) CFLAGS="-w"
     461        @+make $(basename $@)
    462462        @taskset -c 1 ./a.out
    463463        @rm -f a.out
  • src/libcfa/bits/containers.h

    r2b22e050 r1dbc8590  
    191191//-----------------------------------------------------------------------------
    192192#ifdef __cforall
    193         forall(dtype TYPE | sized(TYPE))
     193        trait is_db_node(dtype T) {
     194                T*& get_next( T& );
     195                T*& get_prev( T& );
     196        };
     197#endif
     198
     199#ifdef __cforall
     200        forall(dtype TYPE | is_db_node(TYPE))
    194201        #define T TYPE
    195         #define __getter_t * [T * & next, T * & prev] ( T & )
    196 #else
    197         typedef void (*__generit_c_getter_t)();
    198         #define T void
    199         #define __getter_t __generit_c_getter_t
     202#else
     203        #define T void
    200204#endif
    201205struct __dllist {
    202206        T * head;
    203         __getter_t __get;
    204 };
    205 #undef T
    206 #undef __getter_t
     207};
     208#undef T
    207209
    208210#ifdef __cforall
     
    214216#ifdef __cforall
    215217
    216         forall(dtype T | sized(T))
    217         static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
    218                 this.head{ NULL };
    219                 this.__get = __get;
    220         }
    221 
    222         #define _next .0
    223         #define _prev .1
    224         forall(dtype T | sized(T))
    225         static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
    226                 if ( head ) {
    227                         __get( node )_next = head;
    228                         __get( node )_prev = __get( *head )_prev;
    229                         // inserted node must be consistent before it is seen
    230                         // prevent code movement across barrier
    231                         asm( "" : : : "memory" );
    232                         __get( *head )_prev = &node;
    233                         T & prev = *__get( node )_prev;
    234                         __get( prev )_next = &node;
    235                 }
    236                 else {
    237                         __get( node )_next = &node;
    238                         __get( node )_prev = &node;
    239                 }
    240 
    241                 // prevent code movement across barrier
    242                 asm( "" : : : "memory" );
    243                 head = &node;
    244         }
    245 
    246         forall(dtype T | sized(T))
    247         static inline void remove( __dllist(T) & this, T & node ) with( this ) {
    248                 if ( &node == head ) {
    249                         if ( __get( *head )_next == head ) {
    250                                 head = NULL;
    251                         }
    252                         else {
    253                                 head = __get( *head )_next;
    254                         }
    255                 }
    256                 __get( *__get( node )_next )_prev = __get( node )_prev;
    257                 __get( *__get( node )_prev )_next = __get( node )_next;
    258                 __get( node )_next = NULL;
    259                 __get( node )_prev = NULL;
    260         }
    261         #undef _next
    262         #undef _prev
     218        forall(dtype T | is_db_node(T))
     219        static inline void ?{}( __dllist(T) & this ) with( this ) {
     220                head{ NULL };
     221        }
     222
     223        // forall(dtype T | is_db_node(T) | sized(T))
     224        // static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
     225        //      if ( head ) {
     226        //              get_next( node ) = head;
     227        //              get_prev( node ) = get_prev( *head );
     228        //              // inserted node must be consistent before it is seen
     229        //              // prevent code movement across barrier
     230        //              asm( "" : : : "memory" );
     231        //              get_prev( *head ) = node;
     232        //              T & prev = *get_prev( node );
     233        //              get_next( prev ) = node;
     234        //      }
     235        //      else {
     236        //              get_next( node ) = &node;
     237        //              get_prev( node ) = &node;
     238        //      }
     239
     240        //      // prevent code movement across barrier
     241        //      asm( "" : : : "memory" );
     242        //      head = val;
     243        // }
     244
     245        // forall(dtype T | is_db_node(T) | sized(T))
     246        // static inline T * remove( __dllist(T) & this, T & node ) with( this ) {
     247        //      if ( &node == head ) {
     248        //              if ( get_next( *head ) == head ) {
     249        //                      head = NULL;
     250        //              }
     251        //              else {
     252        //                      head = get_next( *head );
     253        //              }
     254        //      }
     255        //      get_prev( *get_next( node ) ) = get_prev( node );
     256        //      get_next( *get_prev( node ) ) = get_next( node );
     257        //      get_next( node ) = NULL;
     258        //      get_prev( node ) = NULL;
     259        // }
    263260#endif
    264261
  • src/libcfa/concurrency/invoke.h

    r2b22e050 r1dbc8590  
    136136                struct thread_desc * next;
    137137
    138                 struct {
    139                         struct thread_desc * next;
    140                         struct thread_desc * prev;
    141                 } node;
     138                __cfaabi_dbg_debug_do(
     139                        // instrusive link field for debugging
     140                        struct thread_desc * dbg_next;
     141                        struct thread_desc * dbg_prev;
     142                )
    142143     };
    143144
     
    146147                static inline thread_desc * & get_next( thread_desc & this ) {
    147148                        return this.next;
    148                 }
    149 
    150                 static inline [thread_desc *&, thread_desc *& ] __get( thread_desc & this ) {
    151                         return this.node.[next, prev];
    152149                }
    153150
  • src/libcfa/concurrency/kernel

    r2b22e050 r1dbc8590  
    4040
    4141//-----------------------------------------------------------------------------
     42// Cluster
     43struct cluster {
     44        // Ready queue locks
     45        __spinlock_t ready_queue_lock;
     46
     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
     60extern struct cluster * mainCluster;
     61extern Duration default_preemption();
     62
     63void ?{} (cluster & this, const char * name, Duration preemption_rate);
     64void ^?{}(cluster & this);
     65
     66static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
     67static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
     68static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
     69
     70//-----------------------------------------------------------------------------
    4271// Processor
    43 extern struct cluster * mainCluster;
    44 
    4572enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
    4673
     
    74101
    75102        // Cluster from which to get threads
    76         struct cluster * cltr;
     103        cluster * cltr;
    77104
    78105        // Name of the processor
     
    100127        bool pending_preemption;
    101128
    102         // Idle lock
    103 
    104         // Link lists fields
    105129        struct {
    106                 struct processor * next;
    107                 struct processor * prev;
    108         } node;
     130                pthread_mutex_t lock;
     131                pthread_cond_t  cond;
     132        } idle;
    109133
    110134#ifdef __CFA_DEBUG__
     
    114138};
    115139
    116 void  ?{}(processor & this, const char * name, struct cluster & cltr);
     140void  ?{}(processor & this, const char * name, cluster & cltr);
    117141void ^?{}(processor & this);
    118142
    119143static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    120 static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
     144static inline void  ?{}(processor & this, cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    121145static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
    122 
    123 static inline [processor *&, processor *& ] __get( processor & this ) {
    124         return this.node.[next, prev];
    125 }
    126 
    127 //-----------------------------------------------------------------------------
    128 // Cluster
    129 struct 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 };
    153 extern Duration default_preemption();
    154 
    155 void ?{} (cluster & this, const char * name, Duration preemption_rate);
    156 void ^?{}(cluster & this);
    157 
    158 static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    159 static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    160 static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
    161 
    162 static inline [cluster *&, cluster *& ] __get( cluster & this ) {
    163         return this.node.[next, prev];
    164 }
    165146
    166147// Local Variables: //
  • src/libcfa/concurrency/kernel.c

    r2b22e050 r1dbc8590  
    4949thread_desc * mainThread;
    5050
    51 struct { __dllist_t(thread_desc) list; __spinlock_t lock; } global_threads ;
    52 struct { __dllist_t(cluster    ) list; __spinlock_t lock; } global_clusters;
    53 
    5451//-----------------------------------------------------------------------------
    5552// Global state
     
    120117        self_mon_p = &self_mon;
    121118        next = NULL;
    122 
    123         node.next = NULL;
    124         node.prev = NULL;
    125         doregister(this);
     119        __cfaabi_dbg_debug_do(
     120                dbg_next = NULL;
     121                dbg_prev = NULL;
     122                __cfaabi_dbg_thread_register(&this);
     123        )
    126124
    127125        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    169167        ready_queue{};
    170168        ready_queue_lock{};
    171 
    172         procs{ __get };
    173         idles{ __get };
    174 
    175         doregister(this);
    176169}
    177170
    178171void ^?{}(cluster & this) {
    179         unregister(this);
     172
    180173}
    181174
     
    189182
    190183        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
    191 
    192         doregister(this->cltr, this);
    193184
    194185        {
     
    224215                __cfaabi_dbg_print_safe("Kernel : core %p stopping\n", this);
    225216        }
    226 
    227         unregister(this->cltr, this);
    228217
    229218        V( this->terminated );
     
    523512        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    524513
    525         global_threads. list{ __get };
    526         global_threads. lock{};
    527         global_clusters.list{ __get };
    528         global_clusters.lock{};
    529 
    530514        // Initialize the main cluster
    531515        mainCluster = (cluster *)&storage_mainCluster;
     
    655639
    656640static __spinlock_t kernel_abort_lock;
     641static __spinlock_t kernel_debug_lock;
    657642static bool kernel_abort_called = false;
    658643
     
    663648
    664649        // first task to abort ?
    665         if ( kernel_abort_called ) {                    // not first task to abort ?
     650        if ( ! kernel_abort_called ) {                  // not first task to abort ?
     651                kernel_abort_called = true;
     652                unlock( kernel_abort_lock );
     653        }
     654        else {
    666655                unlock( kernel_abort_lock );
    667656
    668657                sigset_t mask;
    669658                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 {
    675                 kernel_abort_called = true;
    676                 unlock( kernel_abort_lock );
     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
    677663        }
    678664
     
    683669        thread_desc * thrd = kernel_data;
    684670
    685         if(thrd) {
    686                 int len = snprintf( abort_text, abort_text_size, "Error occurred while executing thread %.256s (%p)", thrd->self_cor.name, thrd );
     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 );
    687676                __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                 }
    696677        }
    697678        else {
    698                 int len = snprintf( abort_text, abort_text_size, "Error occurred outside of any thread.\n" );
     679                __cfaabi_dbg_bits_write( ".\n", 2 );
    699680        }
    700681}
     
    703684        return get_coroutine(kernelTLS.this_thread) == get_coroutine(mainThread) ? 4 : 2;
    704685}
    705 
    706 static __spinlock_t kernel_debug_lock;
    707686
    708687extern "C" {
     
    759738
    760739//-----------------------------------------------------------------------------
    761 // Global Queues
    762 void doregister( thread_desc & thrd ) {
    763         // lock      ( global_thread.lock );
    764         // push_front( global_thread.list, thrd );
    765         // unlock    ( global_thread.lock );
    766 }
    767 
    768 void unregister( thread_desc & thrd ) {
    769         // lock  ( global_thread.lock );
    770         // remove( global_thread.list, thrd );
    771         // unlock( global_thread.lock );
    772 }
    773 
    774 void doregister( cluster     & cltr ) {
    775         // lock      ( global_cluster.lock );
    776         // push_front( global_cluster.list, cltr );
    777         // unlock    ( global_cluster.lock );
    778 }
    779 
    780 void unregister( cluster     & cltr ) {
    781         // lock  ( global_cluster.lock );
    782         // remove( global_cluster.list, cltr );
    783         // unlock( global_cluster.lock );
    784 }
    785 
    786 
    787 void 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 
    793 void 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 //-----------------------------------------------------------------------------
    800740// Debug
    801741__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
    802772        void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
    803773                this.prev_name = prev_name;
  • src/libcfa/concurrency/kernel_private.h

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

    r2b22e050 r1dbc8590  
    357357        // Block sigalrms to control when they arrive
    358358        sigset_t mask;
    359         sigfillset(&mask);
     359        sigemptyset( &mask );
     360        sigaddset( &mask, SIGALRM );
     361
    360362        if ( pthread_sigmask( SIG_BLOCK, &mask, NULL ) == -1 ) {
    361363            abort( "internal error, pthread_sigmask" );
    362364        }
    363 
    364         sigemptyset( &mask );
    365         sigaddset( &mask, SIGALRM );
    366365
    367366        // Main loop
  • src/libcfa/concurrency/thread.c

    r2b22e050 r1dbc8590  
    3939        curr_cluster = &cl;
    4040        next = NULL;
    41 
    42         node.next = NULL;
    43         node.prev = NULL;
    44         doregister(this);
     41        __cfaabi_dbg_debug_do(
     42                dbg_next = NULL;
     43                dbg_prev = NULL;
     44                __cfaabi_dbg_thread_register(&this);
     45        )
    4546
    4647        monitors{ &self_mon_p, 1, (fptr_t)0 };
     
    4849
    4950void ^?{}(thread_desc& this) with( this ) {
    50         unregister(this);
    5151        ^self_cor{};
    5252}
  • src/libcfa/interpose.c

    r2b22e050 r1dbc8590  
    9898#pragma GCC diagnostic pop
    9999
    100                 // Failure handler
    101                 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );
    102                 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );
    103                 __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    104                 __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    105                 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND);
    106                 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    107                 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     100                __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO ); // Failure handler
     101                __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO ); // Failure handler
     102                __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO ); // Failure handler
     103                __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO ); // Failure handler
     104                __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO ); // Failure handler
     105                __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); // Failure handler
     106                __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); // Failure handler
    108107        }
    109108}
Note: See TracChangeset for help on using the changeset viewer.