Changeset 54f89d5


Ignore:
Timestamp:
Dec 4, 2020, 11:39:23 AM (10 months ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
3c6480b7
Parents:
ab0257b9 (diff), a32cbac2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
3 added
24 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    rab0257b9 r54f89d5  
    22
    33import groovy.transform.Field
    4 
    5 // For skipping stages
    6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils
    74
    85//===========================================================================================================
     
    1512        SrcDir    = pwd tmp: false
    1613        Settings  = null
    17         StageName = ''
     14        Tools     = null
    1815
    1916        // Local variables
     
    6663
    6764                //Store the result of the build log
    68                 currentBuild.result = "${StageName} FAILURE".trim()
     65                currentBuild.result = "${tools.StageName} FAILURE".trim()
    6966        }
    7067
     
    8582//===========================================================================================================
    8683def clean() {
    87         build_stage('Cleanup', true) {
     84        Tools.BuildStage('Cleanup', true) {
    8885                // clean the build by wipping the build directory
    8986                dir(BuildDir) {
     
    9592//Compilation script is done here but environnement set-up and error handling is done in main loop
    9693def checkout() {
    97         build_stage('Checkout', true) {
     94        Tools.BuildStage('Checkout', true) {
    9895                //checkout the source code and clean the repo
    9996                final scmVars = checkout scm
     
    108105        debug = true
    109106        release = Settings.RunAllTests || Settings.RunBenchmark
    110         build_stage('Build : configure', true) {
     107        Tools.BuildStage('Build : configure', true) {
    111108                // Configure must be run inside the tree
    112109                dir (SrcDir) {
     
    136133        }
    137134
    138         build_stage('Build : cfa-cpp', true) {
     135        Tools.BuildStage('Build : cfa-cpp', true) {
    139136                // Build outside of the src tree to ease cleaning
    140137                dir (BuildDir) {
     
    147144        }
    148145
    149         build_stage('Build : libcfa(debug)', debug) {
     146        Tools.BuildStage('Build : libcfa(debug)', debug) {
    150147                // Build outside of the src tree to ease cleaning
    151148                dir (BuildDir) {
     
    154151        }
    155152
    156         build_stage('Build : libcfa(nodebug)', release) {
     153        Tools.BuildStage('Build : libcfa(nodebug)', release) {
    157154                // Build outside of the src tree to ease cleaning
    158155                dir (BuildDir) {
     
    161158        }
    162159
    163         build_stage('Build : install', true) {
     160        Tools.BuildStage('Build : install', true) {
    164161                // Build outside of the src tree to ease cleaning
    165162                dir (BuildDir) {
     
    171168def test() {
    172169        try {
    173                 build_stage('Test: short', !Settings.RunAllTests) {
     170                Tools.BuildStage('Test: short', !Settings.RunAllTests) {
    174171                        dir (BuildDir) {
    175172                                //Run the tests from the tests directory
     
    178175                }
    179176
    180                 build_stage('Test: full', Settings.RunAllTests) {
     177                Tools.BuildStage('Test: full', Settings.RunAllTests) {
    181178                        dir (BuildDir) {
    182179                                        //Run the tests from the tests directory
     
    196193
    197194def benchmark() {
    198         build_stage('Benchmark', Settings.RunBenchmark) {
     195        Tools.BuildStage('Benchmark', Settings.RunBenchmark) {
    199196                dir (BuildDir) {
    200197                        //Append bench results
     
    205202
    206203def build_doc() {
    207         build_stage('Documentation', Settings.BuildDocumentation) {
     204        Tools.BuildStage('Documentation', Settings.BuildDocumentation) {
    208205                dir ('doc/user') {
    209206                        make_doc()
     
    217214
    218215def publish() {
    219         build_stage('Publish', true) {
     216        Tools.BuildStage('Publish', true) {
    220217
    221218                if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' }
     
    506503                ]])
    507504
    508         // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
     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
    509508        checkout scm
     509
     510        Tools = load "Jenkins/tools.groovy"
    510511
    511512        final settings = new BuildSettings(params, env.BRANCH_NAME)
     
    515516
    516517        return settings
    517 }
    518 
    519 def 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         }
    527518}
    528519
  • example/io/simple/server.cfa

    rab0257b9 r54f89d5  
    1313#include <time.hfa>
    1414#include <thread.hfa>
     15#include <concurrency/iofwd.hfa>
    1516
    1617//----------
     
    2122}
    2223
    23 void message( Printer & mutex, char * msg, size_t len ) {
    24         fprintf(stderr, "'%.*s'", len, msg);
     24void message( Printer & mutex, char * _msg, size_t len ) {
     25        fprintf(stderr, "'%.*s'", len, _msg);
    2526}
    2627
     
    2930}
    3031
    31 void error( Printer & mutex, const char * msg, int error) {
    32         fprintf(stderr, "%s - %s\n", msg, strerror(error));
     32void error( Printer & mutex, const char * _msg, int error) {
     33        fprintf(stderr, "%s - %s\n", _msg, strerror(error));
    3334}
    3435
     
    4950        }
    5051}
    51 
    52 //----------
    53 extern ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags);
    54 extern int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
    55 extern int cfa_close(int fd);
    5652
    5753//----------
     
    8884        struct sockaddr_in cli_addr;
    8985        __socklen_t clilen = sizeof(cli_addr);
    90         int newsock = cfa_accept4(sock, (struct sockaddr *) &cli_addr, &clilen, 0);
     86        int newsock = cfa_accept4(sock, (struct sockaddr *) &cli_addr, &clilen, 0, 0, -1`s, 0p, 0p);
    9187        if (newsock < 0) {
    9288                error( printer, "accept", -newsock);
     
    9793
    9894        while(1) {
    99                 int res = cfa_recvmsg(newsock, &msg, 0);
     95                int res = cfa_recvmsg(newsock, &msg, 0, 0, -1`s, 0p, 0p);
    10096                if(res == 0) break;
    10197                if(res < 0) {
     
    107103        }
    108104
    109         ret = cfa_close(newsock);
     105        ret = cfa_close(newsock, 0, -1`s, 0p, 0p);
    110106      if(ret < 0) {
    111107            error( printer, "close new", -ret);
     
    113109      }
    114110
    115         ret = cfa_close(sock);
     111        ret = cfa_close(sock, 0, -1`s, 0p, 0p);
    116112      if(ret < 0) {
    117113            error( printer, "close old", -ret);
  • libcfa/src/bits/containers.hfa

    rab0257b9 r54f89d5  
    1717#include "bits/align.hfa"
    1818#include "bits/defs.hfa"
    19 
     19#include <stdio.h>
    2020//-----------------------------------------------------------------------------
    2121// Array
     
    146146        static inline forall( dtype T | is_node(T) ) {
    147147                void ?{}( __queue(T) & this ) with( this ) {
    148                         head{ 1p };
    149                         tail{ &head };
    150                         verify(*tail == 1p);
     148                        (this.head){ 1p };
     149                        (this.tail){ &this.head };
     150                        verify(*this.tail == 1p);
    151151                }
    152152
    153153                void append( __queue(T) & this, T * val ) with( this ) {
    154                         verify(tail != 0p);
    155                         verify(*tail == 1p);
    156                         *tail = val;
    157                         tail = &get_next( *val );
    158                         *tail = 1p;
     154                        verify(this.tail != 0p);
     155                        verify(*this.tail == 1p);
     156                        *this.tail = val;
     157                        this.tail = &get_next( *val );
     158                        *this.tail = 1p;
    159159                }
    160160
    161161                T * peek( __queue(T) & this ) {
    162162                        verify(*this.tail == 1p);
    163                         T * head = this.head;
    164                         if( head != 1p ) {
     163                        T * front = this.head;
     164                        if( front != 1p ) {
    165165                                verify(*this.tail == 1p);
    166                                 return head;
     166                                return front;
    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( tail == &get_next( *val ) ) {
    196                                 tail = it;
     195                        if( this.tail == &get_next( *val ) ) {
     196                                this.tail = it;
    197197                        }
    198198
    199199                        get_next( *val ) = 0p;
    200200
    201                         verify( (head == 1p) == (&head == tail) );
    202                         verify( *tail == 1p );
     201                        verify( (this.head == 1p) == (&this.head == this.tail) );
     202                        verify( *this.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 ( head ) {
    251                                 __get( node ).next = head;
    252                                 __get( node ).prev = __get( *head ).prev;
     250                        if ( this.head ) {
     251                                __get( node ).next = this.head;
     252                                __get( node ).prev = __get( *this.head ).prev;
    253253                                // inserted node must be consistent before it is seen
    254254                                // prevent code movement across barrier
    255255                                asm( "" : : : "memory" );
    256                                 __get( *head ).prev = &node;
     256                                __get( *this.head ).prev = &node;
    257257                                T & _prev = *__get( node ).prev;
    258258                                __get( _prev ).next = &node;
     
    264264                        // prevent code movement across barrier
    265265                        asm( "" : : : "memory" );
    266                         head = &node;
     266                        this.head = &node;
    267267                }
    268268
    269269                void remove( __dllist(T) & this, T & node ) with( this ) {
    270270                        verify(__get);
    271                         if ( &node == head ) {
    272                                 if ( __get( *head ).next == head ) {
    273                                         head = 0p;
     271                        if ( &node == this.head ) {
     272                                if ( __get( *this.head ).next == this.head ) {
     273                                        this.head = 0p;
    274274                                } else {
    275                                         head = __get( *head ).next;
     275                                        this.head = __get( *this.head ).next;
    276276                                }
    277277                        }
  • libcfa/src/bits/queue.hfa

    rab0257b9 r54f89d5  
    1111        inline {
    1212                // wrappers to make Collection have T
    13                 T * head( Queue(T) & q ) with( q ) {
    14                         return (T *)head( (Collection &)q );
     13                T & head( Queue(T) & q ) with( q ) {
     14                        return *(T *)head( (Collection &)q );
    1515                } // post: empty() & head() == 0 | !empty() & head() in *q
    1616
     
    2323                } // post: empty()
    2424
    25                 T * tail( Queue(T) & q ) with( q ) {
    26                         return last;
     25                T & tail( Queue(T) & q ) with( q ) {
     26                        return *last;
    2727                }
    2828
     
    3434                } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *q
    3535
    36                 void addHead( Queue(T) & q, T * n ) with( q ) {
     36                void addHead( Queue(T) & q, T & n ) with( q ) {
    3737#ifdef __CFA_DEBUG__
    38                         if ( listed( n ) ) abort( "(Queue &)%p.addHead( %p ) : Node is already on another list.", &q, n );
     38                        if ( listed( &n ) ) abort( "(Queue &)%p.addHead( %p ) : Node is already on another list.", &q, &n );
    3939#endif // __CFA_DEBUG__
    4040                        if ( last ) {
    41                                 Next( n ) = head( q );
    42                                 q.root = n;
     41                                Next( &n ) = &head( q );
     42                                q.root = &n;
    4343                        } else {
    44                                 root = last = n;
    45                                 Next( n ) = n;                                                  // last node points to itself
     44                                root = last = &n;
     45                                Next( &n ) = &n;                                                        // last node points to itself
    4646                        }
    4747                }
    4848
    49                 void addTail( Queue(T) & q, T * n ) with( q ) {
     49                void addTail( Queue(T) & q, T & n ) with( q ) {
    5050#ifdef __CFA_DEBUG__
    51                         if ( listed( n ) ) abort( "(Queue &)%p.addTail( %p ) : Node is already on another list.", &q, n );
     51                        if ( listed( &n ) ) abort( "(Queue &)%p.addTail( %p ) : Node is already on another list.", &q, &n );
    5252#endif // __CFA_DEBUG__
    53                         if ( last ) Next( last ) = n;
    54                         else root = n;
    55                         last = n;
    56                         Next( n ) = n;                                                          // last node points to itself
     53                        if ( last ) Next( last ) = &n;
     54                        else root = &n;
     55                        last = &n;
     56                        Next( &n ) = &n;                                                                // last node points to itself
    5757                }
    5858
    59                 void add( Queue(T) & q, T * n ) with( q ) {
     59                void add( Queue(T) & q, T & n ) with( q ) {
    6060                        addTail( q, n );
    6161                }
    6262
    63                 T * dropHead( Queue(T) & q ) with( q ) {
    64                         T * t = head( q );
     63                T & dropHead( Queue(T) & q ) with( q ) {
     64                        T & t = head( q );
    6565                        if ( root ) {
    6666                                root = Next( root );
    67                                 if ( head( q ) == t ) {
     67                                if ( &head( q ) == &t ) {
    6868                                        root = last = 0p;                                       // only one element
    6969                                }
    70                                 Next( t ) = 0p;
     70                                Next( &t ) = 0p;
    7171                        }
    7272                        return t;
    7373                }
    7474
    75                 T * drop( Queue(T) & q ) with( q ) {
     75                T & drop( Queue(T) & q ) with( q ) {
    7676                        return dropHead( q );
    7777                }
    7878
    79                 void remove( Queue(T) & q, T * n ) with( q ) {  // O(n)
     79                void remove( Queue(T) & q, T & n ) with( q ) {  // O(n)
    8080#ifdef __CFA_DEBUG__
    81                         if ( ! listed( (Colable &)(*n) ) ) abort( "(Queue &)%p.remove( %p ) : Node is not on a list.", &q, n );
     81                        if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.remove( %p ) : Node is not on a list.", &q, &n );
    8282#endif // __CFA_DEBUG__
    83                         T * prev = 0;
     83                        T * prev = 0p;
    8484                        T * curr = (T *)root;
    8585                        for ( ;; ) {
    86                                 if (n == curr) {                                                // found => remove
    87                                         if ((T *)root == n) {
     86                                if ( &n == curr ) {                                             // found => remove
     87                                        if ( (T *)root == &n ) {
    8888                                                dropHead( q );
    89                                         } else if (last == n) {
     89                                        } else if ( last == &n ) {
    9090                                                last = prev;
    9191                                                Next( last ) = last;
     
    9393                                                Next( prev ) = Next( curr );
    9494                                        }
    95                                         Next( n ) = 0p;
     95                                        Next( &n ) = 0p;
    9696                                        break;
    9797                                }
    9898#ifdef __CFA_DEBUG__
    9999                                // not found => error
    100                                 if (curr == last) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, n );
     100                                if (curr == last) abort( "(Queue &)%p.remove( %p ) : Node is not in list.", &q, &n );
    101101#endif // __CFA_DEBUG__
    102102                                prev = curr;
     
    105105                } // post: ! listed( n )
    106106
    107                 T * dropTail( Queue(T) & q ) with( q ) { // O(n)
    108                         T * n = tail( q );
    109                         return n ? remove( q, n ), n : 0p;
     107                T & dropTail( Queue(T) & q ) with( q ) { // O(n)
     108                        T & n = tail( q );
     109                        return &n ? remove( q, n ), n : *0p;
    110110                }
    111111
     
    116116                                root = from.root;
    117117                        } else {                                                                        // "to" list not empty
    118                                 Next( last ) = head( from );
     118                                Next( last ) = &head( from );
    119119                        }
    120120                        last = from.last;
     
    124124                // Transfer the "from" list up to node "n" to the end of queue list; the "from" list becomes the list after node "n".
    125125                // Node "n" must be in the "from" list.
    126                 void split( Queue(T) & q, Queue(T) & from, T * n ) with( q ) {
     126                void split( Queue(T) & q, Queue(T) & from, T & n ) with( q ) {
    127127#ifdef __CFA_DEBUG__
    128                         if ( ! listed( (Colable &)(*n) ) ) abort( "(Queue &)%p.split( %p ) : Node is not on a list.", &q, n );
     128                        if ( ! listed( (Colable &)n ) ) abort( "(Queue &)%p.split( %p ) : Node is not on a list.", &q, &n );
    129129#endif // __CFA_DEBUG__
    130130                        Queue(T) to;
    131131                        to.root = from.root;                                            // start of "to" list
    132                         to.last = n;                                                            // end of "to" list
    133                         from.root = Next( n );                                          // start of "from" list
    134                         if ( n == head( from ) ) {                                      // last node in list ?
     132                        to.last = &n;                                                           // end of "to" list
     133                        from.root = Next( &n );                                         // start of "from" list
     134                        if ( &n == &head( from ) ) {                            // last node in list ?
    135135                                from.root = from.last = 0p;                             // mark "from" list empty
    136136                        } else {
    137                                 Next( n ) = n;                                                  // fix end of "to" list
     137                                Next( &n ) = &n;                                                // fix end of "to" list
    138138                        }
    139139                        transfer( q, to );
     
    154154                // create an iterator active in Queue q
    155155                void ?{}( QueueIter(T) & qi, Queue(T) & q ) with( qi ) {
    156                         curr = head( q );
     156                        curr = &head( q );
    157157                } // post: curr = {e in q}
    158158
    159                 void ?{}( QueueIter(T) & qi, T * start ) with( qi ) {
    160                         curr = start;
     159                void ?{}( QueueIter(T) & qi, T & start ) with( qi ) {
     160                        curr = &start;
    161161                } // post: curr = {e in q}
    162162
    163163                // make existing iterator active in Queue q
    164164                void over( QueueIter(T) & qi, Queue(T) & q ) with( qi ) {
    165                         curr = head( q );
     165                        curr = &head( q );
    166166                } // post: curr = {e in q}
    167167
     
    179179
    180180// Local Variables: //
    181 // compile-command: "make install" //
     181// compile-command: "cfa queue.cfa" //
    182182// End: //
  • libcfa/src/bits/queue_example.cfa

    rab0257b9 r54f89d5  
    2727       
    2828        for ( i; 10 ) {
    29                 add( fred, new( 2 * i ) );
     29                add( fred, *new( 2 * i ) );
    3030        }
    3131
     
    3636
    3737        for ( i; 9 ) {
    38                 delete( drop( fred ) );
     38                delete( &drop( fred ) );
    3939        }
    4040
     
    4545       
    4646        for ( i; 10 ) {
    47                 add( fred, new( 2 * i + 1 ) );
     47                add( fred, *new( 2 * i + 1 ) );
    4848        }
    4949        for ( over( fredIter, fred ); fredIter >> f; ) {
     
    7878       
    7979        for ( i; 10 ) {
    80                 add( mary, new( 2 * i ) );
     80                add( mary, *new( 2 * i ) );
    8181        }
    8282
     
    8787       
    8888        for ( i; 9 ) {
    89                 delete( drop( mary ) );
     89                delete( &drop( mary ) );
    9090        }
    9191
     
    9696       
    9797        for ( i; 10 ) {
    98                 add( mary, new( 2 * i + 1 ) );
     98                add( mary, *new( 2 * i + 1 ) );
    9999        }
    100100        for ( over( maryIter, mary ); maryIter >> m; ) {
  • libcfa/src/bits/sequence.hfa

    rab0257b9 r54f89d5  
    1414        } // post: ! listed()
    1515
    16         Seqable * getBack( Seqable & sq ) with( sq ) {
    17                 return back;
     16        Seqable & getBack( Seqable & sq ) with( sq ) {
     17                return *back;
    1818        }
    1919
     
    3030        inline {
    3131                // wrappers to make Collection have T
    32                 T * head( Sequence(T) & s ) with( s ) {
    33                         return (T *)head( (Collection &)s );
     32                T & head( Sequence(T) & s ) with( s ) {
     33                        return *(T *)head( (Collection &)s );
    3434                } // post: empty() & head() == 0 | !empty() & head() in *s
    3535
     
    4747                // Return a pointer to the last sequence element, without removing it. 
    4848                T & tail( Sequence(T) & s ) with( s ) {
    49                         return root ? (T &)Back( head( s ) ) : *0p;     // needs cast?
     49                        return root ? (T &)*Back( &head( s ) ) : *0p;
    5050                }       // post: empty() & tail() == 0 | !empty() & tail() in *s
    5151
     
    5555                        if ( ! listed( n ) ) abort( "(Sequence &)%p.succ( %p ) : Node is not on a list.", &s, n );
    5656#endif // __CFA_DEBUG__
    57                         return Next( n ) == head( s ) ? 0p : Next( n );
    58                 }       // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
     57                        return Next( n ) == &head( s ) ? 0p : Next( n );
     58                } // post: n == tail() & succ(n) == 0 | n != tail() & *succ(n) in *s
    5959
    6060                // Return a pointer to the element before *n, or 0p if there isn't one.
     
    6363                        if ( ! listed( n ) ) abort( "(Sequence &)%p.pred( %p ) : Node is not on a list.", &s, n );
    6464#endif // __CFA_DEBUG__
    65                         return n == head( s ) ? 0p : Back( n );
     65                        return n == &head( s ) ? 0p : Back( n );
    6666                }       // post: n == head() & head(n) == 0 | n != head() & *pred(n) in *s
    6767
     
    7272                        if ( listed( &n ) ) abort( "(Sequence &)%p.insertBef( %p, %p ) : Node is already on another list.", &s, n, &bef );
    7373#endif // __CFA_DEBUG__
    74                         if ( &bef == head( s ) ) {                                      // must change root
     74                        if ( &bef == &head( s ) ) {                                     // must change root
    7575                                if ( root ) {
    76                                         Next( &n ) = head( s );
    77                                         Back( &n ) = Back( head( s ) );
     76                                        Next( &n ) = &head( s );
     77                                        Back( &n ) = Back( &head( s ) );
    7878                                        // inserted node must be consistent before it is seen
    7979                                        asm( "" : : : "memory" );                       // prevent code movement across barrier
    80                                         Back( head( s ) ) = &n;
     80                                        Back( &head( s ) ) = &n;
    8181                                        Next( Back( &n ) ) = &n;
    8282                                } else {
     
    8888                                root = &n;
    8989                        } else {
    90                                 if ( ! &bef ) &bef = head( s );
     90                                if ( ! &bef ) &bef = &head( s );
    9191                                Next( &n ) = &bef;
    9292                                Back( &n ) = Back( &bef );
     
    106106                        if ( ! &aft ) {                                                         // must change root
    107107                                if ( root ) {
    108                                         Next( &n ) = head( s );
    109                                         Back( &n ) = Back( head( s ) );
     108                                        Next( &n ) = &head( s );
     109                                        Back( &n ) = Back( &head( s ) );
    110110                                        // inserted node must be consistent before it is seen
    111111                                        asm( "" : : : "memory" );                       // prevent code movement across barrier
    112                                         Back( head( s ) ) = &n;
     112                                        Back( &head( s ) ) = &n;
    113113                                        Next( Back( &n ) ) = &n;
    114114                                } else {
     
    133133                        if ( ! listed( &n ) ) abort( "(Sequence &)%p.remove( %p ) : Node is not on a list.", &s, &n );
    134134#endif // __CFA_DEBUG__
    135                         if ( &n == head( s ) ) {
    136                                 if ( Next( head( s ) ) == head( s ) ) root = 0p;
    137                                 else root = Next( head(s ) );
     135                        if ( &n == &head( s ) ) {
     136                                if ( Next( &head( s ) ) == &head( s ) ) root = 0p;
     137                                else root = Next( &head( s ) );
    138138                        } // if
    139139                        Back( Next( &n ) ) = Back( &n );
     
    156156                // Remove and return the head element in the sequence.
    157157                T & dropHead( Sequence(T) & s ) {
    158                         T * n = head( s );
    159                         return n ? remove( s, *n ), *n : *0p;
     158                        T & n = head( s );
     159                        return &n ? remove( s, n ), n : *0p;
    160160                }
    161161                // Remove and return the head element in the sequence.
     
    175175                                root = from.root;
    176176                        } else {                                                                        // "to" list not empty
    177                                 T * toEnd = Back( head( s ) );
    178                                 T * fromEnd = Back( head( from ) );
     177                                T * toEnd = Back( &head( s ) );
     178                                T * fromEnd = Back( &head( from ) );
    179179                                Back( root ) = fromEnd;
    180                                 Next( fromEnd ) = head( s );
     180                                Next( fromEnd ) = &head( s );
    181181                                Back( from.root ) = toEnd;
    182                                 Next( toEnd ) = head( from );
     182                                Next( toEnd ) = &head( from );
    183183                        } // if
    184184                        from.root = 0p;                                                         // mark "from" list empty
     
    187187                // Transfer the "from" list up to node "n" to the end of s list; the "from" list becomes the sequence after node "n".
    188188                // Node "n" must be in the "from" list.
    189                 void split( Sequence(T) & s, Sequence(T) & from, T * n ) with( s ) {
    190 #ifdef __CFA_DEBUG__
    191                         if ( ! listed( n ) ) abort( "(Sequence &)%p.split( %p ) : Node is not on a list.", &s, n );
     189                void split( Sequence(T) & s, Sequence(T) & from, T & n ) with( s ) {
     190#ifdef __CFA_DEBUG__
     191                        if ( ! listed( &n ) ) abort( "(Sequence &)%p.split( %p ) : Node is not on a list.", &s, &n );
    192192#endif // __CFA_DEBUG__
    193193                        Sequence(T) to;
    194194                        to.root = from.root;                                            // start of "to" list
    195                         from.root = Next( n );                                          // start of "from" list
     195                        from.root = Next( &n );                                         // start of "from" list
    196196                        if ( to.root == from.root ) {                           // last node in list ?
    197197                                from.root = 0p;                                                 // mark "from" list empty
    198198                        } else {
    199                                 Back( head( from ) ) = Back( head( to ) ); // fix "from" list
    200                                 Next( Back( head( to ) ) ) = head( from );
    201                                 Next( n ) = head( to );                                 // fix "to" list
    202                                 Back( head( to ) ) = n;
     199                                Back( &head( from ) ) = Back( &head( to ) ); // fix "from" list
     200                                Next( Back( &head( to ) ) ) = &head( from );
     201                                Next( &n ) = &head( to );                                       // fix "to" list
     202                                Back( &head( to ) ) = &n;
    203203                        } // if
    204204                        transfer( s, to );
     
    211211        struct SeqIter {
    212212                inline ColIter;
     213                // The Sequence must be passed to pred and succ to check for the end of the Sequence and return 0p. Without
     214                // passing the sequence, traversing would require its length. Thus the iterator needs a pointer to the sequence
     215                // to pass to succ/pred. Both stack and queue just encounter 0p since the lists are not circular.
    213216                Sequence(T) * seq;
    214217        };
     
    223226                        ((ColIter &) si){};
    224227                        seq = &s;
    225                         curr = head( s );
    226                 } // post: elts = null.
    227                
     228                        curr = &head( s );
     229                } // post: elts = null.
     230
     231                void ?{}( SeqIter(T) & si, Sequence(T) & s, T & start ) with( si ) {
     232                        ((ColIter &) si){};
     233                        seq = &s;
     234                        curr = &start;
     235                } // post: elts = null.
     236
    228237                void over( SeqIter(T) & si, Sequence(T) & s ) with( si ) {
    229238                        seq = &s;
    230                         curr = head( s );
     239                        curr = &head( s );
    231240                } // post: elts = {e in s}.
    232241
     
    235244                                &tp = Curr( si );
    236245                                T * n = succ( *seq, Curr( si ) );
    237                                 curr = n == head( *seq ) ? 0p : n;
     246                                curr = n == &head( *seq ) ? 0p : n;
    238247                        } else &tp = 0p;
    239248                        return &tp != 0p;
     
    245254        struct SeqIterRev {
    246255                inline ColIter;
     256                // See above for explanation.
    247257                Sequence(T) * seq;
    248258        };
     
    259269                        curr = &tail( s );
    260270                } // post: elts = null.
    261                
     271
     272                void ?{}( SeqIterRev(T) & si, Sequence(T) & s, T & start ) with( si ) {
     273                        ((ColIter &) si){};
     274                        seq = &s;
     275                        curr = &start;
     276                } // post: elts = null.
     277
    262278                void over( SeqIterRev(T) & si, Sequence(T) & s ) with( si ) {
    263279                        seq = &s;
     
    277293
    278294// Local Variables: //
    279 // compile-command: "make install" //
     295// compile-command: "cfa sequence.hfa" //
    280296// End: //
  • libcfa/src/bits/stack.hfa

    rab0257b9 r54f89d5  
    1010        inline {
    1111                // wrappers to make Collection have T
    12                 T * head( Stack(T) & s ) with( s ) {
    13                         return (T *)head( (Collection &)s );
     12                T & head( Stack(T) & s ) with( s ) {
     13                        return *(T *)head( (Collection &)s );
    1414                } // post: empty() & head() == 0 | !empty() & head() in *this
    1515
     
    2222
    2323                T & top( Stack(T) & s ) with( s ) {
    24                         return *head( s );
     24                        return head( s );
    2525                }
    2626
     
    2929                        if ( listed( (Colable &)(n) ) ) abort( "(Stack &)%p.addHead( %p ) : Node is already on another list.", &s, n );
    3030#endif // __CFA_DEBUG__
    31                         Next( &n ) = head( s ) ? head( s ) : &n;
     31                        Next( &n ) = &head( s ) ? &head( s ) : &n;
    3232                        root = &n;
    3333                }
     
    4242
    4343                T & drop( Stack(T) & s ) with( s ) {
    44                         T & t = *head( s );
     44                        T & t = head( s );
    4545                        if ( root ) {
    4646                                root = ( T *)Next(root);
    47                                 if ( head( s ) == &t ) root = 0p;               // only one element ?
     47                                if ( &head( s ) == &t ) root = 0p;              // only one element ?
    4848                                Next( &t ) = 0p;
    4949                        } // if
     
    7070                // create an iterator active in Stack s
    7171                void ?{}( StackIter(T) & si, Stack(T) & s ) with( si ) {
    72                         curr = head( s );
     72                        curr = &head( s );
    7373                } // post: curr = {e in s}
    7474
     
    7979                // make existing iterator active in Stack q
    8080                void over( StackIter(T) & si, Stack(T) & s ) with( si ) {
    81                         curr = head( s );
     81                        curr = &head( s );
    8282                } // post: curr = {e in s}
    8383
  • libcfa/src/concurrency/alarm.cfa

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

    rab0257b9 r54f89d5  
    5252
    5353        union {
    54                 $thread * thrd; // thrd who created event
    55                 processor * proc;               // proc who created event
     54                $thread * thrd;                                 // thrd who created event
     55                processor * proc;                               // proc who created event
     56                Alarm_Callback callback;                // callback to handle event
    5657        };
    57 
    58         Alarm_Callback callback;
    5958
    6059        bool set                :1;             // whether or not the alarm has be registered
     
    6564void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period );
    6665void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
    67 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
     66void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period );
    6867void ^?{}( alarm_node_t & this );
    6968
  • libcfa/src/concurrency/io.cfa

    rab0257b9 r54f89d5  
    160160        static inline void process(struct io_uring_cqe & cqe ) {
    161161                struct io_future_t * future = (struct io_future_t *)(uintptr_t)cqe.user_data;
    162                 __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", future, cqe.res, data->thrd );
     162                __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", &cqe, cqe.res, future );
    163163
    164164                fulfil( *future, cqe.res );
     
    298298                __u32 mask = *ring.submit_q.mask;
    299299
    300                 disable_interrupts();
    301                         __u32 off = __tls_rand();
    302                 enable_interrupts( __cfaabi_dbg_ctx );
     300                __u32 off = thread_rand();
    303301
    304302                // Loop around looking for an available spot
     
    344342                __u32 ready_mask = ring.submit_q.ready_cnt - 1;
    345343
    346                 disable_interrupts();
    347                         __u32 off = __tls_rand();
    348                 enable_interrupts( __cfaabi_dbg_ctx );
     344                __u32 off = thread_rand();
    349345
    350346                __u32 picked;
  • libcfa/src/concurrency/io/call.cfa.in

    rab0257b9 r54f89d5  
    8484
    8585                /* paranoid */ verifyf( cltr->io.ctxs, "default io contexts for cluster %p are missing\\n", cltr);
    86                 return &cltr->io.ctxs[ __tls_rand() % cltr->io.cnt ];
     86                return &cltr->io.ctxs[ thread_rand() % cltr->io.cnt ];
    8787        }
    8888#endif
  • libcfa/src/concurrency/kernel.cfa

    rab0257b9 r54f89d5  
    619619        lock( kernel_abort_lock __cfaabi_dbg_ctx2 );
    620620
     621        // disable interrupts, it no longer makes sense to try to interrupt this processor
     622        disable_interrupts();
     623
    621624        // first task to abort ?
    622625        if ( kernel_abort_called ) {                    // not first task to abort ?
  • libcfa/src/concurrency/kernel/fwd.hfa

    rab0257b9 r54f89d5  
    132132                }
    133133
     134                extern uint64_t thread_rand();
     135
    134136                //-----------------------------------------------------------------------
    135137                // Statics call at the end of each thread to register statistics
  • libcfa/src/concurrency/locks.cfa

    rab0257b9 r54f89d5  
    1111//// info_thread
    1212///////////////////////////////////////////////////////////////////
     13
    1314forall(dtype L | is_blocking_lock(L)) {
    1415        void ?{}( info_thread(L) & this, $thread * t ) {
     16                ((Seqable &) this){};
    1517                this.t = t;
    1618                this.lock = 0p;
     
    1921
    2022        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) {
     23                ((Seqable &) this){};
    2124                this.t = t;
    2225                this.info = info;
     
    2528        }
    2629
    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 }
     30        void ^?{}( info_thread(L) & this ){ }
     31}
     32
    3533///////////////////////////////////////////////////////////////////
    3634//// Blocking Locks
     
    4745}
    4846
    49 void ^?{}( blocking_lock & this ) {
    50         // default
    51 }
    52 
    53 void ?{}( single_acquisition_lock & this ) {
    54         ((blocking_lock &)this){ false, false };
    55 }
    56 
    57 void ^?{}( single_acquisition_lock & this ) {
    58         // default
    59 }
    60 
    61 void ?{}( owner_lock & this ) {
    62         ((blocking_lock &)this){ true, true };
    63 }
    64 
    65 void ^?{}( owner_lock & this ) {
    66         // default
    67 }
    68 
    69 void ?{}( multiple_acquisition_lock & this ) {
    70         ((blocking_lock &)this){ true, false };
    71 }
    72 
    73 void ^?{}( multiple_acquisition_lock & this ) {
    74         // default
    75 }
     47void ^?{}( blocking_lock & this ) {}
     48void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };}
     49void ^?{}( single_acquisition_lock & this ) {}
     50void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };}
     51void ^?{}( owner_lock & this ) {}
     52void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };}
     53void ^?{}( multiple_acquisition_lock & this ) {}
    7654
    7755void lock( blocking_lock & this ) with( this ) {
    7856        lock( lock __cfaabi_dbg_ctx2 );
    7957        if ( owner == active_thread() && !multi_acquisition) {
    80                 fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead
    81         exit(EXIT_FAILURE);
     58                abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock.");
    8259        } else if ( owner != 0p && owner != active_thread() ) {
    8360                append( blocked_threads, active_thread() );
     
    11087}
    11188
     89void 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
     97void 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
    112105void unlock( blocking_lock & this ) with( this ) {
    113106        lock( lock __cfaabi_dbg_ctx2 );
    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         }
     107        unlock_error_check( this );
    121108        recursion_count--;
    122109        if ( recursion_count == 0 ) {
    123                 $thread * thrd = pop_head( blocked_threads );
    124                 owner = thrd;
    125                 recursion_count = ( thrd ? 1 : 0 );
    126                 wait_count--;
    127                 unpark( thrd );
     110                pop_and_set_new_owner( this );
    128111        }
    129112        unlock( lock );
     
    133116        return wait_count;
    134117}
    135 
    136118
    137119void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) {
     
    152134                owner = t;
    153135                recursion_count = 1;
    154                 #if !defined( __CFA_NO_STATISTICS__ )
    155                         //kernelTLS.this_stats = t->curr_cluster->stats;
    156                 #endif
    157136                unpark( t );
    158137                unlock( lock );
     
    162141void remove_( blocking_lock & this ) with( this ) {
    163142    lock( lock __cfaabi_dbg_ctx2 );
    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         }
     143        unlock_error_check( this );
     144        pop_and_set_new_owner( this );
    175145        unlock( lock );
    176146}
     
    182152// This is temporary until an inheritance bug is fixed
    183153
    184 void lock( single_acquisition_lock & this ){
    185         lock( (blocking_lock &)this );
    186 }
    187 
    188 void unlock( single_acquisition_lock & this ){
    189         unlock( (blocking_lock &)this );
    190 }
    191 
    192 void add_( single_acquisition_lock & this, struct $thread * t ){
    193         add_( (blocking_lock &)this, t );
    194 }
    195 
    196 void remove_( single_acquisition_lock & this ){
    197         remove_( (blocking_lock &)this );
    198 }
    199 
    200 void set_recursion_count( single_acquisition_lock & this, size_t recursion ){
    201         set_recursion_count( (blocking_lock &)this, recursion );
    202 }
    203 
    204 size_t get_recursion_count( single_acquisition_lock & this ){
    205         return get_recursion_count( (blocking_lock &)this );
    206 }
    207 
    208 void lock( owner_lock & this ){
    209         lock( (blocking_lock &)this );
    210 }
    211 
    212 void unlock( owner_lock & this ){
    213         unlock( (blocking_lock &)this );
    214 }
    215 
    216 void add_( owner_lock & this, struct $thread * t ){
    217         add_( (blocking_lock &)this, t );
    218 }
    219 
    220 void remove_( owner_lock & this ){
    221         remove_( (blocking_lock &)this );
    222 }
    223 
    224 void set_recursion_count( owner_lock & this, size_t recursion ){
    225         set_recursion_count( (blocking_lock &)this, recursion );
    226 }
    227 
    228 size_t get_recursion_count( owner_lock & this ){
    229         return get_recursion_count( (blocking_lock &)this );
    230 }
    231 
    232 void lock( multiple_acquisition_lock & this ){
    233         lock( (blocking_lock &)this );
    234 }
    235 
    236 void unlock( multiple_acquisition_lock & this ){
    237         unlock( (blocking_lock &)this );
    238 }
    239 
    240 void add_( multiple_acquisition_lock & this, struct $thread * t ){
    241         add_( (blocking_lock &)this, t );
    242 }
    243 
    244 void remove_( multiple_acquisition_lock & this ){
    245         remove_( (blocking_lock &)this );
    246 }
    247 
    248 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){
    249         set_recursion_count( (blocking_lock &)this, recursion );
    250 }
    251 
    252 size_t get_recursion_count( multiple_acquisition_lock & this ){
    253         return get_recursion_count( (blocking_lock &)this );
    254 }
     154void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
     155void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
     156void add_( single_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
     157void remove_( single_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
     158void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     159size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     160
     161void lock( owner_lock & this ){ lock( (blocking_lock &)this ); }
     162void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); }
     163void add_( owner_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
     164void remove_( owner_lock & this ){ remove_( (blocking_lock &)this ); }
     165void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     166size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
     167
     168void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); }
     169void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); }
     170void add_( multiple_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); }
     171void remove_( multiple_acquisition_lock & this ){ remove_( (blocking_lock &)this ); }
     172void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); }
     173size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); }
    255174
    256175///////////////////////////////////////////////////////////////////
     
    263182        // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin.
    264183            lock( cond->lock __cfaabi_dbg_ctx2 );
    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)
     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)
    268188                        cond->count--;
    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 );
     189                        if( !i->lock ) {
     190                                unpark( i->t );
    274191                } else {
    275                         add_(*copy->lock, copy->t);                     // call lock's add_
     192                        add_(*i->lock, i->t);                   // call lock's add_
    276193                }
    277194            }
     
    279196        }
    280197
    281         void alarm_node_wrap_cast( alarm_node_t & a ) {
    282                 timeout_handler( (alarm_node_wrap(L) &)a );
    283         }
     198        void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); }
    284199
    285200        void ?{}( condition_variable(L) & this ){
     
    287202                this.blocked_threads{};
    288203                this.count = 0;
    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
     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;
     218                        count--;
     219                        if (popped.lock) {
     220                                add_(*popped.lock, popped.t);
     221                        } else {
     222                                unpark(popped.t);
     223                        }
     224                }
    301225        }
    302226
    303227        bool notify_one( condition_variable(L) & this ) with( this ) {
    304228                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;
    309                         count--;
    310                         if (popped->lock) {
    311                                 add_(*popped->lock, popped->t);
    312                         } else {
    313                                 unpark(popped->t);
    314                         }
    315                 }
     229                bool ret = !empty(blocked_threads);
     230                process_popped(this, dropHead( blocked_threads ));
    316231                unlock( lock );
    317232                return ret;
     
    320235        bool notify_all( condition_variable(L) & this ) with(this) {
    321236                lock( lock __cfaabi_dbg_ctx2 );
    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                         }
     237                bool ret = !empty(blocked_threads);
     238                while( !empty(blocked_threads) ) {
     239                        process_popped(this, dropHead( blocked_threads ));
    334240                }
    335241                unlock( lock );
     
    338244
    339245        uintptr_t front( condition_variable(L) & this ) with(this) {
    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
     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
    353267        void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) {
    354268                lock( lock __cfaabi_dbg_ctx2 );
    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                
     269                size_t recursion_count = queue_and_get_recursion(this, &i);
    364270                unlock( lock );
    365271                park( ); // blocks here
    366 
    367272                if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking
    368273        }
     
    371276        void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Time t ) with(this) {
    372277                lock( lock __cfaabi_dbg_ctx2 );
    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 };
     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 };
    377280                node_wrap.cond = &this;
    378                 node_wrap.i = &queue_ptr;
    379 
     281                node_wrap.i = &info;
    380282                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 
    392283                unlock( lock );
    393284                park();
    394 
     285                unregister_self( &node_wrap.alarm_node );
    395286                if (info.lock) set_recursion_count(*info.lock, recursion_count);
    396287        }
     
    462353        }
    463354}
    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

    rab0257b9 r54f89d5  
    55#include "bits/algorithm.hfa"
    66#include "bits/locks.hfa"
     7#include "bits/sequence.hfa"
    78#include "bits/containers.hfa"
    89
     
    3132forall(dtype L | is_blocking_lock(L)) {
    3233        struct info_thread {
     34                inline Seqable;
    3335                struct $thread * t;
    3436                uintptr_t info;
    35                 info_thread(L) * next;
    3637                L * lock;
    3738                bool listed;                                    // true if info_thread is on queue, false otherwise;
     
    4243        void ?{}( info_thread(L) & this, $thread * t, uintptr_t info );
    4344        void ^?{}( info_thread(L) & this );
    44 
    45         info_thread(L) *& get_next( info_thread(L) & this );
    4645}
    4746
     
    5049///////////////////////////////////////////////////////////////////
    5150
     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
    5261struct blocking_lock {
    5362        // Spin lock used for mutual exclusion
     
    5564
    5665        // List of blocked threads
    57         __queue_t( struct $thread ) blocked_threads;
     66        __queue_t( $thread ) blocked_threads;
    5867
    5968        // Count of current blocked threads
     
    135144                __spinlock_t lock;
    136145
     146                info_thread(L) * last_thread;
     147
    137148                // List of blocked threads
    138                 __queue_t( info_thread(L) ) blocked_threads;
     149                Sequence( info_thread(L) ) blocked_threads;
    139150
    140151                // Count of current blocked threads
     
    150161                condition_variable(L) * cond;
    151162
    152                 info_thread(L) ** i;
     163                info_thread(L) * i;
    153164        };
    154165
    155         void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback );
     166        void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );
    156167        void ^?{}( alarm_node_wrap(L) & this );
    157168
  • libcfa/src/concurrency/thread.cfa

    rab0257b9 r54f89d5  
    162162}
    163163
     164uint64_t thread_rand() {
     165        disable_interrupts();
     166        uint64_t ret = __tls_rand();
     167        enable_interrupts( __cfaabi_dbg_ctx );
     168        return ret;
     169}
     170
    164171// Local Variables: //
    165172// mode: c //
  • libcfa/src/interpose.cfa

    rab0257b9 r54f89d5  
    220220}
    221221
     222static volatile int __abort_stage = 0;
     223
    222224// Cannot forward va_list.
    223225void __abort( bool signalAbort, const char fmt[], va_list args ) {
    224         void * kernel_data = kernel_abort();                            // must be done here to lock down kernel
    225         int len;
    226 
    227         signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
    228 
    229         len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
    230         __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    231 
    232         assert( fmt );
    233         len = vsnprintf( abort_text, abort_text_size, fmt, args );
    234         __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
    235 
    236         if ( fmt[strlen( fmt ) - 1] != '\n' ) {                         // add optional newline if missing at the end of the format text
    237                 __cfaabi_bits_write( STDERR_FILENO, "\n", 1 );
    238         } // if
    239         kernel_abort_msg( kernel_data, abort_text, abort_text_size );
    240 
    241         __cfaabi_backtrace( signalAbort ? 4 : 2 );
    242 
    243         __cabi_libc.abort();                                                            // print stack trace in handler
     226        int stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     227
     228        // First stage: stop the cforall kernel and print
     229        if(stage == 1) {
     230                // increment stage
     231                stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     232
     233                // must be done here to lock down kernel
     234                void * kernel_data = kernel_abort();
     235                int len;
     236
     237                signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
     238
     239                len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
     240                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     241
     242                assert( fmt );
     243                len = vsnprintf( abort_text, abort_text_size, fmt, args );
     244                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     245
     246                // add optional newline if missing at the end of the format text
     247                if ( fmt[strlen( fmt ) - 1] != '\n' ) {
     248                        __cfaabi_bits_write( STDERR_FILENO, "\n", 1 );
     249                } // if
     250                kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     251        }
     252
     253        // Second stage: print the backtrace
     254        if(stage == 2) {
     255                // increment stage
     256                stage = __atomic_add_fetch( &__abort_stage, 1, __ATOMIC_SEQ_CST );
     257
     258                // print stack trace in handler
     259                __cfaabi_backtrace( signalAbort ? 4 : 2 );
     260        }
     261
     262        do {
     263                // Finally call abort
     264                __cabi_libc.abort();
     265
     266                // Loop so that we never return
     267        } while(true);
    244268}
    245269
  • src/ResolvExpr/AlternativeFinder.cc

    rab0257b9 r54f89d5  
    131131
    132132        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
    133                 Indenter indent = { indentAmt };
    134 
    135                 std::vector<int> idx;
    136                 idx.reserve(list.size());
    137                 for(int i = 0; i < list.size(); i++) { idx.push_back(i); }
    138 
    139                 std::sort(idx.begin(), idx.end(), [&list](int lhs_idx, int rhs_idx) -> bool {
    140                         const auto & lhs = list.at(lhs_idx);
    141                         const auto & rhs = list.at(rhs_idx);
    142                         if(lhs.expr->location.startsBefore(rhs.expr->location)) return true;
    143                         if(rhs.expr->location.startsBefore(lhs.expr->location)) return false;
    144 
    145                         if(lhs.env.size() < rhs.env.size()) return true;
    146                         if(lhs.env.size() > rhs.env.size()) return false;
    147 
    148                         if(lhs.openVars.size() < rhs.openVars.size()) return true;
    149                         if(lhs.openVars.size() > rhs.openVars.size()) return false;
    150 
    151                         if(lhs.need.size() < rhs.need.size()) return true;
    152                         if(lhs.need.size() > rhs.need.size()) return false;
    153 
    154                         return false;
    155                 });
    156 
    157                 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    158                         i->print( os, indent );
    159                         os << std::endl;
     133                std::vector<std::string> sorted;
     134                sorted.reserve(list.size());
     135                for(const auto & c : list) {
     136                        std::stringstream ss;
     137                        c.print( ss, indentAmt );
     138                        sorted.push_back(ss.str());
     139                }
     140
     141                std::sort(sorted.begin(), sorted.end());
     142
     143                for ( const auto & s : sorted ) {
     144                        os << s << std::endl;
    160145                }
    161146        }
  • src/ResolvExpr/Candidate.cpp

    rab0257b9 r54f89d5  
    4141
    4242void print( std::ostream & os, const CandidateList & cands, Indenter indent ) {
    43         for ( const CandidateRef & cand : cands ) {
    44                 print( os, *cand, indent );
    45                 os << std::endl;
     43        std::vector<std::string> sorted;
     44        sorted.reserve(cands.size());
     45        for(const auto & c : cands) {
     46                std::stringstream ss;
     47                print( ss, *c, indent );
     48                sorted.push_back(ss.str());
     49        }
     50
     51        std::sort(sorted.begin(), sorted.end());
     52
     53        for ( const auto & s : sorted ) {
     54                os << s << std::endl;
    4655        }
    4756}
  • tests/.expect/castError.nast.txt

    rab0257b9 r54f89d5  
    77  char Alternatives are:
    88Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    9       Variable Expression: f: signed int
     9      Variable Expression: f: double
    1010      ... with resolved type:
    11         signed int
     11        double
    1212    ... to:
    1313      char
     
    3939
    4040Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    41       Variable Expression: f: double
     41      Variable Expression: f: signed int
    4242      ... with resolved type:
    43         double
     43        signed int
    4444    ... to:
    4545      char
  • tests/.expect/castError.oast.txt

    rab0257b9 r54f89d5  
    66with resolved type:
    77  char Alternatives are:
     8Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
     9      Variable Expression: f: double
     10      with resolved type:
     11        double
     12    ... to:
     13      char
     14    with resolved type:
     15      char
     16  (types:
     17    char
     18  )
     19  Environment:
     20
    821Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    922      Variable Expression: f: function
     
    1629        ... returning nothing
    1730
    18     ... to:
    19       char
    20     with resolved type:
    21       char
    22   (types:
    23     char
    24   )
    25   Environment:
    26 
    27 Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    28       Variable Expression: f: double
    29       with resolved type:
    30         double
    3131    ... to:
    3232      char
     
    6767        with resolved type:
    6868          signed int
    69         Variable Expression: v: unsigned char
     69        Variable Expression: v: signed short int
    7070        with resolved type:
    71           unsigned char
     71          signed short int
    7272      with resolved type:
    73         unsigned char
     73        signed short int
    7474    ... to: nothing
    7575    with resolved type:
     
    8585        with resolved type:
    8686          signed int
    87         Variable Expression: v: signed short int
     87        Variable Expression: v: unsigned char
    8888        with resolved type:
    89           signed short int
     89          unsigned char
    9090      with resolved type:
    91         signed short int
     91        unsigned char
    9292    ... to: nothing
    9393    with resolved type:
  • tests/errors/.expect/completeType.nast.x64.txt

    rab0257b9 r54f89d5  
    99... with resolved type:
    1010  void Alternatives are:
     11Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
     12      Application of
     13        Variable Expression: *?: forall
     14          DT: data type
     15          function
     16        ... with parameters
     17          pointer to instance of type DT (not function type)
     18        ... returning
     19          reference to instance of type DT (not function type)
     20
     21        ... with resolved type:
     22          pointer to forall
     23            [unbound]:data type
     24            function
     25          ... with parameters
     26            pointer to instance of type [unbound] (not function type)
     27          ... returning
     28            reference to instance of type [unbound] (not function type)
     29
     30        ... to arguments
     31        Variable Expression: x: pointer to instance of struct A without body
     32        ... with resolved type:
     33          pointer to instance of struct A without body
     34
     35      ... with resolved type:
     36        reference to instance of struct A without body
     37    ... to: nothing
     38    ... with resolved type:
     39      void
     40  (types:
     41    void
     42  )
     43  Environment:([unbound]) -> instance of struct A without body (no widening)
     44
     45
    1146Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
    1247      Application of
     
    4277  )
    4378  Environment:([unbound]) -> instance of struct B with body (no widening)
    44 
    45 
    46 Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
    47       Application of
    48         Variable Expression: *?: forall
    49           DT: data type
    50           function
    51         ... with parameters
    52           pointer to instance of type DT (not function type)
    53         ... returning
    54           reference to instance of type DT (not function type)
    55 
    56         ... with resolved type:
    57           pointer to forall
    58             [unbound]:data type
    59             function
    60           ... with parameters
    61             pointer to instance of type [unbound] (not function type)
    62           ... returning
    63             reference to instance of type [unbound] (not function type)
    64 
    65         ... to arguments
    66         Variable Expression: x: pointer to instance of struct A without body
    67         ... with resolved type:
    68           pointer to instance of struct A without body
    69 
    70       ... with resolved type:
    71         reference to instance of struct A without body
    72     ... to: nothing
    73     ... with resolved type:
    74       void
    75   (types:
    76     void
    77   )
    78   Environment:([unbound]) -> instance of struct A without body (no widening)
    7979
    8080
  • tests/meta/.expect/archVast.nast.x64.txt

    rab0257b9 r54f89d5  
    77  char Alternatives are:
    88Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    9       Variable Expression: FX64: signed int
     9      Variable Expression: FX64: double
    1010      ... with resolved type:
    11         signed int
     11        double
    1212    ... to:
    1313      char
     
    3939
    4040Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    41       Variable Expression: FX64: double
     41      Variable Expression: FX64: signed int
    4242      ... with resolved type:
    43         double
     43        signed int
    4444    ... to:
    4545      char
  • tests/meta/.expect/archVast.oast.x64.txt

    rab0257b9 r54f89d5  
    66with resolved type:
    77  char Alternatives are:
     8Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
     9      Variable Expression: FX64: double
     10      with resolved type:
     11        double
     12    ... to:
     13      char
     14    with resolved type:
     15      char
     16  (types:
     17    char
     18  )
     19  Environment:
     20
    821Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    922      Variable Expression: FX64: function
     
    1629        ... returning nothing
    1730
    18     ... to:
    19       char
    20     with resolved type:
    21       char
    22   (types:
    23     char
    24   )
    25   Environment:
    26 
    27 Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    28       Variable Expression: FX64: double
    29       with resolved type:
    30         double
    3131    ... to:
    3232      char
Note: See TracChangeset for help on using the changeset viewer.