Changes in / [7b2a786:a5a67ab8]


Ignore:
Files:
2 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    r7b2a786 ra5a67ab8  
    22
    33import groovy.transform.Field
     4
     5// For skipping stages
     6import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
    47
    58//===========================================================================================================
     
    1215        SrcDir    = pwd tmp: false
    1316        Settings  = null
    14         Tools     = null
     17        StageName = ''
    1518
    1619        // Local variables
     
    6366
    6467                //Store the result of the build log
    65                 currentBuild.result = "${tools.StageName} FAILURE".trim()
     68                currentBuild.result = "${StageName} FAILURE".trim()
    6669        }
    6770
     
    8285//===========================================================================================================
    8386def clean() {
    84         Tools.BuildStage('Cleanup', true) {
     87        build_stage('Cleanup', true) {
    8588                // clean the build by wipping the build directory
    8689                dir(BuildDir) {
     
    9295//Compilation script is done here but environnement set-up and error handling is done in main loop
    9396def checkout() {
    94         Tools.BuildStage('Checkout', true) {
     97        build_stage('Checkout', true) {
    9598                //checkout the source code and clean the repo
    9699                final scmVars = checkout scm
     
    105108        debug = true
    106109        release = Settings.RunAllTests || Settings.RunBenchmark
    107         Tools.BuildStage('Build : configure', true) {
     110        build_stage('Build : configure', true) {
    108111                // Configure must be run inside the tree
    109112                dir (SrcDir) {
     
    133136        }
    134137
    135         Tools.BuildStage('Build : cfa-cpp', true) {
     138        build_stage('Build : cfa-cpp', true) {
    136139                // Build outside of the src tree to ease cleaning
    137140                dir (BuildDir) {
     
    144147        }
    145148
    146         Tools.BuildStage('Build : libcfa(debug)', debug) {
     149        build_stage('Build : libcfa(debug)', debug) {
    147150                // Build outside of the src tree to ease cleaning
    148151                dir (BuildDir) {
     
    151154        }
    152155
    153         Tools.BuildStage('Build : libcfa(nodebug)', release) {
     156        build_stage('Build : libcfa(nodebug)', release) {
    154157                // Build outside of the src tree to ease cleaning
    155158                dir (BuildDir) {
     
    158161        }
    159162
    160         Tools.BuildStage('Build : install', true) {
     163        build_stage('Build : install', true) {
    161164                // Build outside of the src tree to ease cleaning
    162165                dir (BuildDir) {
     
    168171def test() {
    169172        try {
    170                 Tools.BuildStage('Test: short', !Settings.RunAllTests) {
     173                build_stage('Test: short', !Settings.RunAllTests) {
    171174                        dir (BuildDir) {
    172175                                //Run the tests from the tests directory
     
    175178                }
    176179
    177                 Tools.BuildStage('Test: full', Settings.RunAllTests) {
     180                build_stage('Test: full', Settings.RunAllTests) {
    178181                        dir (BuildDir) {
    179182                                        //Run the tests from the tests directory
     
    193196
    194197def benchmark() {
    195         Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
     198        build_stage('Benchmark', Settings.RunBenchmark) {
    196199                dir (BuildDir) {
    197200                        //Append bench results
     
    202205
    203206def build_doc() {
    204         Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
     207        build_stage('Documentation', Settings.BuildDocumentation) {
    205208                dir ('doc/user') {
    206209                        make_doc()
     
    214217
    215218def publish() {
    216         Tools.BuildStage('Publish', true) {
     219        build_stage('Publish', true) {
    217220
    218221                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
     
    503506                ]])
    504507
    505         // It's unfortunate but it looks like we need to checkout the entire repo just to get
    506         // - the pretty git printer
    507         // - Jenkins.tools
     508        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
    508509        checkout scm
    509 
    510         Tools = load "Jenkins/tools.groovy"
    511510
    512511        final settings = new BuildSettings(params, env.BRANCH_NAME)
     
    516515
    517516        return settings
     517}
     518
     519def build_stage(String name, boolean run, Closure block ) {
     520        StageName = name
     521        echo " -------- ${StageName} -------- "
     522        if(run) {
     523                stage(name, block)
     524        } else {
     525                stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) }
     526        }
    518527}
    519528
  • libcfa/src/bits/containers.hfa

    r7b2a786 ra5a67ab8  
    1717#include "bits/align.hfa"
    1818#include "bits/defs.hfa"
    19 #include <stdio.h>
     19
    2020//-----------------------------------------------------------------------------
    2121// Array
     
    146146        static inline forall( dtype T | is_node(T) ) {
    147147                void ?{}( __queue(T) & this ) with( this ) {
    148                         (this.head){ 1p };
    149                         (this.tail){ &this.head };
    150                         verify(*this.tail == 1p);
     148                        head{ 1p };
     149                        tail{ &head };
     150                        verify(*tail == 1p);
    151151                }
    152152
    153153                void append( __queue(T) & this, T * val ) with( this ) {
    154                         verify(this.tail != 0p);
    155                         verify(*this.tail == 1p);
    156                         *this.tail = val;
    157                         this.tail = &get_next( *val );
    158                         *this.tail = 1p;
     154                        verify(tail != 0p);
     155                        verify(*tail == 1p);
     156                        *tail = val;
     157                        tail = &get_next( *val );
     158                        *tail = 1p;
    159159                }
    160160
    161161                T * peek( __queue(T) & this ) {
    162162                        verify(*this.tail == 1p);
    163                         T * front = this.head;
    164                         if( front != 1p ) {
     163                        T * head = this.head;
     164                        if( head != 1p ) {
    165165                                verify(*this.tail == 1p);
    166                                 return front;
     166                                return head;
    167167                        }
    168168                        verify(*this.tail == 1p);
     
    172172                T * pop_head( __queue(T) & this ) {
    173173                        verify(*this.tail == 1p);
    174                         T * _head = this.head;
    175                         if( _head != 1p ) {
    176                                 this.head = get_next( *_head );
    177                                 if( get_next( *_head ) == 1p ) {
     174                        T * head = this.head;
     175                        if( head != 1p ) {
     176                                this.head = get_next( *head );
     177                                if( get_next( *head ) == 1p ) {
    178178                                        this.tail = &this.head;
    179179                                }
    180                                 get_next( *_head ) = 0p;
     180                                get_next( *head ) = 0p;
    181181                                verify(*this.tail == 1p);
    182                                 verify( get_next(*_head) == 0p );
    183                                 return _head;
     182                                verify( get_next(*head) == 0p );
     183                                return head;
    184184                        }
    185185                        verify(*this.tail == 1p);
     
    193193                        (*it) = get_next( *val );
    194194
    195                         if( this.tail == &get_next( *val ) ) {
    196                                 this.tail = it;
     195                        if( tail == &get_next( *val ) ) {
     196                                tail = it;
    197197                        }
    198198
    199199                        get_next( *val ) = 0p;
    200200
    201                         verify( (this.head == 1p) == (&this.head == this.tail) );
    202                         verify( *this.tail == 1p );
     201                        verify( (head == 1p) == (&head == tail) );
     202                        verify( *tail == 1p );
    203203                        return val;
    204204                }
     
    239239        forall(dtype T )
    240240        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
    241                 (this.head){ 0p };
     241                this.head{ 0p };
    242242                this.__get = __get;
    243243        }
     
    248248                void push_front( __dllist(T) & this, T & node ) with( this ) {
    249249                        verify(__get);
    250                         if ( this.head ) {
    251                                 __get( node ).next = this.head;
    252                                 __get( node ).prev = __get( *this.head ).prev;
     250                        if ( head ) {
     251                                __get( node ).next = head;
     252                                __get( node ).prev = __get( *head ).prev;
    253253                                // inserted node must be consistent before it is seen
    254254                                // prevent code movement across barrier
    255255                                asm( "" : : : "memory" );
    256                                 __get( *this.head ).prev = &node;
     256                                __get( *head ).prev = &node;
    257257                                T & _prev = *__get( node ).prev;
    258258                                __get( _prev ).next = &node;
     
    264264                        // prevent code movement across barrier
    265265                        asm( "" : : : "memory" );
    266                         this.head = &node;
     266                        head = &node;
    267267                }
    268268
    269269                void remove( __dllist(T) & this, T & node ) with( this ) {
    270270                        verify(__get);
    271                         if ( &node == this.head ) {
    272                                 if ( __get( *this.head ).next == this.head ) {
    273                                         this.head = 0p;
     271                        if ( &node == head ) {
     272                                if ( __get( *head ).next == head ) {
     273                                        head = 0p;
    274274                                } else {
    275                                         this.head = __get( *this.head ).next;
     275                                        head = __get( *head ).next;
    276276                                }
    277277                        }
  • libcfa/src/concurrency/alarm.cfa

    r7b2a786 ra5a67ab8  
    6060        type = Kernel;
    6161}
    62 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period ) with( this ) {
     62void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) with( this ) {
     63        this.thrd = thrd;
    6364        this.alarm = alarm;
    6465        this.period = period;
  • libcfa/src/concurrency/alarm.hfa

    r7b2a786 ra5a67ab8  
    5252
    5353        union {
    54                 $thread * thrd;                                 // thrd who created event
    55                 processor * proc;                               // proc who created event
    56                 Alarm_Callback callback;                // callback to handle event
     54                $thread * thrd; // thrd who created event
     55                processor * proc;               // proc who created event
    5756        };
     57
     58        Alarm_Callback callback;
    5859
    5960        bool set                :1;             // whether or not the alarm has be registered
     
    6465void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period );
    6566void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
    66 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period );
     67void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
    6768void ^?{}( alarm_node_t & this );
    6869
  • libcfa/src/concurrency/locks.cfa

    r7b2a786 ra5a67ab8  
    1111//// info_thread
    1212///////////////////////////////////////////////////////////////////
    13 
    1413forall(dtype L | is_blocking_lock(L)) {
    1514        void ?{}( info_thread(L) & this, $thread * t ) {
    16                 ((Seqable &) this){};
    1715                this.t = t;
    1816                this.lock = 0p;
     
    2119
    2220        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) {
    23                 ((Seqable &) this){};
    2421                this.t = t;
    2522                this.info = info;
     
    2825        }
    2926
    30         void ^?{}( info_thread(L) & this ){ }
    31 }
    32 
     27        void ^?{}( info_thread(L) & this ){
     28                // default
     29        }
     30
     31        info_thread(L) *& get_next( info_thread(L) & this ) {
     32                return this.next;
     33        }
     34}
    3335///////////////////////////////////////////////////////////////////
    3436//// Blocking Locks
     
    4547}
    4648
    47 void ^?{}( blocking_lock & this ) {}
    48 void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
    49 void ^?{}( single_acquisition_lock & this ) {}
    50 void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
    51 void ^?{}( owner_lock & this ) {}
    52 void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
    53 void ^?{}( multiple_acquisition_lock & this ) {}
     49void ^?{}( blocking_lock & this ) {
     50        // default
     51}
     52
     53void ?{}( single_acquisition_lock & this ) {
     54        ((blocking_lock &)this){ false, false };
     55}
     56
     57void ^?{}( single_acquisition_lock & this ) {
     58        // default
     59}
     60
     61void ?{}( owner_lock & this ) {
     62        ((blocking_lock &)this){ true, true };
     63}
     64
     65void ^?{}( owner_lock & this ) {
     66        // default
     67}
     68
     69void ?{}( multiple_acquisition_lock & this ) {
     70        ((blocking_lock &)this){ true, false };
     71}
     72
     73void ^?{}( multiple_acquisition_lock & this ) {
     74        // default
     75}
    5476
    5577void lock( blocking_lock & this ) with( this ) {
    5678        lock( lock __cfaabi_dbg_ctx2 );
    5779        if ( owner == active_thread() && !multi_acquisition) {
    58                 abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock.");
     80                fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
     81        exit(EXIT_FAILURE);
    5982        } else if ( owner != 0p && owner != active_thread() ) {
    6083                append( blocked_threads, active_thread() );
     
    87110}
    88111
    89 void unlock_error_check( blocking_lock & this ) with( this ) {
    90         if ( owner == 0p ){ // no owner implies lock isn't held
    91                 abort( "There was an attempt to release a lock that isn't held" );
    92         } else if ( strict_owner && owner != active_thread() ) {
    93                 abort( "A thread other than the owner attempted to release an owner lock" );
    94         }
    95 }
    96 
    97 void pop_and_set_new_owner( blocking_lock & this ) with( this ) {
    98         $thread * t = pop_head( blocked_threads );
    99         owner = t;
    100         recursion_count = ( t ? 1 : 0 );
    101         wait_count--;
    102         unpark( t );
    103 }
    104 
    105112void unlock( blocking_lock & this ) with( this ) {
    106113        lock( lock __cfaabi_dbg_ctx2 );
    107         unlock_error_check( this );
     114        if ( owner == 0p ){ // no owner implies lock isn't held
     115                fprintf( stderr, "There was an attempt to release a lock that isn't held" );
     116                return;
     117        } else if ( strict_owner && owner != active_thread() ) {
     118                fprintf( stderr, "A thread other than the owner attempted to release an owner lock" );
     119                return;
     120        }
    108121        recursion_count--;
    109122        if ( recursion_count == 0 ) {
    110                 pop_and_set_new_owner( this );
     123                $thread * thrd = pop_head( blocked_threads );
     124                owner = thrd;
     125                recursion_count = ( thrd ? 1 : 0 );
     126                wait_count--;
     127                unpark( thrd );
    111128        }
    112129        unlock( lock );
     
    116133        return wait_count;
    117134}
     135
    118136
    119137void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) {
     
    134152                owner = t;
    135153                recursion_count = 1;
     154                #if !defined( __CFA_NO_STATISTICS__ )
     155                        //kernelTLS.this_stats = t->curr_cluster->stats;
     156                #endif
    136157                unpark( t );
    137158                unlock( lock );
     
    141162void remove_( blocking_lock & this ) with( this ) {
    142163    lock( lock __cfaabi_dbg_ctx2 );
    143         unlock_error_check( this );
    144         pop_and_set_new_owner( this );
     164        if ( owner == 0p ){ // no owner implies lock isn't held
     165                fprintf( stderr, "A lock that is not held was passed to a synchronization lock" );
     166        } else if ( strict_owner && owner != active_thread() ) {
     167                fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" );
     168        } else {
     169                $thread * thrd = pop_head( blocked_threads );
     170                owner = thrd;
     171                recursion_count = ( thrd ? 1 : 0 );
     172                wait_count--;
     173                unpark( thrd );
     174        }
    145175        unlock( lock );
    146176}
     
    152182// This is temporary until an inheritance bug is fixed
    153183
    154 void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
    155 void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
    156 void add_( single_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    157 void remove_( single_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
    158 void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    159 size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
    160 
    161 void lock( owner_lock & this ){ lock( (blocking_lock &)this ); }
    162 void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); }
    163 void add_( owner_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    164 void remove_( owner_lock & this ){ remove_( (blocking_lock &)this ); }
    165 void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    166 size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
    167 
    168 void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
    169 void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
    170 void add_( multiple_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
    171 void remove_( multiple_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
    172 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
    173 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     184void lock( single_acquisition_lock & this ){
     185        lock( (blocking_lock &)this );
     186}
     187
     188void unlock( single_acquisition_lock & this ){
     189        unlock( (blocking_lock &)this );
     190}
     191
     192void add_( single_acquisition_lock & this, struct $thread * t ){
     193        add_( (blocking_lock &)this, t );
     194}
     195
     196void remove_( single_acquisition_lock & this ){
     197        remove_( (blocking_lock &)this );
     198}
     199
     200void set_recursion_count( single_acquisition_lock & this, size_t recursion ){
     201        set_recursion_count( (blocking_lock &)this, recursion );
     202}
     203
     204size_t get_recursion_count( single_acquisition_lock & this ){
     205        return get_recursion_count( (blocking_lock &)this );
     206}
     207
     208void lock( owner_lock & this ){
     209        lock( (blocking_lock &)this );
     210}
     211
     212void unlock( owner_lock & this ){
     213        unlock( (blocking_lock &)this );
     214}
     215
     216void add_( owner_lock & this, struct $thread * t ){
     217        add_( (blocking_lock &)this, t );
     218}
     219
     220void remove_( owner_lock & this ){
     221        remove_( (blocking_lock &)this );
     222}
     223
     224void set_recursion_count( owner_lock & this, size_t recursion ){
     225        set_recursion_count( (blocking_lock &)this, recursion );
     226}
     227
     228size_t get_recursion_count( owner_lock & this ){
     229        return get_recursion_count( (blocking_lock &)this );
     230}
     231
     232void lock( multiple_acquisition_lock & this ){
     233        lock( (blocking_lock &)this );
     234}
     235
     236void unlock( multiple_acquisition_lock & this ){
     237        unlock( (blocking_lock &)this );
     238}
     239
     240void add_( multiple_acquisition_lock & this, struct $thread * t ){
     241        add_( (blocking_lock &)this, t );
     242}
     243
     244void remove_( multiple_acquisition_lock & this ){
     245        remove_( (blocking_lock &)this );
     246}
     247
     248void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){
     249        set_recursion_count( (blocking_lock &)this, recursion );
     250}
     251
     252size_t get_recursion_count( multiple_acquisition_lock & this ){
     253        return get_recursion_count( (blocking_lock &)this );
     254}
    174255
    175256///////////////////////////////////////////////////////////////////
     
    182263        // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
    183264            lock( cond->lock __cfaabi_dbg_ctx2 );
    184            
    185             if ( i->listed ) {                  // is thread on queue
    186                 cond->last_thread = i;          // REMOVE THIS AFTER DEBUG
    187                         remove( cond->blocked_threads, *i );             //remove this thread O(1)
     265            if ( (*i)->listed ) {                       // is thread on queue
     266                info_thread(L) * copy = *i;
     267                        remove( cond->blocked_threads, i );              //remove this thread O(1)
    188268                        cond->count--;
    189                         if( !i->lock ) {
    190                                 unpark( i->t );
     269                        if( !copy->lock ) {
     270                                #if !defined( __CFA_NO_STATISTICS__ )
     271                                        //kernelTLS.this_stats = copy->t->curr_cluster->stats;
     272                                #endif
     273                                unpark( copy->t );
    191274                } else {
    192                         add_(*i->lock, i->t);                   // call lock's add_
     275                        add_(*copy->lock, copy->t);                     // call lock's add_
    193276                }
    194277            }
     
    196279        }
    197280
    198         void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
     281        void alarm_node_wrap_cast( alarm_node_t & a ) {
     282                timeout_handler( (alarm_node_wrap(L) &)a );
     283        }
    199284
    200285        void ?{}( condition_variable(L) & this ){
     
    202287                this.blocked_threads{};
    203288                this.count = 0;
    204                 this.last_thread = 0p; // REMOVE AFTER DEBUG
    205         }
    206 
    207         void ^?{}( condition_variable(L) & this ){ }
    208 
    209         void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback ) {
    210                 this.alarm_node{ callback, alarm, period };
    211         }
    212 
    213         void ^?{}( alarm_node_wrap(L) & this ) { }
    214 
    215         void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) {
    216                 if(&popped != 0p) {
    217                         popped.listed = false;
     289        }
     290
     291        void ^?{}( condition_variable(L) & this ){
     292                // default
     293        }
     294
     295        void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) {
     296                this.alarm_node{ thrd, alarm, period, callback };
     297        }
     298
     299        void ^?{}( alarm_node_wrap(L) & this ) {
     300                // default
     301        }
     302
     303        bool notify_one( condition_variable(L) & this ) with( this ) {
     304                lock( lock __cfaabi_dbg_ctx2 );
     305                bool ret = !!blocked_threads;
     306                info_thread(L) * popped = pop_head( blocked_threads );
     307                if(popped != 0p) {
     308                        popped->listed = false;
    218309                        count--;
    219                         if (popped.lock) {
    220                                 add_(*popped.lock, popped.t);
     310                        if (popped->lock) {
     311                                add_(*popped->lock, popped->t);
    221312                        } else {
    222                                 unpark(popped.t);
     313                                unpark(popped->t);
    223314                        }
    224315                }
    225         }
    226 
    227         bool notify_one( condition_variable(L) & this ) with( this ) {
    228                 lock( lock __cfaabi_dbg_ctx2 );
    229                 bool ret = !empty(blocked_threads);
    230                 process_popped(this, dropHead( blocked_threads ));
    231316                unlock( lock );
    232317                return ret;
     
    235320        bool notify_all( condition_variable(L) & this ) with(this) {
    236321                lock( lock __cfaabi_dbg_ctx2 );
    237                 bool ret = !empty(blocked_threads);
    238                 while( !empty(blocked_threads) ) {
    239                         process_popped(this, dropHead( blocked_threads ));
     322                bool ret = blocked_threads ? true : false;
     323                while( blocked_threads ) {
     324                        info_thread(L) * popped = pop_head( blocked_threads );
     325                        if(popped != 0p){
     326                                popped->listed = false;
     327                                count--;
     328                                if (popped->lock) {
     329                                        add_(*popped->lock, popped->t);
     330                                } else {
     331                                        unpark(popped->t);
     332                                }
     333                        }
    240334                }
    241335                unlock( lock );
     
    244338
    245339        uintptr_t front( condition_variable(L) & this ) with(this) {
    246                 return empty(blocked_threads) ? NULL : head(blocked_threads).info;
    247         }
    248 
    249         bool empty( condition_variable(L) & this ) with(this) { return empty(blocked_threads); }
    250 
    251         int counter( condition_variable(L) & this ) with(this) { return count; }
    252 
    253         size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) {
    254                 addTail( blocked_threads, *i );
    255                 count++;
    256                 i->listed = true;
    257                 size_t recursion_count = 0;
    258                 if (i->lock) {
    259                         i->t->link.next = 1p;
    260                         recursion_count = get_recursion_count(*i->lock);
    261                         remove_( *i->lock );
    262                 }
    263                 return recursion_count;
    264         }
    265 
    266         // helper for wait()'s' with no timeout
     340                if(!blocked_threads) return NULL;
     341                return peek(blocked_threads)->info;
     342        }
     343
     344        bool empty( condition_variable(L) & this ) with(this) {
     345                return blocked_threads ? false : true;
     346        }
     347
     348        int counter( condition_variable(L) & this ) with(this) {
     349                return count;
     350        }
     351
     352        // helper for wait()'s' without a timeout
    267353        void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
    268354                lock( lock __cfaabi_dbg_ctx2 );
    269                 size_t recursion_count = queue_and_get_recursion(this, &i);
     355                append( this.blocked_threads, &i );
     356                count++;
     357                i.listed = true;
     358                size_t recursion_count;
     359                if (i.lock) {
     360                        recursion_count = get_recursion_count(*i.lock);
     361                        remove_( *i.lock );
     362                }
     363               
    270364                unlock( lock );
    271365                park( ); // blocks here
     366
    272367                if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
    273368        }
     
    276371        void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Time t ) with(this) {
    277372                lock( lock __cfaabi_dbg_ctx2 );
    278                 size_t recursion_count = queue_and_get_recursion(this, &info);
    279                 alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast };
     373
     374                info_thread(L) * queue_ptr = &info;
     375
     376                alarm_node_wrap(L) node_wrap = { info.t, t, 0`s, alarm_node_wrap_cast };
    280377                node_wrap.cond = &this;
    281                 node_wrap.i = &info;
     378                node_wrap.i = &queue_ptr;
     379
    282380                register_self( &node_wrap.alarm_node );
     381
     382                append( blocked_threads, queue_ptr );
     383                info.listed = true;
     384                count++;
     385
     386                size_t recursion_count;
     387                if (info.lock) {
     388                        recursion_count = get_recursion_count(*info.lock);
     389                        remove_( *info.lock );
     390                }
     391
    283392                unlock( lock );
    284393                park();
    285                 unregister_self( &node_wrap.alarm_node );
     394
    286395                if (info.lock) set_recursion_count(*info.lock, recursion_count);
    287396        }
     
    353462        }
    354463}
     464
     465// thread T1 {};
     466// thread T2 {};
     467
     468// multiple_acquisition_lock m;
     469// condition_variable( multiple_acquisition_lock ) c;
     470
     471// void main( T1 & this ) {
     472//      printf("T1 start\n");
     473//      lock(m);
     474//      printf("%d\n", counter(c));
     475//      if(empty(c)) {
     476//              printf("T1 wait\n");
     477//              wait(c,m,12);
     478//      }else{
     479//              printf("%d\n", front(c));
     480//              notify_one(c);
     481//      }
     482//      unlock(m);
     483//      printf("curr thd in main %p \n", active_thread());
     484//      printf("T1 waits for 2s\n");
     485//      lock(m);
     486//      wait( c, m, 2`s );
     487//      unlock(m);
     488//      printf("T1 wakes\n");
     489//      printf("T1 done\n");
     490// }
     491
     492// void main( T2 & this ) {
     493//      printf("T2 start\n");
     494//      lock(m);
     495//      printf("%d\n", counter(c));
     496//      if(empty(c)) {
     497//              printf("T2 wait\n");
     498//              wait(c,m,12);
     499//      }else{
     500//              printf("%d\n", front(c));
     501//              notify_one(c);
     502//      }
     503//      unlock(m);
     504//      printf("T2 done\n");
     505// }
     506
     507// int main() {
     508//      printf("start\n");
     509//      processor p[2];
     510//      {
     511//              T1 t1;
     512//              T2 t2;
     513//      }
     514//      printf("done\n");
     515// }
  • libcfa/src/concurrency/locks.hfa

    r7b2a786 ra5a67ab8  
    55#include "bits/algorithm.hfa"
    66#include "bits/locks.hfa"
    7 #include "bits/sequence.hfa"
    87#include "bits/containers.hfa"
    98
     
    3231forall(dtype L | is_blocking_lock(L)) {
    3332        struct info_thread {
    34                 inline Seqable;
    3533                struct $thread * t;
    3634                uintptr_t info;
     35                info_thread(L) * next;
    3736                L * lock;
    3837                bool listed;                                    // true if info_thread is on queue, false otherwise;
     
    4342        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
    4443        void ^?{}( info_thread(L) & this );
     44
     45        info_thread(L) *& get_next( info_thread(L) & this );
    4546}
    4647
     
    4950///////////////////////////////////////////////////////////////////
    5051
    51 // struct lock_thread {
    52 //      struct $thread * t;
    53 //      lock_thread * next;
    54 // };
    55 
    56 // void ?{}( lock_thread & this, struct $thread * thd );
    57 // void ^?{}( lock_thread & this );
    58 
    59 // lock_thread *& get_next( lock_thread & );
    60 
    6152struct blocking_lock {
    6253        // Spin lock used for mutual exclusion
     
    6455
    6556        // List of blocked threads
    66         __queue_t( $thread ) blocked_threads;
     57        __queue_t( struct $thread ) blocked_threads;
    6758
    6859        // Count of current blocked threads
     
    144135                __spinlock_t lock;
    145136
    146                 info_thread(L) * last_thread;
    147 
    148137                // List of blocked threads
    149                 Sequence( info_thread(L) ) blocked_threads;
     138                __queue_t( info_thread(L) ) blocked_threads;
    150139
    151140                // Count of current blocked threads
     
    161150                condition_variable(L) * cond;
    162151
    163                 info_thread(L) * i;
     152                info_thread(L) ** i;
    164153        };
    165154
    166         void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );
     155        void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
    167156        void ^?{}( alarm_node_wrap(L) & this );
    168157
Note: See TracChangeset for help on using the changeset viewer.