Changes in / [2223c80:856fe3e]


Ignore:
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • benchmark/io/readv.cfa

    r2223c80 r856fe3e  
    5959        unsigned long int nthreads = 2;
    6060        unsigned long int nprocs   = 1;
    61         unsigned flags = 0;
    62         unsigned sublen = 16;
     61        int flags = 0;
    6362
    6463        arg_loop:
    6564        for(;;) {
    6665                static struct option options[] = {
    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'},
     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'},
    7471                        {0, 0, 0, 0}
    7572                };
    7673
    7774                int idx = 0;
    78                 int opt = getopt_long(argc, argv, "d:t:p:b:usl:", options, &idx);
     75                int opt = getopt_long(argc, argv, "d:t:p:b:u", options, &idx);
    7976
    8077                const char * arg = optarg ? optarg : "";
     
    116113                                flags |= CFA_CLUSTER_IO_POLLER_USER_THREAD;
    117114                                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;
    129115                        // Other cases
    130116                        default: /* ? */
     
    137123                                fprintf(stderr, "  -p, --nprocs=NPROCS      Number of kernel threads\n");
    138124                                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");
    141125                                exit(EXIT_FAILURE);
    142126                }
  • configure

    r2223c80 r856fe3e  
    802802with_cfa_name
    803803enable_distcc
    804 with_bwlimit
    805804with_target_hosts
    806805enable_gprofiler
     
    14821481  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
    14831482  --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
    14851483  --with-target-hosts=HOSTS     HOSTS comma seperated list of hosts to build for, format ARCH:debug|nodebug|nolib
    14861484  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
     
    32003198else
    32013199  enable_distcc=no
    3202 fi
    3203 
    3204 
    3205 
    3206 # Check whether --with-bwlimit was given.
    3207 if test "${with_bwlimit+set}" = set; then :
    3208   withval=$with_bwlimit;
    32093200fi
    32103201
  • configure.ac

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

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

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

    r2223c80 r856fe3e  
    707707CONFIG_CFLAGS
    708708ARCH_FLAGS
    709 DIST_BWLIMIT
    710709CFADIR_HASH
    711710LOCAL_CC1
     
    790789enable_silent_rules
    791790enable_distcc
    792 with_bwlimit
    793791with_cfa_name
    794792enable_static
     
    14671465  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
    14681466  --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
    14701467  --with-cfa-name=NAME     NAME too which cfa will be installed
    14711468  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
     
    30503047
    30513048
    3052 
    3053 # Check whether --with-bwlimit was given.
    3054 if test "${with_bwlimit+set}" = set; then :
    3055   withval=$with_bwlimit; DIST_BWLIMIT=$withval
    3056 else
    3057   DIST_BWLIMIT=0
    3058 fi
    3059 
    3060 
    30613049echo -n "checking for distributated build... "
    30623050if test x$enable_distcc = xno; then
     
    30823070  ENABLE_DISTCC_FALSE=
    30833071fi
    3084 
    30853072
    30863073
  • libcfa/configure.ac

    r2223c80 r856fe3e  
    3131        enable_distcc=$enableval, enable_distcc=no)
    3232
    33 AC_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 
    3733echo -n "checking for distributated build... "
    3834if test x$enable_distcc = xno; then
     
    5955AC_SUBST(CFADIR_HASH)
    6056AC_SUBST(CFA_VERSION)
    61 AC_SUBST(DIST_BWLIMIT)
    6257
    6358#==============================================================================
  • libcfa/prelude/Makefile.am

    r2223c80 r856fe3e  
    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@ @DIST_BWLIMIT@
     74        ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
    7575        @echo "Dummy file to track distribution to remote hosts" > ${@}
    7676
  • libcfa/prelude/Makefile.in

    r2223c80 r856fe3e  
    215215DEFS = @DEFS@
    216216DEPDIR = @DEPDIR@
    217 DIST_BWLIMIT = @DIST_BWLIMIT@
    218217DLLTOOL = @DLLTOOL@
    219218DRIVER_DIR = @DRIVER_DIR@
     
    656655
    657656@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
    658 @ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@ @DIST_BWLIMIT@
     657@ENABLE_DISTCC_TRUE@    ${AM_V_GEN}$(srcdir)/../../tools/build/push2dist.sh @CFADIR_HASH@
    659658@ENABLE_DISTCC_TRUE@    @echo "Dummy file to track distribution to remote hosts" > ${@}
    660659
  • libcfa/src/Makefile.in

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

    r2223c80 r856fe3e  
    1818
    1919#include "kernel.hfa"
    20 #include "bitmanip.hfa"
    2120
    2221#if !defined(HAVE_LINUX_IO_URING_H)
    23         void __kernel_io_startup( cluster &, unsigned, bool ) {
     22        void __kernel_io_startup( cluster &, int, bool ) {
    2423                // Nothing to do without io_uring
    2524        }
     
    9291        struct __io_poller_fast {
    9392                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;
    99100                (this.thrd){ "Fast I/O Poller", cltr };
    100101        }
     
    125126                // Like head/tail but not seen by the kernel
    126127                volatile uint32_t alloc;
    127                 volatile uint32_t * ready;
    128                 uint32_t ready_cnt;
     128                volatile uint32_t ready;
    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;
    152147                        } stats;
    153148                #endif
     
    197192                                void * stack;
    198193                                pthread_t kthrd;
    199                                 volatile bool blocked;
    200194                        } slow;
    201195                        __io_poller_fast fast;
     
    207201// I/O Startup / Shutdown logic
    208202//=============================================================================================
    209         void __kernel_io_startup( cluster & this, unsigned io_flags, bool main_cluster ) {
     203        void __kernel_io_startup( cluster & this, int io_flags, bool main_cluster ) {
    210204                this.io = malloc();
    211205
     
    280274                sq.array   = (         uint32_t *)(((intptr_t)sq.ring_ptr) + params.sq_off.array);
    281275                sq.alloc = *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                 }
     276                sq.ready = *sq.tail;
    295277
    296278                // completion queue
     
    325307                        this.io->submit_q.stats.submit_avg.cnt   = 0;
    326308                        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;
    330309                        this.io->completion_q.stats.completed_avg.val = 0;
    331310                        this.io->completion_q.stats.completed_avg.slow_cnt = 0;
     
    347326                // Create the poller thread
    348327                __cfadbg_print_safe(io_core, "Kernel I/O : Creating slow poller for cluter %p\n", &this);
    349                 this.io->poller.slow.blocked = false;
    350328                this.io->poller.slow.stack = __create_pthread( &this.io->poller.slow.kthrd, __io_poller_slow, &this );
    351329        }
     
    369347                if( this.io->cltr_flags & CFA_CLUSTER_IO_POLLER_USER_THREAD ) {
    370348                        with( this.io->poller.fast ) {
     349                                /* paranoid */ verify( waiting ); // The thread shouldn't be in a system call
    371350                                /* paranoid */ verify( this.procs.head == 0p || &this == mainCluster );
    372351                                /* paranoid */ verify( this.idles.head == 0p || &this == mainCluster );
    373352
    374353                                // We need to adjust the clean-up based on where the thread is
    375                                 if( thrd.state == Ready || thrd.preempted != __NO_PREEMPTION ) {
     354                                if( thrd.preempted != __NO_PREEMPTION ) {
    376355
    377356                                        // This is the tricky case
    378357                                        // 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
    379359                                        /* paranoid */ verify( thrd.next == 1p );                // The thread should be the last on the list
    380360                                        /* paranoid */ verify( this.ready_queue.head == &thrd ); // The thread should be the only thing on the list
     
    425405                        if(this.print_stats) {
    426406                                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 
    434407                                        __cfaabi_bits_print_safe( STDERR_FILENO,
    435408                                                "----- I/O uRing Stats -----\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",
     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",
    444414                                                submit_avg.cnt,
    445415                                                ((double)submit_avg.val) / submit_avg.cnt,
    446416                                                (100.0 * submit_avg.block) / submit_avg.cnt,
    447                                                 look_avg.cnt,
    448                                                 lavgv,
    449                                                 lavgb,
    450417                                                completed_avg.slow_cnt + completed_avg.fast_cnt,
    451418                                                completed_avg.slow_cnt,  completed_avg.fast_cnt,
     
    474441                close(this.io->fd);
    475442
    476                 free( this.io->submit_q.ready ); // Maybe null, doesn't matter
    477443                free( this.io );
    478444        }
     
    488454        // Process a single completion message from the io_uring
    489455        // This is NOT thread-safe
    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);
     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);
    522458                if( ret < 0 ) {
    523459                        switch((int)errno) {
     
    561497                __atomic_fetch_add( ring.completion_q.head, count, __ATOMIC_RELAXED );
    562498
    563                 return [count, count > 0 || to_submit > 0];
     499                return count;
    564500        }
    565501
     
    583519                if( ring.cltr_flags & CFA_CLUSTER_IO_POLLER_USER_THREAD ) {
    584520                        while(!__atomic_load_n(&ring.done, __ATOMIC_SEQ_CST)) {
    585 
    586                                 __atomic_store_n( &ring.poller.slow.blocked, true, __ATOMIC_SEQ_CST );
    587 
    588521                                // In the user-thread approach drain and if anything was drained,
    589522                                // batton pass to the user-thread
    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 );
     523                                int count = __drain_io( ring, &mask, 1, true );
    595524
    596525                                // Update statistics
     
    600529                                #endif
    601530
    602                                 if(again) {
     531                                if(count > 0) {
    603532                                        __cfadbg_print_safe(io_core, "Kernel I/O : Moving to ring %p to fast poller\n", &ring);
    604533                                        __unpark( &ring.poller.fast.thrd __cfaabi_dbg_ctx2 );
     
    610539                        while(!__atomic_load_n(&ring.done, __ATOMIC_SEQ_CST)) {
    611540                                //In the naive approach, just poll the io completion queue directly
    612                                 int count;
    613                                 bool again;
    614                                 [count, again] = __drain_io( ring, &mask, 1, true );
     541                                int count = __drain_io( ring, &mask, 1, true );
    615542
    616543                                // Update statistics
     
    639566                // Then loop until we need to start
    640567                while(!__atomic_load_n(&this.ring->done, __ATOMIC_SEQ_CST)) {
    641 
    642568                        // Drain the io
    643                         int count;
    644                         bool again;
    645                         [count, again] = __drain_io( *this.ring, 0p, 0, false );
    646 
    647                         if(!again) reset++;
     569                        this.waiting = false;
     570                        int count = __drain_io( *this.ring, 0p, 0, false );
     571                        reset += count > 0 ? 1 : 0;
    648572
    649573                        // Update statistics
     
    653577                        #endif
    654578
    655                         // If we got something, just yield and check again
     579                        this.waiting = true;
    656580                        if(reset < 5) {
     581                                // If we got something, just yield and check again
    657582                                yield();
    658583                        }
    659                         // We didn't get anything baton pass to the slow poller
    660584                        else {
     585                                // We didn't get anything baton pass to the slow poller
    661586                                __cfadbg_print_safe(io_core, "Kernel I/O : Moving to ring %p to slow poller\n", &this.ring);
     587                                post( this.ring->poller.sem );
     588                                park( __cfaabi_dbg_ctx );
    662589                                reset = 0;
    663 
    664                                 // wake up the slow poller
    665                                 post( this.ring->poller.sem );
    666 
    667                                 // park this thread
    668                                 park( __cfaabi_dbg_ctx );
    669590                        }
    670591                }
    671592
    672593                __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 );
    681594        }
    682595
     
    719632                uint32_t idx = __atomic_fetch_add(&ring.submit_q.alloc, 1ul32, __ATOMIC_SEQ_CST);
    720633
    721                 // Mask the idx now to allow make everything easier to check
    722                 idx &= *ring.submit_q.mask;
     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 );
    723640
    724641                // Return the sqe
    725                 return [&ring.submit_q.sqes[ idx ], idx];
     642                return [&ring.submit_q.sqes[ idx & (*ring.submit_q.mask)], idx];
    726643        }
    727644
    728645        static inline void __submit( struct __io_data & ring, uint32_t idx ) {
    729                 // Get now the data we definetely need
    730                 uint32_t * const tail = ring.submit_q.tail;
     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;
    731651                const uint32_t mask = *ring.submit_q.mask;
    732652
    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();
     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) );
    758662                        }
    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                 }
     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 );
    801675        }
    802676
  • libcfa/src/concurrency/kernel.cfa

    r2223c80 r856fe3e  
    256256}
    257257
    258 void ?{}(cluster & this, const char name[], Duration preemption_rate, unsigned io_flags) with( this ) {
     258void ?{}(cluster & this, const char name[], Duration preemption_rate, int 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 );
    377376                /* 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
    378377                /* 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
     
    385384                /* 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 );
    386385                /* 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 );
    388386                /* paranoid */ verify( ! kernelTLS.preemption_state.enabled );
    389387
  • libcfa/src/concurrency/kernel.hfa

    r2223c80 r856fe3e  
    116116struct __io_data;
    117117
    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
     118#define CFA_CLUSTER_IO_POLLER_USER_THREAD 1 << 0
     119// #define CFA_CLUSTER_IO_POLLER_KERNEL_SIDE 1 << 1
    122120
    123121//-----------------------------------------------------------------------------
     
    161159extern Duration default_preemption();
    162160
    163 void ?{} (cluster & this, const char name[], Duration preemption_rate, unsigned flags);
     161void ?{} (cluster & this, const char name[], Duration preemption_rate, int flags);
    164162void ^?{}(cluster & this);
    165163
    166 static inline void ?{} (cluster & this)                                           { this{"Anonymous Cluster", default_preemption(), 0}; }
    167 static inline void ?{} (cluster & this, Duration preemption_rate)                 { this{"Anonymous Cluster", preemption_rate, 0}; }
    168 static inline void ?{} (cluster & this, const char name[])                        { this{name, default_preemption(), 0}; }
    169 static inline void ?{} (cluster & this, unsigned flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
    170 static inline void ?{} (cluster & this, Duration preemption_rate, unsigned flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
    171 static inline void ?{} (cluster & this, const char name[], unsigned flags)        { this{name, default_preemption(), flags}; }
     164static inline void ?{} (cluster & this)                                      { this{"Anonymous Cluster", default_preemption(), 0}; }
     165static inline void ?{} (cluster & this, Duration preemption_rate)            { this{"Anonymous Cluster", preemption_rate, 0}; }
     166static inline void ?{} (cluster & this, const char name[])                   { this{name, default_preemption(), 0}; }
     167static inline void ?{} (cluster & this, int flags)                           { this{"Anonymous Cluster", default_preemption(), flags}; }
     168static inline void ?{} (cluster & this, Duration preemption_rate, int flags) { this{"Anonymous Cluster", preemption_rate, flags}; }
     169static inline void ?{} (cluster & this, const char name[], int flags)        { this{name, default_preemption(), flags}; }
    172170
    173171static inline [cluster *&, cluster *& ] __get( cluster & this ) __attribute__((const)) { return this.node.[next, prev]; }
  • libcfa/src/concurrency/kernel_private.hfa

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

    r2223c80 r856fe3e  
    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 
    340303}
    341304
  • libcfa/src/exception.c

    r2223c80 r856fe3e  
    121121
    122122
    123 // MEMORY MANAGEMENT =========================================================
     123// TERMINATION ===============================================================
     124
     125// MEMORY MANAGEMENT (still for integers)
     126// May have to move to cfa for constructors and destructors (references).
    124127
    125128// How to clean up an exception in various situations.
     
    200203}
    201204
    202 // CANCELLATION ==============================================================
     205// If this isn't a rethrow (*except==0), delete the provided exception.
     206void __cfaehm_cleanup_terminate( void * except ) {
     207        if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except );
     208}
    203209
    204210// Function needed by force unwind
     
    222228}
    223229
    224 // Cancel the current stack, prefroming approprate clean-up and messaging.
    225 void __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.
    237 void __cfaehm_cleanup_terminate( void * except ) {
    238         if ( *(void**)except ) __cfaehm_delete_exception( *(exception_t **)except );
    239 }
    240 
    241230// The exception that is being thrown must already be stored.
    242231static __attribute__((noreturn)) void __cfaehm_begin_unwind(void) {
     
    256245        // the whole stack.
    257246
    258         // No handler found, go to the default operation.
    259         // Currently this will always be a cancellation.
    260247        if ( ret == _URC_END_OF_STACK ) {
    261                 __cfadbg_print_safe(exception, "Uncaught exception %p\n", &this_exception_storage);
    262 
    263                 __cfaehm_cancel_stack(this_exception_context()->current_exception);
     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();
    264255        }
    265256
  • libcfa/src/exception.h

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

    r2223c80 r856fe3e  
    1010// Created On       : Thu Apr  7 10:25:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Apr 13 15:42:00 2020
    13 // Update Count     : 1
     12// Last Modified On : Thu Apr  7 10:25:00 2020
     13// Update Count     : 0
    1414//
    15 
    16 // WARNING: This is for documentation as it will match ANY type.
    17 trait 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 
    23 forall(dtype T | is_exception(T))
    24 inline void cancel_stack(T & except) __attribute__((noreturn)) {
    25         __cfaehm_cancel_stack( (exception_t *)&except );
    26 }
    2715
    2816// Everything below this line should be considered a patch while the exception
  • libcfa/src/executor.cfa

    r2223c80 r856fe3e  
    44// buffer.
    55
    6 #include <containers/list.hfa>
     6#include <bits/containers.hfa>
    77#include <thread.hfa>
    88#include <stdio.h>
    99
     10forall( dtype T )
     11monitor Buffer {                                        // unbounded buffer
     12    __queue_t( T ) queue;                               // unbounded list of work requests
     13    condition delay;
     14}; // Buffer
     15forall( 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
    1027struct WRequest {                                       // client request, no return
    1128    void (* action)( void );
    12     DLISTED_MGD_IMPL_IN(WRequest)
     29    WRequest * next;                                    // intrusive queue field
    1330}; // WRequest
    14 DLISTED_MGD_IMPL_OUT(WRequest)
    1531
    16 void ?{}( WRequest & req ) with(req) { action = 0; }
    17 void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; }
     32WRequest *& get_next( WRequest & this ) { return this.next; }
     33void ?{}( WRequest & req ) with(req) { action = 0; next = 0; }
     34void ?{}( WRequest & req, void (* action)( void ) ) with(req) { req.action = action; next = 0; }
    1835bool stop( WRequest & req ) { return req.action == 0; }
    1936void doit( WRequest & req ) { req.action(); }
    20 
    21 monitor WRBuffer {                                      // unbounded buffer
    22     dlist( WRequest, WRequest ) queue;                  // unbounded list of work requests
    23     condition delay;
    24 }; // WRBuffer
    25 
    26 void insert( WRBuffer & mutex buf, WRequest * elem ) with(buf) {
    27     insert_last( queue, *elem );                        // insert element into buffer
    28     signal( delay );                                    // restart
    29 } // insert
    30 
    31 WRequest * 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
    3537
    3638// Each worker has its own work buffer to reduce contention between client and server. Hence, work requests arrive and
     
    3840
    3941thread Worker {
    40     WRBuffer * requests;
     42    Buffer( WRequest ) * requests;
    4143    unsigned int start, range;
    4244}; // Worker
     
    5254} // Worker::main
    5355
    54 void ?{}( Worker & worker, cluster * wc, WRBuffer * requests, unsigned int start, unsigned int range ) {
     56void ?{}( Worker & worker, cluster * wc, Buffer( WRequest ) * requests, unsigned int start, unsigned int range ) {
    5557    (*get_thread(worker)){ *wc };                       // create on given cluster
    5658    worker.[requests, start, range] = [requests, start, range];
     
    6062    cluster * cluster;                                  // if workers execute on separate cluster
    6163    processor ** processors;                            // array of virtual processors adding parallelism for workers
    62     WRBuffer * requests;                                // list of work requests
     64    Buffer( WRequest ) * requests;                      // list of work requests
    6365    Worker ** workers;                                  // array of workers executing work requests
    6466    unsigned int nprocessors, nworkers, nmailboxes;     // number of mailboxes/workers/processor tasks
     
    7779    cluster = sepClus ? new( "Executor" ) : active_cluster();
    7880    processors = (processor **)anew( nprocessors );
    79     requests = (WRBuffer *)anew( nmailboxes );
     81    requests = anew( nmailboxes );
    8082    workers = (Worker **)anew( nworkers );
    8183
     
    139141        for ( i; 3000 ) {
    140142            send( exector, workie );
    141             if ( i % 100 == 0 ) {
    142 //              fprintf( stderr, "%d\n", i );
    143                 yield();
    144             }
     143            if ( i % 100 ) yield();
    145144        } // for
    146145    }
  • tests/exceptions/.expect/resume.txt

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

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

    r2223c80 r856fe3e  
    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");
    2921        }
    3022        printf("\n");
  • tests/exceptions/terminate.cfa

    r2223c80 r856fe3e  
    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");
    2921        }
    3022        printf("\n");
  • tests/list/.expect/dlist-insert-remove.txt

    r2223c80 r856fe3e  
    146414640.7
    14651465-
    1466 
    1467 ~~~~~~~~~~ End removal tests on Headed List: First ~~~~~~~~~~
    1468 
    1469 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1470 Test 16-i.  Modifying Freds on MINE
    1471 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1472 ==== fred by MINE before
    1473 1.7
    1474 2.7
    1475 3.7
    1476 -
    1477 1.7
    1478 -
    1479 3.7
    1480 -
    1481 3.7
    1482 2.7
    1483 1.7
    1484 -
    1485 ==== fred by YOURS before
    1486 1.7
    1487 2.7
    1488 3.7
    1489 -
    1490 1.7
    1491 -
    1492 3.7
    1493 -
    1494 3.7
    1495 2.7
    1496 1.7
    1497 -
    1498 ==== fred by MINE after
    1499 2.7
    1500 3.7
    1501 -
    1502 2.7
    1503 -
    1504 3.7
    1505 -
    1506 3.7
    1507 2.7
    1508 -
    1509 ==== fred by YOURS after
    1510 1.7
    1511 2.7
    1512 3.7
    1513 -
    1514 1.7
    1515 -
    1516 3.7
    1517 -
    1518 3.7
    1519 2.7
    1520 1.7
    1521 -
    1522 ==== fred by MINE after
    1523 1.7
    1524 -
    1525 1.7
    1526 -
    1527 -
    1528 -
    1529 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1530 Test 16-ii.  Modifying Freds on YOURS
    1531 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1532 ==== fred by MINE before
    1533 1.7
    1534 2.7
    1535 3.7
    1536 -
    1537 1.7
    1538 -
    1539 3.7
    1540 -
    1541 3.7
    1542 2.7
    1543 1.7
    1544 -
    1545 ==== fred by YOURS before
    1546 1.7
    1547 2.7
    1548 3.7
    1549 -
    1550 1.7
    1551 -
    1552 3.7
    1553 -
    1554 3.7
    1555 2.7
    1556 1.7
    1557 -
    1558 ==== fred by MINE after
    1559 1.7
    1560 2.7
    1561 3.7
    1562 -
    1563 1.7
    1564 -
    1565 3.7
    1566 -
    1567 3.7
    1568 2.7
    1569 1.7
    1570 -
    1571 ==== fred by YOURS after
    1572 2.7
    1573 3.7
    1574 -
    1575 2.7
    1576 -
    1577 3.7
    1578 -
    1579 3.7
    1580 2.7
    1581 -
    1582 ==== fred by YOURS after
    1583 1.7
    1584 -
    1585 1.7
    1586 -
    1587 -
    1588 -
    1589 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1590 Test 16-iii.  Modifying Maries
    1591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1592 ==== mary before
    1593 1.7
    1594 2.7
    1595 3.7
    1596 -
    1597 1.7
    1598 -
    1599 3.7
    1600 -
    1601 3.7
    1602 2.7
    1603 1.7
    1604 -
    1605 ==== mary after
    1606 2.7
    1607 3.7
    1608 -
    1609 2.7
    1610 -
    1611 3.7
    1612 -
    1613 3.7
    1614 2.7
    1615 -
    1616 ==== mary after
    1617 1.7
    1618 -
    1619 1.7
    1620 -
    1621 -
    1622 -
    1623 
    1624 ~~~~~~~~~~ End removal tests on Headed List: Last ~~~~~~~~~~
    1625 
    1626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1627 Test 17-i.  Modifying Freds on MINE
    1628 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1629 ==== fred by MINE before
    1630 1.7
    1631 2.7
    1632 3.7
    1633 -
    1634 1.7
    1635 -
    1636 3.7
    1637 -
    1638 3.7
    1639 2.7
    1640 1.7
    1641 -
    1642 ==== fred by YOURS before
    1643 1.7
    1644 2.7
    1645 3.7
    1646 -
    1647 1.7
    1648 -
    1649 3.7
    1650 -
    1651 3.7
    1652 2.7
    1653 1.7
    1654 -
    1655 ==== fred by MINE after
    1656 1.7
    1657 2.7
    1658 -
    1659 1.7
    1660 -
    1661 2.7
    1662 -
    1663 2.7
    1664 1.7
    1665 -
    1666 ==== fred by YOURS after
    1667 1.7
    1668 2.7
    1669 3.7
    1670 -
    1671 1.7
    1672 -
    1673 3.7
    1674 -
    1675 3.7
    1676 2.7
    1677 1.7
    1678 -
    1679 ==== fred by MINE after
    1680 3.7
    1681 -
    1682 3.7
    1683 -
    1684 -
    1685 -
    1686 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1687 Test 17-ii.  Modifying Freds on YOURS
    1688 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1689 ==== fred by MINE before
    1690 1.7
    1691 2.7
    1692 3.7
    1693 -
    1694 1.7
    1695 -
    1696 3.7
    1697 -
    1698 3.7
    1699 2.7
    1700 1.7
    1701 -
    1702 ==== fred by YOURS before
    1703 1.7
    1704 2.7
    1705 3.7
    1706 -
    1707 1.7
    1708 -
    1709 3.7
    1710 -
    1711 3.7
    1712 2.7
    1713 1.7
    1714 -
    1715 ==== fred by MINE after
    1716 1.7
    1717 2.7
    1718 3.7
    1719 -
    1720 1.7
    1721 -
    1722 3.7
    1723 -
    1724 3.7
    1725 2.7
    1726 1.7
    1727 -
    1728 ==== fred by YOURS after
    1729 1.7
    1730 2.7
    1731 -
    1732 1.7
    1733 -
    1734 2.7
    1735 -
    1736 2.7
    1737 1.7
    1738 -
    1739 ==== fred by YOURS after
    1740 3.7
    1741 -
    1742 3.7
    1743 -
    1744 -
    1745 -
    1746 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1747 Test 17-iii.  Modifying Maries
    1748 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1749 ==== mary before
    1750 1.7
    1751 2.7
    1752 3.7
    1753 -
    1754 1.7
    1755 -
    1756 3.7
    1757 -
    1758 3.7
    1759 2.7
    1760 1.7
    1761 -
    1762 ==== mary after
    1763 1.7
    1764 2.7
    1765 -
    1766 1.7
    1767 -
    1768 2.7
    1769 -
    1770 2.7
    1771 1.7
    1772 -
    1773 ==== mary after
    1774 3.7
    1775 -
    1776 3.7
    1777 -
    1778 -
    1779 -
  • tests/list/dlist-insert-remove.cfa

    r2223c80 r856fe3e  
    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 
    1199 void 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 
    1235 void 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 
    1271 void 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 
    1298 void 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 
    1334 void 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 
    1370 void 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 //
    13991189// Section 5
    14001190//
     
    16321422        test__remove_of_sole__mary();
    16331423
    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 
    16721424        return 0;
    16731425}
  • tools/build/push2dist.sh

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