Changes in / [2ae845e9:2295320]


Ignore:
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • doc/bibliography/pl.bib

    r2ae845e9 r2295320  
    36853685    address     = {Waterloo, Ontario, Canada, N2L 3G1},
    36863686    note        = {\url{http://uwspace.uwaterloo.ca/bitstream/10012/3501/1/Thesis.pdf}},
     3687}
     3688
     3689@article{Hesselink24,
     3690    author      = {Wim A. Hesselink and Peter A. Buhr and Colby A. Parsons},
     3691    title       = {First-Come-First-Served as a Separate Principle},
     3692    journal     = {ACM Trans. Parallel Comput.},
     3693    publisher   = {ACM},
     3694    address     = {New York, NY, USA},
     3695    volume      = 11,
     3696    number      = 4,
     3697    month       = nov,
     3698    year        = 2024,
    36873699}
    36883700
  • doc/uC++toCFA/uC++toCFA.tex

    r2ae845e9 r2295320  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Nov  8 08:22:25 2024
    14 %% Update Count     : 6107
     13%% Last Modified On : Mon Nov 11 21:51:39 2024
     14%% Update Count     : 6144
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    498498
    499499
    500 \section{Coroutines}
     500\section{Coroutine}
    501501
    502502\begin{cquote}
     
    591591
    592592struct StrMsg : @public uActor::Message@ {
     593
    593594        const char * val; // string message
    594 
    595595
    596596        StrMsg( const char * val ) :
     
    600600_Actor Hello { ${\color{red}\LstCommentStyle{// : public uActor}}$
    601601        Allocation receive( Message & msg ) {
    602                 Case( StrMsg, msg ) { // discriminate
     602                Case( @StartMsg@, msg ) { // discriminate
     603
     604                } else Case( StrMsg, msg ) {
    603605                        osacquire( cout ) << msg_d->val << endl;
    604                 };
    605                 return Delete;  // delete after use
     606
     607                } else Case( @StopMsg@, msg )
     608                        return Delete;  // delete actor
     609                return Nodelete;  // reuse actor
    606610        }
    607611};
    608612int main() {
    609613        @uActor::start();@ // start actor system
    610         *new Hello() | *new StrMsg( "hello" );
    611         *new Hello() | *new StrMsg( "bonjour" );
    612         @uActor::stop();@  // wait for all actors to terminate
     614        *new Hello() | uActor::startMsg
     615                | *new StrMsg( "hello" ) | uActor::stopMsg;
     616        *new Hello() | uActor::startMsg
     617                | *new StrMsg( "bonjour" ) | uActor::stopMsg;
     618        @uActor::stop();@  // wait for actors to terminate
    613619}
    614620\end{uC++}
     
    623629        const char * val; // string message
    624630};
    625 void ?{}( StrMsg & msg, char * str ) {
     631void ?{}( StrMsg & msg, const char * str ) {
     632        @set_allocation( msg, Delete );@ // delete after use
    626633        msg.val = str;
    627         @set_allocation( msg, Delete );@ // delete after use
    628 }
    629 struct Hello {
    630         @inline actor;@ // derived actor
    631 };
     634}
     635struct Hello { @inline actor;@ }; // derived actor
     636allocation receive( Hello & receiver, @start_msg_t@ & ) {
     637        return Nodelete;
     638}
    632639allocation receive( Hello & receiver, StrMsg & msg ) {
    633640        mutex( sout ) sout | msg.val;
    634         return Delete;  // delete after use
     641        return Nodelete;  // reuse actor
     642}
     643allocation receive( Hello & receiver, @stop_msg_t@ & ) {
     644        return Delete;  // delete actor
    635645}
    636646
    637647int main() {
    638         @start_actor_system();@  // start actor system
    639         *(Hello *)new() | *(StrMsg *)new( "hello" );
    640         *(Hello *)new() | *(StrMsg *)new( "bonjour" );
    641         @stop_actor_system();@  // wait for all actors to terminate
    642 }
    643 \end{cfa}
    644 \end{tabular}
    645 \end{cquote}
    646 
    647 
    648 \section{Threads}
     648        @actor_start();@  // start actor system
     649        *(Hello *)new() | start_msg
     650                | *(StrMsg *)new( "hello" ) | stop_msg;
     651        *(Hello *)new() | start_msg
     652                | *(StrMsg *)new( "bonjour" ) | stop_msg;
     653        @actor_stop();@  // wait for actors to terminate
     654}
     655\end{cfa}
     656\end{tabular}
     657\end{cquote}
     658
     659
     660\section{Thread}
    649661
    650662\begin{cquote}
     
    710722
    711723
    712 \section{Monitors}
     724\section{Monitor}
    713725
    714726Internal Scheduling
     
    776788\end{tabular}
    777789\end{cquote}
    778 \enlargethispage{1000pt}
     790
     791\newpage
     792
    779793External Scheduling
    780794\begin{cquote}
  • libcfa/src/concurrency/actor.hfa

    r2ae845e9 r2295320  
    398398// TODO: update globals in this file to be static fields once the static fields project is done
    399399static executor * __actor_executor_ = 0p;
    400 static bool __actor_executor_passed = false;                    // was an executor passed to start_actor_system
     400static bool __actor_executor_passed = false;                    // was an executor passed to actor_start
    401401static size_t __num_actors_ = 0;                                                // number of actor objects in system
    402402static struct thread$ * __actor_executor_thd = 0p;              // used to wake executor after actors finish
     
    410410        // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive
    411411        // member must be called to end it
    412         DEBUG_ABORT( __actor_executor_ == 0p, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );
     412        DEBUG_ABORT( __actor_executor_ == 0p, "Creating actor before calling actor_start() can cause undefined behaviour.\n" );
    413413        alloc = Nodelete;
    414414        ticket = __get_next_ticket( *__actor_executor_ );
     
    682682}
    683683
    684 static inline void start_actor_system( size_t num_thds ) {
     684static inline void actor_start( size_t num_thds ) {
    685685        __reset_stats();
    686686        __actor_executor_thd = active_thread();
     
    689689}
    690690
    691 static inline void start_actor_system() { start_actor_system( get_proc_count( *active_cluster() ) ); }
    692 
    693 static inline void start_actor_system( executor & this ) {
     691static inline void actor_start() { actor_start( get_proc_count( *active_cluster() ) ); }
     692
     693static inline void actor_start( executor & this ) {
    694694        __reset_stats();
    695695        __actor_executor_thd = active_thread();
     
    698698}
    699699
    700 static inline void stop_actor_system() {
     700static inline void actor_stop() {
    701701        park();                                                                                         // unparked when actor system is finished
    702702
     
    715715struct finished_msg_t { inline message; } finished_msg = __base_msg_finished;
    716716
    717 allocation receive( actor & this, delete_msg_t & msg ) { return Delete; }
    718 allocation receive( actor & this, destroy_msg_t & msg ) { return Destroy; }
    719 allocation receive( actor & this, finished_msg_t & msg ) { return Finished; }
     717allocation receive( actor & this, delete_msg_t & ) { return Delete; }
     718allocation receive( actor & this, destroy_msg_t & ) { return Destroy; }
     719allocation receive( actor & this, finished_msg_t & ) { return Finished; }
    720720
    721721// Default messages used all the time.
    722 //static struct startmsg_t { inline message; } start_msg; // start actor
    723 //static struct stopmsg_t { inline message; } stop_msg; // terminate actor
     722struct start_msg_t { inline message; } start_msg = __base_msg_finished; // start actor
     723struct stop_msg_t { inline message; } stop_msg = __base_msg_finished; // terminate actor
  • libcfa/src/concurrency/barrier.hfa

    r2ae845e9 r2295320  
    1 //
     1//                               -*- Mode: C -*-
     2//
    23// Cforall Version 1.0.0 Copyright (C) 2022 University of Waterloo
    3 //
     4// 
    45// The contents of this file are covered under the licence agreement in the
    56// file "LICENCE" distributed with Cforall.
    67//
    7 // barrier.hfa -- simple barrier implemented from monitors
    8 //
    9 // Author           : Thierry Delisle
    10 // Created On       : Thu Mar 31 16:51:35 2022
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     :
    14 //
     8// barrier.hfa -- simple barrier implemented using a monitor
     9// 
     10// Author           : Peter A. Buhr
     11// Created On       : Sun Nov 10 08:07:35 2024
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Sun Nov 10 08:11:55 2024
     14// Update Count     : 3
     15// 
    1516
    1617#pragma once
     
    1819#include <monitor.hfa>
    1920
    20 // Simple barrier based on a monitor
     21// Plan 9 inheritance does not work with monitors. Two monitor locks are created.
     22
    2123monitor barrier {
    22         // Number of threads blocking needed to unblock the barrier
    23         // Unsigned should be enough, I don't expect use cases with 2^32 thread barriers.
    24         unsigned width;
    25 
    26         // Current count (counting backwards)
    27         unsigned count;
    28 
    29         // Barrier uses internal scheduling
    30         condition c;
     24        unsigned int group, arrivals;                                           // group size, arrival counter
     25        condition c;                                                                            // wait for group to form
    3126};
    3227
    3328// Constructor
    34 void ?{}( barrier & this, unsigned width ) {
    35         this.width = width;
    36         this.count = width; // Count backwards so initialize at width
     29void ?{}( barrier & b, unsigned group ) {
     30        b.group = b.arrivals = group;                                           // count backwards
    3731}
    3832
    39 // block until the number of threads needed have blocked
    40 // returns an value indicating the reverse order the threads arrived in
    41 // i.e. last thread will return 0 (and not block)
    42 //      second last thread returns 1
    43 //      etc.
    44 // last is an optional hook that will be called by the last thread
    45 // before unblocking the others
    46 static inline unsigned block(barrier & mutex this, fptr_t last = (fptr_t)0 ) {
    47         this.count -= 1; // prefix decrement so we the last is 0 and not 1
    48         unsigned arrival = this.count; // Note arrival order
    49         if(arrival == 0) {
    50                 if(last) last();
    51                 // If arrived last unblock everyone and reset
    52                 signal_all(this.c);
    53                 this.count = this.width;
    54         } else {
    55                 // Otherwise block
    56                 wait(this.c);
    57         }
    58         return arrival; // return arrival order
     33// Returns a value indicating the reverse order the threads arrived i.e. last thread returns 0 (and does not block)
     34// last is an optional hook that is called by the last thread before unblocking the others.
     35static inline unsigned block( barrier & mutex b, fptr_t last = (fptr_t)0 ) with( b ) {
     36        arrivals -= 1;                                                                          // prefix decrement so last is 0 not 1
     37        unsigned arrived = b.arrivals;                                          // note arrival order
     38        if ( arrivals != 0 ) {                                                          // wait for group to form
     39                wait( b.c );
     40        } else {                                                                                        // group formed
     41                if ( last ) last();                                                             // safe to call
     42                signal_all( c );                                                                // unblock group
     43                arrivals = group;                                                               // reset
     44        } // if
     45        return arrived;                                                                         // return arrival order
    5946}
  • tests/concurrency/actors/dynamic.cfa

    r2ae845e9 r2295320  
    4848
    4949        executor e{ 0, 1, 1, false };
    50         start_actor_system( e );
    51 
     50        actor_start( e );
    5251        sout | "started";
    5352
     
    5857        *d_actor | *d_msg;
    5958
    60         stop_actor_system();
    61 
     59        actor_stop();
    6260        sout | "stopped";
    6361}
  • tests/concurrency/actors/executor.cfa

    r2ae845e9 r2295320  
    8484
    8585        sout | "starting";
    86 
    87         start_actor_system( e );
    88 
     86        actor_start( e );
    8987        sout | "started";
    90 
    9188        d_actor actors[ Actors ];
    92 
    9389        for ( i; Actors ) {
    9490                actors[i] | shared_msg;
    9591        } // for
    96 
    9792        sout | "stopping";
    98 
    99         stop_actor_system();
    100 
     93        actor_stop();
    10194        sout | "stopped";
    10295}
  • tests/concurrency/actors/inherit.cfa

    r2ae845e9 r2295320  
    2929        sout | "Start";
    3030        {
    31                 start_actor_system();
     31                actor_start();
    3232                D_msg * dm = alloc();
    3333                (*dm){};
     
    4040                *s | *dm;
    4141                *s2 | *dm2;
    42                 stop_actor_system();
     42                actor_stop();
    4343        }
    4444        {
    45                 start_actor_system();
     45                actor_start();
    4646                Server s[2];
    4747                D_msg * dm = alloc();
     
    5151                s[0] | *dm;
    5252                s[1] | *dm2;
    53                 stop_actor_system();
     53                actor_stop();
    5454        }
    5555        sout | "Finished";
  • tests/concurrency/actors/inline.cfa

    r2ae845e9 r2295320  
    3838        processor p;
    3939        {
    40                 start_actor_system();                                                           // sets up executor
     40                actor_start();                                                          // sets up executor
    4141                d_actor da;
    4242                d_msg * dm = alloc();
    4343                (*dm){ 42, 2423 };
    4444                da | *dm;
    45                 stop_actor_system();                                                            // waits until actors finish
     45                actor_stop();                                                           // waits until actors finish
    4646        }
    4747        {
    48                 start_actor_system();                                                           // sets up executor
     48                actor_start();                                                          // sets up executor
    4949                d_actor da;
    5050                d_msg2 dm{ 29079 };
     
    5454                virtual_dtor * v = &dm;
    5555                da | dm;
    56                 stop_actor_system();                                                            // waits until actors finish
     56                actor_stop();                                                           // waits until actors finish
    5757        }
    5858}
  • tests/concurrency/actors/matrixMultiply.cfa

    r2ae845e9 r2295320  
    8888
    8989        sout | "starting";
    90 
    91         start_actor_system( e );
    92 
     90        actor_start( e );
    9391        sout | "started";
    94 
    9592        derived_msg messages[xr];
    96 
    9793        derived_actor actors[xr];
    9894
     
    10096                messages[r]{ Z[r], X[r], Y };
    10197        } // for
    102 
    10398        for ( r; xr ) {
    10499                actors[r] | messages[r];
     
    106101
    107102        sout | "stopping";
    108 
    109         stop_actor_system();
    110 
     103        actor_stop();
    111104        sout | "stopped";
    112105
  • tests/concurrency/actors/pingpong.cfa

    r2ae845e9 r2295320  
    4747        processor p[Processors - 1];
    4848
    49         start_actor_system( Processors ); // test passing number of processors
     49        actor_start( Processors ); // test passing number of processors
    5050        ping pi_actor;
    5151        pong po_actor;
     
    5454        p_msg m;
    5555        pi_actor | m;
    56         stop_actor_system();
     56        actor_stop();
    5757
    5858        sout | "end";
  • tests/concurrency/actors/poison.cfa

    r2ae845e9 r2295320  
    1515        sout | "Finished";
    1616        {
    17                 start_actor_system();
     17                actor_start();
    1818                Server s[10];
    1919                for ( i; 10 ) {
    2020                        s[i] | finished_msg;
    2121                }
    22                 stop_actor_system();
     22                actor_stop();
    2323        }
    2424
    2525        sout | "Delete";
    2626        {
    27                 start_actor_system();
     27                actor_start();
    2828                for ( i; 10 ) {
    2929                        Server * s = alloc();
     
    3131                        (*s) | delete_msg;
    3232                }
    33                 stop_actor_system();
     33                actor_stop();
    3434        }
    3535
    3636        sout | "Destroy";
    3737        {
    38                 start_actor_system();
     38                actor_start();
    3939                Server s[10];
    4040                for ( i; 10 )
    4141                        s[i] | destroy_msg;
    42                 stop_actor_system();
     42                actor_stop();
    4343                for ( i; 10 )
    4444                        if (s[i].val != 777)
  • tests/concurrency/actors/static.cfa

    r2ae845e9 r2295320  
    4545
    4646        executor e{ 0, 1, 1, false };
    47         start_actor_system( e );
    48 
     47        actor_start( e );
    4948        sout | "started";
    50 
    5149        derived_msg msg;
    52 
    5350        derived_actor actor;
    54 
    5551        actor | msg;
    56 
    57         stop_actor_system();
    58 
     52        actor_stop();
    5953        sout | "stopped";
    6054}
  • tests/concurrency/actors/types.cfa

    r2ae845e9 r2295320  
    6767
    6868        sout | "basic test";
    69         start_actor_system( Processors ); // test passing number of processors
     69        actor_start( Processors ); // test passing number of processors
    7070        derived_actor a;
    7171        d_msg b, c;
     
    7373        c.num = 2;
    7474        a | b | c;
    75         stop_actor_system();
     75        actor_stop();
    7676
    7777        sout | "same message and different actors test";
    78         start_actor_system(); // let system detect # of processors
     78        actor_start(); // let system detect # of processors
    7979        derived_actor2 d_ac2_0, d_ac2_1;
    8080        d_msg d_ac2_msg;
     
    8282        d_ac2_0 | d_ac2_msg;
    8383        d_ac2_1 | d_ac2_msg;
    84         stop_actor_system();
     84        actor_stop();
    8585
    8686       
     
    8888                sout | "same message and different actor types test";
    8989                executor e{ 0, Processors, Processors == 1 ? 1 : Processors * 4, false };
    90                 start_actor_system( e ); // pass an explicit executor
     90                actor_start( e ); // pass an explicit executor
    9191                derived_actor2 d_ac2_2;
    9292                derived_actor3 d_ac3_0;
     
    9595                d_ac3_0 | d_ac23_msg;
    9696                d_ac2_2 | d_ac23_msg;
    97                 stop_actor_system();
     97                actor_stop();
    9898        } // RAII to clean up executor
    9999
     
    101101                sout | "different message types, one actor test";
    102102                executor e{ 1, Processors, Processors == 1 ? 1 : Processors * 4, true };
    103                 start_actor_system( Processors );
     103                actor_start( Processors );
    104104                derived_actor3 a3;
    105105                d_msg b1;
     
    108108                c2.num = 5;
    109109                a3 | b1 | c2;
    110                 stop_actor_system();
     110                actor_stop();
    111111        } // RAII to clean up executor
    112112
     
    114114                sout | "nested inheritance actor test";
    115115                executor e{ 1, Processors, Processors == 1 ? 1 : Processors * 4, true };
    116                 start_actor_system( Processors );
     116                actor_start( Processors );
    117117                derived_actor4 a4;
    118118                d_msg b1;
     
    121121                c2.num = 5;
    122122                a4 | b1 | c2;
    123                 stop_actor_system();
     123                actor_stop();
    124124        } // RAII to clean up executor
    125125
  • tests/concurrency/barrier/order.cfa

    r2ae845e9 r2295320  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // order.cfa -- validates barriers the return value of
    8 //                                 barrier block
     7// order.cfa -- validates barrier return value from barrier block
    98//
    109// Author           : Thierry Delisle
    1110// Created On       : Fri Apr 01 11:39:09 2022
    12 // Last Modified By :
    13 // Last Modified On :
    14 // Update Count     :
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Nov 10 11:22:56 2024
     13// Update Count     : 20
    1514//
    16 
    17 // Test validates barrier and block return value by checking
    18 // that no more than one thread gets the same return value
    1915
    2016#include <concurrency/barrier.hfa>
     
    2319#include <thread.hfa>
    2420
    25 const unsigned NUM_LAPS = 173;
    26 const unsigned NUM_THREADS = 11;
     21enum { NUM_LAPS = 173, NUM_THREADS = 11 };
    2722
    28 // The barrier we are testing
    2923barrier bar = { NUM_THREADS };
    3024
    31 // The return values of the previous generation.
    32 volatile unsigned * generation;
     25volatile unsigned generation = 0;                                               // count laps
     26void last() {
     27        generation += 1;                                                                        // last thread at barrier advances
     28}
     29volatile unsigned * generations;                                                // global array pointer
    3330
    3431thread Tester {};
    3532void main( Tester & this ) {
    36         // Repeat a few times
    37         for(l; NUM_LAPS) {
    38                 // Yield for chaos
    39                 yield( prng(this, 10) );
     33        for ( l; NUM_LAPS ) {
     34                yield( prng( this, 10 ) );                                              // yield for chaos
     35                unsigned int order = block( bar, last );                // block at barrier
    4036
    41                 // Block and what order we arrived
    42                 unsigned ret = block(bar);
    43 
    44                 // Check what was the last generation of that last thread in this position
    45                 unsigned g = generation[ret];
    46 
    47                 // Is it what we expect?
    48                 if(g != l) {
    49                         // Complain that they are different
    50                         sout | "Gen" | l | ": Expeced generation at" | ret | "to be" | l | "was" | g;
    51                 }
    52 
    53                 // Mark the expected next generation
    54                 generation[ret] = l+1;
    55         }
     37                // For G == T, no thread should be able to advance generation until current generation finishes.
     38                if ( generation - 1 != l || generations[order] != l ) { // generation advanced in block
     39                        mutex( sout ) sout | "mismatched generation, expected" | l | "got" | generation;
     40                } // if
     41                generations[order] = l + 1;                                             // every thread advances their current order generation
     42        } // for
    5643}
    5744
    5845int main() {
    59         // Create the data ans zero it.
    6046        volatile unsigned gen_data[NUM_THREADS];
    61         for(t; NUM_THREADS)
    62                 gen_data[t] = 0;
     47        for( t; NUM_THREADS ) gen_data[t] = 0;
     48        generations = gen_data;                                                         // global points at local
    6349
    64         generation = gen_data;
    65 
    66         // Run the experiment
    67         processor p[4];
    68         {
     50        processor p[4];                                                                         // parallelism
     51        {                                                                                                       // run experiment
    6952                Tester testers[NUM_THREADS];
    7053        }
Note: See TracChangeset for help on using the changeset viewer.