Changes in / [c1ea11b:18e683b]


Ignore:
Files:
4 deleted
49 edited

Legend:

Unmodified
Added
Removed
  • benchmark/Makefile.am

    rc1ea11b r18e683b  
    1111## Created On       : Sun May 31 09:08:15 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Sun Jun 23 12:34:29 2019
    14 ## Update Count     : 52
     13## Last Modified On : Tue Nov  6 09:01:23 2018
     14## Update Count     : 26
    1515###############################################################################
    1616
     
    2121include $(top_srcdir)/src/cfa.make
    2222
    23 AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
     23AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
    2424AM_CFAFLAGS = -quiet -nodebug -in-tree
    2525AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
     
    3131BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    3232BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    33 BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    3433
    3534__quiet = verbose
     
    4645__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    4746__bench_v_UPP_verbose = $(AM_V_UPP)
    48 __bench_v_QTHREAD_verbose = $(AM_V_CC)
     47
    4948
    5049
     
    5251REPEAT   = ${abs_top_builddir}/tools/repeat
    5352STATS    = ${abs_top_srcdir}/tools/stat.py
    54 repeats  = 3 # 30
     53repeats  = 30
    5554skipcompile = no
    5655TIME_FORMAT = "%E"
     
    125124
    126125ctxswitch.csv:
    127         @echo "generator,coroutine,thread" > $@
    128         @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     126        @echo "coroutine,thread" > $@
    129127        @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    130128        @+make ctxswitch-cfa_thread.runquiet >> $@
     
    155153        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    156154
    157 ttst_lock$(EXEEXT):
    158         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
    159 
    160155tls-fetch_add$(EXEEXT):
    161156        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
     
    166161        function.run                    \
    167162        fetch_add.run                   \
    168         ttst_lock.run                   \
    169163        tls-fetch_add.run                       \
    170164        ctxswitch-pthread.run           \
    171         ctxswitch-cfa_generator.run     \
    172165        ctxswitch-cfa_coroutine.run     \
    173166        ctxswitch-cfa_thread.run        \
     
    176169        ctxswitch-upp_thread.run        \
    177170        ctxswitch-goroutine.run         \
    178         ctxswitch-java_thread.run       \
    179         ctxswitch-qthreads.run
    180 
     171        ctxswitch-java_thread.run
    181172
    182173if WITH_LIBFIBRE
     
    197188ctxswitch-pthread$(EXEEXT):
    198189        $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
    199 
    200 ctxswitch-cfa_generator$(EXEEXT):
    201         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
    202190
    203191ctxswitch-cfa_coroutine$(EXEEXT):
     
    224212        @echo "java JavaThread" >> a.out
    225213        @chmod a+x a.out
    226 
    227 ctxswitch-qthreads$(EXEEXT):
    228         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    229214
    230215## =========================================================================================================
     
    320305        creation-upp_thread.run                 \
    321306        creation-goroutine.run                  \
    322         creation-java_thread.run                \
    323         creation-qthreads.run
     307        creation-java_thread.run
    324308
    325309creation-cfa_coroutine$(EXEEXT):
     
    349333        @echo "java JavaThread" >> a.out
    350334        @chmod a+x a.out
    351 
    352 creation-qthreads$(EXEEXT):
    353         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    354335
    355336## =========================================================================================================
     
    394375compile-typeof$(EXEEXT):
    395376        @$(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa
     377
  • benchmark/Makefile.in

    rc1ea11b r18e683b  
    371371
    372372# applies to both programs
    373 AM_CFLAGS = -O2 -Wall -Wextra -I$(srcdir) -lrt -pthread # -Werror
     373AM_CFLAGS = -O2 -Wall -Wextra -Werror -I$(srcdir) -lrt -pthread
    374374AM_CFAFLAGS = -quiet -nodebug -in-tree
    375375AM_UPPFLAGS = -quiet -nodebug -multi -std=c++14
     
    380380BENCH_V_JAVAC = $(__bench_v_JAVAC_$(__quiet))
    381381BENCH_V_UPP = $(__bench_v_UPP_$(__quiet))
    382 BENCH_V_QTHREAD = $(__bench_v_QTHREAD_$(__quiet))
    383382__quiet = verbose
    384383__bench_v_CC_quiet = @
     
    394393__bench_v_JAVAC_verbose = $(AM_V_JAVAC)
    395394__bench_v_UPP_verbose = $(AM_V_UPP)
    396 __bench_v_QTHREAD_verbose = $(AM_V_CC)
    397395TOOLSDIR = ${abs_top_builddir}/tools/
    398396REPEAT = ${abs_top_builddir}/tools/repeat
    399397STATS = ${abs_top_srcdir}/tools/stat.py
    400 repeats = 3 # 30
     398repeats = 30
    401399skipcompile = no
    402400TIME_FORMAT = "%E"
     
    404402dummy_SOURCES = dummyC.c dummyCXX.cpp
    405403FIX_NEW_LINES = cat $@ | tr "\n" "\t" | sed -r 's/\t,/,/' | tr "\t" "\n" > $@
    406 CTXSWITCH_DEPEND = loop.run function.run fetch_add.run ttst_lock.run \
     404CTXSWITCH_DEPEND = loop.run function.run fetch_add.run \
    407405        tls-fetch_add.run ctxswitch-pthread.run \
    408         ctxswitch-cfa_generator.run ctxswitch-cfa_coroutine.run \
    409         ctxswitch-cfa_thread.run ctxswitch-cfa_thread2.run \
    410         ctxswitch-upp_coroutine.run ctxswitch-upp_thread.run \
    411         ctxswitch-goroutine.run ctxswitch-java_thread.run \
    412         ctxswitch-qthreads.run $(am__append_1)
     406        ctxswitch-cfa_coroutine.run ctxswitch-cfa_thread.run \
     407        ctxswitch-cfa_thread2.run ctxswitch-upp_coroutine.run \
     408        ctxswitch-upp_thread.run ctxswitch-goroutine.run \
     409        ctxswitch-java_thread.run $(am__append_1)
    413410testdir = $(top_srcdir)/tests
    414411all: all-am
     
    787784
    788785ctxswitch.csv:
    789         @echo "generator,coroutine,thread" > $@
    790         @+make ctxswitch-cfa_generator.runquiet >> $@ && echo -n ',' >> $@
     786        @echo "coroutine,thread" > $@
    791787        @+make ctxswitch-cfa_coroutine.runquiet >> $@ && echo -n ',' >> $@
    792788        @+make ctxswitch-cfa_thread.runquiet >> $@
     
    816812        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/fetch_add.c
    817813
    818 ttst_lock$(EXEEXT):
    819         $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/ttst_lock.c
    820 
    821814tls-fetch_add$(EXEEXT):
    822815        $(BENCH_V_CC)$(COMPILE) -DBENCH_N=500000000  $(srcdir)/tls-fetch_add.c
     
    832825ctxswitch-pthread$(EXEEXT):
    833826        $(BENCH_V_CC)$(COMPILE)    -DBENCH_N=50000000 $(srcdir)/ctxswitch/pthreads.c
    834 
    835 ctxswitch-cfa_generator$(EXEEXT):
    836         $(BENCH_V_CFA)$(CFACOMPILE) -DBENCH_N=50000000 $(srcdir)/ctxswitch/cfa_gen.cfa
    837827
    838828ctxswitch-cfa_coroutine$(EXEEXT):
     
    859849        @echo "java JavaThread" >> a.out
    860850        @chmod a+x a.out
    861 
    862 ctxswitch-qthreads$(EXEEXT):
    863         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    864851
    865852mutex$(EXEEXT) :\
     
    950937        creation-upp_thread.run                 \
    951938        creation-goroutine.run                  \
    952         creation-java_thread.run                \
    953         creation-qthreads.run
     939        creation-java_thread.run
    954940
    955941creation-cfa_coroutine$(EXEEXT):
     
    979965        @echo "java JavaThread" >> a.out
    980966        @chmod a+x a.out
    981 
    982 creation-qthreads$(EXEEXT):
    983         $(BENCH_V_QTHREADS)$(COMPILE) -DBENCH_N=50000000 -I/u/pabuhr/software/qthreads/include -L/u/pabuhr/software/qthreads/lib -Xlinker -R/u/pabuhr/software/qthreads/lib $(srcdir)/ctxswitch/qthreads.c -lqthread
    984967
    985968compile$(EXEEXT) :\
  • benchmark/bench.h

    rc1ea11b r18e683b  
    4545        statement;                                      \
    4646        EndTime = bench_time();                 \
    47         double output =         \
    48             (double)( EndTime - StartTime ) / n;
     47        unsigned long long int output =         \
     48        ( EndTime - StartTime ) / n;
    4949
    5050#if defined(__cforall)
  • benchmark/creation/cfa_cor.cfa

    rc1ea11b r18e683b  
    1010#endif
    1111}
    12 void main(MyCoroutine &) {}
     12void main(MyCoroutine & this) {}
    1313
    1414int main(int argc, char* argv[]) {
    1515        BENCH(
    16                 for ( i; n ) {
     16                for (size_t i = 0; i < n; i++) {
    1717                        MyCoroutine m;
    1818                },
     
    2020        )
    2121
    22         printf("%g\n", result);
     22        printf("%llu\n", result);
    2323}
  • benchmark/creation/cfa_thrd.cfa

    rc1ea11b r18e683b  
    55
    66thread MyThread {};
    7 void main(MyThread &) {}
     7void main(MyThread & this) {}
    88
    99int main(int argc, char* argv[]) {
    1010        BENCH(
    11                 for ( i; n ) {
     11                for (size_t i = 0; i < n; i++) {
    1212                        MyThread m;
    1313                },
     
    1515        )
    1616
    17         printf("%g\n", result);
     17        printf("%llu\n", result);
    1818}
  • benchmark/creation/pthreads.c

    rc1ea11b r18e683b  
    2525        )
    2626
    27         printf("%g\n", result);
     27        printf("%llu\n", result);
    2828}
  • benchmark/creation/upp_cor.cc

    rc1ea11b r18e683b  
    1515        )
    1616
    17         printf("%g\n", result);
     17        printf("%llu\n", result);
    1818}
  • benchmark/creation/upp_thrd.cc

    rc1ea11b r18e683b  
    1515        )
    1616
    17         printf("%g\n", result);
     17        printf("%llu\n", result);
    1818}
  • benchmark/ctxswitch/cfa_cor.cfa

    rc1ea11b r18e683b  
     1#include <stdio.h>
    12#include <kernel.hfa>
    23#include <thread.hfa>
     
    2021
    2122        BENCH(
    22                 for ( i; n ) {
     23                for (size_t i = 0; i < n; i++) {
    2324                        resume( s );
    2425                },
     
    2627        )
    2728
    28         printf("%g\n", result);
     29        printf("%llu\n", result);
    2930}
  • benchmark/ctxswitch/cfa_cor_then.cfa

    rc1ea11b r18e683b  
     1#include <stdio.h>
    12#include <kernel.hfa>
    23#include <thread.hfa>
     
    2223
    2324        BENCH(
    24                 for ( i; n ) {
     25                for (size_t i = 0; i < n; i++) {
    2526                        resume( s );
    2627                },
     
    2829        )
    2930
    30         printf("%g\n", result);
     31        printf("%llu\n", result);
    3132}
  • benchmark/ctxswitch/cfa_thrd.cfa

    rc1ea11b r18e683b  
     1#include <stdio.h>
    12#include <thread.hfa>
    23
     
    56int main(int argc, char* argv[]) {
    67        BENCH(
    7                 for ( i; n ) {
     8                for (size_t i = 0; i < n; i++) {
    89                        yield();
    910                },
     
    1112        )
    1213
    13         printf("%g\n", result);
     14        printf("%llu\n", result);
    1415}
  • benchmark/ctxswitch/cfa_thrd2.cfa

    rc1ea11b r18e683b  
     1#include <stdio.h>
    12#include <thread.hfa>
    23
     
    1617        Fibre f1;
    1718        BENCH(
    18                 for ( i; n ) {
     19                for (size_t i = 0; i < n; i++) {
    1920                        yield();
    2021                },
     
    2223        )
    2324
    24         printf("%g\n", result);
     25        printf("%llu\n", result);
    2526        done = true;
    2627        return 0;
  • benchmark/ctxswitch/kos_fibre.cpp

    rc1ea11b r18e683b  
    1010                result
    1111        )
    12         printf("%g\n", result);
     12        printf("%llu\n", result);
    1313        return 0;
    1414}
  • benchmark/ctxswitch/kos_fibre2.cpp

    rc1ea11b r18e683b  
    1919                result
    2020        )
    21         printf("%g\n", result);
     21        printf("%llu\n", result);
    2222        done = true;
    2323        Fibre::yield();
  • benchmark/ctxswitch/pthreads.c

    rc1ea11b r18e683b  
    1414        )
    1515
    16         printf("%g\n", result);
     16        printf("%llu\n", result);
    1717}
  • benchmark/ctxswitch/upp_cor.cc

    rc1ea11b r18e683b  
    3030        )
    3131
    32         printf("%g\n", result);
     32        printf("%llu\n", result);
    3333}
  • benchmark/ctxswitch/upp_thrd.cc

    rc1ea11b r18e683b  
    1111        )
    1212
    13         printf("%g\n", result);
     13        printf("%llu\n", result);
    1414}
  • benchmark/fetch_add.c

    rc1ea11b r18e683b  
    1919        )
    2020
    21         printf("%g\n", result);
     21        printf("%llu\n", result);
    2222}
  • benchmark/function.c

    rc1ea11b r18e683b  
    1515        )
    1616
    17         printf("%g\n", result);
     17        printf("%llu\n", result);
    1818}
  • benchmark/loop.c

    rc1ea11b r18e683b  
    1111        )
    1212
    13         printf("%g\n", result);
     13        printf("%llu\n", result);
    1414}
  • benchmark/mutex/cfa1.cfa

    rc1ea11b r18e683b  
    1010        M m;
    1111        BENCH(
    12                 for ( i; n ) {
     12                for (size_t i = 0; i < n; i++) {
    1313                        call(m);
    1414                },
     
    1616        )
    1717
    18         printf("%g\n", result);
     18        printf("%llu\n", result);
    1919}
  • benchmark/mutex/cfa2.cfa

    rc1ea11b r18e683b  
    1010        M m1, m2;
    1111        BENCH(
    12                 for ( i; n ) {
     12                for (size_t i = 0; i < n; i++) {
    1313                        call(m1, m2);
    1414                },
     
    1616        )
    1717
    18         printf("%g\n", result);
     18        printf("%llu\n", result);
    1919}
  • benchmark/mutex/cfa4.cfa

    rc1ea11b r18e683b  
    1111        M m1, m2, m3, m4;
    1212        BENCH(
    13                 for ( i; n ) {
     13                for (size_t i = 0; i < n; i++) {
    1414                        call(m1, m2, m3, m4);
    1515                },
     
    1717        )
    1818
    19         printf("%g\n", result);
     19        printf("%llu\n", result);
    2020}
  • benchmark/mutex/pthreads.c

    rc1ea11b r18e683b  
    1919        )
    2020
    21         printf("%g\n", result);
     21        printf("%llu\n", result);
    2222}
  • benchmark/mutex/upp.cc

    rc1ea11b r18e683b  
    1717        )
    1818
    19         printf("%g\n", result);
     19        printf("%llu\n", result);
    2020}
  • benchmark/schedext/cfa1.cfa

    rc1ea11b r18e683b  
    1818        go = 1;
    1919        BENCH(
    20                 for ( i; n ) {
     20                for (size_t i = 0; i < n; i++) {
    2121                        waitfor(call, a1);
    2222                },
     
    2424        )
    2525
    26         printf("%g\n", result);
     26        printf("%llu\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & ) {
     33void main( T & this ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1); }
     
    3737}
    3838
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     39int main(int margc, char* margv[]) {
     40        argc = margc;
     41        argv = margv;
    4042        T t;
    4143        return wait(m1);
  • benchmark/schedext/cfa2.cfa

    rc1ea11b r18e683b  
    1818        go = 1;
    1919        BENCH(
    20                 for ( i; n ) {
     20                for (size_t i = 0; i < n; i++) {
    2121                        waitfor(call, a1, a2);
    2222                },
     
    2424        )
    2525
    26         printf("%g\n", result);
     26        printf("%llu\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & ) {
     33void main( T & this ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1, m2); }
     
    3737}
    3838
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     39int main(int margc, char* margv[]) {
     40        argc = margc;
     41        argv = margv;
    4042        T t;
    4143        return wait(m1, m2);
  • benchmark/schedext/cfa4.cfa

    rc1ea11b r18e683b  
    1818        go = 1;
    1919        BENCH(
    20                 for ( i; n ) {
     20                for (size_t i = 0; i < n; i++) {
    2121                        waitfor(call, a1, a2, a3, a4);
    2222                },
     
    2424        )
    2525
    26         printf("%g\n", result);
     26        printf("%llu\n", result);
    2727        go = 0;
    2828        return 0;
     
    3131thread T {};
    3232void ^?{}( T & mutex this ) {}
    33 void main( T & ) {
     33void main( T & this ) {
    3434        while(go == 0) { yield(); }
    3535        while(go == 1) { call(m1, m2, m3, m4); }
     
    3737}
    3838
    39 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     39int main(int margc, char* margv[]) {
     40        argc = margc;
     41        argv = margv;
    4042        T t;
    4143        return wait(m1, m2, m3, m4);
  • benchmark/schedext/upp.cc

    rc1ea11b r18e683b  
    2020                )
    2121
    22                 printf("%g\n", result);
     22                printf("%llu\n", result);
    2323                go = 0;
    2424                return 0;
  • benchmark/schedint/cfa1.cfa

    rc1ea11b r18e683b  
    2121        go = 1;
    2222        BENCH(
    23                 for ( i; n ) {
     23                for (size_t i = 0; i < n; i++) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%g\n", result);
     29        printf("%llu\n", result);
    3030        go = 0;
    3131        return 0;
     
    3333
    3434thread T {};
    35 void ^?{}( T & mutex ) {}
    36 void main( T & ) {
     35void ^?{}( T & mutex this ) {}
     36void main( T & this ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1); }
     
    4040}
    4141
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     42int main(int margc, char* margv[]) {
     43        argc = margc;
     44        argv = margv;
    4345        T t;
    4446        return wait(m1);
  • benchmark/schedint/cfa2.cfa

    rc1ea11b r18e683b  
    2121        go = 1;
    2222        BENCH(
    23                 for ( i; n ) {
     23                for (size_t i = 0; i < n; i++) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%g\n", result);
     29        printf("%llu\n", result);
    3030        go = 0;
    3131        return 0;
     
    3434thread T {};
    3535void ^?{}( T & mutex this ) {}
    36 void main( T & ) {
     36void main( T & this ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1, m2); }
     
    4040}
    4141
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     42int main(int margc, char* margv[]) {
     43        argc = margc;
     44        argv = margv;
    4345        T t;
    4446        return wait(m1, m2);
  • benchmark/schedint/cfa4.cfa

    rc1ea11b r18e683b  
    2121        go = 1;
    2222        BENCH(
    23                 for ( i; n ) {
     23                for (size_t i = 0; i < n; i++) {
    2424                        wait(c);
    2525                },
     
    2727        )
    2828
    29         printf("%g\n", result);
     29        printf("%llu\n", result);
    3030        go = 0;
    3131        return 0;
     
    3434thread T {};
    3535void ^?{}( T & mutex this ) {}
    36 void main( T & ) {
     36void main( T & this ) {
    3737        while(go == 0) { yield(); }
    3838        while(go == 1) { call(m1, m2, m3, m4); }
     
    4040}
    4141
    42 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     42int main(int margc, char* margv[]) {
     43        argc = margc;
     44        argv = margv;
    4345        T t;
    4446        return wait(m1, m2, m3, m4);
  • benchmark/schedint/pthreads.c

    rc1ea11b r18e683b  
    2727        )
    2828
    29         printf("%g\n", result);
     29        printf("%llu\n", result);
    3030        go = 0;
    3131        pthread_mutex_unlock(&m);
     
    3333}
    3434
    35 void* thread_main(__attribute__((unused)) void * arg ) {
     35void* thread_main(void * a) {
    3636        while(go == 0) { sched_yield(); }
    3737        while(go == 1) { call(); }
     
    3939}
    4040
    41 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     41int main(int margc, char* margv[]) {
     42        argc = margc;
     43        argv = margv;
    4244        pthread_t thread;
    4345        if (pthread_create(&thread, NULL, thread_main, NULL) < 0) {
  • benchmark/schedint/upp.cc

    rc1ea11b r18e683b  
    2323                )
    2424
    25                 printf("%g\n", result);
     25                printf("%llu\n", result);
    2626                go = 0;
    2727                return 0;
     
    3939};
    4040
    41 int main(__attribute__((unused)) int argc, __attribute__((unused)) char* argv[]) {
     41int main(int margc, char* margv[]) {
     42        argc = margc;
     43        argv = margv;
    4244        T t;
    4345        return m.wait();
  • benchmark/tls-fetch_add.c

    rc1ea11b r18e683b  
    2424        )
    2525
    26         printf("%g\n", result);
     26        printf("%llu\n", result);
    2727}
  • doc/bibliography/pl.bib

    rc1ea11b r18e683b  
    948948    author      = {{\textsf{C}{$\mathbf{\forall}$} Features}},
    949949    howpublished= {\href{https://plg.uwaterloo.ca/~cforall/features}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-features}},
    950 }
    951 
    952 @misc{CforallBenchMarks,
    953     contributer = {pabuhr@plg},
    954     key         = {Cforall Benchmarks},
    955     author      = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}},
    956     howpublished= {\href{https://plg.uwaterloo.ca/~cforall/benchmarks}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-benchmarks}},
    957950}
    958951
     
    19261919    year        = 1965,
    19271920    note        = {Reprinted in \cite{Genuys68} pp. 43--112.}
    1928 }
    1929 
    1930 @inproceedings{Adya02,
    1931     contributer = {pabuhr@plg},
    1932     author      = {Adya, Atul and Howell, Jon and Theimer, Marvin and Bolosky, William J. and Douceur, John R.},
    1933     title       = {Cooperative Task Management Without Manual Stack Management},
    1934     booktitle   = {Proceedings of the General Track of the Annual Conference on USENIX Annual Technical Conference},
    1935     series      = {ATEC '02},
    1936     year        = {2002},
    1937     pages       = {289-302},
    1938     publisher   = {USENIX Association},
    1939     address     = {Berkeley, CA, USA},
    1940 }
    1941 
    1942 @misc{CoroutineTS,
    1943     keywords    = {Coroutines TS, C++20, working draft},
    1944     contributer = {pabuhr@plg},
    1945     author      = {Gor Nishanov},
    1946     title       = {Merge Coroutines TS into C++20 Working Draft},
    1947     year        = 2019,
    1948     month       = feb,
    1949     howpublished= {\href{http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p0912r5.html}
    1950                   {http://\-www.open-std.org/\-jtc1/\-sc22/\-wg21/\-docs/\-papers/\-2019/p0912r5.html}},
    19511921}
    19521922
     
    43894359}
    43904360
    4391 
    43924361@article{Liskov86,
    43934362    keywords    = {synchronous communication, concurrency},
     
    44024371    year        = {},
    44034372    pages       = {},
    4404 }
    4405 
    4406 @misc{libdill,
    4407     keywords    = {libdill/libmill Thread Library},
    4408     contributer = {pabuhr@plg},
    4409     author      = {Alex Cornejo, et al},
    4410     title       = {libdill Thread Library},
    4411     year        = 2019,
    4412     howpublished= {\href{http://libdill.org/libdill-2.14.tar.gz}
    4413                   {http://\-libdill.org/\-libdill-2.14.tar.gz}},
    44144373}
    44154374
     
    45344493    year        = 2016,
    45354494    howpublished= {\href{http://blog.reverberate.org/2016/01/making-arbitrarily-large-binaries-from.html}
    4536                   {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}},
     4495                  {
     4496          {http://blog.reverberate.org/\-2016/\-01/\-making-arbitrarily-large-binaries-from.html}
     4497          }},
    45374498    optnote     = {Accessed: 2016-09},
    45384499}
     
    45564517        trivial changes to the source code of the library.
    45574518    }
    4558 }
    4559 
    4560 @misc{Marcel,
    4561     keywords    = {Marcel Thread Library},
    4562     contributer = {pabuhr@plg},
    4563     author      = {Gabriel Antoniu, et al},
    4564     title       = {Marcel Thread Library},
    4565     year        = 2011,
    4566     howpublished= {\href{https://gforge.inria.fr/frs/download.php/file/28643/marcel-2.99.3.tar.gz}
    4567                   {https://\-gforge.inria.fr/\-frs/\-download.php/\-file/\-28643/\-marcel-2.99.3.tar.gz}},
    45684519}
    45694520
  • doc/papers/AMA/AMA-stix/ama/WileyNJD-v2.cls

    rc1ea11b r18e683b  
    24442444     \@afterheading}
    24452445
    2446 \renewcommand\section{\@startsection{section}{1}{\z@}{-25pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}%
    2447 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-22pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}%
     2446\renewcommand\section{\@startsection{section}{1}{\z@}{-27pt \@plus -2pt \@minus -2pt}{12\p@}{\sectionfont}}%
     2447\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-23pt \@plus -2pt \@minus -2pt}{5\p@}{\subsectionfont}}%
    24482448\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-20pt \@plus -2pt \@minus -2pt}{2\p@}{\subsubsectionfont}}%
    24492449%
  • doc/papers/concurrency/Paper.tex

    rc1ea11b r18e683b  
    157157                __float80, float80, __float128, float128, forall, ftype, generator, _Generic, _Imaginary, __imag, __imag__,
    158158                inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or,
    159                 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, thread,
     159                otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, suspend, thread,
    160160                _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__,
    161161                virtual, __volatile, __volatile__, waitfor, when, with, zero_t},
     
    303303However, \Celeven concurrency is largely wrappers for a subset of the pthreads library~\cite{Butenhof97,Pthreads}, and \Celeven and pthreads concurrency is simple, based on thread fork/join in a function and a few locks, which is low-level and error prone;
    304304no high-level language concurrency features are defined.
    305 Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-9 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
     305Interestingly, almost a decade after publication of the \Celeven standard, neither gcc-8, clang-8 nor msvc-19 (most recent versions) support the \Celeven include @threads.h@, indicating little interest in the C11 concurrency approach.
    306306Finally, while the \Celeven standard does not state a threading model, the historical association with pthreads suggests implementations would adopt kernel-level threading (1:1)~\cite{ThreadModel}.
    307307
     
    313313From 2000 onwards, languages like Go~\cite{Go}, Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, D~\cite{D}, and \uC~\cite{uC++,uC++book} have championed the M:N user-threading model, and many user-threading libraries have appeared~\cite{Qthreads,MPC,Marcel}, including putting green threads back into Java~\cite{Quasar}.
    314314The main argument for user-level threading is that they are lighter weight than kernel threads (locking and context switching do not cross the kernel boundary), so there is less restriction on programming styles that encourage large numbers of threads performing medium work-units to facilitate load balancing by the runtime~\cite{Verch12}.
    315 As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{Adya02,vonBehren03}.
     315As well, user-threading facilitates a simpler concurrency approach using thread objects that leverage sequential patterns versus events with call-backs~\cite{vonBehren03}.
    316316Finally, performant user-threading implementations (both time and space) meet or exceed direct kernel-threading implementations, while achieving the programming advantages of high concurrency levels and safety.
    317317
     
    613613Finally, an explicit generator type provides both design and performance benefits, such as multiple type-safe interface functions taking and returning arbitrary types.
    614614\begin{cfa}
    615 int ?()( Fib & fib ) { return `resume( fib )`.fn; } $\C[3.9in]{// function-call interface}$
    616 int ?()( Fib & fib, int N ) { for ( N - 1 ) `fib()`; return `fib()`; } $\C{// use function-call interface to skip N values}$
    617 double ?()( Fib & fib ) { return (int)`fib()` / 3.14159; } $\C{// different return type, cast prevents recursive call}\CRT$
    618 sout | (int)f1() | (double)f1() | f2( 2 ); // alternative interface, cast selects call based on return type, step 2 values
     615int ?()( Fib & fib ) with( fib ) { return `resume( fib )`.fn; }   // function-call interface
     616int ?()( Fib & fib, int N ) with( fib ) { for ( N - 1 ) `fib()`; return `fib()`; }   // use simple interface
     617double ?()( Fib & fib ) with( fib ) { return (int)`fib()` / 3.14159; } // cast prevents recursive call
     618sout | (int)f1() | (double)f1() | f2( 2 );   // simple interface, cast selects call based on return type, step 2 values
    619619\end{cfa}
    620620Now, the generator can be a separately-compiled opaque-type only accessed through its interface functions.
     
    628628With respect to safety, we believe static analysis can discriminate local state from temporary variables in a generator, \ie variable usage spanning @suspend@, and generate a compile-time error.
    629629Finally, our current experience is that most generator problems have simple data state, including local state, but complex execution state, so the burden of creating the generator type is small.
    630 As well, C programmers are not afraid of this kind of semantic programming requirement, if it results in very small, fast generators.
     630As well, C programmers are not afraid with this kind of semantic programming requirement, if it results in very small, fast generators.
    631631
    632632Figure~\ref{f:CFAFormatGen} shows an asymmetric \newterm{input generator}, @Fmt@, for restructuring text into groups of characters of fixed-size blocks, \ie the input on the left is reformatted into the output on the right, where newlines are ignored.
     
    796796This semantics is basically a tail-call optimization, which compilers already perform.
    797797The example shows the assembly code to undo the generator's entry code before the direct jump.
    798 This assembly code depends on what entry code is generated, specifically if there are local variables, and the level of optimization.
     798This assembly code depends on what entry code is generated, specifically if there are local variables and the level of optimization.
    799799To provide this new calling convention requires a mechanism built into the compiler, which is beyond the scope of \CFA at this time.
    800800Nevertheless, it is possible to hand generate any symmetric generators for proof of concept and performance testing.
    801 A compiler could also eliminate other artifacts in the generator simulation to further increase performance, \eg LLVM has various coroutine support~\cite{CoroutineTS}, and \CFA can leverage this support should it fork @clang@.
     801A compiler could also eliminate other artifacts in the generator simulation to further increase performance.
    802802
    803803\begin{figure}
     
    12131213Hence, a compromise solution is necessary that works for asymmetric (acyclic) and symmetric (cyclic) coroutines.
    12141214
    1215 Our solution is to context switch back to the first resumer (starter) once the coroutine ends.
    1216 This semantics works well for the most common asymmetric and symmetric coroutine usage-patterns.
     1215Our solution for coroutine termination works well for the most common asymmetric and symmetric coroutine usage-patterns.
    12171216For asymmetric coroutines, it is common for the first resumer (starter) coroutine to be the only resumer.
    12181217All previous generators converted to coroutines have this property.
     
    12461245
    12471246
    1248 \subsection{Generator / Coroutine Implementation}
     1247\subsection{(Generator) Coroutine Implementation}
    12491248
    12501249A significant implementation challenge for generators/coroutines (and threads in Section~\ref{s:threads}) is adding extra fields to the custom types and related functions, \eg inserting code after/before the coroutine constructor/destructor and @main@ to create/initialize/de-initialize/destroy any extra fields, \eg stack.
     
    12551254class myCoroutine inherits baseCoroutine { ... }
    12561255\end{cfa}
    1257 % The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types.
    1258 The problem is that some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
     1256The problem is that the programming language and its tool chain, \eg debugger, @valgrind@, need to understand @baseCoroutine@ because it infers special property, so type @baseCoroutine@ becomes a de facto keyword and all types inheriting from it are implicitly custom types.
     1257As well, some special properties are not handled by existing language semantics, \eg the execution of constructors/destructors is in the wrong order to implicitly start threads because the thread must start \emph{after} all constructors as it relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
    12591258Alternatives, such as explicitly starting threads as in Java, are repetitive and forgetting to call start is a common source of errors.
    12601259An alternative is composition:
     
    12681267However, there is nothing preventing wrong placement or multiple declarations.
    12691268
    1270 \CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code
    1271 % and when it is unsafe to perform certain optimizations,
    1272 and IDEs using simple parsing can find and manipulate types with special properties.
     1269\CFA custom types make any special properties explicit to the language and its tool chain, \eg the language code-generator knows where to inject code and when it is unsafe to perform certain optimizations, and IDEs using simple parsing can find and manipulate types with special properties.
    12731270The downside of this approach is that it makes custom types a special case in the language.
    12741271Users wanting to extend custom types or build their own can only do so in ways offered by the language.
     
    12851282\end{cfa}
    12861283Note, copying generators/coroutines/threads is not meaningful.
    1287 For example, both the resumer and suspender descriptors can have bi-directional pointers;
    1288 copying these coroutines does not update the internal pointers so behaviour of both copies would be difficult to understand.
     1284For example, a coroutine retains its last resumer and suspends back to it;
     1285having a copy also suspend back to the same resumer is undefined semantics.
    12891286Furthermore, two coroutines cannot logically execute on the same stack.
    12901287A deep coroutine copy, which copies the stack, is also meaningless in an unmanaged language (no garbage collection), like C, because the stack may contain pointers to object within it that require updating for the copy.
    12911288The \CFA @dtype@ property provides no \emph{implicit} copying operations and the @is_coroutine@ trait provides no \emph{explicit} copying operations, so all coroutines must be passed by reference (pointer).
    1292 The function definitions ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the coroutine descriptor from its handle.
     1289The function definitions ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine, and a mechanism to get (read) the currently executing coroutine handle.
    12931290The @main@ function has no return value or additional parameters because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values versus fixed ones.
    12941291The advantage of this approach is that users can easily create different types of coroutines, \eg changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ function, and possibly redefining \textsf{suspend} and @resume@.
     
    14961493\end{tabular}
    14971494\end{cquote}
    1498 Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_thread@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer).
    1499 Similarly, the function definitions ensures there is a statically-typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the thread descriptor from its handle, and a special destructor to prevent deallocation while the thread is executing.
     1495Like coroutines, the @dtype@ property prevents \emph{implicit} copy operations and the @is_coroutine@ trait provides no \emph{explicit} copy operations, so threads must be passed by reference (pointer).
     1496Similarly, the function definitions ensures there is a statically-typed @main@ function that is the thread starting point (first stack frame), a mechanism to get (read) the currently executing thread handle, and a special destructor to prevent deallocation while the thread is executing.
    15001497(The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitor}.)
    15011498The difference between the coroutine and thread is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates the coroutine's stack and starts running the coroutine main on the stack;
     
    16201617% Copying a lock is insecure because it is possible to copy an open lock and then use the open copy when the original lock is closed to simultaneously access the shared data.
    16211618% Copying a monitor is secure because both the lock and shared data are copies, but copying the shared data is meaningless because it no longer represents a unique entity.
    1622 Similarly, the function definitions ensures there is a mechanism to get (read) the monitor descriptor from its handle, and a special destructor to prevent deallocation if a thread using the shared data.
     1619Similarly, the function definitions ensures there is a mechanism to get (read) the currently executing monitor handle, and a special destructor to prevent deallocation if a thread using the shared data.
    16231620The custom monitor type also inserts any locks needed to implement the mutual exclusion semantics.
    16241621
     
    16591656called \newterm{bulk acquire}.
    16601657\CFA guarantees acquisition order is consistent across calls to @mutex@ functions using the same monitors as arguments, so acquiring multiple monitors is safe from deadlock.
    1661 Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem~\cite{BankTransfer}, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking.
     1658Figure~\ref{f:BankTransfer} shows a trivial solution to the bank transfer problem, where two resources must be locked simultaneously, using \CFA monitors with implicit locking and \CC with explicit locking.
    16621659A \CFA programmer only has to manage when to acquire mutual exclusion;
    16631660a \CC programmer must select the correct lock and acquisition mechanism from a panoply of locking options.
     
    18031800Figure~\ref{f:MonitorScheduling} shows general internal/external scheduling (for the bounded-buffer example in Figure~\ref{f:InternalExternalScheduling}).
    18041801External calling threads block on the calling queue, if the monitor is occupied, otherwise they enter in FIFO order.
    1805 Internal threads block on condition queues via @wait@ and reenter from the condition in FIFO order.
    1806 Alternatively, internal threads block on urgent from the @signal_block@ or @waitfor@, and reenter implicitly when the monitor becomes empty, \ie, the thread in the monitor exits or waits.
     1802Internal threads block on condition queues via @wait@ and they reenter from the condition in FIFO order, or they block on urgent via @signal_block@ or @waitfor@ and reenter implicit when the monitor becomes empty, \ie, the thread in the monitor exits or waits.
    18071803
    18081804There are three signalling mechanisms to unblock waiting threads to enter the monitor.
    1809 Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion, so either the signaller or signallee can proceed.
     1805Note, signalling cannot have the signaller and signalled thread in the monitor simultaneously because of the mutual exclusion so only one can proceed.
    18101806For internal scheduling, threads are unblocked from condition queues using @signal@, where the signallee is moved to urgent and the signaller continues (solid line).
    18111807Multiple signals move multiple signallees to urgent, until the condition is empty.
     
    18471843It is common to declare condition variables as monitor fields to prevent shared access, hence no locking is required for access as the conditions are protected by the monitor lock.
    18481844In \CFA, a condition variable can be created/stored independently.
    1849 % To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolean test to detect sharing from other monitors.
     1845To still prevent expensive locking on access, a condition variable is tied to a \emph{group} of monitors on first use, called \newterm{branding}, resulting in a low-cost boolen test to detect sharing from other monitors.
    18501846
    18511847% Signalling semantics cannot have the signaller and signalled thread in the monitor simultaneously, which means:
     
    18561852% The signalling thread continues and the signalled thread is marked for urgent unblocking at the next scheduling point (exit/wait).
    18571853% \item
    1858 % The signalling thread blocks but is marked for urgent unblocking at the next scheduling point and the signalled thread continues.
     1854% The signalling thread blocks but is marked for urgrent unblocking at the next scheduling point and the signalled thread continues.
    18591855% \end{enumerate}
    18601856% The first approach is too restrictive, as it precludes solving a reasonable class of problems, \eg dating service (see Figure~\ref{f:DatingService}).
     
    19651961External scheduling is controlled by the @waitfor@ statement, which atomically blocks the calling thread, releases the monitor lock, and restricts the function calls that can next acquire mutual exclusion.
    19661962If the buffer is full, only calls to @remove@ can acquire the buffer, and if the buffer is empty, only calls to @insert@ can acquire the buffer.
    1967 Threads calling excluded functions block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor.
     1963Calls threads to functions that are currently excluded block outside of (external to) the monitor on the calling queue, versus blocking on condition queues inside of (internal to) the monitor.
    19681964Figure~\ref{f:RWExt} shows a readers/writer lock written using external scheduling, where a waiting reader detects a writer using the resource and restricts further calls until the writer exits by calling @EndWrite@.
    19691965The writer does a similar action for each reader or writer using the resource.
     
    20802076For @wait( e )@, the default semantics is to atomically block the signaller and release all acquired mutex parameters, \ie @wait( e, m1, m2 )@.
    20812077To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @wait( e, m1 )@.
    2082 Wait cannot statically verifies the released monitors are the acquired mutex-parameters without disallowing separately compiled helper functions calling @wait@.
     2078Wait statically verifies the released monitors are the acquired mutex-parameters so unconditional release is safe.
    20832079While \CC supports bulk locking, @wait@ only accepts a single lock for a condition variable, so bulk locking with condition variables is asymmetric.
    20842080Finally, a signaller,
     
    20922088Similarly, for @waitfor( rtn )@, the default semantics is to atomically block the acceptor and release all acquired mutex parameters, \ie @waitfor( rtn, m1, m2 )@.
    20932089To override the implicit multi-monitor wait, specific mutex parameter(s) can be specified, \eg @waitfor( rtn, m1 )@.
    2094 @waitfor@ does statically verify the monitor types passed are the same as the acquired mutex-parameters of the given function or function pointer, hence the function (pointer) prototype must be accessible.
     2090@waitfor@ statically verifies the released monitors are the same as the acquired mutex-parameters of the given function or function pointer.
     2091To statically verify the released monitors match with the accepted function's mutex parameters, the function (pointer) prototype must be accessible.
    20952092% When an overloaded function appears in an @waitfor@ statement, calls to any function with that name are accepted.
    20962093% The rationale is that members with the same name should perform a similar function, and therefore, all should be eligible to accept a call.
     
    21512148The right example accepts either @mem1@ or @mem2@ if @C1@ and @C2@ are true.
    21522149
    2153 An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated, \eg assume the bounded buffer is restructred from a monitor to a thread with the following @main@.
    2154 \begin{cfa}
    2155 void main( Buffer(T) & buffer ) with(buffer) {
    2156         for () {
    2157                 `waitfor( ^?{}, buffer )` break;
    2158                 or when ( count != 20 ) waitfor( insert, buffer ) { ... }
    2159                 or when ( count != 0 ) waitfor( remove, buffer ) { ... }
    2160         }
    2161         // clean up
    2162 }
    2163 \end{cfa}
    2164 When the program main deallocates the buffer, it first calls the buffer's destructor, which is accepted, the destructor runs, and the buffer is deallocated.
    2165 However, the buffer thread cannot continue after the destructor call because the object is gone;
    2166 hence, clean up in @main@ cannot occur, which means destructors for local objects are not run.
    2167 To make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the destructor call is placed on urgent and the acceptor continues execution, which ends the loop, cleans up, and the thread terminates.
    2168 Then, the destructor caller unblocks from urgent to deallocate the object.
    2169 Accepting the destructor is the idiomatic way in \CFA to terminate a thread performing direct communication.
     2150An interesting use of @waitfor@ is accepting the @mutex@ destructor to know when an object is deallocated.
     2151\begin{cfa}
     2152void insert( Buffer(T) & mutex buffer, T elem ) with( buffer ) {
     2153        if ( count == 10 )
     2154                waitfor( remove, buffer ) {
     2155                        // insert elem into buffer
     2156                } or `waitfor( ^?{}, buffer )` throw insertFail;
     2157}
     2158\end{cfa}
     2159When the buffer is deallocated, the current waiter is unblocked and informed, so it can perform an appropriate action.
     2160However, the basic @waitfor@ semantics do not support this functionality, since using an object after its destructor is called is undefined.
     2161Therefore, to make this useful capability work, the semantics for accepting the destructor is the same as @signal@, \ie the call to the destructor is placed on the urgent queue and the acceptor continues execution, which throws an exception to the acceptor and then the caller is unblocked from the urgent queue to deallocate the object.
     2162Accepting the destructor is the idiomatic way to terminate a thread in \CFA.
    21702163
    21712164
     
    23642357
    23652358struct Msg { int i, j; };
    2366 thread GoRtn { int i;  float f;  Msg m; };
    2367 void mem1( GoRtn & mutex gortn, int i ) { gortn.i = i; }
    2368 void mem2( GoRtn & mutex gortn, float f ) { gortn.f = f; }
    2369 void mem3( GoRtn & mutex gortn, Msg m ) { gortn.m = m; }
    2370 void ^?{}( GoRtn & mutex ) {}
    2371 
    2372 void main( GoRtn & gortn ) with( gortn ) {  // thread starts
     2359thread Gortn { int i;  float f;  Msg m; };
     2360void mem1( Gortn & mutex gortn, int i ) { gortn.i = i; }
     2361void mem2( Gortn & mutex gortn, float f ) { gortn.f = f; }
     2362void mem3( Gortn & mutex gortn, Msg m ) { gortn.m = m; }
     2363void ^?{}( Gortn & mutex ) {}
     2364
     2365void main( Gortn & gortn ) with( gortn ) {  // thread starts
    23732366
    23742367        for () {
     
    23832376}
    23842377int main() {
    2385         GoRtn gortn; $\C[2.0in]{// start thread}$
     2378        Gortn gortn; $\C[2.0in]{// start thread}$
    23862379        `mem1( gortn, 0 );` $\C{// different calls}\CRT$
    23872380        `mem2( gortn, 2.5 );`
     
    25412534% However, preemption is necessary for fairness and to reduce tail-latency.
    25422535% For concurrency that relies on spinning, if all cores spin the system is livelocked, whereas preemption breaks the livelock.
    2543 
    2544 
    2545 \begin{comment}
    2546 \subsection{Thread Pools}
    2547 
    2548 In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution.
    2549 If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together.
    2550 While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs.
    2551 Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers.
    2552 While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases.
    2553 As well, concurrency errors return, which threads pools are suppose to mitigate.
    2554 
    2555 \begin{figure}
    2556 \centering
    2557 \begin{tabular}{@{}l|l@{}}
    2558 \begin{cfa}
    2559 struct Adder {
    2560     int * row, cols;
    2561 };
    2562 int operator()() {
    2563         subtotal = 0;
    2564         for ( int c = 0; c < cols; c += 1 )
    2565                 subtotal += row[c];
    2566         return subtotal;
    2567 }
    2568 void ?{}( Adder * adder, int row[$\,$], int cols, int & subtotal ) {
    2569         adder.[rows, cols, subtotal] = [rows, cols, subtotal];
    2570 }
    2571 
    2572 
    2573 
    2574 
    2575 \end{cfa}
    2576 &
    2577 \begin{cfa}
    2578 int main() {
    2579         const int rows = 10, cols = 10;
    2580         int matrix[rows][cols], subtotals[rows], total = 0;
    2581         // read matrix
    2582         Executor executor( 4 ); // kernel threads
    2583         Adder * adders[rows];
    2584         for ( r; rows ) { // send off work for executor
    2585                 adders[r] = new( matrix[r], cols, &subtotal[r] );
    2586                 executor.send( *adders[r] );
    2587         }
    2588         for ( r; rows ) {       // wait for results
    2589                 delete( adders[r] );
    2590                 total += subtotals[r];
    2591         }
    2592         sout | total;
    2593 }
    2594 \end{cfa}
    2595 \end{tabular}
    2596 \caption{Executor}
    2597 \end{figure}
    2598 \end{comment}
     2536%
     2537%
     2538% \subsection{Thread Pools}
     2539%
     2540% In contrast to direct threading is indirect \newterm{thread pools}, \eg Java @executor@, where small jobs (work units) are inserted into a work pool for execution.
     2541% If the jobs are dependent, \ie interact, there is an implicit/explicit dependency graph that ties them together.
     2542% While removing direct concurrency, and hence the amount of context switching, thread pools significantly limit the interaction that can occur among jobs.
     2543% Indeed, jobs should not block because that also blocks the underlying thread, which effectively means the CPU utilization, and therefore throughput, suffers.
     2544% While it is possible to tune the thread pool with sufficient threads, it becomes difficult to obtain high throughput and good core utilization as job interaction increases.
     2545% As well, concurrency errors return, which threads pools are suppose to mitigate.
    25992546
    26002547
     
    26202567The purpose of a cluster is to control the amount of parallelism that is possible among threads, plus scheduling and other execution defaults.
    26212568The default cluster-scheduler is single-queue multi-server, which provides automatic load-balancing of threads on processors.
    2622 However, the design allows changing the scheduler, \eg multi-queue multi-server with work-stealing/sharing across the virtual processors.
     2569However, the scheduler is pluggable, supporting alternative schedulers, such as multi-queue multi-server, with work-stealing/sharing across the virtual processors.
    26232570If several clusters exist, both threads and virtual processors, can be explicitly migrated from one cluster to another.
    26242571No automatic load balancing among clusters is performed by \CFA.
     
    26272574The user cluster is created to contain the application user-threads.
    26282575Having all threads execute on the one cluster often maximizes utilization of processors, which minimizes runtime.
    2629 However, because of limitations of scheduling requirements (real-time), NUMA architecture, heterogeneous hardware, or issues with the underlying operating system, multiple clusters are sometimes necessary.
     2576However, because of limitations of the underlying operating system, heterogeneous hardware, or scheduling requirements (real-time), multiple clusters are sometimes necessary.
    26302577
    26312578
     
    26712618\subsection{Preemption}
    26722619
    2673 Nondeterministic preemption provides fairness from long running threads, and forces concurrent programmers to write more robust programs, rather than relying on code between cooperative scheduling to be atomic.
    2674 This atomic reliance can fail on multi-core machines, because execution across cores is nondeterministic.
    2675 A different reason for not supporting preemption is that it significantly complicates the runtime system, \eg Microsoft runtime does not support interrupts and on Linux systems, interrupts are complex (see below).
     2620Nondeterministic preemption provides fairness from long running threads, and forces concurrent programmers to write more robust programs, rather than relying on section of code between cooperative scheduling to be atomic.
     2621A separate reason for not supporting preemption is that it significantly complicates the runtime system.
    26762622Preemption is normally handled by setting a count-down timer on each virtual processor.
    26772623When the timer expires, an interrupt is delivered, and the interrupt handler resets the count-down timer, and if the virtual processor is executing in user code, the signal handler performs a user-level context-switch, or if executing in the language runtime-kernel, the preemption is ignored or rolled forward to the point where the runtime kernel context switches back to user code.
     
    26822628Because preemption frequency is usually long (1 millisecond) performance cost is negligible.
    26832629
    2684 Linux switched a decade ago from specific to arbitrary process signal-delivery for applications with multiple kernel threads.
     2630However, on current Linux systems:
    26852631\begin{cquote}
    26862632A process-directed signal may be delivered to any one of the threads that does not currently have the signal blocked.
     
    26882634SIGNAL(7) - Linux Programmer's Manual
    26892635\end{cquote}
    2690 Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to an application, is delivered to any of its Linux subprocesses (kernel threads).
    2691 To ensure each virtual processor receives a preemption signal, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events.
     2636Hence, the timer-expiry signal, which is generated \emph{externally} by the Linux kernel to the Linux process, is delivered to any of its Linux subprocesses (kernel threads).
     2637To ensure each virtual processor receives its own preemption signals, a discrete-event simulation is run on a special virtual processor, and only it sets and receives timer events.
    26922638Virtual processors register an expiration time with the discrete-event simulator, which is inserted in sorted order.
    26932639The simulation sets the count-down timer to the value at the head of the event list, and when the timer expires, all events less than or equal to the current time are processed.
     
    27062652
    27072653To verify the implementation of the \CFA runtime, a series of microbenchmarks are performed comparing \CFA with Java OpenJDK-9, Go 1.9.2 and \uC 7.0.0.
    2708 The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.6 LTS, and \uC/\CFA are compiled with gcc 6.5.
     2654The benchmark computer is an AMD Opteron\texttrademark\ 6380 NUMA 64-core, 8 socket, 2.5 GHz processor, running Ubuntu 16.04.3 LTS and \uC and \CFA are compiled with gcc 6.3.
    27092655
    27102656\begin{comment}
     
    27612707\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    27622708\begin{cfa}
    2763 @thread@ MyThread {};
    2764 void @main@( MyThread & ) {}
     2709thread MyThread {};
     2710void main( MyThread & ) {}
    27652711int main() {
    27662712        BENCH( for ( N ) { @MyThread m;@ } )
     
    28042750\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    28052751\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    2806 @coroutine@ C {} c;
     2752coroutine C {} c;
    28072753void main( C & ) { for ( ;; ) { @suspend;@ } }
    28082754int main() { // coroutine test
     
    28252771\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    28262772\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2827 C function              & 2                     & 2             & 0             \\
    2828 \CFA generator  & 2                     & 2             & 0             \\
     2773Kernel Thread   & 333.5 & 332.96        & 4.1   \\
    28292774\CFA Coroutine  & 49    & 48.68         & 0.47  \\
    28302775\CFA Thread             & 105   & 105.57        & 1.37  \\
     
    28322777\uC Thread              & 100   & 99.29         & 0.96  \\
    28332778Goroutine               & 145   & 147.25        & 4.15  \\
    2834 Java Thread             & 373.5 & 375.14        & 8.72  \\
    2835 Pthreads Thread & 333.5 & 332.96        & 4.1
     2779Java Thread             & 373.5 & 375.14        & 8.72
    28362780\end{tabular}
    28372781\end{multicols}
     
    28492793\lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}}
    28502794\begin{cfa}
    2851 @monitor@ M {} m1/*, m2, m3, m4*/;
     2795monitor M {} m1/*, m2, m3, m4*/;
    28522796void __attribute__((noinline))
    2853 do_call( M & @mutex m/*, m2, m3, m4*/@ ) {}
     2797do_call( M & mutex m/*, m2, m3, m4*/ ) {}
    28542798int main() {
    28552799        BENCH(
    2856                 for( N ) do_call( m1/*, m2, m3, m4*/ );
     2800                for( N ) @do_call( m1/*, m2, m3, m4*/ );@
    28572801        )
    28582802        sout | result`ns;
     
    28692813\begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}}
    28702814\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    2871 test and test-and-test lock             & 26            & 26    & 0             \\
     2815C function                                              & 2                     & 2             & 0             \\
     2816FetchAdd + FetchSub                             & 26            & 26    & 0             \\
    28722817Pthreads Mutex Lock                             & 31            & 31.71 & 0.97  \\
    28732818\uC @monitor@ member rtn.               & 31            & 31    & 0             \\
     
    28752820\CFA @mutex@ function, 2 arg.   & 84            & 85.36 & 1.99  \\
    28762821\CFA @mutex@ function, 4 arg.   & 158           & 161   & 4.22  \\
    2877 Java synchronized method                & 27.5          & 29.79 & 2.93
     2822Java synchronized function              & 27.5          & 29.79 & 2.93
    28782823\end{tabular}
    28792824\end{multicols}
     
    28912836\begin{cfa}
    28922837volatile int go = 0;
    2893 @monitor@ M { @condition c;@ } m;
     2838monitor M { condition c; } m;
    28942839void __attribute__((noinline))
    2895 do_call( M & @mutex@ a1 ) { @signal( c );@ }
     2840do_call( M & mutex a1 ) { @signal( c );@ }
    28962841thread T {};
    28972842void main( T & this ) {
     
    29242869\multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\
    29252870Pthreads Cond. Variable         & 6005          & 5681.43       & 835.45        \\
    2926 \uC @signal@                            & 324           & 325.54        & 3.02          \\
     2871\uC @signal@                            & 324           & 325.54        & 3,02          \\
    29272872\CFA @signal@, 1 @monitor@      & 368.5         & 370.61        & 4.77          \\
    29282873\CFA @signal@, 2 @monitor@      & 467           & 470.5         & 6.79          \\
     
    29442889\begin{cfa}
    29452890volatile int go = 0;
    2946 @monitor@ M {} m;
     2891monitor M {} m;
    29472892thread T {};
    29482893void __attribute__((noinline))
    2949 do_call( M & @mutex@ ) {}
     2894do_call( M & mutex ) {}
    29502895void main( T & ) {
    29512896        while ( go == 0 ) { yield(); }
    2952         while ( go == 1 ) { do_call( m ); }
     2897        while ( go == 1 ) { @do_call( m );@ }
    29532898}
    29542899int __attribute__((noinline))
    2955 do_wait( M & @mutex@ m ) {
     2900do_wait( M & mutex m ) {
    29562901        go = 1; // continue other thread
    29572902        BENCH( for ( N ) { @waitfor( do_call, m );@ } )
  • doc/papers/concurrency/annex/local.bib

    rc1ea11b r18e683b  
    6666}
    6767
    68 @misc{BankTransfer,
     68@article{BankTransfer,
    6969        key     = {Bank Transfer},
    7070        keywords        = {Bank Transfer},
    7171        title   = {Bank Account Transfer Problem},
    72         howpublished    = {Wiki Wiki Web, \url{http://wiki.c2.com/?BankAccountTransferProblem}},
     72        publisher       = {Wiki Wiki Web},
     73        address = {http://wiki.c2.com},
    7374        year            = 2010
    7475}
  • doc/papers/concurrency/examples/Fib.cfa

    rc1ea11b r18e683b  
    1313}
    1414
    15 #define FibCtor { 1, 0 }
    16 typedef struct { int fn1, fn; } Fib;
    17 int fib_state( Fib & f ) with(f) {
    18         int ret = fn; fn = fn1; fn1 = fn + ret;
    19         return ret;
     15#define FibCtor { 0, 1 }
     16typedef struct { int fn, fn1; } Fib;
     17int fib_state( Fib & f ) with( f ) {
     18        int fn0 = fn1 + fn2;  fn2 = fn1;  fn = fn0;
     19        return fn1;
    2020}
    2121
     
    3232coroutine Fib2 { int fn; };                                             // used for communication
    3333void main( Fib2 & fib ) with( fib ) {                   // called on first resume
    34         int fn1;                                                                        // precompute first two states
    35         [fn1, fn] = [1, 0];
     34        int fn1 = 1, fn2 = 0;                                           // precompute first two states
    3635        for () {
     36                fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;  // general case
    3737                suspend();                                                              // restart last resume
    38                 [fn1, fn] = [fn, fn + fn1];
    3938        }
    4039}
    41 int ?()( Fib2 & fib ) {                                                 // function-call interface
     40int ?()( Fib2 & fib ) with( fib ) {
    4241        return resume( fib ).fn;                                        // restart last suspend
    4342}
    44 int ?()( Fib2 & fib, int N ) {                                  // skip N values
    45         for ( N - 1 ) fib();                                            // use function-call interface
     43int ?()( Fib2 & fib, int N ) with( fib ) {
     44        for ( N - 1 ) fib();
    4645        return fib();
    4746}
    48 double ?()( Fib2 & fib ) {                                              // different return type
    49         return (int)(fib()) / 3.14159;                          // cast prevents recursive call
     47double ?()( Fib2 & fib ) with( fib ) {
     48        return (int)(fib()) / 3.14159;                                          // restart last suspend
    5049}
    5150
  • doc/user/user.tex

    rc1ea11b r18e683b  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Jun 15 16:29:45 2019
    14 %% Update Count     : 3847
     13%% Last Modified On : Sun May  5 18:24:50 2019
     14%% Update Count     : 3489
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    254254\begin{lstlisting}
    255255®forall( otype T )® T identity( T val ) { return val; }
    256 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§
     256int forty_two = identity( 42 );                         §\C{// T is bound to int, forty\_two == 42}§
    257257\end{lstlisting}
    258258% extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions.
     
    282282
    283283double key = 5.0, vals[10] = { /* 10 sorted floating values */ };
    284 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§
     284double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      §\C{// search sorted array}§
    285285\end{lstlisting}
    286286which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers:
     
    291291
    292292forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
    293         T * result = bsearch( key, arr, size ); §\C{// call first version}§
    294         return result ? result - arr : size; } §\C{// pointer subtraction includes sizeof(T)}§
    295 
    296 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§
     293        T * result = bsearch( key, arr, size ); §\C{// call first version}§
     294        return result ? result - arr : size; }  §\C{// pointer subtraction includes sizeof(T)}§
     295
     296double * val = bsearch( 5.0, vals, 10 );        §\C{// selection based on return type}§
    297297int posn = bsearch( 5.0, vals, 10 );
    298298\end{lstlisting}
     
    306306\begin{lstlisting}
    307307forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
    308 int * ip = malloc(); §\C{// select type and size from left-hand side}§
     308int * ip = malloc();                                            §\C{// select type and size from left-hand side}§
    309309double * dp = malloc();
    310310struct S {...} * sp = malloc();
     
    318318\begin{cfa}
    319319char ®abs®( char );
    320 extern "C" { int ®abs®( int ); } §\C{// use default C routine for int}§
     320extern "C" { int ®abs®( int ); }                        §\C{// use default C routine for int}§
    321321long int ®abs®( long int );
    322322long long int ®abs®( long long int );
     
    426426\begin{cfa}
    427427#ifndef __CFORALL__
    428 #include <stdio.h>§\indexc{stdio.h}§ §\C{// C header file}§
     428#include <stdio.h>§\indexc{stdio.h}§            §\C{// C header file}§
    429429#else
    430 #include <fstream>§\indexc{fstream}§ §\C{// \CFA header file}§
     430#include <fstream>§\indexc{fstream}§            §\C{// \CFA header file}§
    431431#endif
    432432\end{cfa}
     
    512512Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
    513513\begin{cfa}
    514 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§
     514int ®`®otype®`® = 3;                                            §\C{// make keyword an identifier}§
    515515double ®`®forall®`® = 3.5;
    516516\end{cfa}
     
    523523\begin{cfa}
    524524// include file uses the CFA keyword "with".
    525 #if ! defined( with ) §\C{// nesting ?}§
    526 #define with ®`®with®`® §\C{// make keyword an identifier}§
     525#if ! defined( with )                                           §\C{// nesting ?}§
     526#define with ®`®with®`®                                         §\C{// make keyword an identifier}§
    527527#define __CFA_BFD_H__
    528528#endif
    529529
    530 ®#include_next <bfdlink.h> §\C{// must have internal check for multiple expansion}§
     530®#include_next <bfdlink.h>                      §\C{// must have internal check for multiple expansion}§
    531531®
    532532#if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§
     
    544544Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg:
    545545\begin{cfa}
    546 2®_®147®_®483®_®648; §\C{// decimal constant}§
    547 56®_®ul; §\C{// decimal unsigned long constant}§
    548 0®_®377; §\C{// octal constant}§
    549 0x®_®ff®_®ff; §\C{// hexadecimal constant}§
    550 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§
    551 3.141®_®592®_®654; §\C{// floating constant}§
    552 10®_®e®_®+1®_®00; §\C{// floating constant}§
    553 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating}§
    554 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating long constant}§
    555 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§
     5462®_®147®_®483®_®648;                                            §\C{// decimal constant}§
     54756®_®ul;                                                                        §\C{// decimal unsigned long constant}§
     5480®_®377;                                                                        §\C{// octal constant}§
     5490x®_®ff®_®ff;                                                           §\C{// hexadecimal constant}§
     5500x®_®ef3d®_®aa5c;                                                       §\C{// hexadecimal constant}§
     5513.141®_®592®_®654;                                                      §\C{// floating constant}§
     55210®_®e®_®+1®_®00;                                                       §\C{// floating constant}§
     5530x®_®ff®_®ff®_®p®_®3;                                           §\C{// hexadecimal floating}§
     5540x®_®1.ffff®_®ffff®_®p®_®128®_®l;                       §\C{// hexadecimal floating long constant}§
     555L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
    556556\end{cfa}
    557557The rules for placement of underscores are:
     
    612612(Does not make sense for ©do©-©while©.)
    613613\begin{cfa}
    614 if ( ®int x = f()® ) ... §\C{// x != 0}§
    615 if ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§
    616 if ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§
     614if ( ®int x = f()® ) ...                                        §\C{// x != 0}§
     615if ( ®int x = f(), y = g()® ) ...                       §\C{// x != 0 \&\& y != 0}§
     616if ( ®int x = f(), y = g(); x < y® ) ...        §\C{// relational expression}§
    617617if ( ®struct S { int i; } x = { f() }; x.i < 4® ) §\C{// relational expression}§
    618618
    619 while ( ®int x = f()® ) ... §\C{// x != 0}§
    620 while ( ®int x = f(), y = g()® ) ... §\C{// x != 0 \&\& y != 0}§
     619while ( ®int x = f()® ) ...                                     §\C{// x != 0}§
     620while ( ®int x = f(), y = g()® ) ...            §\C{// x != 0 \&\& y != 0}§
    621621while ( ®int x = f(), y = g(); x < y® ) ... §\C{// relational expression}§
    622622while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... §\C{// relational expression}§
     
    892892\begin{cfa}
    893893switch ( x ) {
    894         ®int y = 1;® §\C{// unreachable initialization}§
    895         ®x = 7;® §\C{// unreachable code without label/branch}§
     894        ®int y = 1;®                                                    §\C{// unreachable initialization}§
     895        ®x = 7;®                                                                §\C{// unreachable code without label/branch}§
    896896  case 0: ...
    897897        ...
    898         ®int z = 0;® §\C{// unreachable initialization, cannot appear after case}§
     898        ®int z = 0;®                                                    §\C{// unreachable initialization, cannot appear after case}§
    899899        z = 2;
    900900  case 1:
    901         ®x = z;® §\C{// without fall through, z is uninitialized}§
     901        ®x = z;®                                                                §\C{// without fall through, z is uninitialized}§
    902902}
    903903\end{cfa}
     
    937937  ®case 5:
    938938        ...
    939         ®fallthru®; §\C{// explicit fall through}§
     939        ®fallthru®;                                                             §\C{// explicit fall through}§
    940940  case 7:
    941941        ...
    942         ®break® §\C{// explicit end of switch (redundant)}§
     942        ®break®                                                                 §\C{// explicit end of switch (redundant)}§
    943943  default:
    944944        j = 3;
     
    961961\begin{cfa}
    962962switch ( x ) {
    963         ®int i = 0;® §\C{// allowed only at start}§
     963        ®int i = 0;®                                                    §\C{// allowed only at start}§
    964964  case 0:
    965965        ...
    966         ®int j = 0;® §\C{// disallowed}§
     966        ®int j = 0;®                                                    §\C{// disallowed}§
    967967  case 1:
    968968        {
    969                 ®int k = 0;® §\C{// allowed at different nesting levels}§
     969                ®int k = 0;®                                            §\C{// allowed at different nesting levels}§
    970970                ...
    971           ®case 2:® §\C{// disallow case in nested statements}§
     971          ®case 2:®                                                             §\C{// disallow case in nested statements}§
    972972        }
    973973  ...
     
    10191019\begin{cfa}
    10201020switch ( i ) {
    1021   case ®1~5:® §\C{// 1, 2, 3, 4, 5}§
     1021  case ®1~5:®                                   §\C{// 1, 2, 3, 4, 5}§
    10221022        ...
    1023   case ®10~15:® §\C{// 10, 11, 12, 13, 14, 15}§
     1023  case ®10~15:®                                 §\C{// 10, 11, 12, 13, 14, 15}§
    10241024        ...
    10251025}
     
    11521152Grouping heterogeneous data into \newterm{aggregate}s (structure/union) is a common programming practice, and an aggregate can be further organized into more complex structures, such as arrays and containers:
    11531153\begin{cfa}
    1154 struct S { §\C{// aggregate}§
    1155         char c; §\C{// fields}§
     1154struct S {                                                                      §\C{// aggregate}§
     1155        char c;                                                                 §\C{// fields}§
    11561156        int i;
    11571157        double d;
     
    11621162\begin{cfa}
    11631163void f( S s ) {
    1164         ®s.®c; ®s.®i; ®s.®d; §\C{// access containing fields}§
     1164        ®s.®c; ®s.®i; ®s.®d;                                    §\C{// access containing fields}§
    11651165}
    11661166\end{cfa}
     
    11691169\begin{C++}
    11701170struct S {
    1171         char c; §\C{// fields}§
     1171        char c;                                                                 §\C{// fields}§
    11721172        int i;
    11731173        double d;
    1174         void f() { §\C{// implicit ``this'' aggregate}§
    1175                 ®this->®c; ®this->®i; ®this->®d; §\C{// access containing fields}§
     1174        void f() {                                                              §\C{// implicit ``this'' aggregate}§
     1175                ®this->®c; ®this->®i; ®this->®d;        §\C{// access containing fields}§
    11761176        }
    11771177}
     
    11811181\begin{cfa}
    11821182struct T { double m, n; };
    1183 int S::f( T & t ) { §\C{// multiple aggregate parameters}§
    1184         c; i; d; §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§
    1185         ®t.®m; ®t.®n; §\C{// must qualify}§
     1183int S::f( T & t ) {                                                     §\C{// multiple aggregate parameters}§
     1184        c; i; d;                                                                §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§
     1185        ®t.®m; ®t.®n;                                                   §\C{// must qualify}§
    11861186}
    11871187\end{cfa}
     
    11901190Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    11911191\begin{cfa}
    1192 void f( S & this ) ®with ( this )® { §\C{// with statement}§
    1193         c; i; d; §\C{\color{red}// this.c, this.i, this.d}§
     1192void f( S & this ) ®with ( this )® {            §\C{// with statement}§
     1193        c; i; d;                                                                §\C{\color{red}// this.c, this.i, this.d}§
    11941194}
    11951195\end{cfa}
    11961196with the generality of opening multiple aggregate-parameters:
    11971197\begin{cfa}
    1198 void f( S & s, T & t ) ®with ( s, t )® { §\C{// multiple aggregate parameters}§
    1199         c; i; d; §\C{\color{red}// s.c, s.i, s.d}§
    1200         m; n; §\C{\color{red}// t.m, t.n}§
     1198void f( S & s, T & t ) ®with ( s, t )® {        §\C{// multiple aggregate parameters}§
     1199        c; i; d;                                                                §\C{\color{red}// s.c, s.i, s.d}§
     1200        m; n;                                                                   §\C{\color{red}// t.m, t.n}§
    12011201}
    12021202\end{cfa}
     
    12201220struct T { int ®i®; int k; int m; } t, w;
    12211221with ( s, t ) {
    1222         j + k; §\C{// unambiguous, s.j + t.k}§
    1223         m = 5.0; §\C{// unambiguous, t.m = 5.0}§
    1224         m = 1; §\C{// unambiguous, s.m = 1}§
    1225         int a = m; §\C{// unambiguous, a = s.i }§
    1226         double b = m; §\C{// unambiguous, b = t.m}§
    1227         int c = s.i + t.i; §\C{// unambiguous, qualification}§
    1228         (double)m; §\C{// unambiguous, cast}§
     1222        j + k;                                                                  §\C{// unambiguous, s.j + t.k}§
     1223        m = 5.0;                                                                §\C{// unambiguous, t.m = 5.0}§
     1224        m = 1;                                                                  §\C{// unambiguous, s.m = 1}§
     1225        int a = m;                                                              §\C{// unambiguous, a = s.i }§
     1226        double b = m;                                                   §\C{// unambiguous, b = t.m}§
     1227        int c = s.i + t.i;                                              §\C{// unambiguous, qualification}§
     1228        (double)m;                                                              §\C{// unambiguous, cast}§
    12291229}
    12301230\end{cfa}
     
    12361236There is an interesting problem between parameters and the function-body ©with©, \eg:
    12371237\begin{cfa}
    1238 void ?{}( S & s, int i ) with ( s ) { §\C{// constructor}§
    1239         ®s.i = i;®  j = 3;  m = 5.5; §\C{// initialize fields}§
     1238void ?{}( S & s, int i ) with ( s ) {           §\C{// constructor}§
     1239        ®s.i = i;®  j = 3;  m = 5.5;                    §\C{// initialize fields}§
    12401240}
    12411241\end{cfa}
     
    12561256Finally, a cast may be used to disambiguate among overload variables in a ©with© expression:
    12571257\begin{cfa}
    1258 with ( w ) { ... } §\C{// ambiguous, same name and no context}§
    1259 with ( (S)w ) { ... } §\C{// unambiguous, cast}§
     1258with ( w ) { ... }                                                      §\C{// ambiguous, same name and no context}§
     1259with ( (S)w ) { ... }                                           §\C{// unambiguous, cast}§
    12601260\end{cfa}
    12611261and ©with© expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:
    12621262% \begin{cfa}
    12631263% struct S { int i, j; } sv;
    1264 % with ( sv ) { §\C{// implicit reference}§
     1264% with ( sv ) {                                                         §\C{// implicit reference}§
    12651265%       S & sr = sv;
    1266 %       with ( sr ) { §\C{// explicit reference}§
     1266%       with ( sr ) {                                                   §\C{// explicit reference}§
    12671267%               S * sp = &sv;
    1268 %               with ( *sp ) { §\C{// computed reference}§
    1269 %                       i = 3; j = 4; §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§
     1268%               with ( *sp ) {                                          §\C{// computed reference}§
     1269%                       i = 3; j = 4;                                   §\C{\color{red}// sp--{\textgreater}i, sp--{\textgreater}j}§
    12701270%               }
    1271 %               i = 2; j = 3; §\C{\color{red}// sr.i, sr.j}§
     1271%               i = 2; j = 3;                                           §\C{\color{red}// sr.i, sr.j}§
    12721272%       }
    1273 %       i = 1; j = 2; §\C{\color{red}// sv.i, sv.j}§
     1273%       i = 1; j = 2;                                                   §\C{\color{red}// sv.i, sv.j}§
    12741274% }
    12751275% \end{cfa}
     
    12791279class C {
    12801280        int i, j;
    1281         int mem() { §\C{\color{red}// implicit "this" parameter}§
    1282                 i = 1; §\C{\color{red}// this->i}§
    1283                 j = 2; §\C{\color{red}// this->j}§
     1281        int mem() {                                                             §\C{\color{red}// implicit "this" parameter}§
     1282                i = 1;                                                          §\C{\color{red}// this->i}§
     1283                j = 2;                                                          §\C{\color{red}// this->j}§
    12841284        }
    12851285}
     
    12881288\begin{cfa}
    12891289struct S { int i, j; };
    1290 int mem( S & ®this® ) { §\C{// explicit "this" parameter}§
    1291         ®this.®i = 1; §\C{// "this" is not elided}§
     1290int mem( S & ®this® ) {                                         §\C{// explicit "this" parameter}§
     1291        ®this.®i = 1;                                                   §\C{// "this" is not elided}§
    12921292        ®this.®j = 2;
    12931293}
     
    12971297\CFA provides a ©with© clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references.
    12981298\begin{cfa}
    1299 int mem( S & this ) ®with( this )® { §\C{// with clause}§
    1300         i = 1; §\C{\color{red}// this.i}§
    1301         j = 2; §\C{\color{red}// this.j}§
     1299int mem( S & this ) ®with( this )® {            §\C{// with clause}§
     1300        i = 1;                                                                  §\C{\color{red}// this.i}§
     1301        j = 2;                                                                  §\C{\color{red}// this.j}§
    13021302}
    13031303\end{cfa}
     
    13161316        struct S1 { ... } s1;
    13171317        struct S2 { ... } s2;
    1318         ®with( s1 )® { §\C{// with statement}§
     1318        ®with( s1 )® {                                                  §\C{// with statement}§
    13191319                // access fields of s1 without qualification
    1320                 ®with s2® { §\C{// nesting}§
     1320                ®with s2® {                                                     §\C{// nesting}§
    13211321                        // access fields of s1 and s2 without qualification
    13221322                }
     
    13731373Non-local transfer can cause stack unwinding, \ie non-local routine termination, depending on the kind of raise.
    13741374\begin{cfa}
    1375 exception_t E {}; §\C{// exception type}§
     1375exception_t E {};                                                       §\C{// exception type}§
    13761376void f(...) {
    1377         ... throw E{}; ... §\C{// termination}§
    1378         ... throwResume E{}; ... §\C{// resumption}§
     1377        ... throw E{}; ...                                              §\C{// termination}§
     1378        ... throwResume E{}; ...                                §\C{// resumption}§
    13791379}
    13801380try {
     
    14421442For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
    14431443\begin{cfa}
    1444 int ®(*®f®())[®5®]® {...}; §\C{// definition}§
    1445  ... ®(*®f®())[®3®]® += 1; §\C{// usage}§
     1444int ®(*®f®())[®5®]® {...};                              §\C{// definition}§
     1445 ... ®(*®f®())[®3®]® += 1;                              §\C{// usage}§
    14461446\end{cfa}
    14471447Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
     
    16351635*x = 3;                 // implicit dereference
    16361636int * ®const® y = (int *)104;
    1637 *y = *x;                        // implicit dereference
     1637*y = *x;                // implicit dereference
    16381638\end{cfa}
    16391639\end{tabular}
     
    16491649\hline
    16501650\begin{cfa}
    1651 lda             r1,100   // load address of x
    1652 ld               r2,(r1)   // load value of x
    1653 lda             r3,104   // load address of y
    1654 st               r2,(r3)   // store x into y
     1651lda             r1,100  // load address of x
     1652ld               r2,(r1)          // load value of x
     1653lda             r3,104  // load address of y
     1654st               r2,(r3)          // store x into y
    16551655\end{cfa}
    16561656&
    16571657\begin{cfa}
    16581658
    1659 ld              r2,(100)   // load value of x
    1660 
    1661 st              r2,(104)   // store x into y
     1659ld              r2,(100)        // load value of x
     1660
     1661st              r2,(104)        // store x into y
    16621662\end{cfa}
    16631663\end{tabular}
     
    16731673\begin{cfa}
    16741674int x, y, ®*® p1, ®*® p2, ®**® p3;
    1675 p1 = ®&®x;    // p1 points to x
    1676 p2 = p1;    // p2 points to x
    1677 p1 = ®&®y;    // p1 points to y
    1678 p3 = &p2;  // p3 points to p2
     1675p1 = ®&®x;              // p1 points to x
     1676p2 = p1;                // p2 points to x
     1677p1 = ®&®y;              // p1 points to y
     1678p3 = &p2;               // p3 points to p2
    16791679\end{cfa}
    16801680&
     
    16871687For example, \Index*{Algol68}~\cite{Algol68} infers pointer dereferencing to select the best meaning for each pointer usage
    16881688\begin{cfa}
    1689 p2 = p1 + x; §\C{// compiler infers *p2 = *p1 + x;}§
     1689p2 = p1 + x;                                    §\C{// compiler infers *p2 = *p1 + x;}§
    16901690\end{cfa}
    16911691Algol68 infers the following dereferencing ©*p2 = *p1 + x©, because adding the arbitrary integer value in ©x© to the address of ©p1© and storing the resulting address into ©p2© is an unlikely operation.
     
    16951695In C, objects of pointer type always manipulate the pointer object's address:
    16961696\begin{cfa}
    1697 p1 = p2; §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
    1698 p2 = p1 + x; §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
     1697p1 = p2;                                                §\C{// p1 = p2\ \ rather than\ \ *p1 = *p2}§
     1698p2 = p1 + x;                                    §\C{// p2 = p1 + x\ \ rather than\ \ *p2 = *p1 + x}§
    16991699\end{cfa}
    17001700even though the assignment to ©p2© is likely incorrect, and the programmer probably meant:
    17011701\begin{cfa}
    1702 p1 = p2; §\C{// pointer address assignment}§
    1703 ®*®p2 = ®*®p1 + x; §\C{// pointed-to value assignment / operation}§
     1702p1 = p2;                                                §\C{// pointer address assignment}§
     1703®*®p2 = ®*®p1 + x;                              §\C{// pointed-to value assignment / operation}§
    17041704\end{cfa}
    17051705The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
     
    17181718\begin{cfa}
    17191719int x, y, ®&® r1, ®&® r2, ®&&® r3;
    1720 ®&®r1 = &x; §\C{// r1 points to x}§
    1721 ®&®r2 = &r1; §\C{// r2 points to x}§
    1722 ®&®r1 = &y; §\C{// r1 points to y}§
    1723 ®&&®r3 = ®&®&r2; §\C{// r3 points to r2}§
     1720®&®r1 = &x;                                             §\C{// r1 points to x}§
     1721®&®r2 = &r1;                                    §\C{// r2 points to x}§
     1722®&®r1 = &y;                                             §\C{// r1 points to y}§
     1723®&&®r3 = ®&®&r2;                                §\C{// r3 points to r2}§
    17241724r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); §\C{// implicit dereferencing}§
    17251725\end{cfa}
     
    17371737For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
    17381738\begin{cfa}
    1739 (&®*®)r1 = &x; §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
     1739(&®*®)r1 = &x;                                  §\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}§
    17401740\end{cfa}
    17411741Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
    17421742\begin{cfa}
    1743 (&(&®*®)®*®)r3 = &(&®*®)r2; §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
     1743(&(&®*®)®*®)r3 = &(&®*®)r2;             §\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}§
    17441744\end{cfa}
    17451745Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
     
    17491749int x, *p1 = &x, **p2 = &p1, ***p3 = &p2,
    17501750                 &r1 = x,    &&r2 = r1,   &&&r3 = r2;
    1751 ***p3 = 3; §\C{// change x}§
    1752 r3 = 3; §\C{// change x, ***r3}§
    1753 **p3 = ...; §\C{// change p1}§
    1754 &r3 = ...; §\C{// change r1, (\&*)**r3, 1 cancellation}§
    1755 *p3 = ...; §\C{// change p2}§
    1756 &&r3 = ...; §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
    1757 &&&r3 = p3; §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
     1751***p3 = 3;                                              §\C{// change x}§
     1752r3 = 3;                                                 §\C{// change x, ***r3}§
     1753**p3 = ...;                                             §\C{// change p1}§
     1754&r3 = ...;                                              §\C{// change r1, (\&*)**r3, 1 cancellation}§
     1755*p3 = ...;                                              §\C{// change p2}§
     1756&&r3 = ...;                                             §\C{// change r2, (\&(\&*)*)*r3, 2 cancellations}§
     1757&&&r3 = p3;                                             §\C{// change r3 to p3, (\&(\&(\&*)*)*)r3, 3 cancellations}§
    17581758\end{cfa}
    17591759Furthermore, both types are equally performant, as the same amount of dereferencing occurs for both types.
     
    17621762As for a pointer type, a reference type may have qualifiers:
    17631763\begin{cfa}
    1764 const int cx = 5; §\C{// cannot change cx;}§
    1765 const int & cr = cx; §\C{// cannot change what cr points to}§
    1766 ®&®cr = &cx; §\C{// can change cr}§
    1767 cr = 7; §\C{// error, cannot change cx}§
    1768 int & const rc = x; §\C{// must be initialized}§
    1769 ®&®rc = &x; §\C{// error, cannot change rc}§
    1770 const int & const crc = cx; §\C{// must be initialized}§
    1771 crc = 7; §\C{// error, cannot change cx}§
    1772 ®&®crc = &cx; §\C{// error, cannot change crc}§
     1764const int cx = 5;                                       §\C{// cannot change cx;}§
     1765const int & cr = cx;                            §\C{// cannot change what cr points to}§
     1766®&®cr = &cx;                                            §\C{// can change cr}§
     1767cr = 7;                                                         §\C{// error, cannot change cx}§
     1768int & const rc = x;                                     §\C{// must be initialized}§
     1769®&®rc = &x;                                                     §\C{// error, cannot change rc}§
     1770const int & const crc = cx;                     §\C{// must be initialized}§
     1771crc = 7;                                                        §\C{// error, cannot change cx}§
     1772®&®crc = &cx;                                           §\C{// error, cannot change crc}§
    17731773\end{cfa}
    17741774Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
    17751775\begin{cfa}
    1776 int & const cr = *0; §\C{// where 0 is the int * zero}§
     1776int & const cr = *0;                            §\C{// where 0 is the int * zero}§
    17771777\end{cfa}
    17781778Note, constant reference-types do not prevent \Index{addressing errors} because of explicit storage-management:
     
    17811781cr = 5;
    17821782free( &cr );
    1783 cr = 7; §\C{// unsound pointer dereference}§
     1783cr = 7;                                                         §\C{// unsound pointer dereference}§
    17841784\end{cfa}
    17851785
     
    18061806\begin{cfa}
    18071807int w, x, y, z, & ar[3] = { x, y, z }; §\C{// initialize array of references}§
    1808 &ar[1] = &w; §\C{// change reference array element}§
    1809 typeof( ar[1] ) p; §\C{// (gcc) is int, \ie the type of referenced object}§
    1810 typeof( &ar[1] ) q; §\C{// (gcc) is int \&, \ie the type of reference}§
    1811 sizeof( ar[1] ) == sizeof( int ); §\C{// is true, \ie the size of referenced object}§
    1812 sizeof( &ar[1] ) == sizeof( int *) §\C{// is true, \ie the size of a reference}§
     1808&ar[1] = &w;                                            §\C{// change reference array element}§
     1809typeof( ar[1] ) p;                                      §\C{// (gcc) is int, \ie the type of referenced object}§
     1810typeof( &ar[1] ) q;                                     §\C{// (gcc) is int \&, \ie the type of reference}§
     1811sizeof( ar[1] ) == sizeof( int );       §\C{// is true, \ie the size of referenced object}§
     1812sizeof( &ar[1] ) == sizeof( int *)      §\C{// is true, \ie the size of a reference}§
    18131813\end{cfa}
    18141814
     
    18271827Therefore, for pointer/reference initialization, the initializing value must be an address not a value.
    18281828\begin{cfa}
    1829 int * p = &x; §\C{// assign address of x}§
    1830 ®int * p = x;® §\C{// assign value of x}§
    1831 int & r = x; §\C{// must have address of x}§
     1829int * p = &x;                                           §\C{// assign address of x}§
     1830®int * p = x;®                                          §\C{// assign value of x}§
     1831int & r = x;                                            §\C{// must have address of x}§
    18321832\end{cfa}
    18331833Like the previous example with C pointer-arithmetic, it is unlikely assigning the value of ©x© into a pointer is meaningful (again, a warning is usually given).
     
    18381838Similarly, when a reference type is used for a parameter/return type, the call-site argument does not require a reference operator for the same reason.
    18391839\begin{cfa}
    1840 int & f( int & r ); §\C{// reference parameter and return}§
    1841 z = f( x ) + f( y ); §\C{// reference operator added, temporaries needed for call results}§
     1840int & f( int & r );                                     §\C{// reference parameter and return}§
     1841z = f( x ) + f( y );                            §\C{// reference operator added, temporaries needed for call results}§
    18421842\end{cfa}
    18431843Within routine ©f©, it is possible to change the argument by changing the corresponding parameter, and parameter ©r© can be locally reassigned within ©f©.
     
    18661866void f( int & r );
    18671867void g( int * p );
    1868 f( 3 );                   g( ®&®3 ); §\C{// compiler implicit generates temporaries}§
    1869 f( x + y );             g( ®&®(x + y) ); §\C{// compiler implicit generates temporaries}§
     1868f( 3 );                   g( ®&®3 );            §\C{// compiler implicit generates temporaries}§
     1869f( x + y );             g( ®&®(x + y) );        §\C{// compiler implicit generates temporaries}§
    18701870\end{cfa}
    18711871Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     
    18781878\begin{cfa}
    18791879void f( int i );
    1880 void (* fp)( int ); §\C{// routine pointer}§
    1881 fp = f; §\C{// reference initialization}§
    1882 fp = &f; §\C{// pointer initialization}§
    1883 fp = *f; §\C{// reference initialization}§
    1884 fp(3); §\C{// reference invocation}§
    1885 (*fp)(3); §\C{// pointer invocation}§
     1880void (* fp)( int );                                     §\C{// routine pointer}§
     1881fp = f;                                                         §\C{// reference initialization}§
     1882fp = &f;                                                        §\C{// pointer initialization}§
     1883fp = *f;                                                        §\C{// reference initialization}§
     1884fp(3);                                                          §\C{// reference invocation}§
     1885(*fp)(3);                                                       §\C{// pointer invocation}§
    18861886\end{cfa}
    18871887While C's treatment of routine objects has similarity to inferring a reference type in initialization contexts, the examples are assignment not initialization, and all possible forms of assignment are possible (©f©, ©&f©, ©*f©) without regard for type.
    18881888Instead, a routine object should be referenced by a ©const© reference:
    18891889\begin{cfa}
    1890 ®const® void (®&® fr)( int ) = f; §\C{// routine reference}§
    1891 fr = ... §\C{// error, cannot change code}§
    1892 &fr = ...; §\C{// changing routine reference}§
    1893 fr( 3 ); §\C{// reference call to f}§
    1894 (*fr)(3); §\C{// error, incorrect type}§
     1890®const® void (®&® fr)( int ) = f;       §\C{// routine reference}§
     1891fr = ...                                                        §\C{// error, cannot change code}§
     1892&fr = ...;                                                      §\C{// changing routine reference}§
     1893fr( 3 );                                                        §\C{// reference call to f}§
     1894(*fr)(3);                                                       §\C{// error, incorrect type}§
    18951895\end{cfa}
    18961896because the value of the routine object is a routine literal, \ie the routine code is normally immutable during execution.\footnote{
     
    19141914int x, * px, ** ppx, *** pppx, **** ppppx;
    19151915int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    1916 x = rrrx; §\C[2.0in]{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§
    1917 px = &rrrx; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (\&x)}§
    1918 ppx = &&rrrx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (\&rx)}§
    1919 pppx = &&&rrrx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (\&rrx)}§
    1920 ppppx = &&&&rrrx; §\C{// starting from \&\&\&rrrx, \&\&\&\&rrrx is an rvalue with type int **** (\&rrrx)}§
     1916x = rrrx;               // rrrx is an lvalue with type int &&& (equivalent to x)
     1917px = &rrrx;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (&x)
     1918ppx = &&rrrx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (&rx)
     1919pppx = &&&rrrx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (&rrx)
     1920ppppx = &&&&rrrx; // starting from &&&rrrx, &&&&rrrx is an rvalue with type int **** (&rrrx)
    19211921\end{cfa}
    19221922The following example shows the second rule applied to different \Index{lvalue} contexts:
     
    19241924int x, * px, ** ppx, *** pppx;
    19251925int & rx = x, && rrx = rx, &&& rrrx = rrx ;
    1926 rrrx = 2; §\C{// rrrx is an lvalue with type int \&\&\& (equivalent to x)}§
    1927 &rrrx = px; §\C{// starting from rrrx, \&rrrx is an rvalue with type int *\&\&\& (rx)}§
    1928 &&rrrx = ppx; §\C{// starting from \&rrrx, \&\&rrrx is an rvalue with type int **\&\& (rrx)}§
    1929 &&&rrrx = pppx; §\C{// starting from \&\&rrrx, \&\&\&rrrx is an rvalue with type int ***\& (rrrx)}\CRT§
     1926rrrx = 2;               // rrrx is an lvalue with type int &&& (equivalent to x)
     1927&rrrx = px;             // starting from rrrx, &rrrx is an rvalue with type int *&&& (rx)
     1928&&rrrx = ppx;   // starting from &rrrx, &&rrrx is an rvalue with type int **&& (rrx)
     1929&&&rrrx = pppx; // starting from &&rrrx, &&&rrrx is an rvalue with type int ***& (rrrx)
    19301930\end{cfa}
    19311931
     
    19401940\begin{cfa}
    19411941int x;
    1942 x + 1; §\C[2.0in]{// lvalue variable (int) converts to rvalue for expression}§
     1942x + 1;                  // lvalue variable (int) converts to rvalue for expression
    19431943\end{cfa}
    19441944An rvalue has no type qualifiers (©cv©), so the lvalue qualifiers are dropped.
     
    19501950\begin{cfa}
    19511951int x, &r = x, f( int p );
    1952 x = ®r® + f( ®r® ); §\C{// lvalue reference converts to rvalue}§
     1952x = ®r® + f( ®r® );  // lvalue reference converts to rvalue
    19531953\end{cfa}
    19541954An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
     
    19571957lvalue to reference conversion: \lstinline[deletekeywords=lvalue]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
    19581958\begin{cfa}
    1959 int x, &r = ®x®, f( int & p ); §\C{// lvalue variable (int) convert to reference (int \&)}§
    1960 f( ®x® ); §\C{// lvalue variable (int) convert to reference (int \&)}§
     1959int x, &r = ®x®, f( int & p ); // lvalue variable (int) convert to reference (int &)
     1960f( ®x® );               // lvalue variable (int) convert to reference (int &)
    19611961\end{cfa}
    19621962Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
     
    19681968\begin{cfa}
    19691969int x, & f( int & p );
    1970 f( ®x + 3® );   §\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}§
    1971 ®&f®(...) = &x; §\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT§
     1970f( ®x + 3® );   // rvalue parameter (int) implicitly converts to lvalue temporary reference (int &)
     1971®&f®(...) = &x; // rvalue result (int &) implicitly converts to lvalue temporary reference (int &)
    19721972\end{cfa}
    19731973In both case, modifications to the temporary are inaccessible (\Index{warning}).
     
    21582158in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    21592159\begin{cfa}
    2160 [§\,§] g(); §\C{// no input or output parameters}§
    2161 [ void ] g( void ); §\C{// no input or output parameters}§
     2160[§\,§] g();                                                     §\C{// no input or output parameters}§
     2161[ void ] g( void );                                     §\C{// no input or output parameters}§
    21622162\end{cfa}
    21632163
     
    21772177\begin{cfa}
    21782178typedef int foo;
    2179 int f( int (* foo) ); §\C{// foo is redefined as a parameter name}§
     2179int f( int (* foo) );                           §\C{// foo is redefined as a parameter name}§
    21802180\end{cfa}
    21812181The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     
    21852185C-style declarations can be used to declare parameters for \CFA style routine definitions, \eg:
    21862186\begin{cfa}
    2187 [ int ] f( * int, int * ); §\C{// returns an integer, accepts 2 pointers to integers}§
    2188 [ * int, int * ] f( int ); §\C{// returns 2 pointers to integers, accepts an integer}§
     2187[ int ] f( * int, int * );                      §\C{// returns an integer, accepts 2 pointers to integers}§
     2188[ * int, int * ] f( int );                      §\C{// returns 2 pointers to integers, accepts an integer}§
    21892189\end{cfa}
    21902190The reason for allowing both declaration styles in the new context is for backwards compatibility with existing preprocessor macros that generate C-style declaration-syntax, as in:
    21912191\begin{cfa}
    21922192#define ptoa( n, d ) int (*n)[ d ]
    2193 int f( ptoa( p, 5 ) ) ... §\C{// expands to int f( int (*p)[ 5 ] )}§
    2194 [ int ] f( ptoa( p, 5 ) ) ... §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
     2193int f( ptoa( p, 5 ) ) ...                       §\C{// expands to int f( int (*p)[ 5 ] )}§
     2194[ int ] f( ptoa( p, 5 ) ) ...           §\C{// expands to [ int ] f( int (*p)[ 5 ] )}§
    21952195\end{cfa}
    21962196Again, programmers are highly encouraged to use one declaration form or the other, rather than mixing the forms.
     
    22142214        int z;
    22152215        ... x = 0; ... y = z; ...
    2216         ®return;® §\C{// implicitly return x, y}§
     2216        ®return;®                                                       §\C{// implicitly return x, y}§
    22172217}
    22182218\end{cfa}
     
    22242224[ int x, int y ] f() {
    22252225        ...
    2226 } §\C{// implicitly return x, y}§
     2226}                                                                               §\C{// implicitly return x, y}§
    22272227\end{cfa}
    22282228In this case, the current values of ©x© and ©y© are returned to the calling routine just as if a ©return© had been encountered.
     
    22332233[ int x, int y ] f( int, x, int y ) {
    22342234        ...
    2235 } §\C{// implicitly return x, y}§
     2235}                                                                               §\C{// implicitly return x, y}§
    22362236\end{cfa}
    22372237This notation allows the compiler to eliminate temporary variables in nested routine calls.
    22382238\begin{cfa}
    2239 [ int x, int y ] f( int, x, int y ); §\C{// prototype declaration}§
     2239[ int x, int y ] f( int, x, int y );    §\C{// prototype declaration}§
    22402240int a, b;
    22412241[a, b] = f( f( f( a, b ) ) );
     
    22512251as well, parameter names are optional, \eg:
    22522252\begin{cfa}
    2253 [ int x ] f (); §\C{// returning int with no parameters}§
    2254 [ * int ] g (int y); §\C{// returning pointer to int with int parameter}§
    2255 [ ] h ( int, char ); §\C{// returning no result with int and char parameters}§
    2256 [ * int, int ] j ( int ); §\C{// returning pointer to int and int, with int parameter}§
     2253[ int x ] f ();                                                 §\C{// returning int with no parameters}§
     2254[ * int ] g (int y);                                    §\C{// returning pointer to int with int parameter}§
     2255[ ] h ( int, char );                                    §\C{// returning no result with int and char parameters}§
     2256[ * int, int ] j ( int );                               §\C{// returning pointer to int and int, with int parameter}§
    22572257\end{cfa}
    22582258This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     
    22752275The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    22762276\begin{cfa}
    2277 * [ int x ] () fp; §\C{// pointer to routine returning int with no parameters}§
    2278 * [ * int ] (int y) gp; §\C{// pointer to routine returning pointer to int with int parameter}§
    2279 * [ ] (int,char) hp; §\C{// pointer to routine returning no result with int and char parameters}§
    2280 * [ * int,int ] ( int ) jp; §\C{// pointer to routine returning pointer to int and int, with int parameter}§
     2277* [ int x ] () fp;                                              §\C{// pointer to routine returning int with no parameters}§
     2278* [ * int ] (int y) gp;                                 §\C{// pointer to routine returning pointer to int with int parameter}§
     2279* [ ] (int,char) hp;                                    §\C{// pointer to routine returning no result with int and char parameters}§
     2280* [ * int,int ] ( int ) jp;                             §\C{// pointer to routine returning pointer to int and int, with int parameter}§
    22812281\end{cfa}
    22822282While parameter names are optional, \emph{a routine name cannot be specified};
    22832283for example, the following is incorrect:
    22842284\begin{cfa}
    2285 * [ int x ] f () fp; §\C{// routine name "f" is not allowed}§
     2285* [ int x ] f () fp;                                    §\C{// routine name "f" is not allowed}§
    22862286\end{cfa}
    22872287
     
    23062306whereas a named (keyword) call may be:
    23072307\begin{cfa}
    2308 p( z : 3, x : 4, y : 7 );  §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
     2308p( z : 3, x : 4, y : 7 );       §\C{// rewrite $\Rightarrow$ p( 4, 7, 3 )}§
    23092309\end{cfa}
    23102310Here the order of the arguments is unimportant, and the names of the parameters are used to associate argument values with the corresponding parameters.
     
    23232323For example, the following routine prototypes and definition are all valid.
    23242324\begin{cfa}
    2325 void p( int, int, int ); §\C{// equivalent prototypes}§
     2325void p( int, int, int );                        §\C{// equivalent prototypes}§
    23262326void p( int x, int y, int z );
    23272327void p( int y, int x, int z );
    23282328void p( int z, int y, int x );
    2329 void p( int q, int r, int s ) {} §\C{// match with this definition}§
     2329void p( int q, int r, int s ) {}        §\C{// match with this definition}§
    23302330\end{cfa}
    23312331Forcing matching parameter names in routine prototypes with corresponding routine definitions is possible, but goes against a strong tradition in C programming.
     
    23392339int f( int x, double y );
    23402340
    2341 f( j : 3, i : 4 ); §\C{// 1st f}§
    2342 f( x : 7, y : 8.1 ); §\C{// 2nd f}§
    2343 f( 4, 5 );  §\C{// ambiguous call}§
     2341f( j : 3, i : 4 );                              §\C{// 1st f}§
     2342f( x : 7, y : 8.1 );                    §\C{// 2nd f}§
     2343f( 4, 5 );                                              §\C{// ambiguous call}§
    23442344\end{cfa}
    23452345However, named arguments compound routine resolution in conjunction with conversions:
    23462346\begin{cfa}
    2347 f( i : 3, 5.7 ); §\C{// ambiguous call ?}§
     2347f( i : 3, 5.7 );                                §\C{// ambiguous call ?}§
    23482348\end{cfa}
    23492349Depending on the cost associated with named arguments, this call could be resolvable or ambiguous.
     
    23592359the allowable positional calls are:
    23602360\begin{cfa}
    2361 p(); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    2362 p( 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    2363 p( 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    2364 p( 4, 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
     2361p();                                                    §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     2362p( 4 );                                                 §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     2363p( 4, 4 );                                              §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     2364p( 4, 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 4 )}§
    23652365// empty arguments
    2366 p(  , 4, 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
    2367 p( 4,  , 4 ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
    2368 p( 4, 4,   ); §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
    2369 p( 4,  ,   ); §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
    2370 p(  , 4,   ); §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
    2371 p(  ,  , 4 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
    2372 p(  ,  ,   ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
     2366p(  , 4, 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 4 )}§
     2367p( 4,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 4 )}§
     2368p( 4, 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 4, 3 )}§
     2369p( 4,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 4, 2, 3 )}§
     2370p(  , 4,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 4, 3 )}§
     2371p(  ,  , 4 );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 4 )}§
     2372p(  ,  ,   );                                   §\C{// rewrite $\Rightarrow$ p( 1, 2, 3 )}§
    23732373\end{cfa}
    23742374Here the missing arguments are inserted from the default values in the parameter list.
     
    23942394Default values may only appear in a prototype versus definition context:
    23952395\begin{cfa}
    2396 void p( int x, int y = 2, int z = 3 ); §\C{// prototype: allowed}§
    2397 void p( int, int = 2, int = 3 ); §\C{// prototype: allowed}§
    2398 void p( int x, int y = 2, int z = 3 ) {} §\C{// definition: not allowed}§
     2396void p( int x, int y = 2, int z = 3 );          §\C{// prototype: allowed}§
     2397void p( int, int = 2, int = 3 );                        §\C{// prototype: allowed}§
     2398void p( int x, int y = 2, int z = 3 ) {}        §\C{// definition: not allowed}§
    23992399\end{cfa}
    24002400The reason for this restriction is to allow separate compilation.
     
    24212421\begin{cfa}
    24222422void p( int x, int y = 2, int z = 3... );
    2423 p( 1, 4, 5, 6, z : 3 ); §\C{// assume p( /* positional */, ... , /* named */ );}§
    2424 p( 1, z : 3, 4, 5, 6 ); §\C{// assume p( /* positional */, /* named */, ... );}§
     2423p( 1, 4, 5, 6, z : 3 );         §\C{// assume p( /* positional */, ... , /* named */ );}§
     2424p( 1, z : 3, 4, 5, 6 );         §\C{// assume p( /* positional */, /* named */, ... );}§
    24252425\end{cfa}
    24262426The first call is an error because arguments 4 and 5 are actually positional not ellipse arguments;
     
    24522452Furthermore, overloading cannot handle accessing default arguments in the middle of a positional list, via a missing argument, such as:
    24532453\begin{cfa}
    2454 p( 1, /* default */, 5 ); §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
     2454p( 1, /* default */, 5 );               §\C{// rewrite $\Rightarrow$ p( 1, 2, 5 )}§
    24552455\end{cfa}
    24562456
     
    24652465\begin{cfa}
    24662466struct {
    2467         int f1; §\C{// named field}§
    2468         int f2 : 4; §\C{// named field with bit field size}§
    2469         int : 3; §\C{// unnamed field for basic type with bit field size}§
    2470         int ; §\C{// disallowed, unnamed field}§
    2471         int *; §\C{// disallowed, unnamed field}§
    2472         int (*)( int ); §\C{// disallowed, unnamed field}§
     2467        int f1;                                 §\C{// named field}§
     2468        int f2 : 4;                             §\C{// named field with bit field size}§
     2469        int : 3;                                §\C{// unnamed field for basic type with bit field size}§
     2470        int ;                                   §\C{// disallowed, unnamed field}§
     2471        int *;                                  §\C{// disallowed, unnamed field}§
     2472        int (*)( int );                 §\C{// disallowed, unnamed field}§
    24732473};
    24742474\end{cfa}
     
    24782478\begin{cfa}
    24792479struct {
    2480         int , , ; §\C{// 3 unnamed fields}§
     2480        int , , ;                               §\C{// 3 unnamed fields}§
    24812481}
    24822482\end{cfa}
     
    25722572const unsigned int size = 5;
    25732573int ia[size];
    2574 ... §\C{// assign values to array ia}§
    2575 qsort( ia, size ); §\C{// sort ascending order using builtin ?<?}§
     2574...                                             §\C{// assign values to array ia}§
     2575qsort( ia, size );              §\C{// sort ascending order using builtin ?<?}§
    25762576{
    25772577        ®int ?<?( int x, int y ) { return x > y; }® §\C{// nested routine}§
    2578         qsort( ia, size ); §\C{// sort descending order by local redefinition}§
     2578        qsort( ia, size );      §\C{// sort descending order by local redefinition}§
    25792579}
    25802580\end{cfa}
     
    25842584The following program in undefined in \CFA (and Indexc{gcc})
    25852585\begin{cfa}
    2586 [* [int]( int )] foo() { §\C{// int (* foo())( int )}§
     2586[* [int]( int )] foo() {                §\C{// int (* foo())( int )}§
    25872587        int ®i® = 7;
    25882588        int bar( int p ) {
    2589                 ®i® += 1; §\C{// dependent on local variable}§
     2589                ®i® += 1;                               §\C{// dependent on local variable}§
    25902590                sout | ®i®;
    25912591        }
    2592         return bar; §\C{// undefined because of local dependence}§
     2592        return bar;                                     §\C{// undefined because of local dependence}§
    25932593}
    25942594int main() {
    2595         * [int]( int ) fp = foo(); §\C{// int (* fp)( int )}§
     2595        * [int]( int ) fp = foo();      §\C{// int (* fp)( int )}§
    25962596        sout | fp( 3 );
    25972597}
     
    26062606In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call.
    26072607\begin{cfa}
    2608 f( ®2, x, 3 + i® ); §\C{// element list}§
     2608f( ®2, x, 3 + i® );                             §\C{// element list}§
    26092609\end{cfa}
    26102610A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}.
     
    26232623typedef struct { int quot, rem; } div_t;        §\C[7cm]{// from include stdlib.h}§
    26242624div_t div( int num, int den );
    2625 div_t qr = div( 13, 5 ); §\C{// return quotient/remainder aggregate}§
    2626 printf( "%d %d\n", qr.quot, qr.rem ); §\C{// print quotient/remainder}§
     2625div_t qr = div( 13, 5 );                                        §\C{// return quotient/remainder aggregate}§
     2626printf( "%d %d\n", qr.quot, qr.rem );           §\C{// print quotient/remainder}§
    26272627\end{cfa}
    26282628This approach requires a name for the return type and fields, where \Index{naming} is a common programming-language issue.
     
    26342634For example, consider C's \Indexc{modf} function, which returns the integral and fractional part of a floating value.
    26352635\begin{cfa}
    2636 double modf( double x, double * i ); §\C{// from include math.h}§
    2637 double intp, frac = modf( 13.5, &intp ); §\C{// return integral and fractional components}§
    2638 printf( "%g %g\n", intp, frac ); §\C{// print integral/fractional components}§
     2636double modf( double x, double * i );            §\C{// from include math.h}§
     2637double intp, frac = modf( 13.5, &intp );        §\C{// return integral and fractional components}§
     2638printf( "%g %g\n", intp, frac );                        §\C{// print integral/fractional components}§
    26392639\end{cfa}
    26402640This approach requires allocating storage for the return values, which complicates the call site with a sequence of variable declarations leading to the call.
     
    26632663When a function call is passed as an argument to another call, the best match of actual arguments to formal parameters is evaluated given all possible expression interpretations in the current scope.
    26642664\begin{cfa}
    2665 void g( int, int ); §\C{// 1}§
    2666 void g( double, double ); §\C{// 2}§
    2667 g( div( 13, 5 ) ); §\C{// select 1}§
    2668 g( modf( 13.5 ) ); §\C{// select 2}§
     2665void g( int, int );                                                     §\C{// 1}§
     2666void g( double, double );                                       §\C{// 2}§
     2667g( div( 13, 5 ) );                                                      §\C{// select 1}§
     2668g( modf( 13.5 ) );                                                      §\C{// select 2}§
    26692669\end{cfa}
    26702670In this case, there are two overloaded ©g© routines.
     
    26752675The previous examples can be rewritten passing the multiple returned-values directly to the ©printf© function call.
    26762676\begin{cfa}
    2677 [ int, int ] div( int x, int y ); §\C{// from include stdlib}§
    2678 printf( "%d %d\n", div( 13, 5 ) ); §\C{// print quotient/remainder}§
    2679 
    2680 [ double, double ] modf( double x ); §\C{// from include math}§
    2681 printf( "%g %g\n", modf( 13.5 ) ); §\C{// print integral/fractional components}§
     2677[ int, int ] div( int x, int y );                       §\C{// from include stdlib}§
     2678printf( "%d %d\n", div( 13, 5 ) );                      §\C{// print quotient/remainder}§
     2679
     2680[ double, double ] modf( double x );            §\C{// from include math}§
     2681printf( "%g %g\n", modf( 13.5 ) );                      §\C{// print integral/fractional components}§
    26822682\end{cfa}
    26832683This approach provides the benefits of compile-time checking for appropriate return statements as in aggregation, but without the required verbosity of declaring a new named type.
     
    26892689\begin{cfa}
    26902690int quot, rem;
    2691 [ quot, rem ] = div( 13, 5 ); §\C{// assign multiple variables}§
    2692 printf( "%d %d\n", quot, rem ); §\C{// print quotient/remainder}\CRT§
     2691[ quot, rem ] = div( 13, 5 );                           §\C{// assign multiple variables}§
     2692printf( "%d %d\n", quot, rem );                         §\C{// print quotient/remainder}\CRT§
    26932693\end{cfa}
    26942694Here, the multiple return-values are matched in much the same way as passing multiple return-values to multiple parameters in a call.
     
    27162716In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}.
    27172717\begin{cfa}
    2718 [int, int] ®qr® = div( 13, 5 ); §\C{// initialize tuple variable}§
    2719 printf( "%d %d\n", ®qr® ); §\C{// print quotient/remainder}§
     2718[int, int] ®qr® = div( 13, 5 );                 §\C{// initialize tuple variable}§
     2719printf( "%d %d\n", ®qr® );                              §\C{// print quotient/remainder}§
    27202720\end{cfa}
    27212721It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}.
     
    27232723One way to access the individual components of a tuple variable is with assignment.
    27242724\begin{cfa}
    2725 [ quot, rem ] = qr; §\C{// assign multiple variables}§
     2725[ quot, rem ] = qr;                                             §\C{// assign multiple variables}§
    27262726\end{cfa}
    27272727
     
    27462746[int, double] * p;
    27472747
    2748 int y = x.0; §\C{// access int component of x}§
    2749 y = f().1; §\C{// access int component of f}§
    2750 p->0 = 5; §\C{// access int component of tuple pointed-to by p}§
    2751 g( x.1, x.0 ); §\C{// rearrange x to pass to g}§
    2752 double z = [ x, f() ].0.1; §\C{// access second component of first component of tuple expression}§
     2748int y = x.0;                                                    §\C{// access int component of x}§
     2749y = f().1;                                                              §\C{// access int component of f}§
     2750p->0 = 5;                                                               §\C{// access int component of tuple pointed-to by p}§
     2751g( x.1, x.0 );                                                  §\C{// rearrange x to pass to g}§
     2752double z = [ x, f() ].0.1;                              §\C{// access second component of first component of tuple expression}§
    27532753\end{cfa}
    27542754Tuple-index expressions can occur on any tuple-typed expression, including tuple-returning functions, square-bracketed tuple expressions, and other tuple-index expressions, provided the retrieved component is also a tuple.
     
    28172817double y;
    28182818[int, double] z;
    2819 [y, x] = 3.14; §\C{// mass assignment}§
     2819[y, x] = 3.14;                                                  §\C{// mass assignment}§
    28202820[x, y] = z;                                                         §\C{// multiple assignment}§
    28212821z = 10;                                                         §\C{// mass assignment}§
    2822 z = [x, y]; §\C{// multiple assignment}§
     2822z = [x, y];                                                             §\C{// multiple assignment}§
    28232823\end{cfa}
    28242824Let $L_i$ for $i$ in $[0, n)$ represent each component of the flattened left side, $R_i$ represent each component of the flattened right side of a multiple assignment, and $R$ represent the right side of a mass assignment.
     
    28642864        double c, d;
    28652865        [ void ] f( [ int, int ] );
    2866         f( [ c, a ] = [ b, d ] = 1.5 ); §\C{// assignments in parameter list}§
     2866        f( [ c, a ] = [ b, d ] = 1.5 );  // assignments in parameter list
    28672867\end{cfa}
    28682868The tuple expression begins with a mass assignment of ©1.5© into ©[b, d]©, which assigns ©1.5© into ©b©, which is truncated to ©1©, and ©1.5© into ©d©, producing the tuple ©[1, 1.5]© as a result.
     
    28772877\begin{cfa}
    28782878struct S;
    2879 void ?{}(S *); §\C{// (1)}§
    2880 void ?{}(S *, int); §\C{// (2)}§
    2881 void ?{}(S * double); §\C{// (3)}§
    2882 void ?{}(S *, S); §\C{// (4)}§
    2883 
    2884 [S, S] x = [3, 6.28]; §\C{// uses (2), (3), specialized constructors}§
    2885 [S, S] y; §\C{// uses (1), (1), default constructor}§
    2886 [S, S] z = x.0; §\C{// uses (4), (4), copy constructor}§
     2879void ?{}(S *);         // (1)
     2880void ?{}(S *, int);    // (2)
     2881void ?{}(S * double);  // (3)
     2882void ?{}(S *, S);      // (4)
     2883
     2884[S, S] x = [3, 6.28];  // uses (2), (3), specialized constructors
     2885[S, S] y;              // uses (1), (1), default constructor
     2886[S, S] z = x.0;        // uses (4), (4), copy constructor
    28872887\end{cfa}
    28882888In this example, ©x© is initialized by the multiple constructor calls ©?{}(&x.0, 3)© and ©?{}(&x.1, 6.28)©, while ©y© is initialized by two default constructor calls ©?{}(&y.0)© and ©?{}(&y.1)©.
     
    29252925A member-access tuple may be used anywhere a tuple can be used, \eg:
    29262926\begin{cfa}
    2927 s.[ y, z, x ] = [ 3, 3.2, 'x' ]; §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§
    2928 f( s.[ y, z ] ); §\C{// equivalent to f( s.y, s.z )}§
     2927s.[ y, z, x ] = [ 3, 3.2, 'x' ];                §\C{// equivalent to s.x = 'x', s.y = 3, s.z = 3.2}§
     2928f( s.[ y, z ] );                                                §\C{// equivalent to f( s.y, s.z )}§
    29292929\end{cfa}
    29302930Note, the fields appearing in a record-field tuple may be specified in any order;
     
    29362936void f( double, long );
    29372937
    2938 f( x.[ 0, 3 ] ); §\C{// f( x.0, x.3 )}§
    2939 x.[ 0, 1 ] = x.[ 1, 0 ]; §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§
     2938f( x.[ 0, 3 ] );                                                §\C{// f( x.0, x.3 )}§
     2939x.[ 0, 1 ] = x.[ 1, 0 ];                                §\C{// [ x.0, x.1 ] = [ x.1, x.0 ]}§
    29402940[ long, int, long ] y = x.[ 2, 0, 2 ];
    29412941\end{cfa}
     
    29542954\begin{cfa}
    29552955[ int, float, double ] f();
    2956 [ double, float ] x = f().[ 2, 1 ]; §\C{// f() called once}§
     2956[ double, float ] x = f().[ 2, 1 ];             §\C{// f() called once}§
    29572957\end{cfa}
    29582958
     
    29672967That is, a cast can be used to select the type of an expression when it is ambiguous, as in the call to an overloaded function.
    29682968\begin{cfa}
    2969 int f(); §\C{// (1)}§
    2970 double f(); §\C{// (2)}§
    2971 
    2972 f(); §\C{// ambiguous - (1),(2) both equally viable}§
    2973 (int)f(); §\C{// choose (2)}§
     2969int f();     // (1)
     2970double f();  // (2)
     2971
     2972f();       // ambiguous - (1),(2) both equally viable
     2973(int)f();  // choose (2)
    29742974\end{cfa}
    29752975Since casting is a fundamental operation in \CFA, casts need to be given a meaningful interpretation in the context of tuples.
     
    29792979void g();
    29802980
    2981 (void)f(); §\C{// valid, ignore results}§
    2982 (int)g(); §\C{// invalid, void cannot be converted to int}§
     2981(void)f();  // valid, ignore results
     2982(int)g();   // invalid, void cannot be converted to int
    29832983
    29842984struct A { int x; };
    2985 (struct A)f(); §\C{// invalid, int cannot be converted to A}§
     2985(struct A)f();  // invalid, int cannot be converted to A
    29862986\end{cfa}
    29872987In C, line 4 is a valid cast, which calls ©f© and discards its result.
     
    29992999        [int, [int, int], int] g();
    30003000
    3001         ([int, double])f(); §\C{// (1) valid}§
    3002         ([int, int, int])g(); §\C{// (2) valid}§
    3003         ([void, [int, int]])g(); §\C{// (3) valid}§
    3004         ([int, int, int, int])g(); §\C{// (4) invalid}§
    3005         ([int, [int, int, int]])g(); §\C{// (5) invalid}§
     3001        ([int, double])f();           // (1) valid
     3002        ([int, int, int])g();         // (2) valid
     3003        ([void, [int, int]])g();      // (3) valid
     3004        ([int, int, int, int])g();    // (4) invalid
     3005        ([int, [int, int, int]])g();  // (5) invalid
    30063006\end{cfa}
    30073007
     
    30633063void f([int, int], int, int);
    30643064
    3065 f([0, 0], 0, 0); §\C{// no cost}§
    3066 f(0, 0, 0, 0); §\C{// cost for structuring}§
    3067 f([0, 0,], [0, 0]); §\C{// cost for flattening}§
    3068 f([0, 0, 0], 0); §\C{// cost for flattening and structuring}§
     3065f([0, 0], 0, 0);    // no cost
     3066f(0, 0, 0, 0);      // cost for structuring
     3067f([0, 0,], [0, 0]); // cost for flattening
     3068f([0, 0, 0], 0);    // cost for flattening and structuring
    30693069\end{cfa}
    30703070
     
    31293129[ unsigned int, char ]
    31303130[ double, double, double ]
    3131 [ * int, int * ] §\C{// mix of CFA and ANSI}§
     3131[ * int, int * ]                §\C{// mix of CFA and ANSI}§
    31323132[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
    31333133\end{cfa}
     
    31363136Examples of declarations using tuple types are:
    31373137\begin{cfa}
    3138 [ int, int ] x; §\C{// 2 element tuple, each element of type int}§
    3139 * [ char, char ] y; §\C{// pointer to a 2 element tuple}§
     3138[ int, int ] x;                 §\C{// 2 element tuple, each element of type int}§
     3139* [ char, char ] y;             §\C{// pointer to a 2 element tuple}§
    31403140[ [ int, int ] ] z ([ int, int ]);
    31413141\end{cfa}
     
    31543154[ int, int ] w1;
    31553155[ int, int, int ] w2;
    3156 [ void ] f (int, int, int); §\C{// three input parameters of type int}§
    3157 [ void ] g ([ int, int, int ]); §\C{3 element tuple as input}§
     3156[ void ] f (int, int, int); /* three input parameters of type int */
     3157[ void ] g ([ int, int, int ]); /* 3 element tuple as input */
    31583158f( [ 1, 2, 3 ] );
    31593159f( w1, 3 );
     
    32353235[ int, int, int, int ] w = [ 1, 2, 3, 4 ];
    32363236int x = 5;
    3237 [ x, w ] = [ w, x ]; §\C{// all four tuple coercions}§
     3237[ x, w ] = [ w, x ];            §\C{// all four tuple coercions}§
    32383238\end{cfa}
    32393239Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
     
    33233323both these examples produce indeterminate results:
    33243324\begin{cfa}
    3325 f( x++, x++ ); §\C{// C routine call with side effects in arguments}§
    3326 [ v1, v2 ] = [ x++, x++ ]; §\C{// side effects in righthand side of multiple assignment}§
     3325f( x++, x++ );                          §\C{// C routine call with side effects in arguments}§
     3326[ v1, v2 ] = [ x++, x++ ];      §\C{// side effects in righthand side of multiple assignment}§
    33273327\end{cfa}
    33283328
     
    33463346
    33473347
    3348 \section{I/O Stream Library}
    3349 \label{s:IOStreamLibrary}
    3350 \index{input/output stream library}
    3351 \index{stream library}
    3352 
    3353 The goal of \CFA input/output (I/O) is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
    3354 \CFA I/O combines ideas from C ©printf©, \CC, and Python.
    3355 I/O can be unformatted or formatted.
    3356 Unformatted means \CFA selects the output or input format for values that match with the type of a variable.
    3357 Formatted means additional information is specified to augment how an output or input of value is interpreted.
    3358 \CFA formatting is a cross between C ©printf© and \CC ©cout© manipulators.
    3359 \begin{itemize}
    3360 \item
    3361 ©printf© format codes are dense, making them difficult to read and remember.
    3362 \CFA/\CC format manipulators are named, making them easier to read and remember.
    3363 \item
    3364 ©printf© separates format codes from associated variables, making it difficult to match codes with variables.
    3365 \CFA/\CC co-locate codes with associated variables, where \CFA has the tighter binding.
    3366 \item
    3367 Format manipulators in \CC have global rather than local effect, except ©setw©.
    3368 Hence, it is common programming practice to toggle manipulators on and then back to the default to prevent downstream side-effects.
    3369 Without this programming style, errors occur when moving prints, as manipulator effects incorrectly flow into the new location.
    3370 (To guarantee no side-effects, manipulator values must be saved and restored across function calls.)
    3371 \end{itemize}
    3372 The \CFA header file for the I/O library is \Indexc{fstream.hfa}.
    3373 
    3374 For unformatted output, the common case is printing a sequence of variables separated by whitespace.
     3348\section{I/O Library}
     3349\label{s:IOLibrary}
     3350\index{input/output library}
     3351
     3352The goal of \CFA I/O is to simplify the common cases\index{I/O!common case}, while fully supporting polymorphism and user defined types in a consistent way.
     3353The approach combines ideas from \CC and Python.
     3354The \CFA header file for the I/O library is \Indexc{fstream}.
     3355
     3356The common case is printing out a sequence of variables separated by whitespace.
    33753357\begin{cquote}
    33763358\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     
    33913373&
    33923374\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3393 1® ®2® ®3
     33751 2 3
    33943376\end{cfa}
    33953377\end{tabular}
    33963378\end{cquote}
    3397 The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators and newline.
    3398 Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each value separated by ``\lstinline[showspaces=true]@, @''.
     3379The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
     3380Similar simplification occurs for \Index{tuple} I/O, which prints all tuple values separated by ``\lstinline[showspaces=true]@, @''.
    33993381\begin{cfa}
    34003382[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
    3401 sout | t1 | t2; §\C{// print tuples}§
     3383sout | t1 | t2;                                         §\C{// print tuples}§
    34023384\end{cfa}
    34033385\begin{cfa}[showspaces=true,aboveskip=0pt]
    340433861®, ®2®, ®3 4®, ®5®, ®6
    34053387\end{cfa}
    3406 Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment.
     3388Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority overloadable operator, other than assignment.
    34073389Therefore, fewer output expressions require parenthesis.
    34083390\begin{cquote}
     
    34113393&
    34123394\begin{cfa}
    3413 sout | x * 3 | y + 1 | z << 2 | x == y | ®(®x | y®)® | ®(®x || y®)® | ®(®x > z ? 1 : 2®)®;
     3395sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2);
    34143396\end{cfa}
    34153397\\
     
    34173399&
    34183400\begin{cfa}
    3419 cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << ®(®x | y®)® << ®(®x || y®)® << ®(®x > z ? 1 : 2®)® << endl;
     3401cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
    34203402\end{cfa}
    34213403\\
     
    34263408\end{tabular}
    34273409\end{cquote}
    3428 Input and output use a uniform operator, ©|©, rather than separate operators, as in ©>>© and ©<<© for \CC.
    3429 There is a weak similarity between the \CFA logical-or operator and the \Index{Shell pipe-operator} for moving data, where data flows in the correct direction for input but the opposite direction for output.
    3430 
    3431 For unformatter input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable.
    3432 \begin{cquote}
    3433 \begin{lrbox}{\LstBox}
    3434 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    3435 int x;   double y   char z;
    3436 \end{cfa}
    3437 \end{lrbox}
    3438 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    3439 \multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\
    3440 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    3441 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    3442 sin | x | y | z;
    3443 \end{cfa}
    3444 &
    3445 \begin{cfa}[aboveskip=0pt,belowskip=0pt]
    3446 cin >> x >> y >> z;
    3447 \end{cfa}
    3448 \\
    3449 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3450 ®1® ®2.5® ®A®
    3451 \end{cfa}
    3452 &
    3453 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3454 ®1® ®2.5® ®A®
    3455 \end{cfa}
    3456 \end{tabular}
    3457 \end{cquote}
    3458 
     3410There is a weak similarity between the \CFA logical-or operator and the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
    34593411
    34603412
    34613413\subsection{Implicit Separator}
    34623414
    3463 The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator for output.
     3415The \Index{implicit separator}\index{I/O!separator} character (space/blank) is a separator not a terminator.
    34643416The rules for implicitly adding the separator are:
    34653417\begin{enumerate}
     
    34893441
    34903442\item
     3443A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
     3444%$
     3445\begin{cfa}[mathescape=off]
     3446sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
     3447                | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
     3448\end{cfa}
     3449%$
     3450\begin{cfa}[mathescape=off,basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt]
     3451x ®(®1 x ®[®2 x ®{®3 x ®=®4 x ®$®5 x ®£®6 x ®¥®7 x ®¡®8 x ®¿®9 x ®«®10
     3452\end{cfa}
     3453%$
     3454where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
     3455
     3456\item
    34913457{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
    3492 A seperator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
     3458A seperator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[basicstyle=\tt]@,.;!?)]}%¢»@
    34933459\begin{cfa}[belowskip=0pt]
    34943460sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    35013467
    35023468\item
    3503 A separator does not appear after a C string ending with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off,basicstyle=\tt]@([{=$£¥¡¿«@
    3504 %$
    3505 \begin{cfa}[mathescape=off]
    3506 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
    3507                 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
    3508 \end{cfa}
    3509 %$
    3510 \begin{cfa}[mathescape=off,basicstyle=\tt,showspaces=true,aboveskip=0pt,belowskip=0pt]
    3511 x ®(®1 x ®[®2 x ®{®3 x ®=®4 x ®$®5 x ®£®6 x ®¥®7 x ®¡®8 x ®¿®9 x ®«®10
    3512 \end{cfa}
    3513 %$
    3514 where \lstinline[basicstyle=\tt]@¡¿@ are inverted opening exclamation and question marks, and \lstinline[basicstyle=\tt]@«@ is an opening citation mark.
    3515 
    3516 \item
    3517 A seperator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
     3469A seperator does not appear before or after a C string begining/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@
    35183470\begin{cfa}[belowskip=0pt]
    35193471sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
     
    35343486
    35353487
    3536 \subsection{Separation Manipulators}
    3537 
    3538 The following \Index{manipulator}s control \Index{implicit output separation}.
    3539 The effect of these manipulators is global for an output stream (except ©sepOn© and ©sepOff©).
     3488\subsection{Manipulator}
     3489
     3490The following \CC-style \Index{manipulator}s and routines control implicit seperation.
    35403491\begin{enumerate}
    35413492\item
    3542 \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
     3493Routines \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
    35433494The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    35443495\begin{cfa}[mathescape=off,belowskip=0pt]
    3545 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§
     3496sepSet( sout, ", $" );                                          §\C{// set separator from " " to ", \$"}§
    35463497sout | 1 | 2 | 3 | " \"" | ®sep® | "\"";
    35473498\end{cfa}
     
    35523503%$
    35533504\begin{cfa}[belowskip=0pt]
    3554 sepSet( sout, " " ); §\C{// reset separator to " "}§
     3505sepSet( sout, " " );                                            §\C{// reset separator to " "}§
    35553506sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"";
    35563507\end{cfa}
     
    35603511©sepGet© can be used to store a separator and then restore it:
    35613512\begin{cfa}[belowskip=0pt]
    3562 char store[®sepSize®]; §\C{// sepSize is the maximum separator size}§
    3563 strcpy( store, sepGet( sout ) ); §\C{// copy current separator}§
    3564 sepSet( sout, "_" ); §\C{// change separator to underscore}§
     3513char store[®sepSize®];                                          §\C{// sepSize is the maximum separator size}§
     3514strcpy( store, sepGet( sout ) );                          §\C{// copy current separator}§
     3515sepSet( sout, "_" );                                            §\C{// change separator to underscore}§
    35653516sout | 1 | 2 | 3;
    35663517\end{cfa}
     
    35693520\end{cfa}
    35703521\begin{cfa}[belowskip=0pt]
    3571 sepSet( sout, store ); §\C{// change separator back to original}§
     3522sepSet( sout, store );                                          §\C{// change separator back to original}§
    35723523sout | 1 | 2 | 3;
    35733524\end{cfa}
     
    35773528
    35783529\item
    3579 \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
     3530Routine \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} and \Indexc{sepTuple}\index{manipulator!sepTuple@©sepTuple©}/\Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} get and set the tuple separator-string.
    35803531The tuple separator-string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    35813532\begin{cfa}[belowskip=0pt]
    3582 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§
     3533sepSetTuple( sout, " " );                                       §\C{// set tuple separator from ", " to " "}§
    35833534sout | t1 | t2 | " \"" | ®sepTuple® | "\"";
    35843535\end{cfa}
     
    35873538\end{cfa}
    35883539\begin{cfa}[belowskip=0pt]
    3589 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§
     3540sepSetTuple( sout, ", " );                                      §\C{// reset tuple separator to ", "}§
    35903541sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"";
    35913542\end{cfa}
     
    35963547
    35973548\item
    3598 \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} toggle printing the separator.
     3549Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, \ie the seperator is adjusted with respect to all subsequent printed items.
    35993550\begin{cfa}[belowskip=0pt]
    3600 sout | sepDisable | 1 | 2 | 3; §\C{// turn off implicit separator}§
     3551sout | sepDisable | 1 | 2 | 3;                  §\C{// globally turn off implicit separator}§
    36013552\end{cfa}
    36023553\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36043555\end{cfa}
    36053556\begin{cfa}[belowskip=0pt]
    3606 sout | sepEnable | 1 | 2 | 3; §\C{// turn on implicit separator}§
     3557sout | sepEnable | 1 | 2 | 3;           §\C{// globally turn on implicit separator}§
    36073558\end{cfa}
    36083559\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36113562
    36123563\item
    3613 \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} toggle printing the separator with respect to the next printed item, and then return to the global seperator setting.
     3564Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, \ie the seperator is adjusted only with respect to the next printed item.
    36143565\begin{cfa}[belowskip=0pt]
    3615 sout | 1 | sepOff | 2 | 3; §\C{// turn off implicit separator for the next item
     3566sout | 1 | sepOff | 2 | 3;                      §\C{// locally turn off implicit separator
    36163567\end{cfa}
    36173568\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36193570\end{cfa}
    36203571\begin{cfa}[belowskip=0pt]
    3621 sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// turn on implicit separator for the next item
     3572sout | sepDisable | 1 | sepOn | 2 | 3; §\C{// locally turn on implicit separator
    36223573\end{cfa}
    36233574\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36263577The tuple separator also responses to being turned on and off.
    36273578\begin{cfa}[belowskip=0pt]
    3628 sout | t1 | sepOff | t2; §\C{// locally turn on/off implicit separator}§
     3579sout | t1 | sepOff | t2;                                §\C{// locally turn on/off implicit separator}§
    36293580\end{cfa}
    36303581\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36343585use ©sep© to accomplish this functionality.
    36353586\begin{cfa}[belowskip=0pt]
    3636 sout | sepOn | 1 | 2 | 3 | sepOn; §\C{// sepOn does nothing at start/end of line}§
     3587sout | sepOn | 1 | 2 | 3 | sepOn;       §\C{// sepOn does nothing at start/end of line}§
    36373588\end{cfa}
    36383589\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    36403591\end{cfa}
    36413592\begin{cfa}[belowskip=0pt]
    3642 sout | sep | 1 | 2 | 3 | sep ; §\C{// use sep to print separator at start/end of line}§
     3593sout | sep | 1 | 2 | 3 | sep ;          §\C{// use sep to print separator at start/end of line}§
    36433594\end{cfa}
    36443595\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    36453596® ®1 2 3® ®
    3646 \end{cfa}
    3647 \end{enumerate}
    3648 
    3649 
    3650 \subsection{Newline Manipulators}
    3651 
    3652 The following \Index{manipulator} controls \Index{newline separation} for input and output.
    3653 
    3654 For input:
    3655 \begin{enumerate}[parsep=0pt]
    3656 \item
    3657 \Indexc{nl}\index{manipulator!nl@©nl©} scans characters until the next newline character, i.e., ignore the remaining characters in the line.
    3658 \item
    3659 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} reads the newline character, when reading single characters.
    3660 \item
    3661 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} read the newline character, when reading single characters.
    3662 \end{enumerate}
    3663 For example, in:
    3664 \begin{cfa}
    3665 sin | i | ®nl® | j;
    3666 1 ®2®
    3667 3
    3668 \end{cfa}
    3669 variable ©i© is assigned 1, the 2 is skipped, and variable ©j© is assigned 3.
    3670 
    3671 For output:
    3672 \begin{enumerate}[parsep=0pt]
    3673 \item
    3674 \Indexc{nl}\index{manipulator!nl@©nl©} inserts a newline.
    3675 \begin{cfa}
    3676 sout | nl; §\C{// only print newline}§
    3677 sout | 2; §\C{// implicit newline}§
    3678 sout | 3 | nl | 4 | nl; §\C{// terminating nl merged with implicit newline}§
    3679 sout | 5 | nl | nl; §\C{// again terminating nl merged with implicit newline}§
    3680 sout | 6; §\C{// implicit newline}§
    3681 
    3682 2
    3683 3
    3684 4
    3685 5
    3686 
    3687 6
    3688 \end{cfa}
    3689 Note, a terminating ©nl© is merged (overrides) with the implicit newline at the end of the ©sout© expression, otherwise it is impossible to to print a single newline
    3690 \item
    3691 \Indexc{nlOn}\index{manipulator!nlOn@©nlOn©} implicitly prints a newline at the end of each output expression.
    3692 \item
    3693 \Indexc{nlOff}\index{manipulator!nlOff@©nlOff©} does \emph{not} implicitly print a newline at the end of each output expression.
    3694 \end{enumerate}
    3695 
    3696 
    3697 \subsection{Output Value Manipulators}
    3698 
    3699 The following \Index{manipulator}s control formatting of output values (printing), and only affect the format of the argument.
    3700 \begin{enumerate}
    3701 \item
    3702 \Indexc{bin}( integer )\index{manipulator!bin@©bin©} print value in base 2 preceded by ©0b©/©0B©.
    3703 \begin{cfa}[belowskip=0pt]
    3704 sout | bin( 0 ) | bin( 27HH ) | bin( 27H ) | bin( 27 ) | bin( 27L );
    3705 0b0 0b11011 0b11011 0b11011 0b11011
    3706 sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
    3707 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b(58 1s)100101
    3708 \end{cfa}
    3709 
    3710 \item
    3711 \Indexc{oct}( integer )\index{manipulator!oct@©oct©} print value in base 8 preceded by ©0©.
    3712 \begin{cfa}[belowskip=0pt]
    3713 sout | oct( 0 ) | oct( 27HH ) | oct( 27H ) | oct( 27 ) | oct( 27L );
    3714 0 033 033 033 033
    3715 sout | oct( -27HH ) | oct( -27H ) | oct( -27 ) | oct( -27L );
    3716 0345 0177745 037777777745 01777777777777777777745
    3717 \end{cfa}
    3718 Note, octal 0 is \emph{not} preceded by ©0© to prevent confusion.
    3719 
    3720 \item
    3721 \Indexc{hex}( integer / floating-point )\index{manipulator!hex@©hex©} print value in base 16 preceded by ©0x©/©0X©.
    3722 \begin{cfa}[belowskip=0pt]
    3723 sout | hex( 0 ) | hex( 27HH ) | hex( 27H ) | hex( 27 ) | hex( 27L );
    3724 0 0x1b 0x1b 0x1b 0x1b
    3725 sout | hex( -27HH ) | hex( -27H ) | hex( -27 ) | hex( -27L );
    3726 0xe5 0xffe5 0xffffffe5 0xffffffffffffffe5
    3727 
    3728 sout | hex( 0.0 ) | hex( 27.5F ) | hex( 27.5 ) | hex( 27.5L );
    3729 0x0.p+0 0x1.b8p+4 0x1.b8p+4 0xd.cp+1
    3730 sout | hex( -27.5F ) | hex( -27.5 ) | hex( -27.5L );
    3731 -0x1.b8p+4 -0x1.b8p+4 -0xd.cp+1
    3732 \end{cfa}
    3733 
    3734 \item
    3735 \Indexc{sci}( floating-point )\index{manipulator!sci@©sci©} print value in scientific notation with exponent.
    3736 Default is 6 digits of precision.
    3737 \begin{cfa}[belowskip=0pt]
    3738 sout | sci( 0.0 ) | sci( 27.5 ) | sci( -27.5 );
    3739 0.000000e+00 2.750000e+01 -2.750000e+01
    3740 \end{cfa}
    3741 
    3742 \item
    3743 \Indexc{upcase}( bin / hex / floating-point )\index{manipulator!upcase@©upcase©} print letters in a value in upper case. Lower case is the default.
    3744 \begin{cfa}[belowskip=0pt]
    3745 sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) );
    3746 0®B®11011 0®X®1®B® 2.75®E®-09 0®X®1.®B®8®P®+4
    3747 \end{cfa}
    3748 
    3749 \item
    3750 \Indexc{nobase}( integer )\index{manipulator!nobase@©nobase©} do not precede ©bin©, ©oct©, ©hex© with ©0b©/©0B©, ©0©, or ©0x©/©0X©. Printing the base is the default.
    3751 \begin{cfa}[belowskip=0pt]
    3752 sout | nobase( bin( 27 ) ) | nobase( oct( 27 ) ) | nobase( hex( 27 ) );
    3753 11011 33 1b
    3754 \end{cfa}
    3755 
    3756 \item
    3757 \Indexc{nodp}( floating-point )\index{manipulator!nodp@©nodp©} do not print a decimal point if there are no fractional digits.
    3758 Printing a decimal point is the default, if there are no fractional digits.
    3759 \begin{cfa}[belowskip=0pt]
    3760 sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 );
    3761 0.0 ®0® 27.0 ®27® 27.5
    3762 \end{cfa}
    3763 
    3764 \item
    3765 \Indexc{sign}( integer / floating-point )\index{manipulator!sign@©sign©} prefix with plus or minus sign (©+© or ©-©). Only printing the minus sign is the default.
    3766 \begin{cfa}[belowskip=0pt]
    3767 sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 );
    3768 ®+®27 -27 ®+®27.0 -27.0 ®+®27.5 -27.5
    3769 \end{cfa}
    3770 
    3771 \item
    3772 \Indexc{wd}©( unsigned char minimum, T val )©\index{manipulator!wd@©wd©}, ©wd( unsigned char minimum, unsigned char precision, T val )©
    3773 For all types, ©minimum© is the minimum number of printed characters.
    3774 If the value is shorter than the minimum, it is padded on the right with spaces.
    3775 \begin{cfa}[belowskip=0pt]
    3776 sout | wd( 4, 34) | wd( 3, 34 ) | wd( 2, 34 );
    3777 sout | wd( 10, 4.) | wd( 9, 4. ) | wd( 8, 4. );
    3778 sout | wd( 4, "ab" ) | wd( 3, "ab" ) | wd( 2, "ab" );
    3779 \end{cfa}
    3780 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3781 ®  ®34 ® ®34 34
    3782 ®  ®4.000000 ® ®4.000000 4.000000
    3783 ®  ®ab ® ®ab ab
    3784     ab    ab ab
    3785 \end{cfa}
    3786 If the value is larger, it is printed without truncation, ignoring the ©minimum©.
    3787 \begin{cfa}[belowskip=0pt]
    3788 sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 );
    3789 sout | wd( 4, 3456. ) | wd( 3, 3456. ) | wd( 2, 3456. );
    3790 sout | wd( 4, "abcde" ) | wd( 3, "abcde" ) | wd( 2,"abcde" );
    3791 \end{cfa}
    3792 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3793 3456®7® 345®67® 34®567®
    3794 3456®.® 345®6.® 34®56.®
    3795 abcd®e® abc®de® ab®cde®
    3796 \end{cfa}
    3797 
    3798 For integer types, ©precision© is the minimum number of printed digits.
    3799 If the value is shorter, it is padded on the left with leading zeros.
    3800 \begin{cfa}[belowskip=0pt]
    3801 sout | wd( 4,3, 34 ) | wd( 8,4, 34 ) | wd( 10,10, 34 );
    3802 \end{cfa}
    3803 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3804  ®0®34     ®00®34 ®00000000®34
    3805 \end{cfa}
    3806 If the value is larger, it is printed without truncation, ignoring the ©precision©.
    3807 \begin{cfa}[belowskip=0pt]
    3808 sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 );
    3809 \end{cfa}
    3810 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3811 3456     3456       3456
    3812 \end{cfa}
    3813 If ©precision© is 0, nothing is printed for zero.
    3814 If ©precision© is greater than the minimum, it becomes the minimum.
    3815 \begin{cfa}[belowskip=0pt]
    3816 sout | wd( 4,0, 0 ) | wd( 3,10, 34 );
    3817 \end{cfa}
    3818 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3819 ®    ® ®00000000®34
    3820 \end{cfa}
    3821 For floating-point types, ©precision© is the minimum number of digits after the decimal point.
    3822 \begin{cfa}[belowskip=0pt]
    3823 sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 );
    3824 \end{cfa}
    3825 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3826 27.®500®     27.®5®      28. 27.®50000000®
    3827 \end{cfa}
    3828 For the C-string type, ©precision© is the maximum number of printed characters, so the string is truncared if it exceeds the maximum.
    3829 \begin{cfa}[belowskip=0pt]
    3830 sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" );
    3831 \end{cfa}
    3832 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3833   abcd abcdefgh    abc
    3834 \end{cfa}
    3835 
    3836 \item
    3837 \Indexc{ws( unsigned char minimum, unsigned char significant, floating-point )}\index{manipulator!ws@©ws©}
    3838 For floating-point type, ©minimum© is the same as for manipulator ©wd©, but ©significant© is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©).
    3839 If a value's significant digits is greater than ©significant©, the last significant digit is rounded up.
    3840 \begin{cfa}[belowskip=0pt]
    3841 sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567);
    3842 \end{cfa}
    3843 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3844 234.567 234.5®7®  234.®6®    23®5®
    3845 \end{cfa}
    3846 If a value's magnitude is greater than ©significant©, the value is printed in scientific notation with the specified number of significant digits.
    3847 \begin{cfa}[belowskip=0pt]
    3848 sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.);
    3849 \end{cfa}
    3850 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3851 234567. 2.3457®e+05® 2.346®e+05® 2.35®e+05®
    3852 \end{cfa}
    3853 If ©significant© is greater than ©minimum©, it defines the number of printed characters.
    3854 \begin{cfa}[belowskip=0pt]
    3855 sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.);
    3856 \end{cfa}
    3857 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3858 234567. 234567. 234567. 234567.
    3859 \end{cfa}
    3860 
    3861 \item
    3862 \Indexc{left}( field-width )\index{manipulator!left@©left©} left justify within the given field.
    3863 \begin{cfa}[belowskip=0pt]
    3864 sout | left(wd(4, 27)) | left(wd(10, 27.)) | left(wd(10, 27.5)) | left(wd(4,3, 27)) | left(wd(10,3, 27.5));
    3865 \end{cfa}
    3866 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3867 27®  ® 27.000000  27.500000  027  27.500®    ®
    3868 \end{cfa}
    3869 
    3870 \item
    3871 \Indexc{pad0}( field-width )\index{manipulator!pad0@©pad0©} left pad with zeroes (0).
    3872 \begin{cfa}[belowskip=0pt]
    3873 sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) );
    3874 ®00®27  ®0®27 ®00®27.500
    38753597\end{cfa}
    38763598\end{enumerate}
     
    39333655
    39343656
    3935 \subsection{Input Value Manipulators}
    3936 
    3937 The format of numeric input values in the same as C constants without a trailing type suffix, as the input value-type is denoted by the input variable.
    3938 For ©_Bool© type, the constants are ©true© and ©false©.
    3939 For integral types, any number of digits, optionally preceded by a sign (©+© or ©-©), where a
    3940 \begin{itemize}
    3941 \item
    3942 ©1©-©9© prefix introduces a decimal value (©0©-©9©),
    3943 \item
    3944 ©0© prefix introduces an octal value (©0©-©7©), and
    3945 \item
    3946 ©0x© or ©0X© prefix introduces a hexadecimal value (©0©-©f©) with lower or upper case letters.
    3947 \end{itemize}
    3948 For floating-point types, any number of decimal digits, optionally preceded by a sign (©+© or ©-©), optionally containing a decimal point, and optionally followed by an exponent, ©e© or ©E©, with signed (optional) decimal digits.
    3949 Floating-point values can also be written in hexadecimal format preceded by ©0x© or ©0X© with hexadecimal digits and exponent denoted by ©p© or ©P©.
    3950 
    3951 For the C-string type, the input values are \emph{not} the same as C-string constants, \ie double quotes bracketing arbitrary text with escape sequences.
    3952 Instead, the next sequence of non-whitespace characters are read, and the input sequence is terminated with delimiter ©'\0'©.
    3953 The string variable \emph{must} be large enough to contain the input sequence.
    3954 
    3955 The following \Index{manipulator}s control formatting of input values (reading), and only affect the format of the argument.
    3956 
    3957 \begin{enumerate}
    3958 \item
    3959 \Indexc{skip( const char * pattern )}\index{manipulator!skip@©skip©} / ©skip( unsigned int length )© / ©const char * pattern©
    3960 The argument defines a ©pattern© or ©length©.
    3961 The ©pattern© is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.
    3962 The ©length© is composed of the next $N$ characters, including the newline character.
    3963 If the match successes, the input characters are discarded, and input continues with the next character.
    3964 If the match fails, the input characters are left unread.
    3965 \begin{cfa}[belowskip=0pt]
    3966 char sk[$\,$] = "abc";
    3967 sin | "abc " | skip( sk ) | skip( 5 ); // match input sequence
    3968 \end{cfa}
    3969 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3970 ®abc   ®
    3971 ®abc  ®
    3972 ®xx®
    3973 \end{cfa}
    3974 
    3975 \item
    3976 \Indexc{wdi}©( unsigned int maximum, T & val )©\index{manipulator!wdi@©wdi©}
    3977 For all types except ©char©, ©maximum© is the maximum number of characters read for the current operation.
    3978 \begin{cfa}[belowskip=0pt]
    3979 char s[10];   int i;   double d;   
    3980 sin | wdi( 4, s ) | wdi( 3, i ) | wdi( 8, d );  // c == "abcd", i == 123, d == 3.456E+2
    3981 \end{cfa}
    3982 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3983 ®abcd1233.456E+2®
    3984 \end{cfa}
    3985 Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types.
    3986 Currently, \CFA cannot distinguish between these two manipulators in the middle of an ©sout©/©sin© expression based on return type.
    3987 
    3988 \item
    3989 \Indexc{ignore( T & val )}\index{manipulator!ignore@©ignore©}
    3990 For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument.
    3991 \begin{cfa}[belowskip=0pt]
    3992 double d;
    3993 sin | ignore( d );  // d is unchanged
    3994 \end{cfa}
    3995 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3996 ®  -75.35e-4® 25
    3997 \end{cfa}
    3998 
    3999 \item
    4000 \Indexc{incl( const char * scanset, char * s )}\index{manipulator!incl@©incl©}
    4001 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{in} the set.
    4002 Matching characters are read into the C string and null terminated.
    4003 \begin{cfa}[belowskip=0pt]
    4004 char s[10];
    4005 sin | incl( "abc", s );
    4006 \end{cfa}
    4007 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4008 ®bca®xyz
    4009 \end{cfa}
    4010 
    4011 \item
    4012 \Indexc{excl( const char * scanset, char * s )}\index{manipulator!excl@©excl©}
    4013 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{not in} the set.
    4014 Non-matching characters are read into the C string and null terminated.
    4015 \begin{cfa}[belowskip=0pt]
    4016 char s[10];
    4017 sin | excl( "abc", s );
    4018 \end{cfa}
    4019 \begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4020 ®xyz®bca
    4021 \end{cfa}
    4022 \end{enumerate}
    4023 
    4024 
    40253657\section{Types}
    40263658
     
    43904022\begin{itemize}
    43914023\item
    4392 not determining or writing long generic types,
    4393 \item
    4394 ensuring secondary variables, related to a primary variable, always have the same type.
     4024preventing having to determine or write long generic types,
     4025\item
     4026ensure secondary variables, related to a primary variable, always have the same type.
    43954027\end{itemize}
    43964028
     
    44144046There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type.
    44154047That is, when is the type of the variable more important than the type of its initialization expression.
    4416 For example, if a change is made in an initialization expression, it can cause cascading type changes and/or errors.
     4048For example, if a change is made in an initialization expression, it can cause significant cascading type changes and/or errors.
    44174049At some point, a variable type needs to remain constant and the expression to be in error when it changes.
    44184050
     
    46474279
    46484280coroutine Fibonacci {
    4649         int fn; §\C{// used for communication}§
     4281        int fn;                                                         §\C{// used for communication}§
    46504282};
    46514283void ?{}( Fibonacci * this ) {
     
    46534285}
    46544286void main( Fibonacci * this ) {
    4655         int fn1, fn2; §\C{// retained between resumes}§
    4656         this->fn = 0; §\C{// case 0}§
     4287        int fn1, fn2;                                           §\C{// retained between resumes}§
     4288        this->fn = 0;                                           §\C{// case 0}§
    46574289        fn1 = this->fn;
    4658         suspend(); §\C{// return to last resume}§
    4659 
    4660         this->fn = 1; §\C{// case 1}§
     4290        suspend();                                                      §\C{// return to last resume}§
     4291
     4292        this->fn = 1;                                           §\C{// case 1}§
    46614293        fn2 = fn1;
    46624294        fn1 = this->fn;
    4663         suspend(); §\C{// return to last resume}§
    4664 
    4665         for ( ;; ) { §\C{// general case}§
     4295        suspend();                                                      §\C{// return to last resume}§
     4296
     4297        for ( ;; ) {                                            §\C{// general case}§
    46664298                this->fn = fn1 + fn2;
    46674299                fn2 = fn1;
    46684300                fn1 = this->fn;
    4669                 suspend(); §\C{// return to last resume}§
     4301                suspend();                                              §\C{// return to last resume}§
    46704302        } // for
    46714303}
    46724304int next( Fibonacci * this ) {
    4673         resume( this ); §\C{// transfer to last suspend}§
     4305        resume( this );                                         §\C{// transfer to last suspend}§
    46744306        return this->fn;
    46754307}
     
    62165848In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as:
    62175849\begin{cfa}
    6218 *?§\color{red}\textvisiblespace§*? §\C{// dereference operator, dereference operator}§
    6219 *§\color{red}\textvisiblespace§?*? §\C{// dereference, multiplication operator}§
     5850*?§\color{red}\textvisiblespace§*?              §\C{// dereference operator, dereference operator}§
     5851*§\color{red}\textvisiblespace§?*?              §\C{// dereference, multiplication operator}§
    62205852\end{cfa}
    62215853By default, the first interpretation is selected, which does not yield a meaningful parse.
     
    62695901\eg:
    62705902\begin{cfa}
    6271 x; §\C{// int x}§
    6272 *y; §\C{// int *y}§
    6273 f( p1, p2 ); §\C{// int f( int p1, int p2 );}§
    6274 g( p1, p2 ) int p1, p2; §\C{// int g( int p1, int p2 );}§
     5903x;                                                              §\C{// int x}§
     5904*y;                                                             §\C{// int *y}§
     5905f( p1, p2 );                                    §\C{// int f( int p1, int p2 );}§
     5906g( p1, p2 ) int p1, p2;                 §\C{// int g( int p1, int p2 );}§
    62755907\end{cfa}
    62765908\CFA continues to support K\&R routine definitions:
    62775909\begin{cfa}
    6278 f( a, b, c ) §\C{// default int return}§
    6279         int a, b; char c §\C{// K\&R parameter declarations}§
     5910f( a, b, c )                                    §\C{// default int return}§
     5911        int a, b; char c                        §\C{// K\&R parameter declarations}§
    62805912{
    62815913        ...
     
    62965928int rtn( int i );
    62975929int rtn( char c );
    6298 rtn( 'x' ); §\C{// programmer expects 2nd rtn to be called}§
     5930rtn( 'x' );                                             §\C{// programmer expects 2nd rtn to be called}§
    62995931\end{cfa}
    63005932\item[Rationale:] it is more intuitive for the call to ©rtn© to match the second version of definition of ©rtn© rather than the first.
     
    63185950\item[Change:] make string literals ©const©:
    63195951\begin{cfa}
    6320 char * p = "abc"; §\C{// valid in C, deprecated in \CFA}§
    6321 char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§
     5952char * p = "abc";                               §\C{// valid in C, deprecated in \CFA}§
     5953char * q = expr ? "abc" : "de"; §\C{// valid in C, invalid in \CFA}§
    63225954\end{cfa}
    63235955The type of a string literal is changed from ©[] char© to ©const [] char©.
     
    63265958\begin{cfa}
    63275959char * p = "abc";
    6328 p[0] = 'w'; §\C{// segment fault or change constant literal}§
     5960p[0] = 'w';                                             §\C{// segment fault or change constant literal}§
    63295961\end{cfa}
    63305962The same problem occurs when passing a string literal to a routine that changes its argument.
     
    63385970\item[Change:] remove \newterm{tentative definitions}, which only occurs at file scope:
    63395971\begin{cfa}
    6340 int i; §\C{// forward definition}§
    6341 int *j = ®&i®; §\C{// forward reference, valid in C, invalid in \CFA}§
    6342 int i = 0; §\C{// definition}§
     5972int i;                                                  §\C{// forward definition}§
     5973int *j = ®&i®;                                  §\C{// forward reference, valid in C, invalid in \CFA}§
     5974int i = 0;                                              §\C{// definition}§
    63435975\end{cfa}
    63445976is valid in C, and invalid in \CFA because duplicate overloaded object definitions at the same scope level are disallowed.
     
    63465978\begin{cfa}
    63475979struct X { int i; struct X *next; };
    6348 static struct X a; §\C{// forward definition}§
     5980static struct X a;                              §\C{// forward definition}§
    63495981static struct X b = { 0, ®&a® };§\C{// forward reference, valid in C, invalid in \CFA}§
    6350 static struct X a = { 1, &b }; §\C{// definition}§
     5982static struct X a = { 1, &b };  §\C{// definition}§
    63515983\end{cfa}
    63525984\item[Rationale:] avoids having different initialization rules for builtin types and user-defined types.
     
    63635995struct Person {
    63645996        enum ®Colour® { R, G, B };      §\C[7cm]{// nested type}§
    6365         struct Face { §\C{// nested type}§
    6366                 ®Colour® Eyes, Hair; §\C{// type defined outside (1 level)}§
     5997        struct Face {                           §\C{// nested type}§
     5998                ®Colour® Eyes, Hair;    §\C{// type defined outside (1 level)}§
    63675999        };
    6368         ®.Colour® shirt; §\C{// type defined outside (top level)}§
    6369         ®Colour® pants; §\C{// type defined same level}§
    6370         Face looks[10]; §\C{// type defined same level}§
     6000        ®.Colour® shirt;                        §\C{// type defined outside (top level)}§
     6001        ®Colour® pants;                         §\C{// type defined same level}§
     6002        Face looks[10];                         §\C{// type defined same level}§
    63716003};
    6372 ®Colour® c = R; §\C{// type/enum defined same level}§
     6004®Colour® c = R;                                 §\C{// type/enum defined same level}§
    63736005Person®.Colour® pc = Person®.®R;§\C{// type/enum defined inside}§
    6374 Person®.®Face pretty; §\C{// type defined inside}\CRT§
     6006Person®.®Face pretty;                   §\C{// type defined inside}\CRT§
    63756007\end{cfa}
    63766008In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing.
     
    63896021\item[Difficulty of converting:] Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example:
    63906022\begin{cfa}
    6391 struct Y; §\C{// struct Y and struct X are at the same scope}§
     6023struct Y;                                               §\C{// struct Y and struct X are at the same scope}§
    63926024struct X {
    63936025        struct Y { /* ... */ } y;
     
    64046036\begin{cfa}
    64056037void foo() {
    6406         int * b = malloc( sizeof(int) ); §\C{// implicitly convert void * to int *}§
    6407         char * c = b; §\C{// implicitly convert int * to void *, and then void * to char *}§
     6038        int * b = malloc( sizeof(int) );        §\C{// implicitly convert void * to int *}§
     6039        char * c = b;                           §\C{// implicitly convert int * to void *, and then void * to char *}§
    64086040}
    64096041\end{cfa}
     
    66666298\leavevmode
    66676299\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    6668 forall( otype T | { int ?<?( T, T ); } ) §\C{// location}§
     6300forall( otype T | { int ?<?( T, T ); } )        §\C{// location}§
    66696301T * bsearch( T key, const T * arr, size_t dim );§\indexc{bsearch}§
    66706302
    6671 forall( otype T | { int ?<?( T, T ); } ) §\C{// position}§
     6303forall( otype T | { int ?<?( T, T ); } )        §\C{// position}§
    66726304unsigned int bsearch( T key, const T * arr, size_t dim );
    66736305
     
    66766308
    66776309forall( otype E | { int ?<?( E, E ); } ) {
    6678         E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§ §\C{// location}§
     6310        E * bsearch( E key, const E * vals, size_t dim );§\indexc{bsearch}§     §\C{// location}§
    66796311        size_t bsearch( E key, const E * vals, size_t dim );§\C{// position}§
    66806312        E * bsearchl( E key, const E * vals, size_t dim );§\indexc{bsearchl}§
     
    67246356void srandom( unsigned int seed );§\indexc{srandom}§
    67256357char random( void );§\indexc{random}§
    6726 char random( char u ); §\C{// [0,u)}§
    6727 char random( char l, char u ); §\C{// [l,u)}§
     6358char random( char u );                                          §\C{// [0,u)}§
     6359char random( char l, char u );                          §\C{// [l,u)}§
    67286360int random( void );
    6729 int random( int u ); §\C{// [0,u)}§
    6730 int random( int l, int u ); §\C{// [l,u)}§
     6361int random( int u );                                            §\C{// [0,u)}§
     6362int random( int l, int u );                                     §\C{// [l,u)}§
    67316363unsigned int random( void );
    6732 unsigned int random( unsigned int u ); §\C{// [0,u)}§
     6364unsigned int random( unsigned int u );          §\C{// [0,u)}§
    67336365unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u)}§
    67346366long int random( void );
    6735 long int random( long int u ); §\C{// [0,u)}§
    6736 long int random( long int l, long int u ); §\C{// [l,u)}§
     6367long int random( long int u );                          §\C{// [0,u)}§
     6368long int random( long int l, long int u );      §\C{// [l,u)}§
    67376369unsigned long int random( void );
    67386370unsigned long int random( unsigned long int u ); §\C{// [0,u)}§
     
    67856417[ int, long double ] remquo( long double, long double );
    67866418
    6787 float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§
     6419float div( float, float, int * );§\indexc{div}§ §\C{// alternative name for remquo}§
    67886420double div( double, double, int * );
    67896421long double div( long double, long double, int * );
     
    69416573long double atan2( long double, long double );
    69426574
    6943 float atan( float, float ); §\C{// alternative name for atan2}§
     6575float atan( float, float );                                     §\C{// alternative name for atan2}§
    69446576double atan( double, double );§\indexc{atan}§
    69456577long double atan( long double, long double );
     
    71326764\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    71336765struct Duration {
    7134         int64_t tv; §\C{// nanoseconds}§
     6766        int64_t tv;                                                     §\C{// nanoseconds}§
    71356767};
    71366768
     
    72626894\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    72636895struct Time {
    7264         uint64_t tv; §\C{// nanoseconds since UNIX epoch}§
     6896        uint64_t tv;                                            §\C{// nanoseconds since UNIX epoch}§
    72656897};
    72666898
     
    73336965\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    73346966struct Clock {
    7335         Duration offset; §\C{// for virtual clock: contains offset from real-time}§
    7336         int clocktype; §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§
     6967        Duration offset;                                        §\C{// for virtual clock: contains offset from real-time}§
     6968        int clocktype;                                          §\C{// implementation only -1 (virtual), CLOCK\_REALTIME}§
    73376969};
    73386970
     
    73426974void ?{}( Clock & clk, Duration adj );
    73436975
    7344 Duration getResNsec(); §\C{// with nanoseconds}§
    7345 Duration getRes(); §\C{// without nanoseconds}§
    7346 
    7347 Time getTimeNsec(); §\C{// with nanoseconds}§
    7348 Time getTime(); §\C{// without nanoseconds}§
     6976Duration getResNsec();                                  §\C{// with nanoseconds}§
     6977Duration getRes();                                              §\C{// without nanoseconds}§
     6978
     6979Time getTimeNsec();                                             §\C{// with nanoseconds}§
     6980Time getTime();                                                 §\C{// without nanoseconds}§
    73496981Time getTime( Clock & clk );
    73506982Time ?()( Clock & clk );
     
    73626994
    73636995\begin{cfa}
    7364 void ?{}( Int * this ); §\C{// constructor/destructor}§
     6996void ?{}( Int * this );                                 §\C{// constructor/destructor}§
    73656997void ?{}( Int * this, Int init );
    73666998void ?{}( Int * this, zero_t );
     
    73717003void ^?{}( Int * this );
    73727004
    7373 Int ?=?( Int * lhs, Int rhs ); §\C{// assignment}§
     7005Int ?=?( Int * lhs, Int rhs );                  §\C{// assignment}§
    73747006Int ?=?( Int * lhs, long int rhs );
    73757007Int ?=?( Int * lhs, unsigned long int rhs );
     
    73887020unsigned long int narrow( Int val );
    73897021
    7390 int ?==?( Int oper1, Int oper2 ); §\C{// comparison}§
     7022int ?==?( Int oper1, Int oper2 );               §\C{// comparison}§
    73917023int ?==?( Int oper1, long int oper2 );
    73927024int ?==?( long int oper2, Int oper1 );
     
    74247056int ?>=?( unsigned long int oper1, Int oper2 );
    74257057
    7426 Int +?( Int oper ); §\C{// arithmetic}§
     7058Int +?( Int oper );                                             §\C{// arithmetic}§
    74277059Int -?( Int oper );
    74287060Int ~?( Int oper );
     
    75067138Int ?>>=?( Int * lhs, mp_bitcnt_t shift );
    75077139
    7508 Int abs( Int oper ); §\C{// number functions}§
     7140Int abs( Int oper );                                    §\C{// number functions}§
    75097141Int fact( unsigned long int N );
    75107142Int gcd( Int oper1, Int oper2 );
     
    76177249// implementation
    76187250struct Rational {§\indexc{Rational}§
    7619         long int numerator, denominator; §\C{// invariant: denominator > 0}§
     7251        long int numerator, denominator;        §\C{// invariant: denominator > 0}§
    76207252}; // Rational
    76217253
    7622 Rational rational(); §\C{// constructors}§
     7254Rational rational();                                    §\C{// constructors}§
    76237255Rational rational( long int n );
    76247256Rational rational( long int n, long int d );
     
    76267258void ?{}( Rational * r, one_t );
    76277259
    7628 long int numerator( Rational r ); §\C{// numerator/denominator getter/setter}§
     7260long int numerator( Rational r );               §\C{// numerator/denominator getter/setter}§
    76297261long int numerator( Rational r, long int n );
    76307262long int denominator( Rational r );
    76317263long int denominator( Rational r, long int d );
    76327264
    7633 int ?==?( Rational l, Rational r ); §\C{// comparison}§
     7265int ?==?( Rational l, Rational r );             §\C{// comparison}§
    76347266int ?!=?( Rational l, Rational r );
    76357267int ?<?( Rational l, Rational r );
     
    76387270int ?>=?( Rational l, Rational r );
    76397271
    7640 Rational -?( Rational r ); §\C{// arithmetic}§
     7272Rational -?( Rational r );                              §\C{// arithmetic}§
    76417273Rational ?+?( Rational l, Rational r );
    76427274Rational ?-?( Rational l, Rational r );
     
    76447276Rational ?/?( Rational l, Rational r );
    76457277
    7646 double widen( Rational r ); §\C{// conversion}§
     7278double widen( Rational r );                             §\C{// conversion}§
    76477279Rational narrow( double f, long int md );
    76487280
  • libcfa/src/concurrency/coroutine.hfa

    rc1ea11b r18e683b  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 17:49:39 2019
    13 // Update Count     : 9
     12// Last Modified On : Fri Mar 30 18:23:45 2018
     13// Update Count     : 8
    1414//
    1515
     
    5353forall(dtype T | is_coroutine(T))
    5454void prime(T & cor);
    55 
    56 static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    5755
    5856//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/invoke.h

    rc1ea11b r18e683b  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 22 18:19:13 2019
    13 // Update Count     : 40
     12// Last Modified On : Sat May 19 08:23:21 2018
     13// Update Count     : 31
    1414//
    1515
     
    4646        #ifdef __cforall
    4747        extern "Cforall" {
    48                 static inline struct thread_desc             *& get_next( struct thread_desc             & this );
    49                 static inline struct __condition_criterion_t *& get_next( struct __condition_criterion_t & this );
     48                static inline struct thread_desc             * & get_next( struct thread_desc             & this );
     49                static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    5050
    5151                extern thread_local struct KernelThreadData {
     
    199199        #ifdef __cforall
    200200        extern "Cforall" {
    201                 static inline thread_desc *& get_next( thread_desc & this ) {
     201                static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
     202                static inline struct thread_desc    * active_thread   () { return TL_GET( this_thread    ); }
     203                static inline struct processor      * active_processor() { return TL_GET( this_processor ); } // UNSAFE
     204
     205                static inline thread_desc * & get_next( thread_desc & this ) {
    202206                        return this.next;
    203207                }
     
    206210                        return this.node.[next, prev];
    207211                }
     212
     213                static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    208214
    209215                static inline void ?{}(__monitor_group_t & this) {
  • libcfa/src/concurrency/kernel.cfa

    rc1ea11b r18e683b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 20 17:21:23 2019
    13 // Update Count     : 25
     12// Last Modified On : Mon Apr  9 16:11:46 2018
     13// Update Count     : 24
    1414//
    1515
     
    907907void doregister( cluster * cltr, thread_desc & thrd ) {
    908908        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    909         cltr->nthreads += 1;
    910909        push_front(cltr->threads, thrd);
    911910        unlock    (cltr->thread_list_lock);
     
    915914        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    916915        remove(cltr->threads, thrd );
    917         cltr->nthreads -= 1;
    918916        unlock(cltr->thread_list_lock);
    919917}
     
    921919void doregister( cluster * cltr, processor * proc ) {
    922920        lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    923         cltr->nprocessors += 1;
    924921        push_front(cltr->procs, *proc);
    925922        unlock    (cltr->proc_list_lock);
     
    929926        lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    930927        remove(cltr->procs, *proc );
    931         cltr->nprocessors -= 1;
    932928        unlock(cltr->proc_list_lock);
    933929}
  • libcfa/src/concurrency/kernel.hfa

    rc1ea11b r18e683b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 22 11:39:17 2019
    13 // Update Count     : 16
     12// Last Modified On : Tue Apr 10 14:46:49 2018
     13// Update Count     : 10
    1414//
    1515
     
    9191        this.lock = NULL;
    9292}
    93 static inline void ^?{}(FinishAction &) {}
     93static inline void ^?{}(FinishAction & this) {}
    9494
    9595// Processor
     
    176176        __dllist_t(struct processor) procs;
    177177        __dllist_t(struct processor) idles;
    178         unsigned int nprocessors;
    179 
    180         // List of threads
     178
     179        // List of processors
    181180        __spinlock_t thread_list_lock;
    182181        __dllist_t(struct thread_desc) threads;
    183         unsigned int nthreads;
    184182
    185183        // Link lists fields
     
    202200}
    203201
    204 static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
    205 static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
    206 
    207202// Local Variables: //
    208203// mode: c //
  • libcfa/src/concurrency/thread.hfa

    rc1ea11b r18e683b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 17:51:33 2019
    13 // Update Count     : 5
     12// Last Modified On : Thu Mar 29 14:07:11 2018
     13// Update Count     : 4
    1414//
    1515
     
    9191void yield( unsigned times );
    9292
    93 static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); }
    94 
    9593// Local Variables: //
    9694// mode: c //
  • src/ResolvExpr/Cost.h

    rc1ea11b r18e683b  
    1010// Created On       : Sun May 17 09:39:50 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 11:39:13 2019
    13 // Update Count     : 63
     12// Last Modified On : Mon Apr 29 18:33:44 2019
     13// Update Count     : 49
    1414//
    1515
     
    2121
    2222namespace ResolvExpr {
     23#if 0
     24
     25        //*************************** OLD ***************************
     26
     27        class Cost {
     28          private:
     29                Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
     30                          int varCost, int specCost, int referenceCost );
     31          public:
     32                Cost & incUnsafe( int inc = 1 );
     33                Cost & incPoly( int inc = 1 );
     34                Cost & incSafe( int inc = 1 );
     35                Cost & incSign( int inc = 1 );
     36                Cost & incVar( int inc = 1 );
     37                Cost & decSpec( int inc = 1 );
     38                Cost & incReference( int inc = 1 );
     39
     40                int get_unsafeCost() const { return unsafeCost; }
     41                int get_polyCost() const { return polyCost; }
     42                int get_safeCost() const { return safeCost; }
     43                int get_signCost() const { return signCost; }
     44                int get_varCost() const { return varCost; }
     45                int get_specCost() const { return specCost; }
     46                int get_referenceCost() const { return referenceCost; }
     47
     48                Cost operator+( const Cost &other ) const;
     49                Cost &operator+=( const Cost &other );
     50                bool operator<( const Cost &other ) const;
     51                bool operator==( const Cost &other ) const;
     52                bool operator!=( const Cost &other ) const;
     53                friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
     54                // returns negative for *this < other, 0 for *this == other, positive for *this > other
     55                int compare( const Cost &other ) const;
     56
     57                static const Cost zero;
     58                static const Cost infinity;
     59
     60                static const Cost unsafe;
     61                static const Cost poly;
     62                static const Cost safe;
     63                static const Cost sign;
     64                static const Cost var;
     65                static const Cost spec;
     66                static const Cost reference;
     67
     68          private:
     69                int unsafeCost;     ///< Unsafe (narrowing) conversions
     70                int polyCost;       ///< Count of parameters and return values bound to some poly type
     71                int safeCost;       ///< Safe (widening) conversions
     72                int signCost;       ///< Count of safe sign conversions
     73                int varCost;        ///< Count of polymorphic type variables
     74                int specCost;       ///< Polymorphic type specializations (type assertions), negative cost
     75                int referenceCost;  ///< reference conversions
     76        };
     77
     78        inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
     79                                           int varCost, int specCost, int referenceCost )
     80                : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),
     81                  varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
     82
     83        inline Cost & Cost::incUnsafe( int inc ) {
     84                if ( *this == infinity ) return *this;
     85                unsafeCost += inc;
     86                return *this;
     87        }
     88
     89        inline Cost & Cost::incPoly( int inc ) {
     90                if ( *this == infinity ) return *this;
     91                polyCost += inc;
     92                return *this;
     93        }
     94
     95        inline Cost & Cost::incSafe( int inc ) {
     96                if ( *this == infinity ) return *this;
     97                safeCost += inc;
     98                return *this;
     99        }
     100
     101        inline Cost & Cost::incSign( int inc ) {
     102                if ( *this == infinity ) return *this;
     103                signCost += inc;
     104                return *this;
     105        }
     106
     107        inline Cost & Cost::incVar( int inc ) {
     108                if ( *this == infinity ) return *this;
     109                varCost += inc;
     110                return *this;
     111        }
     112
     113        inline Cost& Cost::decSpec( int dec ) {
     114                if ( *this == infinity ) return *this;
     115                specCost -= dec;
     116                return *this;
     117        }
     118
     119        inline Cost & Cost::incReference( int inc ) {
     120                if ( *this == infinity ) return *this;
     121                referenceCost += inc;
     122                return *this;
     123        }
     124
     125        inline Cost Cost::operator+( const Cost &other ) const {
     126                if ( *this == infinity || other == infinity ) return infinity;
     127                return Cost{
     128                        unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
     129                                signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,
     130                                referenceCost + other.referenceCost };
     131        }
     132
     133        inline Cost &Cost::operator+=( const Cost &other ) {
     134                if ( *this == infinity ) return *this;
     135                if ( other == infinity ) {
     136                        *this = infinity;
     137                        return *this;
     138                }
     139                unsafeCost += other.unsafeCost;
     140                polyCost += other.polyCost;
     141                safeCost += other.safeCost;
     142                signCost += other.signCost;
     143                varCost += other.varCost;
     144                specCost += other.specCost;
     145                referenceCost += other.referenceCost;
     146                return *this;
     147        }
     148
     149        inline bool Cost::operator<( const Cost &other ) const {
     150                if ( *this == infinity ) return false;
     151                if ( other == infinity ) return true;
     152
     153                if ( unsafeCost > other.unsafeCost ) {
     154                        return false;
     155                } else if ( unsafeCost < other.unsafeCost ) {
     156                        return true;
     157                } else if ( polyCost > other.polyCost ) {
     158                        return false;
     159                } else if ( polyCost < other.polyCost ) {
     160                        return true;
     161                } else if ( safeCost > other.safeCost ) {
     162                        return false;
     163                } else if ( safeCost < other.safeCost ) {
     164                        return true;
     165                } else if ( signCost > other.signCost ) {
     166                        return false;
     167                } else if ( signCost < other.signCost ) {
     168                        return true;
     169                } else if ( varCost > other.varCost ) {
     170                        return false;
     171                } else if ( varCost < other.varCost ) {
     172                        return true;
     173                } else if ( specCost > other.specCost ) {
     174                        return false;
     175                } else if ( specCost > other.specCost ) {
     176                        return true;
     177                } else if ( referenceCost > other.referenceCost ) {
     178                        return false;
     179                } else if ( referenceCost < other.referenceCost ) {
     180                        return true;
     181                } else {
     182                        return false;
     183                } // if
     184        }
     185
     186        inline int Cost::compare( const Cost &other ) const {
     187                if ( *this == infinity ) return +1;
     188                if ( other == infinity ) return -1;
     189
     190                int c = unsafeCost - other.unsafeCost; if ( c ) return c;
     191                c = polyCost - other.polyCost; if ( c ) return c;
     192                c = safeCost - other.safeCost; if ( c ) return c;
     193                c = signCost - other.signCost; if ( c ) return c;
     194                c = varCost - other.varCost; if ( c ) return c;
     195                c = specCost - other.specCost; if ( c ) return c;
     196                return referenceCost - other.referenceCost;
     197        }
     198
     199        inline bool Cost::operator==( const Cost &other ) const {
     200                return unsafeCost == other.unsafeCost
     201                        && polyCost == other.polyCost
     202                        && safeCost == other.safeCost
     203                        && signCost == other.signCost
     204                        && varCost == other.varCost
     205                        && specCost == other.specCost
     206                        && referenceCost == other.referenceCost;
     207        }
     208
     209        inline bool Cost::operator!=( const Cost &other ) const {
     210                return !( *this == other );
     211        }
     212
     213        inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
     214                return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "
     215                          << cost.safeCost << ", " << cost.signCost << ", "
     216                                  << cost.varCost << ", " << cost.specCost << ", "
     217                          << cost.referenceCost << " )";
     218        }
     219
     220#else
     221
     222        //*************************** NEW ***************************
     223
    23224        // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the
    24225        // specialization cost is a negative value so a correction is needed is a few places.
     
    170371                                  << ", " << cost.get_referenceCost() << " )";
    171372        }
     373#endif // 0
    172374} // namespace ResolvExpr
    173375
  • tests/concurrent/examples/boundedBufferTHREAD.cfa

    rc1ea11b r18e683b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // boundedBufferTHREAD.c --
     7// boundedBufferEXT.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Apr 18 22:52:12 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 21 11:50:12 2019
    13 // Update Count     : 24
     12// Last Modified On : Fri Jun 21 08:15:58 2019
     13// Update Count     : 23
    1414//
    1515
  • tools/stat.py

    rc1ea11b r18e683b  
    1111                content = f.readlines()
    1212                content = [x.strip() for x in content]
    13                 content = [float(x) for x in content]   # expect floating-point strings
    14                 content.remove(max(content))            # need at least 4 data values because
    15                 content.remove(min(content))            # the max and min values are removed
    16                 med = numpy.median(content)
    17                 avg = numpy.mean  (content)
    18                 std = numpy.std   (content)
    19                 print "median {0:.1f} avg {1:.1f} stddev {2:.2f}".format( med, avg, std )
     13                content = [int(x) for x in content]
     14                content.remove(max(content))
     15                content.remove(min(content))
     16                med = numpy.around( numpy.median(content), decimals=1)
     17                avg = numpy.around( numpy.mean  (content), decimals=2)
     18                std = numpy.around( numpy.std   (content), decimals=2)
     19                print "median {0} avg {1} stddev {2}".format( med, avg, std )
    2020
    2121
Note: See TracChangeset for help on using the changeset viewer.