Changeset c352893


Ignore:
Timestamp:
May 5, 2017, 3:42:38 PM (7 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
f04288f
Parents:
f57668a (diff), 982ed5b (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

Quick save while I switch computers.

Location:
src
Files:
6 added
3 deleted
19 edited
3 moved

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rf57668a rc352893  
    262262                        } // if
    263263                } else {
    264                         output << typeDecl->typeString() << " " << typeDecl->get_name();
     264                        output << typeDecl->genTypeString() << " " << typeDecl->get_name();
     265                        if ( typeDecl->get_kind() != TypeDecl::Any && typeDecl->get_sized() ) {
     266                                output << " | sized(" << typeDecl->get_name() << ")";
     267                        }
    265268                        if ( ! typeDecl->get_assertions().empty() ) {
    266269                                output << " | { ";
     
    769772        void CodeGenerator::visit( ExprStmt * exprStmt ) {
    770773                assert( exprStmt );
    771                 // cast the top-level expression to void to reduce gcc warnings.
    772                 Expression * expr = new CastExpr( exprStmt->get_expr() );
     774                Expression * expr = exprStmt->get_expr();
     775                if ( genC ) {
     776                        // cast the top-level expression to void to reduce gcc warnings.
     777                        expr = new CastExpr( expr );
     778                }
    773779                expr->accept( *this );
    774780                output << ";";
  • src/CodeGen/Generate.cc

    rf57668a rc352893  
    2222#include "SynTree/Declaration.h"
    2323#include "CodeGenerator.h"
    24 #include "Tuples/Tuples.h"
     24#include "GenType.h"
     25#include "SynTree/SynTree.h"
     26#include "SynTree/Type.h"
     27#include "SynTree/BaseSyntaxNode.h"
     28// #include "Tuples/Tuples.h"
    2529
    2630using namespace std;
     
    3943                } // for
    4044        }
     45
     46        void generate( BaseSyntaxNode * node, std::ostream & os ) {
     47                if ( Type * type = dynamic_cast< Type * >( node ) ) {
     48                        os << CodeGen::genPrettyType( type, "" );
     49                } else {
     50                        CodeGen::CodeGenerator cgv( os, true, false );
     51                        node->accept( cgv );
     52                }
     53                os << std::endl;
     54        }
    4155} // namespace CodeGen
    4256
  • src/CodeGen/Generate.h

    rf57668a rc352893  
    2525        /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
    2626        void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false );
     27
     28        /// Generate code for a single node -- helpful for debugging in gdb
     29        void generate( BaseSyntaxNode * node, std::ostream & os );
    2730} // namespace CodeGen
    2831
  • src/Concurrency/Keywords.cc

    rf57668a rc352893  
    246246        //=============================================================================================
    247247        void ConcurrentSueKeyword::visit(StructDecl * decl) {
     248                Visitor::visit(decl);
    248249                if( decl->get_name() == type_name ) {
    249250                        assert( !type_decl );
     
    385386        //=============================================================================================
    386387        void MutexKeyword::visit(FunctionDecl* decl) {
     388                Visitor::visit(decl);           
     389
    387390                std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
    388391                if( mutexArgs.empty() ) return;
     
    402405
    403406        void MutexKeyword::visit(StructDecl* decl) {
     407                Visitor::visit(decl);
     408
    404409                if( decl->get_name() == "monitor_desc" ) {
    405410                        assert( !monitor_decl );
     
    504509        //=============================================================================================
    505510        void ThreadStarter::visit(FunctionDecl * decl) {
     511                Visitor::visit(decl);
     512               
    506513                if( ! InitTweak::isConstructor(decl->get_name()) ) return;
    507514
  • src/GenPoly/PolyMutator.cc

    rf57668a rc352893  
    5050
    5151        Statement * PolyMutator::mutateStatement( Statement *stmt ) {
     52                // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     53                ValueGuard< std::list< Statement* > > oldStmtsToAdd( stmtsToAdd );
     54                ValueGuard< std::list< Statement* > > oldStmtsToAddAfter( stmtsToAddAfter );
     55                ValueGuard< TypeSubstitution * > oldEnv( env );
     56                stmtsToAdd.clear();
     57                stmtsToAddAfter.clear();
     58
    5259                Statement *newStmt = maybeMutate( stmt, *this );
    5360                if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
     
    8390
    8491        Statement * PolyMutator::mutate(IfStmt *ifStmt) {
     92                ifStmt->set_condition(  mutateExpression( ifStmt->get_condition() ) );
    8593                ifStmt->set_thenPart(  mutateStatement( ifStmt->get_thenPart() ) );
    8694                ifStmt->set_elsePart(  mutateStatement( ifStmt->get_elsePart() ) );
    87                 ifStmt->set_condition(  mutateExpression( ifStmt->get_condition() ) );
    8895                return ifStmt;
    8996        }
    9097
    9198        Statement * PolyMutator::mutate(WhileStmt *whileStmt) {
     99                whileStmt->set_condition(  mutateExpression( whileStmt->get_condition() ) );
    92100                whileStmt->set_body(  mutateStatement( whileStmt->get_body() ) );
    93                 whileStmt->set_condition(  mutateExpression( whileStmt->get_condition() ) );
    94101                return whileStmt;
    95102        }
    96103
    97104        Statement * PolyMutator::mutate(ForStmt *forStmt) {
    98                 forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
    99105                mutateAll( forStmt->get_initialization(), *this );
    100106                forStmt->set_condition(  mutateExpression( forStmt->get_condition() ) );
    101107                forStmt->set_increment(  mutateExpression( forStmt->get_increment() ) );
     108                forStmt->set_body(  mutateStatement( forStmt->get_body() ) );
    102109                return forStmt;
    103110        }
    104111
    105112        Statement * PolyMutator::mutate(SwitchStmt *switchStmt) {
     113                switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
    106114                mutateStatementList( switchStmt->get_statements() );
    107                 switchStmt->set_condition( mutateExpression( switchStmt->get_condition() ) );
    108115                return switchStmt;
    109116        }
    110117
    111118        Statement * PolyMutator::mutate(CaseStmt *caseStmt) {
     119                caseStmt->set_condition(  mutateExpression( caseStmt->get_condition() ) );
    112120                mutateStatementList( caseStmt->get_statements() );
    113                 caseStmt->set_condition(  mutateExpression( caseStmt->get_condition() ) );
    114121                return caseStmt;
    115122        }
  • src/ResolvExpr/AlternativeFinder.cc

    rf57668a rc352893  
    766766                        } // if
    767767                } // for
    768                 // function may return struct or union value, in which case we need to add alternatives for implicit conversions to each of the anonymous members
     768
     769                candidates.clear();
     770                candidates.splice( candidates.end(), alternatives );
     771
     772                findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
     773
     774                // function may return struct or union value, in which case we need to add alternatives for implicit
     775                // conversions to each of the anonymous members, must happen after findMinCost since anon conversions
     776                // are never the cheapest expression
    769777                for ( const Alternative & alt : alternatives ) {
    770778                        addAnonConversions( alt );
    771779                }
    772 
    773                 candidates.clear();
    774                 candidates.splice( candidates.end(), alternatives );
    775 
    776                 findMinCost( candidates.begin(), candidates.end(), std::back_inserter( alternatives ) );
    777780
    778781                if ( alternatives.empty() && targetType && ! targetType->isVoid() ) {
  • src/SynTree/BaseSyntaxNode.h

    rf57668a rc352893  
    1818
    1919#include "Common/utility.h"
     20#include "Visitor.h"
    2021
    2122class BaseSyntaxNode {
    2223  public:
    2324        CodeLocation location;
     25
     26        virtual void accept( Visitor & v ) = 0; // temporary -- needs to be here so that BaseSyntaxNode is polymorphic and can be dynamic_cast
    2427};
    2528
  • src/SynTree/Declaration.h

    rf57668a rc352893  
    204204
    205205        virtual std::string typeString() const;
     206        virtual std::string genTypeString() const;
    206207
    207208        virtual TypeDecl *clone() const { return new TypeDecl( *this ); }
  • src/SynTree/SynTree.h

    rf57668a rc352893  
    2121#include <map>
    2222#include <iostream>
     23
     24class BaseSyntaxNode;
    2325
    2426class Declaration;
  • src/SynTree/TypeDecl.cc

    rf57668a rc352893  
    2929}
    3030
     31std::string TypeDecl::genTypeString() const {
     32        static const std::string kindNames[] = { "otype", "dtype", "ftype", "ttype" };
     33        return kindNames[ kind ];
     34}
     35
    3136std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ) {
    3237  return os << data.kind << ", " << data.isComplete;
  • src/benchmark/CorCtxSwitch.c

    rf57668a rc352893  
    33#include <thread>
    44
    5 #include <unistd.h>                                     // sysconf
    6 #include <sys/times.h>                                  // times
    7 #include <time.h>
    8 
    9 inline unsigned long long int Time() {
    10     timespec ts;
    11     clock_gettime(
    12 #if defined( __linux__ )
    13          CLOCK_THREAD_CPUTIME_ID,
    14 #elif defined( __freebsd__ )
    15          CLOCK_PROF,
    16 #elif defined( __solaris__ )
    17          CLOCK_HIGHRES,
    18 #else
    19     #error uC++ : internal error, unsupported architecture
    20 #endif
    21          &ts );
    22     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
    23 } // Time
     5#include "bench.h"
    246
    257coroutine GreatSuspender {};
     
    4224}
    4325
    44 #ifndef N
    45 #define N 100000000
    46 #endif
    47 
    4826int main() {
    4927        const unsigned int NoOfTimes = N;
  • src/benchmark/Makefile.am

    rf57668a rc352893  
    4444        @rm -f ./a.out
    4545
     46sched-int:
     47        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
     48        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     49                ./a.out ; \
     50        done
     51        @rm -f ./a.out
     52
     53monitor:
     54        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
     55        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     56                ./a.out ; \
     57        done
     58        @rm -f ./a.out
     59
    4660csv-data:
    4761        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
  • src/benchmark/Makefile.in

    rf57668a rc352893  
    492492        @rm -f ./a.out
    493493
     494sched-int:
     495        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 SchedInt.c
     496        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     497                ./a.out ; \
     498        done
     499        @rm -f ./a.out
     500
     501monitor:
     502        ${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -DN=10000000 Monitor.c
     503        @for number in 1 2 3 4 5 6 7 8 9 10; do \
     504                ./a.out ; \
     505        done
     506        @rm -f ./a.out
     507
    494508csv-data:
    495509        @${CC} ${AM_CFLAGS} ${CFLAGS} ${ccflags} @CFA_FLAGS@ -nodebug -lrt -quiet -DN=10000000 csv-data.c
  • src/benchmark/ThrdCtxSwitch.c

    rf57668a rc352893  
    33#include <thread>
    44
    5 #include <unistd.h>                                     // sysconf
    6 #include <sys/times.h>                                  // times
    7 #include <time.h>
    8 
    9 inline unsigned long long int Time() {
    10     timespec ts;
    11     clock_gettime(
    12 #if defined( __linux__ )
    13          CLOCK_THREAD_CPUTIME_ID,
    14 #elif defined( __freebsd__ )
    15          CLOCK_PROF,
    16 #elif defined( __solaris__ )
    17          CLOCK_HIGHRES,
    18 #else
    19     #error uC++ : internal error, unsupported architecture
    20 #endif
    21          &ts );
    22     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
    23 } // Time
    24  
    25 #ifndef N
    26 #define N 100000000
    27 #endif
     5#include "bench.h"
    286
    297int main() {
  • src/benchmark/bench.c

    rf57668a rc352893  
    44#include <thread>
    55
    6 #include <unistd.h>                                     // sysconf
    7 #include <sys/times.h>                                  // times
    8 #include <time.h>
    9 
    10 inline unsigned long long int Time() {
    11     timespec ts;
    12     clock_gettime(
    13 #if defined( __linux__ )
    14          CLOCK_THREAD_CPUTIME_ID,
    15 #elif defined( __freebsd__ )
    16          CLOCK_PROF,
    17 #elif defined( __solaris__ )
    18          CLOCK_HIGHRES,
    19 #else
    20     #error uC++ : internal error, unsupported architecture
    21 #endif
    22          &ts );
    23     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
    24 } // Time
     6#include "bench.h"
    257
    268//=======================================
  • src/benchmark/csv-data.c

    rf57668a rc352893  
    11#include <fstream>
     2#include <monitor>
    23#include <stdlib>
    34#include <thread>
    45
    5 extern "C" {
    6 #include <unistd.h>                                     // sysconf
    7 #include <sys/times.h>                                  // times
    8 #include <time.h>
    9 }
    10 
    11 inline unsigned long long int Time() {
    12     timespec ts;
    13     clock_gettime(
    14 #if defined( __linux__ )
    15          CLOCK_THREAD_CPUTIME_ID,
    16 #elif defined( __freebsd__ )
    17          CLOCK_PROF,
    18 #elif defined( __solaris__ )
    19          CLOCK_HIGHRES,
    20 #else
    21     #error uC++ : internal error, unsupported architecture
    22 #endif
    23          &ts );
    24     return 1000000000LL * ts.tv_sec + ts.tv_nsec;
    25 } // Time
     6#include "bench.h"
    267
    278coroutine GreatSuspender {};
     
    4829#endif
    4930
    50 
    51 
     31//-----------------------------------------------------------------------------
     32// coroutine context switch
    5233long long int measure_coroutine() {
    5334        const unsigned int NoOfTimes = N;
     
    6748}
    6849
     50//-----------------------------------------------------------------------------
     51// thread context switch
    6952long long int measure_thread() {
    7053        const unsigned int NoOfTimes = N;
     
    8063}
    8164
     65//-----------------------------------------------------------------------------
     66// single monitor entry
     67monitor mon_t {};
     68void dummy( mon_t * mutex m ) {}
     69
     70long long int measure_1_monitor_entry() {
     71        const unsigned int NoOfTimes = N;
     72        long long int StartTime, EndTime;
     73        mon_t mon;
     74
     75        StartTime = Time();
     76        for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
     77                dummy( &mon );
     78        }
     79        EndTime = Time();
     80
     81        return ( EndTime - StartTime ) / NoOfTimes;
     82}
     83
     84//-----------------------------------------------------------------------------
     85// multi monitor entry
     86void dummy( mon_t * mutex m1,  mon_t * mutex m2 ) {}
     87
     88long long int measure_2_monitor_entry() {
     89        const unsigned int NoOfTimes = N;
     90        long long int StartTime, EndTime;
     91        mon_t mon1, mon2;
     92
     93        StartTime = Time();
     94        for ( volatile unsigned int i = 0; i < NoOfTimes; i += 1 ) {
     95                dummy( &mon1, &mon2 );
     96        }
     97        EndTime = Time();
     98
     99        return ( EndTime - StartTime ) / NoOfTimes;
     100}
     101
     102//-----------------------------------------------------------------------------
     103// single internal sched entry
     104mon_t mon1;
     105
     106condition cond1a;
     107condition cond1b;
     108
     109thread thrd1a { long long int * out; };
     110thread thrd1b {};
     111
     112void ?{}( thrd1a * this, long long int * out ) {
     113        this->out = out;
     114}
     115
     116void side1A( mon_t * mutex a, long long int * out ) {
     117        long long int StartTime, EndTime;
     118
     119        StartTime = Time();
     120        for( int i = 0;; i++ ) {
     121                signal(&cond1a);
     122                if( i > N ) break;
     123                wait(&cond1b);
     124        }
     125        EndTime = Time();
     126
     127        *out = ( EndTime - StartTime ) / N;
     128}
     129
     130void side1B( mon_t * mutex a ) {
     131        for( int i = 0;; i++ ) {
     132                signal(&cond1b);
     133                if( i > N ) break;
     134                wait(&cond1a);
     135        }
     136}
     137
     138void main( thrd1a * this ) { side1A( &mon1, this->out ); }
     139void main( thrd1b * this ) { side1B( &mon1 ); }
     140
     141long long int measure_1_sched_int() {
     142        long long int t;
     143        {
     144                thrd1a a = { &t };
     145                thrd1b b;
     146        }
     147        return t;
     148}
     149
     150//-----------------------------------------------------------------------------
     151// multi internal sched entry
     152mon_t mon2;
     153
     154condition cond2a;
     155condition cond2b;
     156
     157thread thrd2a { long long int * out; };
     158thread thrd2b {};
     159
     160void ?{}( thrd2a * this, long long int * out ) {
     161        this->out = out;
     162}
     163
     164void side2A( mon_t * mutex a, mon_t * mutex b, long long int * out ) {
     165        long long int StartTime, EndTime;
     166
     167        StartTime = Time();
     168        for( int i = 0;; i++ ) {
     169                signal(&cond2a);
     170                if( i > N ) break;
     171                wait(&cond2b);
     172        }
     173        EndTime = Time();
     174
     175        *out = ( EndTime - StartTime ) / N;
     176}
     177
     178void side2B( mon_t * mutex a, mon_t * mutex b ) {
     179        for( int i = 0;; i++ ) {
     180                signal(&cond2b);
     181                if( i > N ) break;
     182                wait(&cond2a);
     183        }
     184}
     185
     186void main( thrd2a * this ) { side2A( &mon1, &mon2, this->out ); }
     187void main( thrd2b * this ) { side2B( &mon1, &mon2 ); }
     188
     189long long int measure_2_sched_int() {
     190        long long int t;
     191        {
     192                thrd2a a = { &t };
     193                thrd2b b;
     194        }
     195        return t;
     196}
     197
     198//-----------------------------------------------------------------------------
     199// main loop
    82200int main()
    83201{
    84         sout | time(NULL) | ',' | measure_coroutine() | ',' | measure_thread() | endl;
    85 }
     202        sout | time(NULL) | ',';
     203        sout | measure_coroutine() | ',';
     204        sout | measure_thread() | ',';
     205        sout | measure_1_monitor_entry() | ',';
     206        sout | measure_2_monitor_entry() | ',';
     207        sout | measure_1_sched_int() | ',';
     208        sout | measure_2_sched_int() | endl;
     209}
  • src/libcfa/concurrency/thread.c

    rf57668a rc352893  
    4040        this->next = NULL;
    4141
    42         this->current_monitors      = NULL;
    43         this->current_monitor_count = 0;
     42        this->current_monitors      = &this->mon;
     43        this->current_monitor_count = 1;
    4444}
    4545
  • src/tests/Makefile.am

    rf57668a rc352893  
    2222concurrent=yes
    2323quick_test+= coroutine thread monitor
    24 concurrent_test=coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt
     24concurrent_test=coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
    2525else
    2626concurrent=no
  • src/tests/Makefile.in

    rf57668a rc352893  
    230230@BUILD_CONCURRENCY_TRUE@concurrent = yes
    231231@BUILD_CONCURRENCY_FALSE@concurrent_test =
    232 @BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt
     232@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int-disjoint sched-int-barge sched-int-wait sched-ext sched-ext-multi preempt
    233233
    234234# applies to both programs
  • src/tests/sched-int-barge.c

    rf57668a rc352893  
    22#include <kernel>
    33#include <monitor>
     4#include <stdlib>
    45#include <thread>
    56
     
    1213        int counter;
    1314        state_t state;
     15
     16        unsigned short do_signal;
     17        unsigned short do_wait2;
     18        unsigned short do_wait1;
    1419};
    1520
     
    1823        this->counter = 0;
    1924        this->state = BARGE;
     25
     26        this->do_signal = 6;
     27        this->do_wait1  = 1;
     28        this->do_wait2  = 3;
    2029}
    2130
     
    3342        c->counter++;
    3443
     44        if( (c->counter % 1000) == 0 ) sout | c->counter | endl;
     45
    3546        int action = c->counter % 10;
    3647
    37         if( action == 1 || action == 3 ) {
    38                 if(c->state != BARGE) {
    39                         sout | "ERROR Mutual exclusion is inconsistent for wait" | endl;
    40                         abort();
    41                 }
     48        if( action == 0 ) {
     49                c->do_signal = max( ((unsigned)rand48()) % 10, 1);
     50                c->do_wait1 = ((unsigned)rand48()) % (c->do_signal);
     51                c->do_wait2 = ((unsigned)rand48()) % (c->do_signal);
    4252
     53                // if(c->do_wait1 == c->do_wait2) sout | "Same" | endl;
     54        }
     55
     56        if( action == c->do_wait1 || action == c->do_wait2 ) {
    4357                c->state = WAIT;
    4458                wait( &cond );
    4559
    4660                if(c->state != SIGNAL) {
    47                         sout | "ERROR Barging detected" | endl;
     61                        sout | "ERROR Barging detected" | c->counter | endl;
    4862                        abort();
    4963                }
    5064        }
    51         else if( action == 6 ) {
    52                 if(c->state != BARGE) {
    53                         sout | "ERROR Mutual exclusion is inconsistent for signal" | endl;
    54                         abort();
    55                 }
    56 
     65        else if( action == c->do_signal ) {
    5766                c->state = SIGNAL;
    5867
     
    6473        }
    6574
    66         if( (c->counter % 1000) == 0 ) sout | c->counter | endl;
    67         if( c->counter == 100_000 ) c->done = true;
     75        if( c->counter >= 100_000 ) c->done = true;
    6876        return !c->done;
    6977}
     
    8290
    8391int main(int argc, char* argv[]) {
    84         processor p[3];
     92        rand48seed(0);
     93        processor p;
    8594        {
    86                 Threads t[20];
     95                Threads t[17];
    8796        }
    8897}
  • src/tests/sched-int-wait.c

    rf57668a rc352893  
    22#include <kernel>
    33#include <monitor>
     4#include <stdlib>
    45#include <thread>
    56
     
    1213condition condAB, condAC, condBC, condABC;
    1314
    14 thread Signaler {};
     15thread Signaler {
     16        int signals[4];
     17};
     18
     19void ?{}( Signaler * this ){
     20        this->signals[0] = 0;
     21        this->signals[1] = 0;
     22        this->signals[2] = 0;
     23        this->signals[3] = 0;
     24}
     25
    1526thread WaiterAB {};
    1627thread WaiterAC {};
     
    1829thread WaiterABC{};
    1930
    20 int state;
    21 
    22 /*
    23 multi phase
    24 */
     31volatile bool done;
    2532
    2633//----------------------------------------------------------------------------------------------------
     
    3542
    3643void wait( condition * cond, global_t * mutex a, global_t * mutex b ) {
    37         state++;
    38         sout | "Waiting" | state | endl;
    3944        wait( cond );
    40         sout | "Waking" | state | endl;
    41         state--;
    4245}
    4346
    4447void wait( condition * cond, global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
    45         state++;
    46         sout | "Waiting" | state | endl;
    4748        wait( cond );
    48         sout | "Waking" | state | endl;
    49         state--;
    5049}
    5150
    5251//----------------------------------------------------------------------------------------------------
    5352// Signaler
    54 // signals respectively AB, AC, BC, ABC
    55 void signalerABC( global_t * mutex a, global_t * mutex b, global_t * mutex c ) {
    56         sout | "Signaling ABC" | endl;
    57         signal( &condABC, a, b, c );
    58         sout | "Signaling AB" | endl;
    59         signal( &condAB , a, b );
    60         sout | "Signaling BC" | endl;
    61         signal( &condBC , b, c );
    62         sout | "Signaling AC" | endl;
    63         signal( &condAC , a, c );
    64 }
     53void main( Signaler* this ) {
    6554
    66 void signalerAB( global_t * mutex a, global_t * mutex b, global_t * c ) {
    67         signalerABC(a, b, c);
    68 }
     55        while( true ) {
     56                int action = (unsigned)rand48() % 4;
     57                bool finished = true;
    6958
    70 void signalerA( global_t * mutex a, global_t * b, global_t * c ) {
    71         signalerAB (a, b, c);
    72 }
     59                for(int i = 0; i < 4; i++) {
     60                        if( this->signals[action] < 10_000 ) {
     61                                finished = false;
     62                                break;
     63                        }
     64                        else {
     65                                action = (action + 1) % 4;
     66                        }
     67                }
    7368
    74 void main( Signaler* this ) {
    75         while( state != 4 ) { yield(); }
    76         signalerA( &globalA, &globalB, &globalC );
     69                this->signals[action]++;
     70                if( finished ) break;
     71
     72                //sout | action | this->signals[0] | this->signals[1] | this->signals[2] | this->signals[3] | endl;
     73
     74                switch( action ) {
     75                        case 0:
     76                                signal( &condABC, &globalA, &globalB, &globalC );
     77                                break;
     78                        case 1:
     79                                signal( &condAB , &globalA, &globalB );
     80                                break;
     81                        case 2:
     82                                signal( &condBC , &globalB, &globalC );
     83                                break;
     84                        case 3:
     85                                signal( &condAC , &globalA, &globalC );
     86                                break;
     87                        default:
     88                                sout | "Something went wrong" | endl;
     89                                abort();
     90                }
     91        }       
    7792}
    7893
     
    8095// Waiter ABC
    8196void main( WaiterABC* this ) {
    82         while( state != 0 ) { yield(); }
    83         wait( &condABC, &globalA, &globalB, &globalC );
     97        while( !done ) {
     98                wait( &condABC, &globalA, &globalB, &globalC );
     99        }
    84100}
    85101
     
    87103// Waiter AB
    88104void main( WaiterAB* this ) {
    89         while( state != 1 ) { yield(); }
    90         wait( &condAB , &globalA, &globalB );
     105        while( !done ) {
     106                wait( &condAB , &globalA, &globalB );
     107        }
    91108}
    92109
     
    94111// Waiter AC
    95112void main( WaiterAC* this ) {
    96         while( state != 2 ) { yield(); }
    97         wait( &condAC , &globalA, &globalC );
     113        while( !done ) {
     114                wait( &condAC , &globalA, &globalC );
     115        }
    98116}
    99117
     
    101119// Waiter BC
    102120void main( WaiterBC* this ) {
    103         while( state != 3 ) { yield(); }
    104         wait( &condBC , &globalB, &globalC );
     121        while( !done ) {
     122                wait( &condBC , &globalB, &globalC );
     123        }
    105124}
    106125
     
    108127// Main
    109128int main(int argc, char* argv[]) {
    110         state = 0;
     129        done = false;
    111130        processor p;
    112131        {
     
    115134                WaiterBC  c;
    116135                WaiterAC  d;
    117                 Signaler  e;
     136                {
     137                        Signaler  e;
     138                }
     139                done = true;
     140                signal( &condABC, &globalA, &globalB, &globalC );
     141                signal( &condAB , &globalA, &globalB );
     142                signal( &condBC , &globalB, &globalC );
     143                signal( &condAC , &globalA, &globalC );
    118144        }
    119145}
Note: See TracChangeset for help on using the changeset viewer.