Changeset 2223c80


Ignore:
Timestamp:
May 13, 2020, 6:34:09 PM (4 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
365cb03f, 9c438546
Parents:
856fe3e (diff), 979df46 (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:
26 edited

Legend:

Unmodified
Added
Removed
  • benchmark/io/readv.cfa

    r856fe3e r2223c80  
    5959        unsigned long int nthreads = 2;
    6060        unsigned long int nprocs   = 1;
    61         int flags = 0;
     61        unsigned flags = 0;
     62        unsigned sublen = 16;
    6263
    6364        arg_loop:
    6465        for(;;) {
    6566                static struct option options[] = {
    66                         {"duration",   required_argument, 0, 'd'},
    67                         {"nthreads",   required_argument, 0, 't'},
    68                         {"nprocs",     required_argument, 0, 'p'},
    69                         {"bufsize",    required_argument, 0, 'b'},
    70                         {"userthread", no_argument      , 0, 'u'},
     67                        {"duration",     required_argument, 0, 'd'},
     68                        {"nthreads",     required_argument, 0, 't'},
     69                        {"nprocs",       required_argument, 0, 'p'},
     70                        {"bufsize",      required_argument, 0, 'b'},
     71                        {"userthread",   no_argument      , 0, 'u'},
     72                        {"submitthread", no_argument      , 0, 's'},
     73                        {"submitlength", required_argument, 0, 'l'},
    7174                        {0, 0, 0, 0}
    7275                };
    7376
    7477                int idx = 0;
    75                 int opt = getopt_long(argc, argv, "d:t:p:b:u", options, &idx);
     78                int opt = getopt_long(argc, argv, "d:t:p:b:usl:", options, &idx);
    7679
    7780                const char * arg = optarg ? optarg : "";
     
    113116                                flags |= CFA_CLUSTER_IO_POLLER_USER_THREAD;
    114117                                break;
     118                        case 's':
     119                                flags |= CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS;
     120                                break;
     121                        case 'l':
     122                                sublen = strtoul(arg, &end, 10);
     123                                if(*end != '\0' && sublen < 16) {
     124                                        fprintf(stderr, "Submit length must be at least 16, was %s\n", arg);
     125                                        goto usage;
     126                                }
     127                                flags |= (sublen << CFA_CLUSTER_IO_BUFFLEN_OFFSET);
     128                                break;
    115129                        // Other cases
    116130                        default: /* ? */
     
    123137                                fprintf(stderr, "  -p, --nprocs=NPROCS      Number of kernel threads\n");
    124138                                fprintf(stderr, "  -b, --buflen=SIZE        Number of bytes to read per request\n");
     139                                fprintf(stderr, "  -u, --userthread         If set, cluster uses user-thread to poll I/O\n");
     140                                fprintf(stderr, "  -s, --submitthread       If set, cluster uses polling thread to submit I/O\n");
    125141                                exit(EXIT_FAILURE);
    126142                }
  • configure

    r856fe3e r2223c80  
    802802with_cfa_name
    803803enable_distcc
     804with_bwlimit
    804805with_target_hosts
    805806enable_gprofiler
     
    14811482  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
    14821483  --with-cfa-name=NAME     NAME too which cfa will be installed
     1484  --with-bwlimit=RATE     RATE the maximum rate at which rsync will be limited when using distributed builds
    14831485  --with-target-hosts=HOSTS     HOSTS comma seperated list of hosts to build for, format ARCH:debug|nodebug|nolib
    14841486  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
     
    31983200else
    31993201  enable_distcc=no
     3202fi
     3203
     3204
     3205
     3206# Check whether --with-bwlimit was given.
     3207if test "${with_bwlimit+set}" = set; then :
     3208  withval=$with_bwlimit;
    32003209fi
    32013210
  • configure.ac

    r856fe3e r2223c80  
    6464        [  --enable-distcc     whether or not to enable distributed compilation],
    6565        enable_distcc=$enableval, enable_distcc=no)
     66
     67AC_ARG_WITH(bwlimit,
     68        [  --with-bwlimit=RATE     RATE the maximum rate at which rsync will be limited when using distributed builds],
     69        [], [])
    6670
    6771AM_CONDITIONAL([ENABLE_DISTCC], [test x$enable_distcc = xyes])
  • doc/proposals/vtable.md

    r856fe3e r2223c80  
    237237default is provided or not, the second syntax can be used to pick a
    238238parameter on instantiation.
     239
     240### Extension: Object Access
     241This requires that the resolution scope (see below) is at the type level or
     242has explicate points with names. These are the tables and table names used
     243here.
     244
     245The system already knows where to find the virtual table and the object. If
     246the tables have particular identities, or on the user side names, then it is
     247meaningful to check if a binding virtual table is the same* as another. The
     248main use of this is virtual table declarations also give the type they bind
     249and if a binding table matches a known table then the underlyind object in the
     250trait object must be of that type.
     251
     252* By identity, by value would work and in some senses be more flexiable. But
     253  it would be slower and refering to further away functions would be harder.
     254
     255This gives one of the main new features of the hierarchical use of virtual
     256tables (see below); the ability to recover the underlying object. Or a pointer
     257of the approprate type it which both reflects the implementation and gives a
     258convenent way to encode the boolean/conditional aspect of the operation which
     259is that a different virtual table might be in use.
     260
     261There are two general ways to reperent this; a cast or a field access. The
     262cast is traditional and would definitely fit if a single pointer repersents
     263a trait object with the virtual table as part of the object. However for a
     264double pointer field access might be more approprate. By this system though
     265it is not the type that is used as the identifier but the virtual table. If
     266there is one table per type than it becomes equivilant again. Otherwise the
     267table has to be used as the identifier and the type is just a result of that
     268which seems important for syntax.
    239269
    240270Hierarchy
     
    560590be used in only some of the declarations.
    561591
    562     trait combiner fee = (summation_instance, sum);
     592    trait combiner fee = {summation_instance, sum};
    563593    trait combiner foe = summation_instance;
    564594
  • libcfa/Makefile.in

    r856fe3e r2223c80  
    253253DEFS = @DEFS@
    254254DEPDIR = @DEPDIR@
     255DIST_BWLIMIT = @DIST_BWLIMIT@
    255256DLLTOOL = @DLLTOOL@
    256257DRIVER_DIR = @DRIVER_DIR@
  • libcfa/configure

    r856fe3e r2223c80  
    707707CONFIG_CFLAGS
    708708ARCH_FLAGS
     709DIST_BWLIMIT
    709710CFADIR_HASH
    710711LOCAL_CC1
     
    789790enable_silent_rules
    790791enable_distcc
     792with_bwlimit
    791793with_cfa_name
    792794enable_static
     
    14651467  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
    14661468  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
     1469  --with-bwlimit=RATE     RATE the maximum rate at which rsync will be limited when using distributed builds
    14671470  --with-cfa-name=NAME     NAME too which cfa will be installed
    14681471  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
     
    30473050
    30483051
     3052
     3053# Check whether --with-bwlimit was given.
     3054if test "${with_bwlimit+set}" = set; then :
     3055  withval=$with_bwlimit; DIST_BWLIMIT=$withval
     3056else
     3057  DIST_BWLIMIT=0
     3058fi
     3059
     3060
    30493061echo -n "checking for distributated build... "
    30503062if test x$enable_distcc = xno; then
     
    30703082  ENABLE_DISTCC_FALSE=
    30713083fi
     3084
    30723085
    30733086
  • libcfa/configure.ac

    r856fe3e r2223c80  
    3131        enable_distcc=$enableval, enable_distcc=no)
    3232
     33AC_ARG_WITH(bwlimit,
     34        [  --with-bwlimit=RATE     RATE the maximum rate at which rsync will be limited when using distributed builds],
     35        DIST_BWLIMIT=$withval, DIST_BWLIMIT=0)
     36
    3337echo -n "checking for distributated build... "
    3438if test x$enable_distcc = xno; then
     
    5559AC_SUBST(CFADIR_HASH)
    5660AC_SUBST(CFA_VERSION)
     61AC_SUBST(DIST_BWLIMIT)
    5762
    5863#==============================================================================
  • libcfa/prelude/Makefile.am

    r856fe3e r2223c80  
    7272if ENABLE_DISTCC
    7373distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
    74         ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     74        ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@ @DIST_BWLIMIT@
    7575        @echo "Dummy file to track distribution to remote hosts" > ${@}
    7676
  • libcfa/prelude/Makefile.in

    r856fe3e r2223c80  
    215215DEFS = @DEFS@
    216216DEPDIR = @DEPDIR@
     217DIST_BWLIMIT = @DIST_BWLIMIT@
    217218DLLTOOL = @DLLTOOL@
    218219DRIVER_DIR = @DRIVER_DIR@
     
    655656
    656657@ENABLE_DISTCC_TRUE@distribution: @LOCAL_CFACC@ @LOCAL_CC1@ @CFACPP@ gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c $(srcdir)/../../tools/build/push2dist.sh
    657 @ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
     658@ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@ @DIST_BWLIMIT@
    658659@ENABLE_DISTCC_TRUE@    @echo "Dummy file to track distribution to remote hosts" > ${@}
    659660
  • libcfa/src/Makefile.in

    r856fe3e r2223c80  
    307307DEFS = @DEFS@
    308308DEPDIR = @DEPDIR@
     309DIST_BWLIMIT = @DIST_BWLIMIT@
    309310DLLTOOL = @DLLTOOL@
    310311DRIVER_DIR = @DRIVER_DIR@
  • libcfa/src/concurrency/io.cfa

    r856fe3e r2223c80  
    1818
    1919#include "kernel.hfa"
     20#include "bitmanip.hfa"
    2021
    2122#if !defined(HAVE_LINUX_IO_URING_H)
    22         void __kernel_io_startup( cluster &, int, bool ) {
     23        void __kernel_io_startup( cluster &, unsigned, bool ) {
    2324                // Nothing to do without io_uring
    2425        }
     
    9192        struct __io_poller_fast {
    9293                struct __io_data * ring;
    93                 bool waiting;
    9494                $thread thrd;
    9595        };
     
    9797        void ?{}( __io_poller_fast & this, struct cluster & cltr ) {
    9898                this.ring = cltr.io;
    99                 this.waiting = true;
    10099                (this.thrd){ "Fast I/O Poller", cltr };
    101100        }
     
    126125                // Like head/tail but not seen by the kernel
    127126                volatile uint32_t alloc;
    128                 volatile uint32_t ready;
     127                volatile uint32_t * ready;
     128                uint32_t ready_cnt;
    129129
    130130                __spinlock_t lock;
     
    145145                                        volatile unsigned long long int block;
    146146                                } submit_avg;
     147                                struct {
     148                                        volatile unsigned long long int val;
     149                                        volatile unsigned long long int cnt;
     150                                        volatile unsigned long long int block;
     151                                } look_avg;
    147152                        } stats;
    148153                #endif
     
    192197                                void * stack;
    193198                                pthread_t kthrd;
     199                                volatile bool blocked;
    194200                        } slow;
    195201                        __io_poller_fast fast;
     
    201207// I/O Startup / Shutdown logic
    202208//=============================================================================================
    203         void __kernel_io_startup( cluster & this, int io_flags, bool main_cluster ) {
     209        void __kernel_io_startup( cluster & this, unsigned io_flags, bool main_cluster ) {
    204210                this.io = malloc();
    205211
     
    274280                sq.array   = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
    275281                sq.alloc = *sq.tail;
    276                 sq.ready = *sq.tail;
     282
     283                if( io_flags & CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS ) {
     284                        /* paranoid */ verify( is_pow2( io_flags >> CFA_CLUSTER_IO_BUFFLEN_OFFSET ) || ((io_flags >> CFA_CLUSTER_IO_BUFFLEN_OFFSET) < 8)  );
     285                        sq.ready_cnt = max(io_flags >> CFA_CLUSTER_IO_BUFFLEN_OFFSET, 8);
     286                        sq.ready = alloc_align( 64, sq.ready_cnt );
     287                        for(i; sq.ready_cnt) {
     288                                sq.ready[i] = -1ul32;
     289                        }
     290                }
     291                else {
     292                        sq.ready_cnt = 0;
     293                        sq.ready = 0p;
     294                }
    277295
    278296                // completion queue
     
    307325                        this.io->submit_q.stats.submit_avg.cnt   = 0;
    308326                        this.io->submit_q.stats.submit_avg.block = 0;
     327                        this.io->submit_q.stats.look_avg.val   = 0;
     328                        this.io->submit_q.stats.look_avg.cnt   = 0;
     329                        this.io->submit_q.stats.look_avg.block = 0;
    309330                        this.io->completion_q.stats.completed_avg.val = 0;
    310331                        this.io->completion_q.stats.completed_avg.slow_cnt = 0;
     
    326347                // Create the poller thread
    327348                __cfadbg_print_safe(io_core, "Kernel I/O : Creating slow poller for cluter %p\n", &this);
     349                this.io->poller.slow.blocked = false;
    328350                this.io->poller.slow.stack = __create_pthread( &this.io->poller.slow.kthrd, __io_poller_slow, &this );
    329351        }
     
    347369                if( this.io->cltr_flags & CFA_CLUSTER_IO_POLLER_USER_THREAD ) {
    348370                        with( this.io->poller.fast ) {
    349                                 /* paranoid */ verify( waiting ); // The thread shouldn't be in a system call
    350371                                /* paranoid */ verify( this.procs.head == 0p || &this == mainCluster );
    351372                                /* paranoid */ verify( this.idles.head == 0p || &this == mainCluster );
    352373
    353374                                // We need to adjust the clean-up based on where the thread is
    354                                 if( thrd.preempted != __NO_PREEMPTION ) {
     375                                if( thrd.state == Ready || thrd.preempted != __NO_PREEMPTION ) {
    355376
    356377                                        // This is the tricky case
    357378                                        // The thread was preempted and now it is on the ready queue
    358                                         /* paranoid */ verify( thrd.state == Active );           // The thread better be in this state
    359379                                        /* paranoid */ verify( thrd.next == 1p );                // The thread should be the last on the list
    360380                                        /* paranoid */ verify( this.ready_queue.head == &thrd ); // The thread should be the only thing on the list
     
    405425                        if(this.print_stats) {
    406426                                with(this.io->submit_q.stats, this.io->completion_q.stats) {
     427                                        double lavgv = 0;
     428                                        double lavgb = 0;
     429                                        if(look_avg.cnt != 0) {
     430                                                lavgv = ((double)look_avg.val  ) / look_avg.cnt;
     431                                                lavgb = ((double)look_avg.block) / look_avg.cnt;
     432                                        }
     433
    407434                                        __cfaabi_bits_print_safe( STDERR_FILENO,
    408435                                                "----- I/O uRing Stats -----\n"
    409                                                 "- total submit calls  : %'15llu\n"
    410                                                 "- avg submit          : %'18.2lf\n"
    411                                                 "- pre-submit block %%  : %'18.2lf\n"
    412                                                 "- total wait calls    : %'15llu   (%'llu slow, %'llu fast)\n"
    413                                                 "- avg completion/wait : %'18.2lf\n",
     436                                                "- total submit calls     : %'15llu\n"
     437                                                "- avg submit             : %'18.2lf\n"
     438                                                "- pre-submit block %%     : %'18.2lf\n"
     439                                                "- total ready search     : %'15llu\n"
     440                                                "- avg ready search len   : %'18.2lf\n"
     441                                                "- avg ready search block : %'18.2lf\n"
     442                                                "- total wait calls       : %'15llu   (%'llu slow, %'llu fast)\n"
     443                                                "- avg completion/wait    : %'18.2lf\n",
    414444                                                submit_avg.cnt,
    415445                                                ((double)submit_avg.val) / submit_avg.cnt,
    416446                                                (100.0 * submit_avg.block) / submit_avg.cnt,
     447                                                look_avg.cnt,
     448                                                lavgv,
     449                                                lavgb,
    417450                                                completed_avg.slow_cnt + completed_avg.fast_cnt,
    418451                                                completed_avg.slow_cnt,  completed_avg.fast_cnt,
     
    441474                close(this.io->fd);
    442475
     476                free( this.io->submit_q.ready ); // Maybe null, doesn't matter
    443477                free( this.io );
    444478        }
     
    454488        // Process a single completion message from the io_uring
    455489        // This is NOT thread-safe
    456         static int __drain_io( struct __io_data & ring, sigset_t * mask, int waitcnt, bool in_kernel ) {
    457                 int ret = syscall( __NR_io_uring_enter, ring.fd, 0, waitcnt, IORING_ENTER_GETEVENTS, mask, _NSIG / 8);
     490        static [int, bool] __drain_io( & struct __io_data ring, * sigset_t mask, int waitcnt, bool in_kernel ) {
     491                unsigned to_submit = 0;
     492                if( ring.cltr_flags & CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS ) {
     493
     494                        // If the poller thread also submits, then we need to aggregate the submissions which are ready
     495                        uint32_t * tail = ring.submit_q.tail;
     496                        const uint32_t mask = *ring.submit_q.mask;
     497
     498                        // Go through the list of ready submissions
     499                        for( i; ring.submit_q.ready_cnt ) {
     500                                // replace any submission with the sentinel, to consume it.
     501                                uint32_t idx = __atomic_exchange_n( &ring.submit_q.ready[i], -1ul32, __ATOMIC_RELAXED);
     502
     503                                // If it was already the sentinel, then we are done
     504                                if( idx == -1ul32 ) continue;
     505
     506                                // If we got a real submission, append it to the list
     507                                ring.submit_q.array[ ((*tail) + to_submit) & mask ] = idx & mask;
     508                                to_submit++;
     509                        }
     510
     511                        // Increment the tail based on how many we are ready to submit
     512                        __atomic_fetch_add(tail, to_submit, __ATOMIC_SEQ_CST);
     513
     514                        // update statistics
     515                        #if !defined(__CFA_NO_STATISTICS__)
     516                                ring.submit_q.stats.submit_avg.val += to_submit;
     517                                ring.submit_q.stats.submit_avg.cnt += 1;
     518                        #endif
     519                }
     520
     521                int ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, waitcnt, IORING_ENTER_GETEVENTS, mask, _NSIG / 8);
    458522                if( ret < 0 ) {
    459523                        switch((int)errno) {
     
    497561                __atomic_fetch_add( ring.completion_q.head, count, __ATOMIC_RELAXED );
    498562
    499                 return count;
     563                return [count, count > 0 || to_submit > 0];
    500564        }
    501565
     
    519583                if( ring.cltr_flags & CFA_CLUSTER_IO_POLLER_USER_THREAD ) {
    520584                        while(!__atomic_load_n(&ring.done, __ATOMIC_SEQ_CST)) {
     585
     586                                __atomic_store_n( &ring.poller.slow.blocked, true, __ATOMIC_SEQ_CST );
     587
    521588                                // In the user-thread approach drain and if anything was drained,
    522589                                // batton pass to the user-thread
    523                                 int count = __drain_io( ring, &mask, 1, true );
     590                                int count;
     591                                bool again;
     592                                [count, again] = __drain_io( ring, &mask, 1, true );
     593
     594                                __atomic_store_n( &ring.poller.slow.blocked, false, __ATOMIC_SEQ_CST );
    524595
    525596                                // Update statistics
     
    529600                                #endif
    530601
    531                                 if(count > 0) {
     602                                if(again) {
    532603                                        __cfadbg_print_safe(io_core, "Kernel I/O : Moving to ring %p to fast poller\n", &ring);
    533604                                        __unpark( &ring.poller.fast.thrd __cfaabi_dbg_ctx2 );
     
    539610                        while(!__atomic_load_n(&ring.done, __ATOMIC_SEQ_CST)) {
    540611                                //In the naive approach, just poll the io completion queue directly
    541                                 int count = __drain_io( ring, &mask, 1, true );
     612                                int count;
     613                                bool again;
     614                                [count, again] = __drain_io( ring, &mask, 1, true );
    542615
    543616                                // Update statistics
     
    566639                // Then loop until we need to start
    567640                while(!__atomic_load_n(&this.ring->done, __ATOMIC_SEQ_CST)) {
     641
    568642                        // Drain the io
    569                         this.waiting = false;
    570                         int count = __drain_io( *this.ring, 0p, 0, false );
    571                         reset += count > 0 ? 1 : 0;
     643                        int count;
     644                        bool again;
     645                        [count, again] = __drain_io( *this.ring, 0p, 0, false );
     646
     647                        if(!again) reset++;
    572648
    573649                        // Update statistics
     
    577653                        #endif
    578654
    579                         this.waiting = true;
     655                        // If we got something, just yield and check again
    580656                        if(reset < 5) {
    581                                 // If we got something, just yield and check again
    582657                                yield();
    583658                        }
     659                        // We didn't get anything baton pass to the slow poller
    584660                        else {
    585                                 // We didn't get anything baton pass to the slow poller
    586661                                __cfadbg_print_safe(io_core, "Kernel I/O : Moving to ring %p to slow poller\n", &this.ring);
     662                                reset = 0;
     663
     664                                // wake up the slow poller
    587665                                post( this.ring->poller.sem );
     666
     667                                // park this thread
    588668                                park( __cfaabi_dbg_ctx );
    589                                 reset = 0;
    590669                        }
    591670                }
    592671
    593672                __cfadbg_print_safe(io_core, "Kernel I/O : Fast poller for ring %p stopping\n", &this.ring);
     673        }
     674
     675        static inline void __wake_poller( struct __io_data & ring ) __attribute__((artificial));
     676        static inline void __wake_poller( struct __io_data & ring ) {
     677                if(!__atomic_load_n( &ring.poller.slow.blocked, __ATOMIC_SEQ_CST)) return;
     678
     679                sigval val = { 1 };
     680                pthread_sigqueue( ring.poller.slow.kthrd, SIGUSR1, val );
    594681        }
    595682
     
    632719                uint32_t idx = __atomic_fetch_add(&ring.submit_q.alloc, 1ul32, __ATOMIC_SEQ_CST);
    633720
    634                 // Validate that we didn't overflow anything
    635                 // Check that nothing overflowed
    636                 /* paranoid */ verify( true );
    637 
    638                 // Check that it goes head -> tail -> alloc and never head -> alloc -> tail
    639                 /* paranoid */ verify( true );
     721                // Mask the idx now to allow make everything easier to check
     722                idx &= *ring.submit_q.mask;
    640723
    641724                // Return the sqe
    642                 return [&ring.submit_q.sqes[ idx & (*ring.submit_q.mask)], idx];
     725                return [&ring.submit_q.sqes[ idx ], idx];
    643726        }
    644727
    645728        static inline void __submit( struct __io_data & ring, uint32_t idx ) {
    646                 // get mutual exclusion
    647                 lock(ring.submit_q.lock __cfaabi_dbg_ctx2);
    648 
    649                 // Append to the list of ready entries
    650                 uint32_t * tail = ring.submit_q.tail;
     729                // Get now the data we definetely need
     730                uint32_t * const tail = ring.submit_q.tail;
    651731                const uint32_t mask = *ring.submit_q.mask;
    652732
    653                 ring.submit_q.array[ (*tail) & mask ] = idx & mask;
    654                 __atomic_fetch_add(tail, 1ul32, __ATOMIC_SEQ_CST);
    655 
    656                 // Submit however, many entries need to be submitted
    657                 int ret = syscall( __NR_io_uring_enter, ring.fd, 1, 0, 0, 0p, 0);
    658                 if( ret < 0 ) {
    659                         switch((int)errno) {
    660                         default:
    661                                 abort( "KERNEL ERROR: IO_URING SUBMIT - %s\n", strerror(errno) );
    662                         }
    663                 }
    664 
    665                 // update statistics
    666                 #if !defined(__CFA_NO_STATISTICS__)
    667                         ring.submit_q.stats.submit_avg.val += 1;
    668                         ring.submit_q.stats.submit_avg.cnt += 1;
    669                 #endif
    670 
    671                 unlock(ring.submit_q.lock);
    672                 // Make sure that idx was submitted
    673                 // Be careful to not get false positive if we cycled the entire list or that someone else submitted for us
    674                 __cfadbg_print_safe( io, "Kernel I/O : Performed io_submit for %p, returned %d\n", active_thread(), ret );
     733                // There are 2 submission schemes, check which one we are using
     734                if( ring.cltr_flags & CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS ) {
     735                        // If the poller thread submits, then we just need to add this to the ready array
     736
     737                        /* paranoid */ verify( idx <= mask   );
     738                        /* paranoid */ verify( idx != -1ul32 );
     739
     740                        // We need to find a spot in the ready array
     741                        __attribute((unused)) int len   = 0;
     742                        __attribute((unused)) int block = 0;
     743                        uint32_t expected = -1ul32;
     744                        uint32_t ready_mask = ring.submit_q.ready_cnt - 1;
     745                        uint32_t off = __tls_rand();
     746                        LOOKING: for() {
     747                                for(i; ring.submit_q.ready_cnt) {
     748                                        uint32_t ii = (i + off) & ready_mask;
     749                                        if( __atomic_compare_exchange_n( &ring.submit_q.ready[ii], &expected, idx, true, __ATOMIC_SEQ_CST, __ATOMIC_RELAXED ) ) {
     750                                                break LOOKING;
     751                                        }
     752
     753                                        len ++;
     754                                }
     755
     756                                block++;
     757                                yield();
     758                        }
     759
     760                        __wake_poller( ring );
     761
     762                        // update statistics
     763                        #if !defined(__CFA_NO_STATISTICS__)
     764                                __atomic_fetch_add( &ring.submit_q.stats.look_avg.val,   len,   __ATOMIC_RELAXED );
     765                                __atomic_fetch_add( &ring.submit_q.stats.look_avg.block, block, __ATOMIC_RELAXED );
     766                                __atomic_fetch_add( &ring.submit_q.stats.look_avg.cnt,   1,     __ATOMIC_RELAXED );
     767                        #endif
     768
     769                        __cfadbg_print_safe( io, "Kernel I/O : Added %u to ready for %p\n", idx, active_thread() );
     770                }
     771                else {
     772                        // get mutual exclusion
     773                        lock(ring.submit_q.lock __cfaabi_dbg_ctx2);
     774
     775                        // Append to the list of ready entries
     776
     777                        /* paranoid */ verify( idx <= mask );
     778
     779                        ring.submit_q.array[ (*tail) & mask ] = idx & mask;
     780                        __atomic_fetch_add(tail, 1ul32, __ATOMIC_SEQ_CST);
     781
     782                        // Submit however, many entries need to be submitted
     783                        int ret = syscall( __NR_io_uring_enter, ring.fd, 1, 0, 0, 0p, 0);
     784                        if( ret < 0 ) {
     785                                switch((int)errno) {
     786                                default:
     787                                        abort( "KERNEL ERROR: IO_URING SUBMIT - %s\n", strerror(errno) );
     788                                }
     789                        }
     790
     791                        // update statistics
     792                        #if !defined(__CFA_NO_STATISTICS__)
     793                                ring.submit_q.stats.submit_avg.val += 1;
     794                                ring.submit_q.stats.submit_avg.cnt += 1;
     795                        #endif
     796
     797                        unlock(ring.submit_q.lock);
     798
     799                        __cfadbg_print_safe( io, "Kernel I/O : Performed io_submit for %p, returned %d\n", active_thread(), ret );
     800                }
    675801        }
    676802
  • libcfa/src/concurrency/kernel.cfa

    r856fe3e r2223c80  
    256256}
    257257
    258 void ?{}(cluster & this, const char name[], Duration preemption_rate, int io_flags) with( this ) {
     258void ?{}(cluster & this, const char name[], Duration preemption_rate, unsigned io_flags) with( this ) {
    259259        this.name = name;
    260260        this.preemption_rate = preemption_rate;
     
    374374
    375375                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
     376                /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    376377                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor
    377378                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor
     
    384385                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst );
    385386                /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst );
     387                /* paranoid */ verify( kernelTLS.this_thread == thrd_dst );
    386388                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    387389
  • libcfa/src/concurrency/kernel.hfa

    r856fe3e r2223c80  
    116116struct __io_data;
    117117
    118 #define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0
    119 // #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 1
     118#define CFA_CLUSTER_IO_POLLER_USER_THREAD    1 << 0 // 0x1
     119#define CFA_CLUSTER_IO_POLLER_THREAD_SUBMITS 1 << 1 // 0x2
     120// #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 2 // 0x4
     121#define CFA_CLUSTER_IO_BUFFLEN_OFFSET        16
    120122
    121123//-----------------------------------------------------------------------------
     
    159161extern Duration default_preemption();
    160162
    161 void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);
     163void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned flags);
    162164void ^?{}(cluster & this);
    163165
    164 static inline void ?{} (cluster & this)                                      { this{"Anonymous Cluster", default_preemption(), 0}; }
    165 static inline void ?{} (cluster & this, Duration preemption_rate)            { this{"Anonymous Cluster", preemption_rate, 0}; }
    166 static inline void ?{} (cluster & this, const char name[])                   { this{name, default_preemption(), 0}; }
    167 static inline void ?{} (cluster & this, int flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
    168 static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
    169 static inline void ?{} (cluster & this, const char name[], int flags)        { this{name, default_preemption(), flags}; }
     166static inline void ?{} (cluster & this)                                           { this{"Anonymous Cluster", default_preemption(), 0}; }
     167static inline void ?{} (cluster & this, Duration preemption_rate)                 { this{"Anonymous Cluster", preemption_rate, 0}; }
     168static inline void ?{} (cluster & this, const char name[])                        { this{name, default_preemption(), 0}; }
     169static inline void ?{} (cluster & this, unsigned flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
     170static inline void ?{} (cluster & this, Duration preemption_rate, unsigned flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
     171static inline void ?{} (cluster & this, const char name[], unsigned flags)        { this{name, default_preemption(), flags}; }
    170172
    171173static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
  • libcfa/src/concurrency/kernel_private.hfa

    r856fe3e r2223c80  
    7777//-----------------------------------------------------------------------------
    7878// I/O
    79 void __kernel_io_startup     ( cluster &, int, bool );
     79void __kernel_io_startup     ( cluster &, unsigned, bool );
    8080void __kernel_io_finish_start( cluster & );
    8181void __kernel_io_prepare_stop( cluster & );
  • libcfa/src/containers/list.hfa

    r856fe3e r2223c80  
    301301                $prev_link(list_pos) = (Telem*) 0p;
    302302        }
     303
     304        static inline bool ?`is_empty(dlist(Tnode, Telem) &list) {
     305                assert( &list != 0p );
     306                $dlinks(Telem) *listLinks = & list.$links;
     307                if (listLinks->next.is_terminator) {
     308                        assert(listLinks->prev.is_terminator);
     309                        assert(listLinks->next.terminator);
     310                        assert(listLinks->prev.terminator);
     311                        return true;
     312                } else {
     313                        assert(!listLinks->prev.is_terminator);
     314                        assert(listLinks->next.elem);
     315                        assert(listLinks->prev.elem);
     316                        return false;
     317                }
     318        }
     319
     320        static inline Telem & pop_first(dlist(Tnode, Telem) &list) {
     321                assert( &list != 0p );
     322                assert( !list`is_empty );
     323                $dlinks(Telem) *listLinks = & list.$links;
     324                Telem & first = *listLinks->next.elem;
     325                Tnode & list_pos_first  = $tempcv_e2n( first );
     326                remove(list_pos_first);
     327                return first;
     328        }
     329
     330        static inline Telem & pop_last(dlist(Tnode, Telem) &list) {
     331                assert( &list != 0p );
     332                assert( !list`is_empty );
     333                $dlinks(Telem) *listLinks = & list.$links;
     334                Telem & last = *listLinks->prev.elem;
     335                Tnode & list_pos_last  = $tempcv_e2n( last );
     336                remove(list_pos_last);
     337                return last;
     338        }
     339
    303340}
    304341
  • libcfa/src/exception.c

    r856fe3e r2223c80  
    121121
    122122
    123 // TERMINATION ===============================================================
    124 
    125 // MEMORY MANAGEMENT (still for integers)
    126 // May have to move to cfa for constructors and destructors (references).
     123// MEMORY MANAGEMENT =========================================================
    127124
    128125// How to clean up an exception in various situations.
     
    203200}
    204201
    205 // If this isn't a rethrow (*except==0), delete the provided exception.
    206 void __cfaehm_cleanup_terminate( void * except ) {
    207         if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except );
    208 }
     202// CANCELLATION ==============================================================
    209203
    210204// Function needed by force unwind
     
    228222}
    229223
     224// Cancel the current stack, prefroming approprate clean-up and messaging.
     225void __cfaehm_cancel_stack( exception_t * exception ) {
     226        // TODO: Detect current stack and pick a particular stop-function.
     227        _Unwind_Reason_Code ret;
     228        ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
     229        printf("UNWIND ERROR %d after force unwind\n", ret);
     230        abort();
     231}
     232
     233
     234// TERMINATION ===============================================================
     235
     236// If this isn't a rethrow (*except==0), delete the provided exception.
     237void __cfaehm_cleanup_terminate( void * except ) {
     238        if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except );
     239}
     240
    230241// The exception that is being thrown must already be stored.
    231242static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) {
     
    245256        // the whole stack.
    246257
     258        // No handler found, go to the default operation.
     259        // Currently this will always be a cancellation.
    247260        if ( ret == _URC_END_OF_STACK ) {
    248                 // No proper handler was found. This can be handled in many ways, C++ calls std::terminate.
    249                 // Here we force unwind the stack, basically raising a cancellation.
    250                 printf("Uncaught exception %p\n", &this_exception_storage);
    251 
    252                 ret = _Unwind_ForcedUnwind( &this_exception_storage, _Stop_Fn, (void*)0x22 );
    253                 printf("UNWIND ERROR %d after force unwind\n", ret);
    254                 abort();
     261                __cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage);
     262
     263                __cfaehm_cancel_stack(this_exception_context()->current_exception);
    255264        }
    256265
  • libcfa/src/exception.h

    r856fe3e r2223c80  
    3838
    3939
     40void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn));
     41
    4042// Used in throw statement translation.
    4143void __cfaehm_throw_terminate(exception_t * except) __attribute__((noreturn));
  • libcfa/src/exception.hfa

    r856fe3e r2223c80  
    1010// Created On       : Thu Apr  7 10:25:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thu Apr  7 10:25:00 2020
    13 // Update Count     : 0
     12// Last Modified On : Wed Apr 13 15:42:00 2020
     13// Update Count     : 1
    1414//
     15
     16// WARNING: This is for documentation as it will match ANY type.
     17trait is_exception(dtype T) {
     18        /* The first field must be a pointer to a virtual table.
     19         * That virtual table must be a decendent of the base exception virtual table.
     20         */
     21};
     22
     23forall(dtype T | is_exception(T))
     24inline void cancel_stack(T & except) __attribute__((noreturn)) {
     25        __cfaehm_cancel_stack( (exception_t *)&except );
     26}
    1527
    1628// Everything below this line should be considered a patch while the exception
  • libcfa/src/executor.cfa

    r856fe3e r2223c80  
    44// buffer.
    55
    6 #include <bits/containers.hfa>
     6#include <containers/list.hfa>
    77#include <thread.hfa>
    88#include <stdio.h>
    99
    10 forall( dtype T )
    11 monitor Buffer {                                        // unbounded buffer
    12     __queue_t( T ) queue;                               // unbounded list of work requests
    13     condition delay;
    14 }; // Buffer
    15 forall( dtype T | is_node(T) ) {
    16     void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {
    17         append( queue, elem );                          // insert element into buffer
    18         signal( delay );                                // restart
    19     } // insert
    20 
    21     T * remove( Buffer( T ) & mutex buf ) with(buf) {
    22         if ( queue.head != 0 ) wait( delay );                   // no request to process ? => wait
    23 //      return pop_head( queue );
    24     } // remove
    25 } // distribution
    26 
    2710struct WRequest {                                       // client request, no return
    2811    void (* action)( void );
    29     WRequest * next;                                    // intrusive queue field
     12    DLISTED_MGD_IMPL_IN(WRequest)
    3013}; // WRequest
     14DLISTED_MGD_IMPL_OUT(WRequest)
    3115
    32 WRequest *& get_next( WRequest & this ) { return this.next; }
    33 void ?{}( WRequest & req ) with(req) { action = 0; next = 0; }
    34 void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; next = 0; }
     16void ?{}( WRequest & req ) with(req) { action = 0; }
     17void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; }
    3518bool stop( WRequest & req ) { return req.action == 0; }
    3619void doit( WRequest & req ) { req.action(); }
     20
     21monitor WRBuffer {                                      // unbounded buffer
     22    dlist( WRequest, WRequest ) queue;                  // unbounded list of work requests
     23    condition delay;
     24}; // WRBuffer
     25
     26void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) {
     27    insert_last( queue, *elem );                        // insert element into buffer
     28    signal( delay );                                    // restart
     29} // insert
     30
     31WRequest * remove( WRBuffer & mutex buf ) with(buf) {
     32    if ( queue`is_empty ) wait( delay );                // no request to process ? => wait
     33    return & pop_first( queue );
     34} // remove
    3735
    3836// Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and
     
    4038
    4139thread Worker {
    42     Buffer( WRequest ) * requests;
     40    WRBuffer * requests;
    4341    unsigned int start, range;
    4442}; // Worker
     
    5452} // Worker::main
    5553
    56 void ?{}( Worker & worker, cluster * wc, Buffer( WRequest ) * requests, unsigned int start, unsigned int range ) {
     54void ?{}( Worker & worker, cluster * wc, WRBuffer * requests, unsigned int start, unsigned int range ) {
    5755    (*get_thread(worker)){ *wc };                       // create on given cluster
    5856    worker.[requests, start, range] = [requests, start, range];
     
    6260    cluster * cluster;                                  // if workers execute on separate cluster
    6361    processor ** processors;                            // array of virtual processors adding parallelism for workers
    64     Buffer( WRequest ) * requests;                      // list of work requests
     62    WRBuffer * requests;                                // list of work requests
    6563    Worker ** workers;                                  // array of workers executing work requests
    6664    unsigned int nprocessors, nworkers, nmailboxes;     // number of mailboxes/workers/processor tasks
     
    7977    cluster = sepClus ? new( "Executor" ) : active_cluster();
    8078    processors = (processor **)anew( nprocessors );
    81     requests = anew( nmailboxes );
     79    requests = (WRBuffer *)anew( nmailboxes );
    8280    workers = (Worker **)anew( nworkers );
    8381
     
    141139        for ( i; 3000 ) {
    142140            send( exector, workie );
    143             if ( i % 100 ) yield();
     141            if ( i % 100 == 0 ) {
     142//              fprintf( stderr, "%d\n", i );
     143                yield();
     144            }
    144145        } // for
    145146    }
  • tests/exceptions/.expect/resume.txt

    r856fe3e r2223c80  
    44end of try clause
    55Exiting: simple try clause
     6
     7catch-all
    68
    79throwing child exception
  • tests/exceptions/.expect/terminate.txt

    r856fe3e r2223c80  
    33simple catch
    44Exiting: simple catch clause
     5
     6catch-all
    57
    68throwing child exception
  • tests/exceptions/resume.cfa

    r856fe3e r2223c80  
    1919                loud_exit a = "simple catch clause";
    2020                printf("simple catch\n");
     21        }
     22        printf("\n");
     23
     24        // Throw catch-all test.
     25        try {
     26                throwResume &(zen){};
     27        } catchResume (exception_t * error) {
     28                printf("catch-all\n");
    2129        }
    2230        printf("\n");
  • tests/exceptions/terminate.cfa

    r856fe3e r2223c80  
    1717                printf("end of try clause\n");
    1818        } catch (zen * error) {
    19         loud_exit a = "simple catch clause";
     19                loud_exit a = "simple catch clause";
    2020                printf("simple catch\n");
     21        }
     22        printf("\n");
     23
     24        // Throw catch-all test.
     25        try {
     26                throw &(zen){};
     27        } catch (exception_t * error) {
     28                printf("catch-all\n");
    2129        }
    2230        printf("\n");
  • tests/list/.expect/dlist-insert-remove.txt

    r856fe3e r2223c80  
    146414640.7
    14651465-
     1466
     1467~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~
     1468
     1469~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1470Test 16-i.  Modifying Freds on MINE
     1471~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1472==== fred by MINE before
     14731.7
     14742.7
     14753.7
     1476-
     14771.7
     1478-
     14793.7
     1480-
     14813.7
     14822.7
     14831.7
     1484-
     1485==== fred by YOURS before
     14861.7
     14872.7
     14883.7
     1489-
     14901.7
     1491-
     14923.7
     1493-
     14943.7
     14952.7
     14961.7
     1497-
     1498==== fred by MINE after
     14992.7
     15003.7
     1501-
     15022.7
     1503-
     15043.7
     1505-
     15063.7
     15072.7
     1508-
     1509==== fred by YOURS after
     15101.7
     15112.7
     15123.7
     1513-
     15141.7
     1515-
     15163.7
     1517-
     15183.7
     15192.7
     15201.7
     1521-
     1522==== fred by MINE after
     15231.7
     1524-
     15251.7
     1526-
     1527-
     1528-
     1529~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1530Test 16-ii.  Modifying Freds on YOURS
     1531~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1532==== fred by MINE before
     15331.7
     15342.7
     15353.7
     1536-
     15371.7
     1538-
     15393.7
     1540-
     15413.7
     15422.7
     15431.7
     1544-
     1545==== fred by YOURS before
     15461.7
     15472.7
     15483.7
     1549-
     15501.7
     1551-
     15523.7
     1553-
     15543.7
     15552.7
     15561.7
     1557-
     1558==== fred by MINE after
     15591.7
     15602.7
     15613.7
     1562-
     15631.7
     1564-
     15653.7
     1566-
     15673.7
     15682.7
     15691.7
     1570-
     1571==== fred by YOURS after
     15722.7
     15733.7
     1574-
     15752.7
     1576-
     15773.7
     1578-
     15793.7
     15802.7
     1581-
     1582==== fred by YOURS after
     15831.7
     1584-
     15851.7
     1586-
     1587-
     1588-
     1589~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1590Test 16-iii.  Modifying Maries
     1591~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1592==== mary before
     15931.7
     15942.7
     15953.7
     1596-
     15971.7
     1598-
     15993.7
     1600-
     16013.7
     16022.7
     16031.7
     1604-
     1605==== mary after
     16062.7
     16073.7
     1608-
     16092.7
     1610-
     16113.7
     1612-
     16133.7
     16142.7
     1615-
     1616==== mary after
     16171.7
     1618-
     16191.7
     1620-
     1621-
     1622-
     1623
     1624~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~
     1625
     1626~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1627Test 17-i.  Modifying Freds on MINE
     1628~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1629==== fred by MINE before
     16301.7
     16312.7
     16323.7
     1633-
     16341.7
     1635-
     16363.7
     1637-
     16383.7
     16392.7
     16401.7
     1641-
     1642==== fred by YOURS before
     16431.7
     16442.7
     16453.7
     1646-
     16471.7
     1648-
     16493.7
     1650-
     16513.7
     16522.7
     16531.7
     1654-
     1655==== fred by MINE after
     16561.7
     16572.7
     1658-
     16591.7
     1660-
     16612.7
     1662-
     16632.7
     16641.7
     1665-
     1666==== fred by YOURS after
     16671.7
     16682.7
     16693.7
     1670-
     16711.7
     1672-
     16733.7
     1674-
     16753.7
     16762.7
     16771.7
     1678-
     1679==== fred by MINE after
     16803.7
     1681-
     16823.7
     1683-
     1684-
     1685-
     1686~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1687Test 17-ii.  Modifying Freds on YOURS
     1688~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1689==== fred by MINE before
     16901.7
     16912.7
     16923.7
     1693-
     16941.7
     1695-
     16963.7
     1697-
     16983.7
     16992.7
     17001.7
     1701-
     1702==== fred by YOURS before
     17031.7
     17042.7
     17053.7
     1706-
     17071.7
     1708-
     17093.7
     1710-
     17113.7
     17122.7
     17131.7
     1714-
     1715==== fred by MINE after
     17161.7
     17172.7
     17183.7
     1719-
     17201.7
     1721-
     17223.7
     1723-
     17243.7
     17252.7
     17261.7
     1727-
     1728==== fred by YOURS after
     17291.7
     17302.7
     1731-
     17321.7
     1733-
     17342.7
     1735-
     17362.7
     17371.7
     1738-
     1739==== fred by YOURS after
     17403.7
     1741-
     17423.7
     1743-
     1744-
     1745-
     1746~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1747Test 17-iii.  Modifying Maries
     1748~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     1749==== mary before
     17501.7
     17512.7
     17523.7
     1753-
     17541.7
     1755-
     17563.7
     1757-
     17583.7
     17592.7
     17601.7
     1761-
     1762==== mary after
     17631.7
     17642.7
     1765-
     17661.7
     1767-
     17682.7
     1769-
     17702.7
     17711.7
     1772-
     1773==== mary after
     17743.7
     1775-
     17763.7
     1777-
     1778-
     1779-
  • tests/list/dlist-insert-remove.cfa

    r856fe3e r2223c80  
    11871187////////////////////////////////////////////////////////////
    11881188//
     1189// Section 4f
     1190//
     1191// Test cases of pop_first, pop_last
     1192//
     1193// Example of call-side user code
     1194//
     1195////////////////////////////////////////////////////////////
     1196
     1197// These cases assume element removal at first-last is correct
     1198
     1199void test__pop_first__fred_mine() {
     1200
     1201        fred f1 = {1.7};
     1202        fred f2 = {2.7};
     1203        fred f3 = {3.7};
     1204
     1205        dlist(fred_in_mine, fred) flm;
     1206        insert_last(flm, f1);
     1207        insert_last(flm, f2);
     1208        insert_last(flm, f3);
     1209
     1210        dlist(fred_in_yours, fred) fly;
     1211        insert_last(fly, f1);
     1212        insert_last(fly, f2);
     1213        insert_last(fly, f3);
     1214
     1215        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1216        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1217
     1218        verify(validate(fly));
     1219        verify(validate(flm));
     1220
     1221        fred & popped = pop_first(flm);
     1222
     1223        verify(validate(fly));
     1224        verify(validate(flm));
     1225
     1226        printMyFreddies(flm`first, flm`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1227        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1228
     1229        // observe f1 is now solo in mine; in yours, it was just traversed
     1230        printMyFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
     1231
     1232        assert( &popped == & f1 );
     1233}
     1234
     1235void test__pop_first__fred_yours() {
     1236
     1237        fred f1 = {1.7};
     1238        fred f2 = {2.7};
     1239        fred f3 = {3.7};
     1240
     1241        dlist(fred_in_mine, fred) flm;
     1242        insert_last(flm, f1);
     1243        insert_last(flm, f2);
     1244        insert_last(flm, f3);
     1245
     1246        dlist(fred_in_yours, fred) fly;
     1247        insert_last(fly, f1);
     1248        insert_last(fly, f2);
     1249        insert_last(fly, f3);
     1250
     1251        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1252        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1253
     1254        verify(validate(fly));
     1255        verify(validate(flm));
     1256
     1257        fred & popped = pop_first(fly);
     1258
     1259        verify(validate(fly));
     1260        verify(validate(flm));
     1261
     1262        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1263        printYourFreddies(fly`first, fly`last, 0);   // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1264
     1265        // observe f1 is now solo in yours; in mine, it was just traversed
     1266        printYourFreddies(f1, *0p, 0);    // 1.7; 1.7; ;
     1267
     1268        assert( &popped == &f1 );
     1269}
     1270
     1271void test__pop_first__maries() {
     1272
     1273        mary m1 = {1.7};
     1274        mary m2 = {2.7};
     1275        mary m3 = {3.7};
     1276
     1277        dlist(mary, mary) ml;
     1278        insert_last(ml, m1);
     1279        insert_last(ml, m2);
     1280        insert_last(ml, m3);
     1281
     1282        printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1283
     1284        verify(validate(ml));
     1285
     1286        mary & popped = pop_first(ml);
     1287
     1288        verify(validate(ml));
     1289
     1290        printMariatheotokos(ml`first, ml`last, 0);     // 2.7, 3.7;       2.7;  3.7;  3.7, 2.7      (modified)
     1291
     1292        // observe m1 is now solo
     1293        printMariatheotokos(m1, *0p, 0);               // 1.7; 1.7; ;
     1294
     1295        assert( &popped == &m1 );
     1296}
     1297
     1298void test__pop_last__fred_mine() {
     1299
     1300        fred f1 = {1.7};
     1301        fred f2 = {2.7};
     1302        fred f3 = {3.7};
     1303
     1304        dlist(fred_in_mine, fred) flm;
     1305        insert_last(flm, f1);
     1306        insert_last(flm, f2);
     1307        insert_last(flm, f3);
     1308
     1309        dlist(fred_in_yours, fred) fly;
     1310        insert_last(fly, f1);
     1311        insert_last(fly, f2);
     1312        insert_last(fly, f3);
     1313
     1314        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1315        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1316
     1317        verify(validate(fly));
     1318        verify(validate(flm));
     1319
     1320        fred & popped = pop_last(flm);
     1321
     1322        verify(validate(fly));
     1323        verify(validate(flm));
     1324
     1325        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1326        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1327
     1328        // observe f3 is now solo in mine; in yours, it was just traversed
     1329        printMyFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
     1330
     1331        assert( &popped == & f3 );
     1332}
     1333
     1334void test__pop_last__fred_yours() {
     1335
     1336        fred f1 = {1.7};
     1337        fred f2 = {2.7};
     1338        fred f3 = {3.7};
     1339
     1340        dlist(fred_in_mine, fred) flm;
     1341        insert_last(flm, f1);
     1342        insert_last(flm, f2);
     1343        insert_last(flm, f3);
     1344
     1345        dlist(fred_in_yours, fred) fly;
     1346        insert_last(fly, f1);
     1347        insert_last(fly, f2);
     1348        insert_last(fly, f3);
     1349
     1350        printMyFreddies(flm`first, flm`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1351        printYourFreddies(fly`first, fly`last, 1);   // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1352
     1353        verify(validate(fly));
     1354        verify(validate(flm));
     1355
     1356        fred & popped = pop_last(fly);
     1357
     1358        verify(validate(fly));
     1359        verify(validate(flm));
     1360
     1361        printMyFreddies(flm`first, flm`last, 0);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7 (unmodified)
     1362        printYourFreddies(fly`first, fly`last, 0);   // 1.7, 2.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1363
     1364        // observe f3 is now solo in yours; in mine, it was just traversed
     1365        printYourFreddies(f3, *0p, 0);    // 3.7; 3.7; ;
     1366
     1367        assert( &popped == & f3 );
     1368}
     1369
     1370void test__pop_last__maries() {
     1371
     1372        mary m1 = {1.7};
     1373        mary m2 = {2.7};
     1374        mary m3 = {3.7};
     1375
     1376        dlist(mary, mary) ml;
     1377        insert_last(ml, m1);
     1378        insert_last(ml, m2);
     1379        insert_last(ml, m3);
     1380
     1381        printMariatheotokos(ml`first, ml`last, 1);     // 1.7, 2.7, 3.7;  1.7;  3.7;  3.7, 2.7, 1.7
     1382
     1383        verify(validate(ml));
     1384
     1385        mary & popped = pop_last(ml);
     1386
     1387        verify(validate(ml));
     1388
     1389        printMariatheotokos(ml`first, ml`last, 0);     // 1.7, 1.7;       1.7;  2.7;  2.7, 1.7      (modified)
     1390
     1391        // observe m1 is now solo
     1392        printMariatheotokos(m3, *0p, 0);               // 3.7; 3.7; ;
     1393
     1394        assert( &popped == &m3 );
     1395}
     1396
     1397////////////////////////////////////////////////////////////
     1398//
    11891399// Section 5
    11901400//
     
    14221632        test__remove_of_sole__mary();
    14231633
     1634        sout | "";
     1635        sout | "~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~";
     1636        sout | "";
     1637
     1638        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1639        sout | "Test 16-i.  Modifying Freds on MINE";
     1640        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1641        test__pop_first__fred_mine();
     1642
     1643        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1644        sout | "Test 16-ii.  Modifying Freds on YOURS";
     1645        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1646        test__pop_first__fred_yours();
     1647
     1648        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1649        sout | "Test 16-iii.  Modifying Maries";
     1650        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1651        test__pop_first__maries();
     1652
     1653        sout | "";
     1654        sout | "~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~";
     1655        sout | "";
     1656
     1657        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1658        sout | "Test 17-i.  Modifying Freds on MINE";
     1659        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1660        test__pop_last__fred_mine();
     1661
     1662        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1663        sout | "Test 17-ii.  Modifying Freds on YOURS";
     1664        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1665        test__pop_last__fred_yours();
     1666
     1667        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1668        sout | "Test 17-iii.  Modifying Maries";
     1669        sout | "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
     1670        test__pop_last__maries();
     1671
    14241672        return 0;
    14251673}
  • tools/build/push2dist.sh

    r856fe3e r2223c80  
    22
    33hash="$1"
     4bwlim="$2"
    45valid=$(distcc -j 2> /dev/null)
    56# if test "${valid}" != 0
     
    2425function push() {
    2526        ssh ${host} "mkdir -p ~/.cfadistcc/${hash}/"
    26         rsync -a ${dV} ${files} ${host}:~/.cfadistcc/${hash}/.
     27        rsync --bwlimit=${bwlim} -a ${dV} ${files} ${host}:~/.cfadistcc/${hash}/.
    2728}
    2829
Note: See TracChangeset for help on using the changeset viewer.