Changeset ce55a81


Ignore:
Timestamp:
Sep 4, 2020, 2:14:10 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
14d8a9b
Parents:
56c44dc (diff), 2801829 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
24 added
66 edited
8 moved

Legend:

Unmodified
Added
Removed
  • .gitignore

    r56c44dc rce55a81  
    1818**/Makefile
    1919**/Makefile.in
     20**/Makefile.dist.in
    2021/version
    2122
  • Makefile.am

    r56c44dc rce55a81  
    2121
    2222SUBDIRS = driver src . @LIBCFA_TARGET_DIRS@
     23DIST_SUBDIRS = driver src . libcfa benchmark longrun_tests tests tools tools/prettyprinter
    2324
    2425@LIBCFA_TARGET_MAKEFILES@ : Makefile $(srcdir)/libcfa/configure
     
    2627        @ls $(config_file) || (echo "Missing config.data, re-run configure script again" && false)
    2728        @$(eval config_data = $(shell cat $(config_file)))
    28         @echo "Configuring libcfa with '$(config_data)''"
     29        @echo "Configuring libcfa ($(abs_top_srcdir)/libcfa/configure) with '$(config_data)' from $(shell pwd) / $(dir $@)"
    2930        @cd $(dir $@) && $(abs_top_srcdir)/libcfa/configure $(config_data)
    3031
     
    3233
    3334man1_MANS = doc/man/cfa.1
     35
     36EXTRA_DIST = LICENSE doc/man/cfa.1 libcfa/configure libcfa/Makefile.dist.am libcfa/Makefile.dist.in
    3437
    3538debug=yes
  • benchmark/Makefile.am

    r56c44dc rce55a81  
    6666# Dummy hack tricks
    6767EXTRA_PROGRAMS = dummy # build but do not install
    68 dummy_SOURCES = dummyC.c dummyCXX.cpp
     68nodist_dummy_SOURCES = dummyC.c dummyCXX.cpp
    6969
    7070dummyC.c:
     
    8080## =========================================================================================================
    8181
    82 all : basic$(EXEEXT) ctxswitch$(EXEEXT) mutex$(EXEEXT) schedint$(EXEEXT) schedext$(EXEEXT) creation$(EXEEXT)
     82# all is used by make dist so ignore it
     83all:
     84
     85all-bench : basic$(EXEEXT) ctxswitch$(EXEEXT) mutex$(EXEEXT) schedint$(EXEEXT) schedext$(EXEEXT) creation$(EXEEXT)
    8386
    8487basic_loop_DURATION = 15000000000
     
    476479## =========================================================================================================
    477480
    478 compile$(EXEEXT) :              \
     481bcompile$(EXEEXT) :             \
    479482        compile-array.make      \
    480483        compile-attributes.make \
  • configure.ac

    r56c44dc rce55a81  
    137137                \'--enable-gprofiler=*) ;;
    138138                \'--disable-gprofiler) ;;
     139
     140                # skip this, it only causes problems
     141                \'--srcdir=*) ;;
    139142
    140143                # append all other arguments to the sub configure arguments
     
    202205
    203206        LIBCFA_TARGET_DIRS="${LIBCFA_TARGET_DIRS} ${lib_dir}"
     207        LIBCFA_1TARGET_DIR="${lib_dir}"
    204208        LIBCFA_TARGET_MAKEFILES="${LIBCFA_TARGET_MAKEFILES} ${lib_dir}/Makefile"
    205209
     
    213217
    214218AC_SUBST(LIBCFA_TARGET_DIRS)
     219AC_SUBST(LIBCFA_1TARGET_DIR)
    215220AC_SUBST(LIBCFA_TARGET_MAKEFILES)
    216221
     
    278283        driver/Makefile
    279284        src/Makefile
    280         benchmark/Makefile
     285        libcfa/Makefile:libcfa/Makefile.dist.in
    281286        tests/Makefile
    282287        longrun_tests/Makefile
     288        benchmark/Makefile
    283289        tools/Makefile
    284290        tools/prettyprinter/Makefile
  • doc/LaTeXmacros/common.tex

    r56c44dc rce55a81  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri May 24 07:59:54 2019
    14 %% Update Count     : 382
     13%% Last Modified On : Fri Sep  4 13:56:52 2020
     14%% Update Count     : 383
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3636% Names used in the document.
    3737
     38\usepackage{xspace}
    3839\newcommand{\CFAIcon}{\textsf{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
    3940\newcommand{\CFA}{\protect\CFAIcon}             % safe for section/caption
     
    241242}%
    242243
     244\usepackage{listings}                                                                   % format program code
    243245\usepackage{lstlang}
    244246
  • doc/man/cfa.1

    r56c44dc rce55a81  
    1111.\" Created On       : Wed Jul 26 22:34:47 2017
    1212.\" Last Modified By : Peter A. Buhr
    13 .\" Last Modified On : Thu Jul 27 10:29:29 2017
    14 .\" Update Count     : 44
     13.\" Last Modified On : Wed Sep  2 17:59:53 2020
     14.\" Update Count     : 78
    1515.\"
    1616.\" nroff -man cfa.1
     
    2323.ds Cf "Cforall
    2424.\"
    25 .TH cfa 1 2017-07-27 cfa-\*(Mg
     25.TH CFA 1 "2020-09-2" cfa-\*(Mg "\*(Cf Project"
    2626.SH NAME
    27 cfa \- \*(Cf Translator and Runtime Library
     27cfa \- \*(Cf project translator and runtime library to enhance C
    2828.SH SYNOPSIS
    29 cfa [gcc-options] [C/\*(Cf source-files] [assembler/loader files]
     29cfa [cfa/gcc-options]
     30    [cfa/c source-files]
     31    [assembler/loader files]
    3032.SH DESCRIPTION
     33\*(Cf (C-for-all) is an open-source project extending ISO C with modern safety and productivity features, while still ensuring backwards compatibility with C and its programmers.
     34
    3135The cfa command compiles C and \*(Cf source files and links C/\*(Cf object
    3236files named on the command line.
     
    3438The cfa command introduces a translator pass over the specified source files
    3539after the C preprocessor but before the C compilation.  The translator converts
    36 new \*(Cf constructs into C statements.  The cfa command also provides the
    37 runtime library, which is linked with each \*(Cf application.
     40new \*(Cf constructs into C statements.  The cfa command also provides a fully
     41concurrent (user-level threads) runtime library, which is linked with the
     42\*(Cf application.
    3843
    3944The command line options depend on the particular C compiler used (gcc/clang
    4045supported).  As with most C compilers, the output is sent to the file a.out(5)
    4146unless the -o option is present on the command line.  See the reference pages
    42 for gcc(1) for more information.
     47for gcc(1) for more information on command line options.
    4348.SH OPTIONS
    4449When multiple conflicting options appear on the command line, e.g.,
     
    5055All of the options available to the gcc compiler are available to the cfa
    5156translator.  The following gcc flags are implicitly turned on:
    52 .IP -std=gnu99 3
    53 The 1999 C standard plus GNU extensions.
    54 .IP -fgnu89-inline
    55 Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files.
     57.IP "-std=gnu11" 3
     58The 2011 C standard plus GNU extensions.
     59.IP "-fgnu89-inline"
     60Use the traditional GNU semantics for inline routines in C11 mode, which allows inline routines in header files.
     61.IP "-imacros stdbool.h"
     62Include stdbool.h to get defines for bool/true/false.
     63.IP "-latomic -lm"
     64Provide access to double-wide CAS instruction and math library.
    5665.LP
    5766The following additional options are available:
    58 .IP -CFA 3
     67.IP "-CFA" 3
    5968Only the C preprocessor and the \*(Cf translator steps are performed and the transformed program is written to standard output, which makes it possible to examine the code generated by the \*(Cf translator.
    6069The generated code starts with the standard \*(Cf prelude.
    61 .IP -debug
     70.IP "-debug"
    6271The program is linked with the debugging version of the runtime system.
    6372The debug version performs runtime checks to help during the debugging phase of a \*(Cf program, but can substantially slow program execution.
    6473The runtime checks should only be removed after the program is completely debugged.
    6574.B This option is the default.
    66 .IP -nodebug
     75.IP "-nodebug"
    6776The program is linked with the non-debugging version of the runtime system, so the execution of the program is faster.
    6877.I However, no runtime checks or asserts are performed so errors usually result in abnormal program behaviour or termination.
    69 .IP -help
     78.IP "-help"
    7079Information about the set of \*(Cf compilation flags is printed.
    71 .IP -nohelp
     80.IP "-nohelp"
    7281Information about the set of \*(Cf compilation flags is not printed.
    7382.B This option is the default.
    74 .IP -quiet
     83.IP "-quiet"
    7584The \*(Cf compilation message is not printed at the beginning of a compilation.
    76 .IP -noquiet
     85.IP "-noquiet"
    7786The \*(Cf compilation message is printed at the beginning of a compilation.
    7887.B This option is the default.
     
    8190available.  These variables allow conditional compilation of programs that must
    8291work differently in these situations.
    83 .IP __CFA_MAJOR__ 3
     92.IP "__CFA_MAJOR__" 3
    8493is available during preprocessing and its value is the major version number of \*(Cf.
    85 .IP __CFA_MINOR__
     94.IP "__CFA_MINOR__"
    8695is available during preprocessing and its value is the minor version number of \*(Cf.
    87 .IP __CFA_PATCH__
     96.IP "__CFA_PATCH__"
    8897is available during preprocessing and its value is the patch level number of \*(Cf.
    8998.IP "__CFA__, __CFORALL__, and __cforall"
    9099are always available during preprocessing and have no value.
    91 .IP __CFA_DEBUG__
     100.IP "__CFA_DEBUG__"
    92101is available during preprocessing if the -debug compilation option is
    93102specified.
     
    116125.SH REFERENCES
    117126.HP 3
    118 \*(Cf Reference and Rational Manual
     127.I \*(Cf Home Page
    119128.br
    120 http://plg.uwaterloo.ca/~cforall/refrat.pdf
     129https://cforall.uwaterloo.ca
    121130.HP
    122131.I \*(Cf User Manual
    123132.br
    124 http://plg.uwaterloo.ca/~cforall/user.pdf
     133https://cforall.uwaterloo.ca/doc/user.pdf
     134.SH BUILDS
     135Nightly builds are available here https://cforall.uwaterloo.ca/jenkins
    125136.SH BUGS
    126 Bugs should be reported to trac@plg.cs.uwaterloo.ca.
     137Bugs reportss are available here https://cforall.uwaterloo.ca/trac
    127138.SH COPYRIGHT
    128139\*(Cf is covered under the licence agreement in the distribution.
    129140.SH AUTHORS
    130141Andrew Beach, Richard Bilson, Peter A. Buhr, Thierry Delisle, Glen Ditchfield,
    131 Rodolfo G. Esteves, Aaron Moss, Rob Schluntz
     142Rodolfo G. Esteves, Aaron Moss, Rob Schluntz, Mubeen Zulfiqar
  • doc/theses/thierry_delisle_PhD/comp_II/Makefile

    r56c44dc rce55a81  
    1212
    1313## Define the text source files.
    14 
    15 SOURCES = ${addsuffix .tex, \
    16 comp_II \
    17 }
    18 
    1914FIGURES = ${addsuffix .tex, \
    20         base \
    21         empty \
    2215        emptybit \
    2316        emptytree \
    2417        emptytls \
    2518        resize \
    26         system \
    2719}
    2820
    2921PICTURES = ${addsuffix .pstex, \
     22        base \
     23        empty \
     24        system \
    3025}
    3126
     
    3732
    3833## Define the documents that need to be made.
     34all: comp_II.pdf presentation.pdf
     35comp_II.pdf: ${FIGURES} ${PICTURES}
     36presentation.pdf: presentationstyle.sty base.dark.pstex empty.dark.pstex system.dark.pstex
    3937
    40 DOCUMENT = comp_II.pdf
     38DOCUMENT = comp_II.pdf presentation.pdf
    4139BASE = ${basename ${DOCUMENT}}
    4240
     
    5250# File Dependencies #
    5351
    54 ${DOCUMENT} : ${BASE}.ps
     52%.pdf : build/%.ps | ${Build}
    5553        ps2pdf $<
    5654
    57 ${BASE}.ps : ${BASE}.dvi
    58         dvips ${Build}/$< -o $@
     55build/%.ps : build/%.dvi | ${Build}
     56        dvips $< -o $@
    5957
    60 ${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} \
    61                 ${Macros}/common.tex ${Macros}/indexstyle ../../../bibliography/pl.bib \
    62                 local.bib glossary.tex | ${Build}
     58build/%.dvi : %.tex Makefile | ${Build}
    6359        # Must have *.aux file containing citations for bibtex
    64         if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
    65         -${BibTeX} ${Build}/${basename $@}
     60        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} $< ; fi
     61        -${BibTeX} ${basename $@}
    6662        # Some citations reference others so run again to resolve these citations
    67         ${LaTeX} ${basename $@}.tex
    68         -${BibTeX} ${Build}/${basename $@}
     63        ${LaTeX} $<
     64        -${BibTeX} ${basename $@}
    6965        # Make index from *.aux entries and input index at end of document
    70         makeglossaries -q -s ${Build}/${basename $@}.ist ${Build}/${basename $@}
     66        -makeglossaries -q -s ${basename $@}.ist ${basename $@}
    7167        # Run again to finish citations
    72         ${LaTeX} ${basename $@}.tex
     68        ${LaTeX} $<
    7369
    7470## Define the default recipes.
     
    7773        mkdir -p ${Build}
    7874
    79 %.tex : img/%.fig ${Build}
     75%.tex : img/%.fig | ${Build}
    8076        fig2dev -L eepic $< > ${Build}/$@
    8177
     
    8783        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
    8884
     85## pstex with inverted colors
     86%.dark.pstex : img/%.fig Makefile | ${Build}
     87        fig2dev -L pstex $< > ${Build}/$@
     88        sed -i 's/\/col-1 {0 setgray} bind def/\/col-1 {1 setgray} bind def/g' ${Build}/$@
     89        sed -i 's/\/col0 {0.000 0.000 0.000 srgb} bind def/\/col0 {1.000 1.000 1.000 srgb} bind def/g' ${Build}/$@
     90        sed -i 's/\/col7 {1.000 1.000 1.000 srgb} bind def/\/col7 {0.000 0.000 0.000 srgb} bind def/g' ${Build}/$@
     91        fig2dev -L pstex_t -p ${Build}/$@ $< > ${Build}/$@_t
     92
    8993# Local Variables: #
    9094# compile-command: "make" #
  • doc/theses/thierry_delisle_PhD/comp_II/comp_II.tex

    r56c44dc rce55a81  
    6363It aims to add high-productivity features while maintaining the predictable performance of C.
    6464As such, concurrency in \CFA\cite{Delisle19} aims to offer simple and safe high-level tools while still allowing performant code.
    65 \CFA concurrent code is written in the synchronous programming paradigm but uses \glspl{uthrd} in order to achieve the simplicity and maintainability of synchronous programming without sacrificing the efficiency of asynchronous programing.
     65\CFA concurrent code is written in the synchronous programming paradigm but uses \glspl{uthrd} in order to achieve the simplicity and maintainability of synchronous programming without sacrificing the efficiency of asynchronous programming.
    6666As such, the \CFA \newterm{scheduler} is a preemptive user-level scheduler that maps \glspl{uthrd} onto \glspl{kthrd}.
    6767
     
    7575and the cost of scheduling, \ie deciding which thread to run next among all the threads ready to run.
    7676\end{enumerate}
    77 The first cost is generally constant and fixed\footnote{Affecting the constant context-switch cost is whether it is done in one step, after the scheduling, or in two steps, context-switching to a fixed third-thread before scheduling.}, while the scheduling cost can vary based on the system state.
    78 Adding multiple \glspl{kthrd} does not fundamentally change the scheduler semantics or requirements, it simply adds new correctness requirements, \ie \newterm{linearizability}\footnote{Meaning however fast the CPU threads run, there is an equivalent sequential order that gives the same result.}, and a new dimension to performance: scalability, where scheduling cost now also depends on contention.
    79 
     77The first cost is generally constant and fixed\footnote{Affecting the constant context-switch cost is whether it is done in one step, after the scheduling, or in two steps, context-switching to a third fixed thread before scheduling.}, while the scheduling cost can vary based on the system state.
     78Adding multiple \glspl{kthrd} does not fundamentally change the scheduler semantics or requirements, it simply adds new correctness requirements, \ie \newterm{linearizability}\footnote{Meaning, however fast the CPU threads run, there is an equivalent sequential order that gives the same result.}, and a new dimension to performance: scalability, where scheduling cost now also depends on contention.
    8079The more threads switch, the more the administration cost of scheduling becomes noticeable.
    8180It is therefore important to build a scheduler with the lowest possible cost and latency.
     
    8483While the illusion of simultaneity is easier to reason about, it can break down if the scheduler allows too much unfairness.
    8584Therefore, the scheduler should offer as much fairness as needed to guarantee eventual progress, but use unfairness to help performance.
    86 In practice, threads must wait in turn but there can be advantages to unfair scheduling, similar to the the express cash-register at a grocery store.
     85In practice, threads must wait in turn but there can be advantages to unfair scheduling, similar to the express cash register at a grocery store.
    8786
    8887The goal of this research is to produce a scheduler that is simple for programmers to understand and offers good performance.
     
    9392\end{quote}
    9493
    95 For a general purpose scheduler, it is impossible to produce an optimal algorithm as it would require knowledge of the future behaviour of threads.
    96 As such, scheduling performance is generally either defined by the best case scenario, \ie a workload to which the scheduler is tailored, or the worst case scenario, \ie the scheduler behaves no worst than \emph{X}.
     94For a general-purpose scheduler, it is impossible to produce an optimal algorithm as it would require knowledge of the future behaviour of threads.
     95As such, scheduling performance is generally either defined by the best-case scenario, \ie a workload to which the scheduler is tailored, or the worst-case scenario, \ie the scheduler behaves no worse than \emph{X}.
    9796For this proposal, the performance is evaluated using the second approach to allow \CFA programmers to rely on scheduling performance.
    9897Because there is no optimal scheduler, ultimately \CFA may allow programmers to write their own scheduler; but that is not the subject of this proposal, which considers only the default scheduler.
     
    101100To achieve the \CFA scheduling goal includes:
    102101\begin{enumerate}
    103 \item
    104 producing a scheduling strategy with sufficient fairness guarantees,
    105 \item
    106 creating an abstraction layer over the operating system to handle kernel-threads spinning unnecessarily,
    107 \item
    108 scheduling blocking I/O operations,
    109 \item
    110 and writing sufficient library tools to allow developers to indirectly use the scheduler, either through tuning knobs or replacing the default scheduler.
     102        \item producing a scheduling strategy with sufficient fairness guarantees,
     103        \item creating an abstraction layer over the operating system to handle kernel-threads spinning unnecessarily,
     104        \item scheduling blocking I/O operations,
     105        \item and writing sufficient library tools to allow developers to indirectly use the scheduler, either through tuning knobs or replacing the default scheduler.
    111106\end{enumerate}
    112107
     
    119114\paragraph{Correctness} As with any other concurrent data structure or algorithm, the correctness requirement is paramount.
    120115The scheduler cannot allow threads to be dropped from the ready queue, \ie scheduled but never run, or be executed multiple times when only being scheduled once.
    121 Since \CFA concurrency has no spurious wakeup, this definition of correctness also means the scheduler should have no spurious wakeup.
     116Since \CFA concurrency has no spurious wake up, this definition of correctness also means the scheduler should have no spurious wake up.
    122117The \CFA scheduler must be correct.
    123118
     
    130125The \CFA scheduler should offer good performance for all three metrics.
    131126
    132 \paragraph{Fairness} Like performance, this requirement has several aspect : eventual progress, predictability and performance reliability.
     127\paragraph{Fairness} Like performance, this requirement has several aspects : eventual progress, predictability and performance reliability.
    133128\newterm{Eventual progress} guarantees every scheduled thread is eventually run, \ie prevent starvation.
    134 As a hard requirement, the \CFA scheduler must guarantee eventual progress, otherwise the above mentioned illusion of simultaneous execution is broken and the scheduler becomes much more complex to reason about.
    135 \newterm{Predictability} and \newterm{reliability} means similar workloads achieve similar performance and programmer execution intuition is respected.
    136 For example, a thread that yields aggressively should not run more often then other tasks.
     129As a hard requirement, the \CFA scheduler must guarantee eventual progress, otherwise the above-mentioned illusion of simultaneous execution is broken and the scheduler becomes much more complex to reason about.
     130\newterm{Predictability} and \newterm{reliability} mean similar workloads achieve similar performance and programmer execution intuition is respected.
     131For example, a thread that yields aggressively should not run more often than other tasks.
    137132While this is intuitive, it does not hold true for many work-stealing or feedback based schedulers.
    138133The \CFA scheduler must guarantee eventual progress and should be predictable and offer reliable performance.
     
    150145
    151146\begin{enumerate}
    152         \item Threads live long enough for useful feedback information to be to gathered.
     147        \item Threads live long enough for useful feedback information to be gathered.
    153148        \item Threads belong to multiple users so fairness across threads is insufficient.
    154149\end{enumerate}
     
    157152Since \CFA has the explicit goal of allowing many smaller threads, this can naturally lead to threads with much shorter lifetimes that are only scheduled a few times.
    158153Scheduling strategies based on feedback cannot be effective in these cases because there is no opportunity to measure the metrics that underlie the algorithm.
    159 Note, the problem of \newterm{feedback convergence} (reacting too slowly to scheduling events) is not specific to short lived threads but can also occur with threads that show drastic changes in scheduling, \eg threads running for long periods of time and then suddenly blocking and unblocking quickly and repeatedly.
     154Note, the problem of \newterm{feedback convergence} (reacting too slowly to scheduling events) is not specific to short-lived threads but can also occur with threads that show drastic changes in scheduling, \eg threads running for long periods of time and then suddenly blocking and unblocking quickly and repeatedly.
    160155
    161156In the context of operating systems, these concerns can be overshadowed by a more pressing concern : security.
     
    164159In the case of the \CFA scheduler, every thread runs in the same user space and is controlled by the same user.
    165160Fairness across users is therefore a given and it is then possible to safely ignore the possibility that threads are malevolent.
    166 This approach allows for a much simpler fairness metric and in this proposal \emph{fairness} is defined as: when multiple threads are cycling through the system, the total ordering of threads being scheduled, \ie pushed onto the ready-queue, should not differ much from the total ordering of threads being executed, \ie popped from the ready-queue.
     161This approach allows for a much simpler fairness metric and in this proposal \emph{fairness} is defined as: when multiple threads are cycling through the system, the total ordering of threads being scheduled, \ie pushed onto the ready queue, should not differ much from the total ordering of threads being executed, \ie popped from the ready queue.
    167162
    168163Since feedback is not necessarily feasible within the lifetime of all threads and a simple fairness metric can be used, the scheduling strategy proposed for the \CFA runtime does not use per-threads feedback.
     
    172167Another broad category of schedulers are priority schedulers.
    173168In these scheduling strategies, threads have priorities and the runtime schedules the threads with the highest priority before scheduling other threads.
    174 Threads with equal priority are scheduled using a secondary strategy, often something simple like round-robin or FIFO.
     169Threads with equal priority are scheduled using a secondary strategy, often something simple like round robin or FIFO.
    175170A consequence of priority is that, as long as there is a thread with a higher priority that desires to run, a thread with a lower priority does not run.
    176171This possible starving of threads can dramatically increase programming complexity since starving threads and priority inversion (prioritizing a lower priority thread) can both lead to serious problems.
    177172
    178173An important observation is that threads do not need to have explicit priorities for problems to occur.
    179 Indeed, any system with multiple ready-queues that attempts to exhaust one queue before accessing the other queues, essentially provide implicit priority, which can encounter starvation problems.
     174Indeed, any system with multiple ready queues that attempts to exhaust one queue before accessing the other queues, essentially provide implicit priority, which can encounter starvation problems.
    180175For example, a popular scheduling strategy that suffers from implicit priorities is work stealing.
    181176\newterm{Work stealing} is generally presented as follows:
     
    191186
    192187\subsection{Schedulers without feedback or priorities}
    193 This proposal conjectures that is is possible to construct a default scheduler for the \CFA runtime that offers good scalability and a simple fairness guarantee that is easy for programmers to reason about.
     188This proposal conjectures that it is possible to construct a default scheduler for the \CFA runtime that offers good scalability and a simple fairness guarantee that is easy for programmers to reason about.
    194189The simplest fairness guarantee is FIFO ordering, \ie threads scheduled first run first.
    195190However, enforcing FIFO ordering generally conflicts with scalability across multiple processors because of the additional synchronization.
     
    217212Pushing new data is done by selecting one of these underlying queues at random, recording a timestamp for the operation and pushing to the selected queue.
    218213Popping is done by selecting two queues at random and popping from the queue with the oldest timestamp.
    219 A higher number of underlying queues leads to less contention on each queue and therefore better performance.
     214A higher number of underlying queues lead to less contention on each queue and therefore better performance.
    220215In a loaded system, it is highly likely the queues are non-empty, \ie several tasks are on each of the underlying queues.
    221216This means that selecting a queue at random to pop from is highly likely to yield a queue with available items.
     
    224219\begin{figure}
    225220        \begin{center}
    226                 \input{base}
     221                \input{base.pstex_t}
    227222        \end{center}
    228223        \caption{Relaxed FIFO list at the base of the scheduler: an array of strictly FIFO lists.
    229 The timestamp is in all nodes and cell arrays.}
     224        The timestamp is in all nodes and cell arrays.}
    230225        \label{fig:base}
    231226\end{figure}
     
    233228\begin{figure}
    234229        \begin{center}
    235                 \input{empty}
     230                \input{empty.pstex_t}
    236231        \end{center}
    237232        \caption{``More empty'' state of the queue: the array contains many empty cells.}
     
    245240Overall performance is therefore influenced by the contention on the underlying queues and pop performance is influenced by the item density.
    246241
    247 This leads to four performance cases for the centralized ready-queue, as depicted in Table~\ref{tab:perfcases}.
     242This leads to four performance cases for the centralized ready queue, as depicted in Table~\ref{tab:perfcases}.
    248243The number of processors (many or few) refers to the number of kernel threads \emph{actively} attempting to pop user threads from the queues, not the total number of kernel threads.
    249244The number of threads (many or few) refers to the number of user threads ready to be run.
     
    321316Sparse global information helps high-contention cases but increases latency in zero-contention-cases, to read and ``aggregate'' the information\footnote{Hierarchical structures, \eg binary search tree, effectively aggregate information but follow pointer chains, learning information at each node.
    322317Similarly, other sparse schemes need to read multiple cachelines to acquire all the information needed.}.
    323 Finally, dense local information has both the advantages of low latency in zero-contention cases and scalability in high-contention cases, however the information can become stale making it difficult to use to ensure correctness.
    324 The fact that these solutions have these fundamental limits suggest to me a better solution that attempts to combine these properties in an interesting ways.
     318Finally, dense local information has both the advantages of low latency in zero-contention cases and scalability in high-contention cases. However the information can become stale making it difficult to use to ensure correctness.
     319The fact that these solutions have these fundamental limits suggest to me a better solution that attempts to combine these properties in an interesting way.
    325320Also, the lock discussed in Section~\ref{sec:resize} allows for solutions that adapt to the number of processors, which could also prove useful.
    326321
     
    328323
    329324How much scalability is actually needed is highly debatable.
    330 \emph{libfibre}\cite{libfibre} has compared favorably to other schedulers in webserver tests\cite{Karsten20} and uses a single atomic counter in its scheduling algorithm similarly to the proposed bitmask.
     325\emph{libfibre}\cite{libfibre} has compared favourably to other schedulers in webserver tests\cite{Karsten20} and uses a single atomic counter in its scheduling algorithm similarly to the proposed bitmask.
    331326As such, the single atomic instruction on a shared cacheline may be sufficiently performant.
    332327
    333328I have built a prototype of this ready queue in the shape of a data queue, \ie nodes on the queue are structures with a single int representing a thread and intrusive data fields.
    334 Using this prototype I ran preliminary performance experiments that confirm the expected performance in Table~\ref{tab:perfcases}.
     329Using this prototype, I ran preliminary performance experiments that confirm the expected performance in Table~\ref{tab:perfcases}.
    335330However, these experiments only offer a hint at the actual performance of the scheduler since threads form more complex operations than simple integer nodes, \eg threads are not independent of each other, when a thread blocks some other thread must intervene to wake it.
    336331
     
    341336\begin{figure}
    342337        \begin{center}
    343                 \input{system}
     338                \input{system.pstex_t}
    344339        \end{center}
    345340        \caption{Global structure of the \CFA runtime system.}
     
    354349This assumption is made both in the design of the proposed scheduler as well as in the original design of the \CFA runtime system.
    355350As such, the proposed scheduler must honour the correctness of this behaviour but does not have any performance objectives with regard to resizing a cluster.
    356 How long adding or removing processors take and how much this disrupts the performance of other threads is considered a secondary concern since it should be amortized over long period of times.
     351How long adding or removing processors take and how much this disrupts the performance of other threads is considered a secondary concern since it should be amortized over long periods of times.
    357352However, as mentioned in Section~\ref{sec:queue}, contention on the underlying queues can have a direct impact on performance.
    358353The number of underlying queues must therefore be adjusted as the number of processors grows or shrinks.
     
    372367This description effectively matches with the description of a reader-writer lock, infrequent but invasive updates among frequent read operations.
    373368In the case of the ready queue described above, read operations are operations that push or pop from the ready queue but do not invalidate any references to the ready queue data structures.
    374 Writes on the other hand would add or remove inner queues, invalidating references to the array of inner queues in a process.
     369Writes, on the other hand, would add or remove inner queues, invalidating references to the array of inner queues in a process.
    375370Therefore, the current proposed approach to this problem is to add a per-cluster reader-writer lock around the ready queue to prevent restructuring of the ready-queue data-structure while threads are being pushed or popped.
    376371
     
    380375
    381376\paragraph{Objectives and Existing Work}
    382 The lock must offer scalability and performance on par with the actual ready-queue in order not to introduce a new bottleneck.
     377The lock must offer scalability and performance on par with the actual ready queue in order not to introduce a new bottleneck.
    383378I have already built a lock that fits the desired requirements and preliminary testing show scalability and performance that exceed the target.
    384379As such, I do not consider this lock to be a risk for this project.
     
    396391give back unneeded CPU time associated with a process to other user processors executing on the computer,
    397392\item
    398 and reduce energy consumption in cases where more idle kernel-threads translate to idle CPUs, which can cycle down.
     393and reduce energy consumption in cases where more idle kernel-threads translate into idle CPUs, which can cycle down.
    399394\end{enumerate}
    400395Support for idle sleep broadly involves calling the operating system to block the kernel thread and handling the race between a blocking thread and the waking thread, and handling which kernel thread should sleep or wake up.
     
    403398This operation is equivalent to the classic problem of missing signals when using condition variables: the ``sleepy'' processor indicates its intention to block but has not yet gone to sleep when another processor attempts to wake it up.
    404399The waking-up operation sees the blocked process and signals it, but the blocking process is racing to sleep so the signal is missed.
    405 In cases where kernel threads are managed as processors on the current cluster, loosing signals is not necessarily critical, because at least some processors on the cluster are awake and may check for more processors eventually.
     400In cases where kernel threads are managed as processors on the current cluster, losing signals is not necessarily critical, because at least some processors on the cluster are awake and may check for more processors eventually.
    406401Individual processors always finish scheduling user threads before looking for new work, which means that the last processor to go to sleep cannot miss threads scheduled from inside the cluster (if they do, that demonstrates the ready queue is not linearizable).
    407402However, this guarantee does not hold if threads are scheduled from outside the cluster, either due to an external event like timers and I/O, or due to a user (or kernel) thread migrating from a different cluster.
     
    413408
    414409Another important issue is avoiding kernel threads sleeping and waking frequently because there is a significant operating-system cost.
    415 This scenario happens when a program oscillates between high and low activity, needing most and then less processors.
     410This scenario happens when a program oscillates between high and low activity, needing most and then fewer processors.
    416411A possible partial solution is to order the processors so that the one which most recently went to sleep is woken up.
    417412This allows other sleeping processors to reach deeper sleep state (when these are available) while keeping ``hot'' processors warmer.
     
    420415
    421416A final important aspect of idle sleep is when should processors make the decision to sleep and when is it appropriate for sleeping processors to be woken up.
    422 Processors that are unnecessarily unblocked lead to unnecessary contention, CPU usage, and power consumption, while too many sleeping processors can lead to sub-optimal throughput.
    423 Furthermore, transitions from sleeping to awake and vice-versa also add unnecessary latency.
     417Processors that are unnecessarily unblocked lead to unnecessary contention, CPU usage, and power consumption, while too many sleeping processors can lead to suboptimal throughput.
     418Furthermore, transitions from sleeping to awake and vice versa also add unnecessary latency.
    424419There is already a wealth of research on the subject\cite{schillings1996engineering, wiki:thunderherd} and I may use an existing approach for the idle-sleep heuristic in this project, \eg\cite{Karsten20}.
    425420
     
    430425It is preferable to block the user thread performing the I/O and reuse the underlying kernel-thread to run other ready user threads.
    431426This approach requires intercepting user-thread calls to I/O operations, redirecting them to an asynchronous I/O interface, and handling the multiplexing/demultiplexing between the synchronous and asynchronous API.
    432 As such, there are three components needed to implemented support for asynchronous I/O:
     427As such, there are three components needed to implement support for asynchronous I/O:
    433428\begin{enumerate}
    434429\item
     
    446441It is sufficient to make one work in the complex context of the \CFA runtime.
    447442\uC uses the $select$\cite{select} as its interface, which handles ttys, pipes and sockets, but not disk.
    448 $select$ entails significant complexity and is being replaced in UNIX operating-systems, which make it a less interesting alternative.
     443$select$ entails significant complexity and is being replaced in UNIX operating systems, which make it a less interesting alternative.
    449444Another popular interface is $epoll$\cite{epoll}, which is supposed to be cheaper than $select$.
    450 However, $epoll$ also does not handle the file system and anectodal evidence suggest it has problem with linux pipes and $TTY$s.
     445However, $epoll$ also does not handle the file system and anecdotal evidence suggest it has problems with Linux pipes and $TTY$s.
    451446A popular cross-platform alternative is $libuv$\cite{libuv}, which offers asynchronous sockets and asynchronous file system operations (among other features).
    452447However, as a full-featured library it includes much more than I need and could conflict with other features of \CFA unless significant effort is made to merge them together.
    453448A very recent alternative that I am investigating is $io_uring$\cite{io_uring}.
    454 It claims to address some of the issues with $epoll$ and my early investigating suggest that the claim is accurate.
    455 $io_uring$ uses a much more general approach where system calls are register to a queue and later executed by the kernel, rather than relying on system calls to return an error instead of blocking and subsequently waiting for changes on file descriptors.
     449It claims to address some of the issues with $epoll$ and my early investigating suggests that the claim is accurate.
     450$io_uring$ uses a much more general approach where system calls are registered to a queue and later executed by the kernel, rather than relying on system calls to return an error instead of blocking and subsequently waiting for changes on file descriptors.
    456451I believe this approach allows for fewer problems, \eg the manpage for $open$\cite{open} states:
    457452\begin{quote}
    458         Note that [the $O_NONBLOCK$ flag] has no effect for regular files and block devices;
    459         that is, I/O operations will (briefly) block when device activity is required, regardless of whether $O_NONBLOCK$ is set.
    460         Since $O_NONBLOCK$ semantics might eventually be implemented, applications should not depend upon blocking behavior when specifying this flag for regular files and block devices.
     453Note that [the $O_NONBLOCK$ flag] has no effect for regular files and block devices;
     454that is, I/O operations will (briefly) block when device activity is required, regardless of whether $O_NONBLOCK$ is set.
     455Since $O_NONBLOCK$ semantics might eventually be implemented, applications should not depend upon blocking behaviour when specifying this flag for regular files and block devices.
    461456\end{quote}
    462457This makes approach based on $epoll$/$select$ less reliable since they may not work for every file descriptors.
    463 For this reason, I plan to use $io_uring$ as the OS abstraction for the \CFA runtime, unless further work shows problems I haven't encountered yet.
     458For this reason, I plan to use $io_uring$ as the OS abstraction for the \CFA runtime unless further work shows problems I haven't encountered yet.
    464459However, only a small subset of the features are available in Ubuntu as of April 2020\cite{wiki:ubuntu-linux}, which will limit performance comparisons.
    465460I do not believe this will affect the comparison result.
     
    490485\section{Discussion}
    491486I believe that runtime system and scheduling are still open topics.
    492 Many ``state of the art'' production frameworks still use single threaded event-loops because of performance considerations, \eg \cite{nginx-design}, and, to my knowledge, no wideyl available system language offers modern threading facilities.
     487Many ``state of the art'' production frameworks still use single-threaded event loops because of performance considerations, \eg \cite{nginx-design}, and, to my knowledge, no widely available system language offers modern threading facilities.
    493488I believe the proposed work offers a novel runtime and scheduling package, where existing work only offers fragments that users must assemble themselves when possible.
    494489
     
    501496\hline November 2020 & March 2021   & Completion of the implementation. \\
    502497\hline March 2021 & April 2021  & Final Performance experiments. \\
    503 \hline May 2021 & August 2021 & Thesis writing and defense. \\
     498\hline May 2021 & August 2021 & Thesis writing and defence. \\
    504499\hline
    505500\end{tabular}
  • doc/theses/thierry_delisle_PhD/comp_II/img/base.fig

    r56c44dc rce55a81  
    1 #FIG 3.2  Produced by xfig version 3.2.5c
     1#FIG 3.2  Produced by xfig version 3.2.7b
    22Landscape
    33Center
    44Inches
    5 Letter 
     5Letter
    66100.00
    77Single
     
    13131 3 0 1 0 0 50 -1 20 0.000 1 0.0000 6975 4200 20 20 6975 4200 6995 4200
    1414-6
    15 6 2400 2100 3000 2700
    16 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 2400 300 300 2700 2400 3000 2400
    17 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
    18          2400 2475 3000 2475
    19 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 2650 TS\001
    20 -6
    21 6 2400 3000 3000 3600
    22 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 3300 300 300 2700 3300 3000 3300
    23 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
    24          2400 3375 3000 3375
    25 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 3550 TS\001
    26 -6
    27151 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3900 2400 300 300 3900 2400 4200 2400
    28161 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3900 3300 300 300 3900 3300 4200 3300
     
    33211 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6300 3300 300 300 6300 3300 6600 3300
    34221 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4509 3302 300 300 4509 3302 4809 3302
     231 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 3300 300 300 2700 3300 3000 3300
     241 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 2400 300 300 2700 2400 3000 2400
    35252 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
    3626         3000 3900 3000 4500
     
    7363        1 1 1.00 45.00 90.00
    7464         6300 4200 6300 3600
    75 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
     652 1 0 1 -1 7 50 -1 -1 0.000 0 0 -1 1 0 2
    7666        1 1 1.00 45.00 90.00
    7767         2700 4200 2700 3600
     
    8171        1 1 1.00 45.00 90.00
    8272         4500 4200 4500 3600
    83 4 2 0 50 -1 0 12 0.0000 2 180 660 2100 4200 Array of\001
    84 4 2 0 50 -1 0 12 0.0000 2 165 600 2100 4425 Queues\001
    85 4 2 0 50 -1 0 12 0.0000 2 135 645 2100 3075 Threads\001
    86 4 2 0 50 -1 0 12 0.0000 2 180 525 2100 2850 Ready\001
    87 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 4450 TS\001
     732 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
     74         2400 3375 3000 3375
     752 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
     76         2400 2475 3000 2475
     774 2 -1 50 -1 0 12 0.0000 2 135 630 2100 3075 Threads\001
     784 2 -1 50 -1 0 12 0.0000 2 165 450 2100 2850 Ready\001
     794 1 -1 50 -1 0 11 0.0000 2 135 180 2700 4450 TS\001
     804 2 -1 50 -1 0 12 0.0000 2 165 720 2100 4200 Array of\001
     814 2 -1 50 -1 0 12 0.0000 2 150 540 2100 4425 Queues\001
     824 1 -1 50 -1 0 11 0.0000 2 135 180 2700 3550 TS\001
     834 1 -1 50 -1 0 11 0.0000 2 135 180 2700 2650 TS\001
  • doc/theses/thierry_delisle_PhD/comp_II/img/empty.fig

    r56c44dc rce55a81  
    1 #FIG 3.2  Produced by xfig version 3.2.5c
     1#FIG 3.2  Produced by xfig version 3.2.7b
    22Landscape
    33Center
    44Inches
    5 Letter 
     5Letter
    66100.00
    77Single
     
    4141        1 1 1.00 45.00 90.00
    4242         2700 4200 2700 3600
    43 4 2 0 50 -1 0 12 0.0000 2 180 660 2100 4200 Array of\001
    44 4 2 0 50 -1 0 12 0.0000 2 165 600 2100 4425 Queues\001
    45 4 2 0 50 -1 0 12 0.0000 2 135 645 2100 3075 Threads\001
    46 4 2 0 50 -1 0 12 0.0000 2 180 525 2100 2850 Ready\001
     434 2 -1 50 -1 0 12 0.0000 2 165 720 2100 4200 Array of\001
     444 2 -1 50 -1 0 12 0.0000 2 150 540 2100 4425 Queues\001
     454 2 -1 50 -1 0 12 0.0000 2 135 630 2100 3075 Threads\001
     464 2 -1 50 -1 0 12 0.0000 2 165 450 2100 2850 Ready\001
  • doc/theses/thierry_delisle_PhD/comp_II/img/system.fig

    r56c44dc rce55a81  
    33Center
    44Inches
    5 Letter 
     5Letter
    66100.00
    77Single
     
    1651654 1 -1 0 0 0 10 0.0000 2 105 990 2175 3525 Discrete-event\001
    1661664 1 -1 0 0 0 10 0.0000 2 135 795 2175 4350 preemption\001
    167 4 0 -1 0 0 0 10 0.0000 2 150 1290 2325 4875 genrator/coroutine\001
     1674 0 -1 0 0 0 10 0.0000 2 150 1290 2325 4875 generator/coroutine\001
    1681684 0 -1 0 0 0 10 0.0000 2 120 270 4050 4875 task\001
    1691694 0 -1 0 0 0 10 0.0000 2 105 450 7050 4875 cluster\001
  • driver/cfa.cc

    r56c44dc rce55a81  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 20 23:43:59 2020
    13 // Update Count     : 436
     12// Last Modified On : Wed Sep  2 17:59:20 2020
     13// Update Count     : 438
    1414//
    1515
     
    437437                #endif // __x86_64__
    438438                args[nargs++] = "-ldl";
    439                 args[nargs++] = "-lrt";
    440439                args[nargs++] = "-lm";
    441440        } // if
  • libcfa/prelude/Makefile.am

    r56c44dc rce55a81  
    2222cfalibdir = ${CFA_LIBDIR}
    2323cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cfa bootloader.c defines.hfa
     24
     25EXTRA_DIST = bootloader.cf builtins.c builtins.def extras.c extras.regx extras.regx2 prelude-gen.cc prototypes.awk prototypes.c prototypes.sed sync-builtins.cf
    2426
    2527CC = @LOCAL_CFACC@
  • libcfa/src/Makefile.am

    r56c44dc rce55a81  
    3131# AM_CFAFLAGS for only cfa source
    3232# use -no-include-stdhdr to prevent rebuild cycles
    33 # The built sources must not depend on the installed headers
    34 AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
     33# The built sources must not depend on the installed inst_headers_src
     34AM_CFAFLAGS = -quiet -cfalib -I$(srcdir)/stdhdr -I$(srcdir)/concurrency $(if $(findstring ${gdbwaittarget}, ${@}), -XCFA --gdb) @CONFIG_CFAFLAGS@
    3535AM_CFLAGS = -g -Wall -Wno-unused-function -fPIC -fexceptions -pthread @ARCH_FLAGS@ @CONFIG_CFLAGS@
    3636AM_CCASFLAGS = -g -Wall -Wno-unused-function @ARCH_FLAGS@ @CONFIG_CFLAGS@
     
    3939#----------------------------------------------------------------------------------------------------------------
    4040if BUILDLIB
    41 headers_nosrc = bitmanip.hfa exception.hfa math.hfa gmp.hfa time_t.hfa clock.hfa \
    42                 bits/align.hfa bits/containers.hfa bits/defs.hfa bits/debug.hfa bits/locks.hfa \
    43                 containers/list.hfa containers/stackLockFree.hfa concurrency/iofwd.hfa
     41inst_headers_nosrc = \
     42        bitmanip.hfa \
     43        clock.hfa \
     44        exception.hfa \
     45        gmp.hfa \
     46        math.hfa \
     47        time_t.hfa \
     48        bits/align.hfa \
     49        bits/containers.hfa \
     50        bits/debug.hfa \
     51        bits/defs.hfa \
     52        bits/locks.hfa \
     53        concurrency/iofwd.hfa \
     54        containers/list.hfa \
     55        containers/stackLockFree.hfa
    4456
    45 headers = common.hfa fstream.hfa heap.hfa iostream.hfa iterator.hfa limits.hfa rational.hfa \
    46                 time.hfa stdlib.hfa parseargs.hfa \
    47                 containers/maybe.hfa containers/pair.hfa containers/result.hfa containers/vector.hfa
     57inst_headers_src = \
     58        common.hfa \
     59        fstream.hfa \
     60        heap.hfa \
     61        iostream.hfa \
     62        iterator.hfa \
     63        limits.hfa \
     64        parseargs.hfa \
     65        rational.hfa \
     66        stdlib.hfa \
     67        time.hfa \
     68        containers/maybe.hfa \
     69        containers/pair.hfa \
     70        containers/result.hfa \
     71        containers/vector.hfa
    4872
    49 libsrc = startup.cfa interpose.cfa bits/debug.cfa assert.cfa exception.c virtual.c ${headers:.hfa=.cfa}
     73libsrc = ${inst_headers_src} ${inst_headers_src:.hfa=.cfa} \
     74        assert.cfa \
     75        bits/algorithm.hfa \
     76        bits/debug.cfa \
     77        exception.c \
     78        exception.h \
     79        interpose.cfa \
     80        lsda.h \
     81        startup.cfa \
     82        startup.hfa \
     83        virtual.c \
     84        virtual.h
    5085
    5186# not all platforms support concurrency, add option do disable it
    52 thread_headers_nosrc = bits/random.hfa concurrency/invoke.h concurrency/kernel/fwd.hfa
     87inst_thread_headers_nosrc = \
     88        bits/random.hfa \
     89        concurrency/invoke.h \
     90        concurrency/kernel/fwd.hfa
    5391
    54 thread_headers = concurrency/coroutine.hfa concurrency/thread.hfa concurrency/kernel.hfa \
    55                 concurrency/monitor.hfa concurrency/mutex.hfa concurrency/exception.hfa
     92inst_thread_headers_src = \
     93        concurrency/coroutine.hfa \
     94        concurrency/exception.hfa \
     95        concurrency/kernel.hfa \
     96        concurrency/monitor.hfa \
     97        concurrency/mutex.hfa \
     98        concurrency/thread.hfa
    5699
    57 thread_libsrc = concurrency/CtxSwitch-@ARCHITECTURE@.S concurrency/alarm.cfa \
    58                 concurrency/invoke.c concurrency/io.cfa concurrency/iocall.cfa \
    59                 concurrency/io/setup.cfa \
    60                 concurrency/kernel/startup.cfa concurrency/preemption.cfa \
    61                 concurrency/ready_queue.cfa concurrency/stats.cfa \
    62                 ${thread_headers:.hfa=.cfa}
     100thread_libsrc = ${inst_thread_headers_src} ${inst_thread_headers_src:.hfa=.cfa} \
     101        bits/signal.hfa \
     102        concurrency/alarm.cfa \
     103        concurrency/alarm.hfa \
     104        concurrency/CtxSwitch-@ARCHITECTURE@.S \
     105        concurrency/invoke.c \
     106        concurrency/io.cfa \
     107        concurrency/io/setup.cfa \
     108        concurrency/io/types.hfa \
     109        concurrency/iocall.cfa \
     110        concurrency/iofwd.hfa \
     111        concurrency/kernel_private.hfa \
     112        concurrency/kernel/startup.cfa \
     113        concurrency/preemption.cfa \
     114        concurrency/preemption.hfa \
     115        concurrency/ready_queue.cfa \
     116        concurrency/ready_subqueue.hfa \
     117        concurrency/snzi.hfa \
     118        concurrency/stats.cfa \
     119        concurrency/stats.hfa \
     120        concurrency/stats.hfa
     121
    63122else
    64 headers =
    65 thread_headers =
    66 headers_nosrc =
    67 thread_headers_nosrc =
     123inst_headers_src =
     124inst_thread_headers_src =
     125inst_headers_nosrc =
     126inst_thread_headers_nosrc =
    68127libsrc =
    69128endif
     
    115174
    116175#----------------------------------------------------------------------------------------------------------------
    117 libcfa_la_SOURCES = prelude.cfa ${libsrc}
     176libcfa_la_SOURCES = ${libsrc}
     177nodist_libcfa_la_SOURCES = prelude.cfa
    118178libcfa_la_LDFLAGS = -version-info @CFA_VERSION@
    119179
     
    124184
    125185cfa_includedir = $(CFA_INCDIR)
    126 nobase_cfa_include_HEADERS = ${stdhdr} ${headers} ${headers_nosrc} ${thread_headers} ${thread_headers_nosrc}
     186nobase_cfa_include_HEADERS = ${stdhdr} ${inst_headers_src} ${inst_headers_nosrc} ${inst_thread_headers_src} ${inst_thread_headers_nosrc}
     187EXTRA_DIST = stdhdr
    127188
    128189#----------------------------------------------------------------------------------------------------------------
  • libcfa/src/bits/defs.hfa

    r56c44dc rce55a81  
    1010// Created On       : Thu Nov  9 13:24:10 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 13 22:00:23 2020
    13 // Update Count     : 19
     12// Last Modified On : Wed Aug 26 16:22:32 2020
     13// Update Count     : 20
    1414//
    1515
     
    4949
    5050static inline long long int rdtscl(void) {
    51         #if defined( __aarch64__ )
     51        #if defined( __i386 ) || defined( __x86_64 )
     52        unsigned int lo, hi;
     53        __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
     54        return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
     55        #elif defined( __aarch64__ ) || defined( __arm__ )
    5256        // https://github.com/google/benchmark/blob/v1.1.0/src/cycleclock.h#L116
    5357        long long int virtual_timer_value;
     
    5559        return virtual_timer_value;
    5660        #else
    57         unsigned int lo, hi;
    58         __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
    59         return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
     61                #error unsupported hardware architecture
    6062        #endif // __ARM_ARCH
    6163}
  • libcfa/src/bits/locks.hfa

    r56c44dc rce55a81  
    218218        }
    219219
    220         // Semaphore which only supports a single thread and one post
    221         // Semaphore which only supports a single thread
     220        // Synchronozation primitive which only supports a single thread and one post
     221        // Similar to a binary semaphore with a 'one shot' semantic
     222        // is expected to be discarded after each party call their side
    222223        struct oneshot {
     224                // Internal state :
     225                //     0p     : is initial state (wait will block)
     226                //     1p     : fulfilled (wait won't block)
     227                // any thread : a thread is currently waiting
    223228                struct $thread * volatile ptr;
    224229        };
     
    231236                void ^?{}(oneshot & this) {}
    232237
     238                // Wait for the post, return immidiately if it already happened.
     239                // return true if the thread was parked
    233240                bool wait(oneshot & this) {
    234241                        for() {
     
    244251                }
    245252
     253                // Mark as fulfilled, wake thread if needed
     254                // return true if a thread was unparked
    246255                bool post(oneshot & this) {
    247256                        struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
     
    251260                }
    252261        }
     262
     263        // base types for future to build upon
     264        // It is based on the 'oneshot' type to allow multiple futures
     265        // to block on the same instance, permitting users to block a single
     266        // thread on "any of" [a given set of] futures.
     267        // does not support multiple threads waiting on the same future
     268        struct future_t {
     269                // Internal state :
     270                //     0p      : is initial state (wait will block)
     271                //     1p      : fulfilled (wait won't block)
     272                //     2p      : in progress ()
     273                //     3p      : abandoned, server should delete
     274                // any oneshot : a context has been setup to wait, a thread could wait on it
     275                struct oneshot * volatile ptr;
     276        };
     277
     278        static inline {
     279                void  ?{}(future_t & this) {
     280                        this.ptr = 0p;
     281                }
     282
     283                void ^?{}(future_t & this) {}
     284
     285                // check if the future is available
     286                bool available( future_t & this ) {
     287                        return this.ptr == 1p;
     288                }
     289
     290                // Prepare the future to be waited on
     291                // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
     292                bool setup( future_t & this, oneshot & wait_ctx ) {
     293                        /* paranoid */ verify( wait_ctx.ptr == 0p );
     294                        // The future needs to set the wait context
     295                        for() {
     296                                struct oneshot * expected = this.ptr;
     297                                // Is the future already fulfilled?
     298                                if(expected == 1p) return false; // Yes, just return false (didn't block)
     299
     300                                // The future is not fulfilled, try to setup the wait context
     301                                /* paranoid */ verify( expected == 0p );
     302                                if(__atomic_compare_exchange_n(&this.ptr, &expected, &wait_ctx, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     303                                        return true;
     304                                }
     305                        }
     306                }
     307
     308                // Stop waiting on a future
     309                // When multiple futures are waited for together in "any of" pattern
     310                // futures that weren't fulfilled before the thread woke up
     311                // should retract the wait ctx
     312                // intented to be use by wait, wait_any, waitfor, etc. rather than used directly
     313                void retract( future_t & this, oneshot & wait_ctx ) {
     314                        // Remove the wait context
     315                        struct oneshot * got = __atomic_exchange_n( &this.ptr, 0p, __ATOMIC_SEQ_CST);
     316
     317                        // got == 0p: future was never actually setup, just return
     318                        if( got == 0p ) return;
     319
     320                        // got == wait_ctx: since fulfil does an atomic_swap,
     321                        // if we got back the original then no one else saw context
     322                        // It is safe to delete (which could happen after the return)
     323                        if( got == &wait_ctx ) return;
     324
     325                        // got == 1p: the future is ready and the context was fully consumed
     326                        // the server won't use the pointer again
     327                        // It is safe to delete (which could happen after the return)
     328                        if( got == 1p ) return;
     329
     330                        // got == 2p: the future is ready but the context hasn't fully been consumed
     331                        // spin until it is safe to move on
     332                        if( got == 2p ) {
     333                                while( this.ptr != 1p ) Pause();
     334                                return;
     335                        }
     336
     337                        // got == any thing else, something wen't wrong here, abort
     338                        abort("Future in unexpected state");
     339                }
     340
     341                // Mark the future as abandoned, meaning it will be deleted by the server
     342                void abandon( future_t & this ) {
     343                        struct oneshot * got = __atomic_exchange_n( &this.ptr, 3p, __ATOMIC_SEQ_CST);
     344
     345                        // got == 2p: the future is ready but the context hasn't fully been consumed
     346                        // spin until it is safe to move on
     347                        if( got == 2p ) {
     348                                while( this.ptr != 1p ) Pause();
     349                        }
     350                        return;
     351                }
     352
     353                // from the server side, mark the future as fulfilled
     354                // delete it if needed
     355                bool fulfil( future_t & this ) {
     356                        for() {
     357                                struct oneshot * expected = this.ptr;
     358                                // was this abandoned?
     359                                if( expected == 3p ) { free( &this ); return false; }
     360
     361                                /* paranoid */ verify( expected != 1p ); // Future is already fulfilled, should not happen
     362                                /* paranoid */ verify( expected != 2p ); // Future is bein fulfilled by someone else, this is even less supported then the previous case.
     363
     364                                // If there is a wait context, we need to consume it and mark it as consumed after
     365                                // If there is no context then we can skip the in progress phase
     366                                struct oneshot * want = expected == 0p ? 1p : 2p;
     367                                if(__atomic_compare_exchange_n(&this.ptr, &expected, want, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
     368                                        if( expected == 0p ) { /* paranoid */ verify( this.ptr == 1p); return false; }
     369                                        bool ret = post( *expected );
     370                                        __atomic_store_n( &this.ptr, 1p, __ATOMIC_SEQ_CST);
     371                                        return ret;
     372                                }
     373                        }
     374
     375                }
     376
     377                // Wait for the future to be fulfilled
     378                bool wait( future_t & this ) {
     379                        oneshot temp;
     380                        if( !setup(this, temp) ) return false;
     381
     382                        // Wait context is setup, just wait on it
     383                        bool ret = wait( temp );
     384
     385                        // Wait for the future to tru
     386                        while( this.ptr == 2p ) Pause();
     387                        // Make sure the state makes sense
     388                        // Should be fulfilled, could be in progress but it's out of date if so
     389                        // since if that is the case, the oneshot was fulfilled (unparking this thread)
     390                        // and the oneshot should not be needed any more
     391                        __attribute__((unused)) struct oneshot * was = this.ptr;
     392                        /* paranoid */ verifyf( was == 1p, "Expected this.ptr to be 1p, was %p\n", was );
     393
     394                        // Mark the future as fulfilled, to be consistent
     395                        // with potential calls to avail
     396                        // this.ptr = 1p;
     397                        return ret;
     398                }
     399        }
    253400#endif
  • libcfa/src/concurrency/CtxSwitch-arm64.S

    r56c44dc rce55a81  
    22// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    33//
    4 // CtxSwitch-arm.S --
     4// CtxSwitch-arm64.S --
    55//
    66// Author           : Peter A. Buhr
    77// Created On       : Sun Aug 16 07:50:13 2020
    88// Last Modified By : Peter A. Buhr
    9 // Last Modified On : Thu Aug 20 18:43:51 2020
    10 // Update Count     : 24
     9// Last Modified On : Wed Aug 26 16:24:59 2020
     10// Update Count     : 25
    1111//
    1212
     
    2626#define SAVE            20 * 8
    2727
    28         .file "CtxSwitch-arm.S"
     28        .file "CtxSwitch-arm64.S"
    2929        .text
    3030        .align 2
    3131        .global __cfactx_switch
    32         .type __cfactx_switch, @function
     32        .type __cfactx_switch, %function
    3333__cfactx_switch:
    3434
     
    9191        .align 2
    9292        .global __cfactx_invoke_stub
    93         .type __cfactx_invoke_stub, @function
     93        .type __cfactx_invoke_stub, %function
    9494__cfactx_invoke_stub:
    9595        mov x0, x19                                                     // load main as parameter 0
  • libcfa/src/concurrency/kernel.cfa

    r56c44dc rce55a81  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 14 15:23:00 2020
    13 // Update Count     : 69
     12// Last Modified On : Mon Aug 31 07:08:20 2020
     13// Update Count     : 71
    1414//
    1515
     
    7474                )
    7575
    76 #elif defined( __ARM_ARCH )
     76#elif defined( __arm__ )
     77        #define __x87_store
     78        #define __x87_load
     79
     80#elif defined( __aarch64__ )
    7781        #define __x87_store              \
    7882                uint32_t __fpcntl[2];    \
     
    9397
    9498#else
    95         #error unknown hardware architecture
     99        #error unsupported hardware architecture
    96100#endif
    97101
  • libcfa/src/concurrency/preemption.cfa

    r56c44dc rce55a81  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 21 13:45:32 2020
    13 // Update Count     : 52
     12// Last Modified On : Wed Aug 26 16:46:03 2020
     13// Update Count     : 53
    1414//
    1515
     
    5656#elif defined( __x86_64 )
    5757#define CFA_REG_IP gregs[REG_RIP]
    58 #elif defined( __ARM_ARCH )
     58#elif defined( __arm__ )
     59#define CFA_REG_IP arm_pc
     60#elif defined( __aarch64__ )
    5961#define CFA_REG_IP pc
    6062#else
    61 #error unknown hardware architecture
     63#error unsupported hardware architecture
    6264#endif
    6365
  • libcfa/src/exception.c

    r56c44dc rce55a81  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 21 11:27:56 2020
    13 // Update Count     : 29
     12// Last Modified On : Sat Aug 29 15:52:22 2020
     13// Update Count     : 34
    1414//
    1515
     
    1818
    1919#include "exception.h"
    20 
    21 // Implementation of the secret header is hardware dependent.
    22 #if defined( __x86_64 ) || defined( __i386 )
    23 #elif defined( __ARM_ARCH )
    24 #warning FIX ME: check if anything needed for ARM
    25 #else
    26 #warning Exception Handling: No known architecture detected.
    27 #endif
    2820
    2921#include <stdlib.h>
     
    3426#include "stdhdr/assert.h"
    3527
    36 // FIX ME: temporary hack to keep ARM build working
     28#if defined( __ARM_ARCH )
     29#warning FIX ME: temporary hack to keep ARM build working
    3730#ifndef _URC_FATAL_PHASE1_ERROR
    3831#define _URC_FATAL_PHASE1_ERROR 3
     
    4134#define _URC_FATAL_PHASE2_ERROR 2
    4235#endif // ! _URC_FATAL_PHASE2_ERROR
     36#endif // __ARM_ARCH
    4337
    4438#include "lsda.h"
     
    626620
    627621#pragma GCC pop_options
     622
     623#elif defined( __ARM_ARCH )
     624_Unwind_Reason_Code __gcfa_personality_v0(
     625                int version,
     626                _Unwind_Action actions,
     627                unsigned long long exception_class,
     628                struct _Unwind_Exception * unwind_exception,
     629                struct _Unwind_Context * unwind_context) {
     630        return _URC_CONTINUE_UNWIND;
     631}
     632
     633__attribute__((noinline))
     634void __cfaehm_try_terminate(void (*try_block)(),
     635                void (*catch_block)(int index, exception_t * except),
     636                __attribute__((unused)) int (*match_block)(exception_t * except)) {
     637}
     638#else
     639        #error unsupported hardware architecture
    628640#endif // __x86_64 || __i386
  • libcfa/src/heap.cfa

    r56c44dc rce55a81  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 24 20:29:24 2020
    13 // Update Count     : 926
     12// Last Modified On : Thu Sep  3 16:22:54 2020
     13// Update Count     : 943
    1414//
    1515
     
    2929#include "math.hfa"                                                                             // ceiling
    3030#include "bitmanip.hfa"                                                                 // is_pow2, ceiling2
    31 
    32 #define MIN(x, y) (y > x ? x : y)
    3331
    3432static bool traceHeap = false;
     
    956954
    957955                headers( "realloc", naddr, header, freeElem, bsize, oalign );
    958                 memcpy( naddr, oaddr, MIN( osize, size ) );             // copy bytes
     956                memcpy( naddr, oaddr, min( osize, size ) );             // copy bytes
    959957                free( oaddr );
    960958
     
    12181216        #endif // __STATISTICS__
    12191217
    1220         // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    1221   if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    1222   if ( unlikely( oaddr == 0p ) ) {
    1223                 #ifdef __STATISTICS__
    1224                 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    1225                 #endif // __STATISTICS__
    1226                 return memalignNoStats( nalign, size );
    1227         } // if
    1228 
    12291218        if ( unlikely( nalign < libAlign() ) ) nalign = libAlign(); // reset alignment to minimum
    12301219        #ifdef __CFA_DEBUG__
     
    12331222        #endif // __CFA_DEBUG__
    12341223
    1235         HeapManager.Storage.Header * header;
    1236         HeapManager.FreeHeader * freeElem;
    1237         size_t bsize, oalign;
    1238         headers( "resize", oaddr, header, freeElem, bsize, oalign );
    1239         size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    1240 
    1241         if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1242                 if ( oalign > libAlign() ) {                                    // fake header ?
     1224        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1225  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
     1226  if ( unlikely( oaddr == 0p ) ) {
     1227                #ifdef __STATISTICS__
     1228                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
     1229                #endif // __STATISTICS__
     1230                return memalignNoStats( nalign, size );
     1231        } // if
     1232
     1233        // Attempt to reuse existing storage.
     1234        HeapManager.Storage.Header * header = headerAddr( oaddr );
     1235        if ( unlikely ( ( header->kind.fake.alignment & 1 == 1 &&       // old fake header ?
     1236                                 (uintptr_t)oaddr % nalign == 0 &&                              // lucky match ?
     1237                                 header->kind.fake.alignment <= nalign &&               // ok to leave LSB at 1
     1238                                 nalign <= 128 )                                                                // not too much alignment storage wasted ?
     1239                        ||   ( header->kind.fake.alignment & 1 != 1 &&          // old real header ( aligned on libAlign ) ?
     1240                                 nalign == libAlign() ) ) ) {                                   // new alignment also on libAlign
     1241
     1242                HeapManager.FreeHeader * freeElem;
     1243                size_t bsize, oalign;
     1244                headers( "resize", oaddr, header, freeElem, bsize, oalign );
     1245                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
     1246
     1247                if ( size <= odsize && odsize <= size * 2 ) { // allow 50% wasted data storage
    12431248                        headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1244                 } // if
    1245                 if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    1246                         header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1247                         header->kind.real.size = size;                          // reset allocation size
     1249
     1250                        header->kind.real.blockSize &= -2;              // turn off 0 fill
     1251                        header->kind.real.size = size;                  // reset allocation size
    12481252                        return oaddr;
    12491253                } // if
     
    12671271        #endif // __CFA_DEBUG__
    12681272
     1273        // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
     1274  if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
     1275  if ( unlikely( oaddr == 0p ) ) {
     1276                #ifdef __STATISTICS__
     1277                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     1278                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     1279                #endif // __STATISTICS__
     1280                return memalignNoStats( nalign, size );
     1281        } // if
     1282
    12691283        HeapManager.Storage.Header * header;
    12701284        HeapManager.FreeHeader * freeElem;
     
    12721286        headers( "realloc", oaddr, header, freeElem, bsize, oalign );
    12731287
    1274         if ( oalign <= nalign && (uintptr_t)oaddr % nalign == 0 ) { // <= alignment and new alignment happens to match
    1275                 if ( oalign > libAlign() ) {                                    // fake header ?
    1276                         headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    1277                 } // if
     1288        // Attempt to reuse existing storage.
     1289        if ( unlikely ( ( header->kind.fake.alignment & 1 == 1 &&       // old fake header ?
     1290                                 (uintptr_t)oaddr % nalign == 0 &&                              // lucky match ?
     1291                                 header->kind.fake.alignment <= nalign &&               // ok to leave LSB at 1
     1292                                 nalign <= 128 )                                                                // not too much alignment storage wasted ?
     1293                        ||   ( header->kind.fake.alignment & 1 != 1 &&          // old real header ( aligned on libAlign ) ?
     1294                                 nalign == libAlign() ) ) ) {                                   // new alignment also on libAlign
     1295
     1296                headerAddr( oaddr )->kind.fake.alignment = nalign | 1; // update alignment (could be the same)
    12781297                return realloc( oaddr, size );
     1298
    12791299        } // if
    12801300
     
    12861306        #endif // __STATISTICS__
    12871307
    1288         // If size is equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
    1289   if ( unlikely( size == 0 ) ) { free( oaddr ); return 0p; } // special cases
    1290   if ( unlikely( oaddr == 0p ) ) return memalignNoStats( nalign, size );
    1291 
    12921308        size_t osize = header->kind.real.size;                          // old allocation size
    12931309        bool ozfill = (header->kind.real.blockSize & 2) != 0; // old allocation zero filled
     
    12961312
    12971313        headers( "realloc", naddr, header, freeElem, bsize, oalign );
    1298         memcpy( naddr, oaddr, MIN( osize, size ) );                     // copy bytes
     1314        memcpy( naddr, oaddr, min( osize, size ) );                     // copy bytes
    12991315        free( oaddr );
    13001316
  • libcfa/src/stdlib.hfa

    r56c44dc rce55a81  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 14 23:38:50 2020
    13 // Update Count     : 504
     12// Last Modified On : Tue Sep  1 20:32:34 2020
     13// Update Count     : 505
    1414//
    1515
     
    4444
    4545// Macro because of returns
    46 #define $VAR_ALLOC( allocation, alignment ) \
    47         if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( (size_t)sizeof(T) ); /* C allocation */ \
    48         else return (T *)alignment( _Alignof(T), sizeof(T) )
    49 
    5046#define $ARRAY_ALLOC( allocation, alignment, dim ) \
    5147        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( dim, (size_t)sizeof(T) ); /* C allocation */ \
    5248        else return (T *)alignment( _Alignof(T), dim, sizeof(T) )
    5349
    54 #define $RE_SPECIALS( ptr, size, allocation, alignment ) \
    55         if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { \
    56                 if ( unlikely( size == 0 ) ) free( ptr ); \
    57                 $VAR_ALLOC( malloc, memalign ); \
    58         } /* if */
    59 
    6050static inline forall( dtype T | sized(T) ) {
    6151        // Cforall safe equivalents, i.e., implicit size specification
    6252
    6353        T * malloc( void ) {
    64                 $VAR_ALLOC( malloc, memalign );
     54                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation
     55                else return (T *)memalign( _Alignof(T), sizeof(T) );
    6556        } // malloc
    6657
     
    7465
    7566        T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
    76                 $RE_SPECIALS( ptr, size, malloc, memalign );
    7767                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
    7868                else return (T *)(void *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
     
    8070
    8171        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    82                 $RE_SPECIALS( ptr, size, malloc, memalign );
    8372                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    8473                else return (T *)(void *)realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc
     
    189178                size_t copy_end = 0;
    190179
    191                 if(Resize) {
    192                         ptr = (T*) (void *) resize( (int *)Resize, Align, Dim * size );
    193                 } else if (Realloc) {
     180                if ( Resize ) {
     181                        ptr = (T*) (void *) resize( (void *)Resize, Align, Dim * size );
     182                } else if ( Realloc ) {
    194183                        if (Fill.tag != '0') copy_end = min(malloc_size( Realloc ), Dim * size);
    195                         ptr = (T*) (void *) realloc( (int *)Realloc, Align, Dim * size );
     184                        ptr = (T*) (void *) realloc( (void *)Realloc, Align, Dim * size );
    196185                } else {
    197186                        ptr = (T*) (void *) memalign( Align, Dim * size );
     
    201190                        memset( (char *)ptr + copy_end, (int)Fill.c, Dim * size - copy_end );
    202191                } else if(Fill.tag == 't') {
    203                         for ( int i = copy_end; i <= Dim * size - size ; i += size ) {
     192                        for ( int i = copy_end; i < Dim * size; i += size ) {
    204193                                memcpy( (char *)ptr + i, &Fill.t, size );
    205194                        }
     
    207196                        memcpy( (char *)ptr + copy_end, Fill.at, min(Dim * size - copy_end, Fill.size) );
    208197                } else if(Fill.tag == 'T') {
    209                         for ( int i = copy_end; i <= Dim * size - size ; i += size ) {
     198                        for ( int i = copy_end; i < Dim * size; i += size ) {
    210199                                memcpy( (char *)ptr + i, Fill.at, size );
    211200                        }
  • src/AST/Convert.cpp

    r56c44dc rce55a81  
    705705                        new KeywordCastExpr(
    706706                                get<Expression>().accept1(node->arg),
    707                                 castTarget
     707                                castTarget,
     708                                {node->concrete_target.field, node->concrete_target.getter}
    708709                        )
    709710                );
     
    20872088                                old->location,
    20882089                                GET_ACCEPT_1(arg, Expr),
    2089                                 castTarget
     2090                                castTarget,
     2091                                {old->concrete_target.field, old->concrete_target.getter}
    20902092                        )
    20912093                );
  • src/AST/Copy.hpp

    r56c44dc rce55a81  
    2121#include "Stmt.hpp"
    2222#include "Type.hpp"
     23#include <unordered_set>
     24#include <unordered_map>
    2325
    2426namespace ast {
  • src/AST/Expr.hpp

    r56c44dc rce55a81  
    312312public:
    313313        ptr<Expr> arg;
     314        struct Concrete {
     315                std::string field;
     316                std::string getter;
     317
     318                Concrete() = default;
     319                Concrete(const Concrete &) = default;
     320        };
    314321        ast::AggregateDecl::Aggregate target;
     322        Concrete concrete_target;
     323
    315324
    316325        KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t )
    317326        : Expr( loc ), arg( a ), target( t ) {}
     327
     328        KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t, const Concrete & ct )
     329        : Expr( loc ), arg( a ), target( t ), concrete_target( ct ) {}
    318330
    319331        /// Get a name for the target type
  • src/AST/Pass.hpp

    r56c44dc rce55a81  
    4848//
    4949// Several additional features are available through inheritance
     50// | PureVisitor           - makes the visitor pure, it never modifies nodes in place and always
     51//                           clones nodes it needs to make changes to
    5052// | WithTypeSubstitution  - provides polymorphic const TypeSubstitution * env for the
    5153//                           current expression
     
    266268
    267269/// Keep track of the polymorphic const TypeSubstitution * env for the current expression
     270
     271/// If used the visitor will always clone nodes.
     272struct PureVisitor {};
     273
    268274struct WithConstTypeSubstitution {
    269275        const TypeSubstitution * env = nullptr;
  • src/AST/Pass.impl.hpp

    r56c44dc rce55a81  
    5757
    5858namespace ast {
     59        template<typename node_t>
     60        node_t * shallowCopy( const node_t * node );
     61
    5962        namespace __pass {
    6063                // Check if this is either a null pointer or a pointer to an empty container
     
    6265                static inline bool empty( T * ptr ) {
    6366                        return !ptr || ptr->empty();
     67                }
     68
     69                template< typename core_t, typename node_t >
     70                static inline node_t* mutate(const node_t *node) {
     71                        return std::is_base_of<PureVisitor, core_t>::value ? ::ast::shallowCopy(node) : ::ast::mutate(node);
    6472                }
    6573
     
    320328
    321329                if( __pass::differs(old_val, new_val) ) {
    322                         auto new_parent = mutate(parent);
     330                        auto new_parent = __pass::mutate<core_t>(parent);
    323331                        new_parent->*child = new_val;
    324332                        parent = new_parent;
     
    334342                        if ( node->forall.empty() ) return;
    335343
    336                         node_t * mut = mutate( node );
     344                        node_t * mut = __pass::mutate<core_t>( node );
    337345                        mut->forall = subs->clone( node->forall, *this );
    338346                        node = mut;
     
    894902
    895903                if(mutated) {
    896                         auto n = mutate(node);
     904                        auto n = __pass::mutate<core_t>(node);
    897905                        n->clauses = std::move( new_clauses );
    898906                        node = n;
     
    904912                        auto nval = call_accept( node->field ); \
    905913                        if(nval != node->field ) { \
    906                                 auto nparent = mutate(node); \
     914                                auto nparent = __pass::mutate<core_t>(node); \
    907915                                nparent->field = nval; \
    908916                                node = nparent; \
     
    16101618
    16111619                if(mutated) {
    1612                         auto n = mutate(node);
     1620                        auto n = __pass::mutate<core_t>(node);
    16131621                        n->associations = std::move( new_kids );
    16141622                        node = n;
     
    19401948                        }
    19411949                        if (mutated) {
    1942                                 auto new_node = mutate( node );
     1950                                auto new_node = __pass::mutate<core_t>( node );
    19431951                                new_node->typeEnv.swap( new_map );
    19441952                                node = new_node;
     
    19561964                        }
    19571965                        if (mutated) {
    1958                                 auto new_node = mutate( node );
     1966                                auto new_node = __pass::mutate<core_t>( node );
    19591967                                new_node->varEnv.swap( new_map );
    19601968                                node = new_node;
  • src/AST/Pass.proto.hpp

    r56c44dc rce55a81  
    2222template<typename core_t>
    2323class Pass;
     24
     25struct PureVisitor;
    2426
    2527namespace __pass {
  • src/AST/Print.cpp

    r56c44dc rce55a81  
    2121#include "Type.hpp"
    2222#include "TypeSubstitution.hpp"
     23#include "CompilationState.h"
    2324
    2425#include "Common/utility.h" // for group_iterate
     
    239240
    240241                if ( node->result ) {
    241                         os << endl << indent << "... with resolved type:" << endl;
    242                         ++indent;
    243                         os << indent;
    244                         node->result->accept( *this );
    245                         --indent;
     242                        if (!deterministic_output) {
     243                                os << endl << indent << "... with resolved type:" << endl;
     244                                ++indent;
     245                                os << indent;
     246                                node->result->accept( *this );
     247                                --indent;
     248                        }
    246249                }
    247250
  • src/AST/TypeSubstitution.hpp

    r56c44dc rce55a81  
    4646        template< typename SynTreeClass >
    4747        struct ApplyResult {
    48                 // const SynTreeClass * node;
    4948                ast::ptr<SynTreeClass> node;
    5049                int count;
     
    159158
    160159// definitition must happen after PassVisitor is included so that WithGuards can be used
    161 struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
     160struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter>, public PureVisitor {
    162161                static size_t traceId;
    163162
     
    187186        assert( input );
    188187        Pass<Substituter> sub( *this, false );
    189         input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) );
     188        input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
    190189        return { input, sub.core.subCount };
    191190}
     
    195194        assert( input );
    196195        Pass<Substituter> sub( *this, true );
    197         input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) );
     196        input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) );
    198197        return { input, sub.core.subCount };
    199198}
  • src/AST/module.mk

    r56c44dc rce55a81  
    1717SRC_AST = \
    1818        AST/AssertAcyclic.cpp \
     19        AST/AssertAcyclic.hpp \
    1920        AST/Attribute.cpp \
     21        AST/Attribute.hpp \
     22        AST/Bitfield.hpp \
     23        AST/Chain.hpp \
    2024        AST/Convert.cpp \
     25        AST/Convert.hpp \
     26        AST/Copy.hpp \
     27        AST/CVQualifiers.hpp \
    2128        AST/Decl.cpp \
     29        AST/Decl.hpp \
    2230        AST/DeclReplacer.cpp \
     31        AST/DeclReplacer.hpp \
     32        AST/Eval.hpp \
    2333        AST/Expr.cpp \
     34        AST/Expr.hpp \
    2435        AST/ForallSubstitutionTable.cpp \
     36        AST/ForallSubstitutionTable.hpp \
     37        AST/ForallSubstitutor.hpp \
     38        AST/FunctionSpec.hpp \
     39        AST/Fwd.hpp \
    2540        AST/GenericSubstitution.cpp \
     41        AST/GenericSubstitution.hpp \
    2642        AST/Init.cpp \
     43        AST/Init.hpp \
     44        AST/Label.hpp \
    2745        AST/LinkageSpec.cpp \
     46        AST/LinkageSpec.hpp \
    2847        AST/Node.cpp \
     48        AST/Node.hpp \
     49        AST/ParseNode.hpp \
    2950        AST/Pass.cpp \
     51        AST/Pass.hpp \
     52        AST/Pass.impl.hpp \
     53        AST/Pass.proto.hpp \
    3054        AST/Print.cpp \
     55        AST/Print.hpp \
    3156        AST/Stmt.cpp \
     57        AST/Stmt.hpp \
     58        AST/StorageClasses.hpp \
    3259        AST/SymbolTable.cpp \
     60        AST/SymbolTable.hpp \
    3361        AST/Type.cpp \
     62        AST/Type.hpp \
    3463        AST/TypeEnvironment.cpp \
    35         AST/TypeSubstitution.cpp
     64        AST/TypeEnvironment.hpp \
     65        AST/TypeSubstitution.cpp \
     66        AST/TypeSubstitution.hpp \
     67        AST/Visitor.hpp
    3668
    3769SRC += $(SRC_AST)
  • src/CodeGen/module.mk

    r56c44dc rce55a81  
    2020SRC_CODEGEN = \
    2121        CodeGen/CodeGenerator.cc \
     22        CodeGen/CodeGenerator.h \
    2223        CodeGen/FixMain.cc \
     24        CodeGen/FixMain.h \
    2325        CodeGen/GenType.cc \
    24         CodeGen/OperatorTable.cc
     26        CodeGen/GenType.h \
     27        CodeGen/OperatorTable.cc \
     28        CodeGen/OperatorTable.h \
     29        CodeGen/Options.h
    2530
    26 SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc
     31SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/Generate.h CodeGen/FixNames.cc CodeGen/FixNames.h
    2732SRCDEMANGLE += $(SRC_CODEGEN)
  • src/CodeTools/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += CodeTools/DeclStats.cc \
     17SRC += \
     18        CodeTools/DeclStats.cc \
     19        CodeTools/DeclStats.h \
    1820        CodeTools/ResolvProtoDump.cc \
    19         CodeTools/TrackLoc.cc
     21        CodeTools/ResolvProtoDump.h \
     22        CodeTools/TrackLoc.cc \
     23        CodeTools/TrackLoc.h
  • src/Common/module.mk

    r56c44dc rce55a81  
    1717SRC_COMMON = \
    1818      Common/Assert.cc \
     19      Common/CodeLocation.h \
     20      Common/CompilerError.h \
     21      Common/Debug.h \
     22      Common/ErrorObjects.h \
    1923      Common/Eval.cc \
     24      Common/FilterCombos.h \
     25      Common/Indenter.h \
    2026      Common/PassVisitor.cc \
     27      Common/PassVisitor.h \
     28      Common/PassVisitor.impl.h \
     29      Common/PassVisitor.proto.h \
     30      Common/PersistentMap.h \
     31      Common/ScopedMap.h \
    2132      Common/SemanticError.cc \
     33      Common/SemanticError.h \
     34      Common/Stats.h \
     35      Common/Stats/Base.h \
    2236      Common/Stats/Counter.cc \
     37      Common/Stats/Counter.h \
    2338      Common/Stats/Heap.cc \
     39      Common/Stats/Heap.h \
    2440      Common/Stats/Stats.cc \
    2541      Common/Stats/Time.cc \
    26       Common/UniqueName.cc
     42      Common/Stats/Time.h \
     43      Common/UnimplementedError.h \
     44      Common/UniqueName.cc \
     45      Common/UniqueName.h \
     46      Common/utility.h \
     47      Common/VectorMap.h
    2748
    2849SRC += $(SRC_COMMON) Common/DebugMalloc.cc
  • src/Concurrency/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += Concurrency/Keywords.cc Concurrency/Waitfor.cc
     17SRC += Concurrency/Keywords.cc Concurrency/Keywords.h Concurrency/Waitfor.cc Concurrency/Waitfor.h
    1818SRCDEMANGLE += Concurrency/Keywords.cc
    1919
  • src/ControlStruct/module.mk

    r56c44dc rce55a81  
    1717SRC_CONTROLSTRUCT = \
    1818        ControlStruct/ForExprMutator.cc \
     19        ControlStruct/ForExprMutator.h \
    1920        ControlStruct/LabelFixer.cc \
     21        ControlStruct/LabelFixer.h \
    2022        ControlStruct/LabelGenerator.cc \
     23        ControlStruct/LabelGenerator.h \
    2124        ControlStruct/MLEMutator.cc \
    22         ControlStruct/Mutate.cc
     25        ControlStruct/MLEMutator.h \
     26        ControlStruct/Mutate.cc \
     27        ControlStruct/Mutate.h
    2328
    24 SRC += $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc
     29SRC += $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc ControlStruct/ExceptTranslate.h
    2530SRCDEMANGLE += $(SRC_CONTROLSTRUCT)
    2631
  • src/GenPoly/module.mk

    r56c44dc rce55a81  
    1616
    1717SRC += GenPoly/Box.cc \
     18       GenPoly/Box.h \
     19       GenPoly/ErasableScopedMap.h \
     20       GenPoly/FindFunction.cc \
     21       GenPoly/FindFunction.h \
    1822       GenPoly/GenPoly.cc \
     23       GenPoly/GenPoly.h \
     24       GenPoly/InstantiateGeneric.cc \
     25       GenPoly/InstantiateGeneric.h \
     26       GenPoly/Lvalue.cc \
     27       GenPoly/Lvalue.h \
     28       GenPoly/ScopedSet.h \
    1929       GenPoly/ScrubTyVars.cc \
    20        GenPoly/Lvalue.cc \
     30       GenPoly/ScrubTyVars.h \
    2131       GenPoly/Specialize.cc \
    22        GenPoly/FindFunction.cc \
    23        GenPoly/InstantiateGeneric.cc
     32       GenPoly/Specialize.h
    2433
    25 SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc
     34SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/GenPoly.h GenPoly/Lvalue.cc GenPoly/Lvalue.h
    2635
  • src/InitTweak/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += InitTweak/GenInit.cc \
     17SRC += \
     18        InitTweak/FixGlobalInit.cc \
     19        InitTweak/FixGlobalInit.h \
    1820        InitTweak/FixInit.cc \
    19         InitTweak/FixGlobalInit.cc \
    20         InitTweak/InitTweak.cc
     21        InitTweak/FixInit.h \
     22        InitTweak/GenInit.cc \
     23        InitTweak/GenInit.h \
     24        InitTweak/InitTweak.cc \
     25        InitTweak/InitTweak.h
    2126
    22 SRCDEMANGLE += InitTweak/GenInit.cc \
    23         InitTweak/InitTweak.cc
     27SRCDEMANGLE += \
     28        InitTweak/GenInit.cc \
     29        InitTweak/GenInit.h \
     30        InitTweak/InitTweak.cc \
     31        InitTweak/InitTweak.h
    2432
  • src/Makefile.am

    r56c44dc rce55a81  
    2020
    2121SRC = main.cc \
     22      CompilationState.cc \
     23      CompilationState.h \
    2224      MakeLibCfa.cc \
    23       CompilationState.cc
     25        MakeLibCfa.h
    2426
    2527SRCDEMANGLE = CompilationState.cc
     
    6668___driver_cfa_cpp_SOURCES = $(SRC)
    6769___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
     70EXTRA_DIST = include/cassert include/optional BasicTypes-gen.cc
    6871
    6972AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG)
  • src/Parser/module.mk

    r56c44dc rce55a81  
    2323       Parser/ExpressionNode.cc \
    2424       Parser/InitializerNode.cc \
     25       Parser/lex.ll \
    2526       Parser/ParseNode.cc \
     27       Parser/ParseNode.h \
     28       Parser/parser.yy \
     29       Parser/ParserTypes.h \
     30       Parser/parserutility.cc \
     31       Parser/parserutility.h \
    2632       Parser/StatementNode.cc \
    2733       Parser/TypeData.cc \
     34       Parser/TypeData.h \
    2835       Parser/TypedefTable.cc \
    29        Parser/lex.ll \
    30        Parser/parser.yy \
    31        Parser/parserutility.cc
     36       Parser/TypedefTable.h
    3237
    3338MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
  • src/ResolvExpr/CandidateFinder.cpp

    r56c44dc rce55a81  
    10891089                }
    10901090
     1091                void postvisit( const ast::KeywordCastExpr * castExpr ) {
     1092                        const auto & loc = castExpr->location;
     1093                        assertf( castExpr->result, "Cast target should have been set in Validate." );
     1094                        auto ref = castExpr->result.strict_as<ast::ReferenceType>();
     1095                        auto inst = ref->base.strict_as<ast::StructInstType>();
     1096                        auto target = inst->base.get();
     1097
     1098                        CandidateFinder finder{ symtab, tenv };
     1099
     1100                        auto pick_alternatives = [target, this](CandidateList & found, bool expect_ref) {
     1101                                for(auto & cand : found) {
     1102                                        const ast::Type * expr = cand->expr->result.get();
     1103                                        if(expect_ref) {
     1104                                                auto res = dynamic_cast<const ast::ReferenceType*>(expr);
     1105                                                if(!res) { continue; }
     1106                                                expr = res->base.get();
     1107                                        }
     1108
     1109                                        if(auto insttype = dynamic_cast<const ast::TypeInstType*>(expr)) {
     1110                                                auto td = cand->env.lookup(insttype->name);
     1111                                                if(!td) { continue; }
     1112                                                expr = td->bound.get();
     1113                                        }
     1114
     1115                                        if(auto base = dynamic_cast<const ast::StructInstType*>(expr)) {
     1116                                                if(base->base == target) {
     1117                                                        candidates.push_back( std::move(cand) );
     1118                                                        reason.code = NoReason;
     1119                                                }
     1120                                        }
     1121                                }
     1122                        };
     1123
     1124                        try {
     1125                                // Attempt 1 : turn (thread&)X into ($thread&)X.__thrd
     1126                                // Clone is purely for memory management
     1127                                std::unique_ptr<const ast::Expr> tech1 { new ast::UntypedMemberExpr(loc, new ast::NameExpr(loc, castExpr->concrete_target.field), castExpr->arg) };
     1128
     1129                                // don't prune here, since it's guaranteed all alternatives will have the same type
     1130                                finder.find( tech1.get(), ResolvMode::withoutPrune() );
     1131                                pick_alternatives(finder.candidates, false);
     1132
     1133                                return;
     1134                        } catch(SemanticErrorException & ) {}
     1135
     1136                        // Fallback : turn (thread&)X into ($thread&)get_thread(X)
     1137                        std::unique_ptr<const ast::Expr> fallback { ast::UntypedExpr::createDeref(loc,  new ast::UntypedExpr(loc, new ast::NameExpr(loc, castExpr->concrete_target.getter), { castExpr->arg })) };
     1138                        // don't prune here, since it's guaranteed all alternatives will have the same type
     1139                        finder.find( fallback.get(), ResolvMode::withoutPrune() );
     1140
     1141                        pick_alternatives(finder.candidates, true);
     1142
     1143                        // Whatever happens here, we have no more fallbacks
     1144                }
     1145
    10911146                void postvisit( const ast::UntypedMemberExpr * memberExpr ) {
    10921147                        CandidateFinder aggFinder{ symtab, tenv };
  • src/ResolvExpr/Unify.cc

    r56c44dc rce55a81  
    767767                /// If this isn't done when satifying ttype assertions, then argument lists can have
    768768                /// different size and structure when they should be compatible.
    769                 struct TtypeExpander_new : public ast::WithShortCircuiting {
     769                struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor {
    770770                        ast::TypeEnvironment & tenv;
    771771
     
    793793                                // TtypeExpander pass is impure (may mutate nodes in place)
    794794                                // need to make nodes shared to prevent accidental mutation
    795                                 ast::ptr<ast::DeclWithType> dc = d;
    796                                 dc = dc->accept( expander );
     795                                ast::ptr<ast::DeclWithType> dc = d->accept(expander);
    797796                                auto types = flatten( dc->get_type() );
    798797                                for ( ast::ptr< ast::Type > & t : types ) {
     
    11141113                        ast::Pass<TtypeExpander_new> expander{ tenv };
    11151114
    1116                         ast::ptr<ast::TupleType> tuplec = tuple;
    1117                         ast::ptr<ast::TupleType> tuple2c = tuple2;
    1118                         const ast::Type * flat = tuplec->accept( expander );
    1119                         const ast::Type * flat2 = tuple2c->accept( expander );
     1115                        const ast::Type * flat = tuple->accept( expander );
     1116                        const ast::Type * flat2 = tuple2->accept( expander );
    11201117
    11211118                        auto types = flatten( flat );
  • src/ResolvExpr/module.mk

    r56c44dc rce55a81  
    1919      ResolvExpr/Alternative.cc \
    2020      ResolvExpr/AlternativeFinder.cc \
     21      ResolvExpr/AlternativeFinder.h \
     22      ResolvExpr/Alternative.h \
    2123      ResolvExpr/Candidate.cpp \
    2224      ResolvExpr/CandidateFinder.cpp \
     25      ResolvExpr/CandidateFinder.hpp \
     26      ResolvExpr/Candidate.hpp \
    2327      ResolvExpr/CastCost.cc \
    2428      ResolvExpr/CommonType.cc \
    2529      ResolvExpr/ConversionCost.cc \
     30      ResolvExpr/ConversionCost.h \
     31      ResolvExpr/Cost.h \
    2632      ResolvExpr/CurrentObject.cc \
     33      ResolvExpr/CurrentObject.h \
    2734      ResolvExpr/ExplodedActual.cc \
     35      ResolvExpr/ExplodedActual.h \
    2836      ResolvExpr/ExplodedArg.cpp \
     37      ResolvExpr/ExplodedArg.hpp \
    2938      ResolvExpr/FindOpenVars.cc \
     39      ResolvExpr/FindOpenVars.h \
    3040      ResolvExpr/Occurs.cc \
    3141      ResolvExpr/PolyCost.cc \
     
    3343      ResolvExpr/PtrsCastable.cc \
    3444      ResolvExpr/RenameVars.cc \
     45      ResolvExpr/RenameVars.h \
    3546      ResolvExpr/ResolveAssertions.cc \
     47      ResolvExpr/ResolveAssertions.h \
    3648      ResolvExpr/Resolver.cc \
     49      ResolvExpr/Resolver.h \
    3750      ResolvExpr/ResolveTypeof.cc \
     51      ResolvExpr/ResolveTypeof.h \
     52      ResolvExpr/ResolvMode.h \
    3853      ResolvExpr/SatisfyAssertions.cpp \
     54      ResolvExpr/SatisfyAssertions.hpp \
    3955      ResolvExpr/SpecCost.cc \
    4056      ResolvExpr/TypeEnvironment.cc \
    41       ResolvExpr/Unify.cc
     57      ResolvExpr/TypeEnvironment.h \
     58      ResolvExpr/typeops.h \
     59      ResolvExpr/Unify.cc \
     60      ResolvExpr/Unify.h \
     61      ResolvExpr/WidenMode.h
    4262
    43 SRC += $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc
     63
     64SRC += $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc ResolvExpr/AlternativePrinter.h
    4465SRCDEMANGLE += $(SRC_RESOLVEXPR)
  • src/SymTab/module.mk

    r56c44dc rce55a81  
    1717SRC_SYMTAB = \
    1818      SymTab/Autogen.cc \
     19      SymTab/Autogen.h \
    1920      SymTab/FixFunction.cc \
     21      SymTab/FixFunction.h \
    2022      SymTab/Indexer.cc \
     23      SymTab/Indexer.h \
    2124      SymTab/Mangler.cc \
    2225      SymTab/ManglerCommon.cc \
    23       SymTab/Validate.cc
     26      SymTab/Mangler.h \
     27      SymTab/Validate.cc \
     28      SymTab/Validate.h
    2429
    2530SRC += $(SRC_SYMTAB)
  • src/SynTree/Expression.cc

    r56c44dc rce55a81  
    3030#include "Type.h"                    // for Type, BasicType, Type::Qualifiers
    3131#include "TypeSubstitution.h"        // for TypeSubstitution
     32#include "CompilationState.h"        // for deterministic_output
    3233
    3334#include "GenPoly/Lvalue.h"
     
    7172
    7273        if ( result ) {
    73                 os << std::endl << indent << "with resolved type:" << std::endl;
    74                 os << (indent+1);
    75                 result->print( os, indent+1 );
     74                if (!deterministic_output) {
     75                        os << std::endl << indent << "with resolved type:" << std::endl;
     76                        os << (indent+1);
     77                        result->print( os, indent+1 );
     78                }
    7679        }
    7780
     
    299302}
    300303
    301 KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) {
    302 }
    303 
    304 KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {
    305 }
     304KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) {}
     305KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target, const KeywordCastExpr::Concrete & concrete_target ) : Expression(), arg(arg), target( target ), concrete_target(concrete_target) {}
     306
     307KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {}
    306308
    307309KeywordCastExpr::~KeywordCastExpr() {
  • src/SynTree/Expression.h

    r56c44dc rce55a81  
    248248
    249249        KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target );
     250        KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target, const Concrete & concrete_target );
    250251        KeywordCastExpr( const KeywordCastExpr & other );
    251252        virtual ~KeywordCastExpr();
  • src/SynTree/module.mk

    r56c44dc rce55a81  
    2020      SynTree/ApplicationExpr.cc \
    2121      SynTree/ArrayType.cc \
     22      SynTree/Attribute.cc \
     23      SynTree/Attribute.h \
    2224      SynTree/AttrType.cc \
    23       SynTree/Attribute.cc \
     25      SynTree/BaseSyntaxNode.h \
    2426      SynTree/BasicType.cc \
    2527      SynTree/CommaExpr.cc \
    2628      SynTree/CompoundStmt.cc \
    2729      SynTree/Constant.cc \
     30      SynTree/Constant.h \
     31      SynTree/Declaration.cc \
     32      SynTree/Declaration.h \
     33      SynTree/DeclarationWithType.cc \
    2834      SynTree/DeclReplacer.cc \
     35      SynTree/DeclReplacer.h \
    2936      SynTree/DeclStmt.cc \
    30       SynTree/Declaration.cc \
    31       SynTree/DeclarationWithType.cc \
    3237      SynTree/Expression.cc \
     38      SynTree/Expression.h \
    3339      SynTree/FunctionDecl.cc \
    3440      SynTree/FunctionType.cc \
    3541      SynTree/Initializer.cc \
     42      SynTree/Initializer.h \
     43      SynTree/Label.h \
    3644      SynTree/LinkageSpec.cc \
     45      SynTree/LinkageSpec.h \
     46      SynTree/Mutator.h \
    3747      SynTree/NamedTypeDecl.cc \
    3848      SynTree/ObjectDecl.cc \
     
    4151      SynTree/ReferenceType.cc \
    4252      SynTree/Statement.cc \
     53      SynTree/Statement.h \
     54      SynTree/SynTree.h \
    4355      SynTree/TupleExpr.cc \
    4456      SynTree/TupleType.cc \
     
    4658      SynTree/TypeDecl.cc \
    4759      SynTree/TypeExpr.cc \
     60      SynTree/Type.h \
     61      SynTree/TypeofType.cc \
    4862      SynTree/TypeSubstitution.cc \
    49       SynTree/TypeofType.cc \
     63      SynTree/TypeSubstitution.h \
    5064      SynTree/VarArgsType.cc \
     65      SynTree/Visitor.h \
    5166      SynTree/VoidType.cc \
    5267      SynTree/ZeroOneType.cc
  • src/Tuples/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \
    18         Tuples/Tuples.cc
    19 SRCDEMANGLE += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \
    20         Tuples/Tuples.cc
     17SRC_TUPLES = \
     18        Tuples/Explode.cc \
     19        Tuples/Explode.h \
     20        Tuples/TupleAssignment.cc \
     21        Tuples/TupleExpansion.cc \
     22        Tuples/Tuples.cc \
     23        Tuples/Tuples.h
     24
     25
     26SRC += $(SRC_TUPLES)
     27SRCDEMANGLE += $(SRC_TUPLES)
  • src/Validate/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
    18 SRCDEMANGLE += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
     17SRC += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h
     18SRCDEMANGLE += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h
  • src/Virtual/module.mk

    r56c44dc rce55a81  
    1515###############################################################################
    1616
    17 SRC += Virtual/ExpandCasts.cc
     17SRC += Virtual/ExpandCasts.cc Virtual/ExpandCasts.h
  • tests/.expect/alloc-ERROR.txt

    r56c44dc rce55a81  
    1 alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped:
     1alloc.cfa:361:1 error: No reasonable alternatives for expression Applying untyped:
    22  Name: ?=?
    33...to:
     
    1616          Name: stp
    1717
    18       with resolved type:
    19         unsigned long int
    2018
    2119
    2220
    23 alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped:
     21alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped:
    2422  Name: ?=?
    2523...to:
     
    3028    Name: stp
    3129    constant expression (10 10: signed int)
    32     with resolved type:
    33       signed int
    3430
    3531
    36 alloc.cfa:364:1 error: No reasonable alternatives for expression Applying untyped:
     32alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped:
    3733  Name: ?=?
    3834...to:
  • tests/.expect/alloc.txt

    r56c44dc rce55a81  
    14140xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    1515CFA array alloc, fill 0xef
    16 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef
     160xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    1717CFA array alloc, fill from array
    18 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef, 0xefefefef 0xefefefef,
     180xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef, 0xdeadbeef 0xdeadbeef,
    1919
    2020C realloc
    21 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef
     210xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    2222CFA realloc
    23 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0xefefefef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
     230xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101
    2424
    2525CFA realloc array alloc
  • tests/.expect/castError.txt

    r56c44dc rce55a81  
    33  Name: f
    44... to:
    5   char
    6 with resolved type:
    75  char Alternatives are:
    86Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
     
    119      ... returning nothing
    1210
    13       with resolved type:
    14         pointer to function
    15           accepting unspecified arguments
    16         ... returning nothing
    17 
    1811    ... to:
    19       char
    20     with resolved type:
    2112      char
    2213  (types:
     
    2718Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    2819      Variable Expression: f: double
    29       with resolved type:
    30         double
    3120    ... to:
    32       char
    33     with resolved type:
    3421      char
    3522  (types:
     
    4027Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of:
    4128      Variable Expression: f: signed int
    42       with resolved type:
    43         signed int
    4429    ... to:
    45       char
    46     with resolved type:
    4730      char
    4831  (types:
     
    5639  Comma Expression:
    5740    constant expression (3 3: signed int)
    58     with resolved type:
    59       signed int
    6041    Name: v
    61 ... to: nothing
    62 with resolved type:
    63   void  Alternatives are:
     42... to: nothing Alternatives are:
    6443Cost ( 0, 0, 2, 0, 0, 0, 0 ): Generated Cast of:
    6544      Comma Expression:
    6645        constant expression (3 3: signed int)
    67         with resolved type:
    68           signed int
    6946        Variable Expression: v: unsigned char
    70         with resolved type:
    71           unsigned char
    72       with resolved type:
    73         unsigned char
    7447    ... to: nothing
    75     with resolved type:
    76       void
    7748  (types:
    7849    void
     
    8354      Comma Expression:
    8455        constant expression (3 3: signed int)
    85         with resolved type:
    86           signed int
    8756        Variable Expression: v: signed short int
    88         with resolved type:
    89           signed short int
    90       with resolved type:
    91         signed short int
    9257    ... to: nothing
    93     with resolved type:
    94       void
    9558  (types:
    9659    void
     
    10669    char
    10770
    108 with resolved type:
    109   instance of struct S with body 1
    110   ... with parameters
    111     char
    112 
  • tests/.expect/init1.txt

    r56c44dc rce55a81  
    1111... to:
    1212  reference to signed int
    13 with resolved type:
    14   reference to signed int
    1513init1.cfa:97:1 error: No reasonable alternatives for expression Applying untyped:
    1614  Name: ?{}
     
    1816  Generated Cast of:
    1917    Variable Expression: _retval_f_py: pointer to signed int
    20     with resolved type:
    21       pointer to signed int
    2218  ... to:
    23     reference to pointer to signed int
    24   with resolved type:
    2519    reference to pointer to signed int
    2620  Name: px
     
    3024... to:
    3125  reference to float
    32 with resolved type:
    33   reference to float
    3426init1.cfa:107:1 error: No reasonable alternatives for expression Applying untyped:
    3527  Name: ?{}
     
    3729  Generated Cast of:
    3830    Variable Expression: _retval_f_py2: pointer to float
    39     with resolved type:
    40       pointer to float
    4131  ... to:
    42     reference to pointer to float
    43   with resolved type:
    4432    reference to pointer to float
    4533  Name: cpx
     
    4937... to:
    5038  reference to instance of type T (not function type)
    51 with resolved type:
    52   reference to instance of type T (not function type)
    5339init1.cfa:118:1 error: No reasonable alternatives for expression Applying untyped:
    5440  Name: ?{}
     
    5642  Generated Cast of:
    5743    Variable Expression: _retval_anycvt: pointer to instance of type T (not function type)
    58     with resolved type:
    59       pointer to instance of type T (not function type)
    6044  ... to:
    61     reference to pointer to instance of type T (not function type)
    62   with resolved type:
    6345    reference to pointer to instance of type T (not function type)
    6446  Name: s
  • tests/Makefile.am

    r56c44dc rce55a81  
    6767avl_test_SOURCES = avltree/avl_test.cfa avltree/avl0.cfa avltree/avl1.cfa avltree/avl2.cfa avltree/avl3.cfa avltree/avl4.cfa avltree/avl-private.cfa
    6868# automake doesn't know we still need C/CPP rules so pretend like we have a C program
    69 _dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp
     69nodist__dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp
    7070
    7171#----------------------------------------------------------------------------------------------------------------
  • tests/alloc.cfa

    r56c44dc rce55a81  
    4747        free( ip );
    4848
    49         ip = alloc_set( fill );                                                         // CFA alloc, fill
     49        ip = alloc( fill`fill );                                                                // CFA alloc, fill
    5050        printf( "CFA alloc, fill %08x\n", *ip );
    5151        free( ip );
    5252
    53         ip = alloc_set( 3 );                                                            // CFA alloc, fill
     53        ip = alloc( 3`fill );                                                           // CFA alloc, fill
    5454        printf( "CFA alloc, fill %d\n", *ip );
    5555        free( ip );
     
    7878        free( ip );
    7979
    80         ip = alloc_set( 2 * dim, fill );                                        // CFA array alloc, fill
     80        ip = alloc( 2 * dim, fill`fill );                                       // CFA array alloc, fill
    8181        printf( "CFA array alloc, fill %#hhx\n", fill );
    8282        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     
    8484        free( ip );
    8585
    86         ip = alloc_set( 2 * dim, 0xdeadbeef );                          // CFA array alloc, fill
     86        ip = alloc( 2 * dim, ((int)0xdeadbeef)`fill );                          // CFA array alloc, fill
    8787        printf( "CFA array alloc, fill %#hhx\n", 0xdeadbeef );
    8888        for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); }
     
    9090        // do not free
    9191
    92         ip1 = alloc_set( 2 * dim, ip, 2 * dim );                                // CFA array alloc, fill
     92        ip1 = alloc( 2 * dim, [ip, 2 * dim]`fill );                             // CFA array alloc, fill
    9393        printf( "CFA array alloc, fill from array\n" );
    9494        for ( i; 2 * dim ) { printf( "%#x %#x, ", ip[i], ip1[i] ); }
     
    117117        printf( "\n" );
    118118
    119         ip = alloc( ip, dim );                                                          // CFA realloc array alloc
     119        ip = alloc( dim, ip`realloc );                                                          // CFA realloc array alloc
    120120        for ( i; dim ) { ip[i] = 0xdeadbeef; }
    121121        printf( "CFA realloc array alloc\n" );
     
    124124        // do not free
    125125
    126         ip = alloc( ip, 2 * dim );                                                      // CFA realloc array alloc
     126        ip = alloc( 2 * dim, ip`realloc );                                                      // CFA realloc array alloc
    127127        for ( i; dim ~ 2 * dim ) { ip[i] = 0x1010101; }         // fill upper part
    128128        printf( "CFA realloc array alloc\n" );
     
    131131        // do not free
    132132
    133         ip = alloc( ip, dim );                                                          // CFA realloc array alloc
     133        ip = alloc( dim, ip`realloc );                                                          // CFA realloc array alloc
    134134        printf( "CFA realloc array alloc\n" );
    135135        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     
    137137        // do not free
    138138
    139         ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill
     139        ip = alloc( 3 * dim, ip`realloc, fill`fill );                           // CFA realloc array alloc, fill
    140140        printf( "CFA realloc array alloc, fill\n" );
    141141        for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); }
     
    143143        // do not free
    144144
    145         ip = alloc_set( ip, dim, fill );                                        // CFA realloc array alloc, fill
     145        ip = alloc( dim, ip`realloc, fill`fill );                                       // CFA realloc array alloc, fill
    146146        printf( "CFA realloc array alloc, fill\n" );
    147147        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     
    149149        // do not free
    150150
    151         ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill
     151        ip = alloc( 3 * dim, ip`realloc, fill`fill );                           // CFA realloc array alloc, fill
    152152        printf( "CFA realloc array alloc, fill\n" );
    153153        for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); }
     
    155155        // do not free
    156156#if 0 // FIX ME
    157         ip = alloc_set( ip, 5 * dim, 5 );                                       // CFA realloc array alloc, 5
     157        ip = alloc( 5 * dim, ip`realloc, 5`fill );                                      // CFA realloc array alloc, 5
    158158        printf( "CFA realloc array alloc, 5\n" );
    159159        for ( i; 5 * dim ) { printf( "%#x ", ip[i] ); }
     
    161161        // do not free
    162162
    163         ip = alloc_set( ip, dim, 5 );                                           // CFA realloc array alloc, 5
     163        ip = alloc( dim, ip`realloc, 5`fill );                                          // CFA realloc array alloc, 5
    164164        printf( "CFA realloc array alloc, 5\n" );
    165165        for ( i; dim ) { printf( "%#x ", ip[i] ); }
     
    167167        // do not free
    168168
    169         ip = alloc_set( ip, 5 * dim, 5 );                                       // CFA realloc array alloc, 5
     169        ip = alloc( 5 * dim, ip`realloc, 5`fill );                                      // CFA realloc array alloc, 5
    170170        printf( "CFA realloc array alloc, 5\n" );
    171171        for ( i; 5 * dim ) { printf( "%#x ", ip[i] ); }
     
    182182    ip = alloc();
    183183        *ip = 5;
    184     double * dp = alloc( ip );
     184    double * dp = alloc( ip`resize );
    185185        *dp = 5.5;
    186     S * sp = alloc( dp );
     186    S * sp = alloc( dp`resize );
    187187        *sp = (S){ {0, 1, 2, 3, 4} };
    188     ip = alloc( sp );
     188    ip = alloc( sp`resize );
    189189        *ip = 3;
    190190    free( ip );
     
    195195    ip = alloc( 5 );
    196196        for ( i; 5 ) { ip[i] = 5; }
    197     dp = alloc( ip, 5 );
     197    dp = alloc( 5, ip`resize );
    198198        for ( i; 5 ) { dp[i] = 5.5; }
    199     sp = alloc( dp, 5 );
     199    sp = alloc( 5, dp`resize );
    200200        for ( i; 5 ) { sp[i] = (S){ {0, 1, 2, 3, 4} }; }
    201     ip = alloc( sp, 3 );
     201    ip = alloc( 3, sp`resize );
    202202        for ( i; 3 ) { ip[i] = 3; }
    203     ip = alloc( ip, 7 );
     203    ip = alloc( 7, ip`realloc );
    204204        for ( i; 7 ) { ip[i] = 7; }
    205     ip = alloc( ip, 7, false );
     205    ip = alloc( 7, ip`resize );
    206206        for ( i; 7 ) { ip[i] = 7; }
    207207    free( ip );
     
    237237        free( stp );
    238238
    239         stp = &(*alloc_align( Alignment)){ 42, 42.5 };          // CFA alloc_align
     239        stp = &(*alloc( Alignment`align)){ 42, 42.5 };          // CFA alloc_align
    240240        assert( (uintptr_t)stp % Alignment == 0 );
    241241        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
    242242        free( stp );
    243243
    244         stp = &(*alloc_align( Alignment )){ 42, 42.5 };         // CFA alloc_align
     244        stp = &(*alloc( Alignment`align )){ 42, 42.5 };         // CFA alloc_align
    245245        assert( (uintptr_t)stp % Alignment == 0 );
    246246        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
    247247        free( stp );
    248248
    249         stp = alloc_align_set( Alignment, fill );                       // CFA memalign, fill
     249        stp = alloc( Alignment`align, fill`fill );                      // CFA memalign, fill
    250250        assert( (uintptr_t)stp % Alignment == 0 );
    251251        printf( "CFA alloc_align fill %#x %a\n", stp->x, stp->y );
    252252        free( stp );
    253253
    254         stp = alloc_align_set( Alignment, (Struct){ 42, 42.5 } ); // CFA memalign, fill
     254        stp = alloc( Alignment`align, (Struct){ 42, 42.5 }`fill ); // CFA memalign, fill
    255255        assert( (uintptr_t)stp % Alignment == 0 );
    256256        printf( "CFA alloc_align fill %d %g\n", stp->x, stp->y );
    257257        // do not free
    258258
    259         stp = &(*alloc_align( stp, 4096 )){ 42, 42.5 };         // CFA realign
     259        stp = &(*alloc( stp`realloc, 4096`align )){ 42, 42.5 };         // CFA realign
    260260        assert( (uintptr_t)stp % 4096 == 0 );
    261261        printf( "CFA alloc_align %d %g\n", stp->x, stp->y );
     
    266266        printf( "\n" );
    267267
    268         stp = alloc_align( Alignment, dim );                // CFA array memalign
     268        stp = alloc( dim, Alignment`align );                // CFA array memalign
    269269        assert( (uintptr_t)stp % Alignment == 0 );
    270270        for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; }
     
    274274        free( stp );
    275275
    276         stp = alloc_align_set( Alignment, dim, fill );          // CFA array memalign, fill
     276        stp = alloc( dim, Alignment`align, fill`fill );         // CFA array memalign, fill
    277277        assert( (uintptr_t)stp % Alignment == 0 );
    278278        printf( "CFA array alloc_align, fill\n" );
     
    281281        free( stp );
    282282
    283         stp = alloc_align_set( Alignment, dim, (Struct){ 42, 42.5 } ); // CFA array memalign, fill
     283        stp = alloc( dim, Alignment`align, ((Struct){ 42, 42.5 })`fill ); // CFA array memalign, fill
    284284        assert( (uintptr_t)stp % Alignment == 0 );
    285285        printf( "CFA array alloc_align, fill\n" );
     
    288288        // do not free
    289289
    290         stp1 = alloc_align_set( Alignment, dim, stp, dim );     // CFA array memalign, fill
     290        stp1 = alloc( dim, Alignment`align, [stp, dim]`fill );  // CFA array memalign, fill
    291291        assert( (uintptr_t)stp % Alignment == 0 );
    292292        printf( "CFA array alloc_align, fill array\n" );
     
    295295        free( stp1 );
    296296
    297         stp = alloc_align( stp, 4096, dim );                            // CFA aligned realloc array
     297        stp = alloc( dim, stp`realloc, 4096`align );                            // CFA aligned realloc array
    298298        assert( (uintptr_t)stp % 4096 == 0 );
    299299        for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; }
     
    325325        for ( i; dim ) { printf( "%#x %a, ", sta1[i].x, sta1[i].y ); }
    326326        printf( "\n" );
    327 
    328327
    329328        // new, non-array types
  • tests/concurrent/examples/boundedBufferEXT.cfa

    r56c44dc rce55a81  
    11//
    22// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
    3 // 
     3//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
     
    8787}
    8888
     89enum { Prods = 4, Cons = 5 };
     90Producer * prods[Prods];
     91Consumer * cons[Cons];
     92
    8993int main() {
    9094        Buffer(int) buffer;
    91         enum { Prods = 4, Cons = 5 };
    92         Producer * prods[Prods];
    93         Consumer * cons[Cons];
    9495        int sums[Cons];
    9596        int i;
  • tests/errors/.expect/completeType.x64.txt

    r56c44dc rce55a81  
    66    Name: x
    77
    8 ... to: nothing
    9 with resolved type:
    10   void  Alternatives are:
     8... to: nothing Alternatives are:
    119Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
    1210      Application of
     
    2220
    2321
    24         with resolved type:
    25           pointer to forall
    26             _90_4_DT: data type
    27             function
    28           ... with parameters
    29             intrinsic pointer to instance of type _90_4_DT (not function type)
    30           ... returning
    31             _retval__operator_deref: reference to instance of type _90_4_DT (not function type)
    32             ... with attributes:
    33               Attribute with name: unused
    34 
    35 
    3622      ... to arguments
    3723        Variable Expression: x: pointer to instance of struct A with body 0
    38         with resolved type:
    39           pointer to instance of struct A with body 0
    4024
    41       with resolved type:
    42         reference to instance of struct A with body 0
    4325    ... to: nothing
    44     with resolved type:
    45       void
    4626  (types:
    4727    void
     
    6343
    6444
    65         with resolved type:
    66           pointer to forall
    67             _90_4_DT: data type
    68             function
    69           ... with parameters
    70             intrinsic pointer to instance of type _90_4_DT (not function type)
    71           ... returning
    72             _retval__operator_deref: reference to instance of type _90_4_DT (not function type)
    73             ... with attributes:
    74               Attribute with name: unused
    75 
    76 
    7745      ... to arguments
    7846        Variable Expression: x: pointer to instance of struct B with body 1
    79         with resolved type:
    80           pointer to instance of struct B with body 1
    8147
    82       with resolved type:
    83         reference to instance of struct B with body 1
    8448    ... to: nothing
    85     with resolved type:
    86       void
    8749  (types:
    8850    void
     
    159121            ... returning nothing
    160122
    161             with resolved type:
    162               pointer to forall
    163                 _109_0_T: sized data type
    164                 ... with assertions
    165                   ?=?: pointer to function
    166                   ... with parameters
    167                     reference to instance of type _109_0_T (not function type)
    168                     instance of type _109_0_T (not function type)
    169                   ... returning
    170                     _retval__operator_assign: instance of type _109_0_T (not function type)
    171                     ... with attributes:
    172                       Attribute with name: unused
    173 
    174 
    175                   ?{}: pointer to function
    176                   ... with parameters
    177                     reference to instance of type _109_0_T (not function type)
    178                   ... returning nothing
    179 
    180                   ?{}: pointer to function
    181                   ... with parameters
    182                     reference to instance of type _109_0_T (not function type)
    183                     instance of type _109_0_T (not function type)
    184                   ... returning nothing
    185 
    186                   ^?{}: pointer to function
    187                   ... with parameters
    188                     reference to instance of type _109_0_T (not function type)
    189                   ... returning nothing
    190 
    191 
    192                 function
    193               ... with parameters
    194                 pointer to instance of type _109_0_T (not function type)
    195               ... returning nothing
    196 
    197123          ... to arguments
    198124            Variable Expression: z: pointer to instance of type T (not function type)
    199             with resolved type:
    200               pointer to instance of type T (not function type)
    201125
    202           with resolved type:
    203             void
    204126        (types:
    205127          void
  • tests/errors/.expect/completeType.x86.txt

    r56c44dc rce55a81  
    66    Name: x
    77
    8 ... to: nothing
    9 with resolved type:
    10   void  Alternatives are:
     8... to: nothing Alternatives are:
    119Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of:
    1210      Application of
     
    2220
    2321
    24         with resolved type:
    25           pointer to forall
    26             _89_4_DT: data type
    27             function
    28           ... with parameters
    29             intrinsic pointer to instance of type _89_4_DT (not function type)
    30           ... returning
    31             _retval__operator_deref: reference to instance of type _89_4_DT (not function type)
    32             ... with attributes:
    33               Attribute with name: unused
    34 
    35 
    3622      ... to arguments
    3723        Variable Expression: x: pointer to instance of struct A with body 0
    38         with resolved type:
    39           pointer to instance of struct A with body 0
    4024
    41       with resolved type:
    42         reference to instance of struct A with body 0
    4325    ... to: nothing
    44     with resolved type:
    45       void
    4626  (types:
    4727    void
     
    6343
    6444
    65         with resolved type:
    66           pointer to forall
    67             _89_4_DT: data type
    68             function
    69           ... with parameters
    70             intrinsic pointer to instance of type _89_4_DT (not function type)
    71           ... returning
    72             _retval__operator_deref: reference to instance of type _89_4_DT (not function type)
    73             ... with attributes:
    74               Attribute with name: unused
    75 
    76 
    7745      ... to arguments
    7846        Variable Expression: x: pointer to instance of struct B with body 1
    79         with resolved type:
    80           pointer to instance of struct B with body 1
    8147
    82       with resolved type:
    83         reference to instance of struct B with body 1
    8448    ... to: nothing
    85     with resolved type:
    86       void
    8749  (types:
    8850    void
     
    159121            ... returning nothing
    160122
    161             with resolved type:
    162               pointer to forall
    163                 _108_0_T: sized data type
    164                 ... with assertions
    165                   ?=?: pointer to function
    166                   ... with parameters
    167                     reference to instance of type _108_0_T (not function type)
    168                     instance of type _108_0_T (not function type)
    169                   ... returning
    170                     _retval__operator_assign: instance of type _108_0_T (not function type)
    171                     ... with attributes:
    172                       Attribute with name: unused
    173 
    174 
    175                   ?{}: pointer to function
    176                   ... with parameters
    177                     reference to instance of type _108_0_T (not function type)
    178                   ... returning nothing
    179 
    180                   ?{}: pointer to function
    181                   ... with parameters
    182                     reference to instance of type _108_0_T (not function type)
    183                     instance of type _108_0_T (not function type)
    184                   ... returning nothing
    185 
    186                   ^?{}: pointer to function
    187                   ... with parameters
    188                     reference to instance of type _108_0_T (not function type)
    189                   ... returning nothing
    190 
    191 
    192                 function
    193               ... with parameters
    194                 pointer to instance of type _108_0_T (not function type)
    195               ... returning nothing
    196 
    197123          ... to arguments
    198124            Variable Expression: z: pointer to instance of type T (not function type)
    199             with resolved type:
    200               pointer to instance of type T (not function type)
    201125
    202           with resolved type:
    203             void
    204126        (types:
    205127          void
  • tests/literals.cfa

    r56c44dc rce55a81  
    1010// Created On       : Sat Sep  9 16:34:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 20 13:51:12 2020
    13 // Update Count     : 225
     12// Last Modified On : Sat Aug 29 10:57:56 2020
     13// Update Count     : 226
    1414//
    1515
     
    151151        -0X0123456789.0123456789P-09;  -0X0123456789.0123456789P-09f;  -0X0123456789.0123456789P-09l;  -0X0123456789.0123456789P-09F;  -0X0123456789.0123456789P-09L;
    152152
     153#if defined( __i386 ) || defined( __x86_64 )
    153154#if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
    154155// floating with length, gcc f16/f128x unsupported and no prelude code for any _FloatXXx, so they work by conversion to long double
     
    194195        /* -0x123456789.0123456789P-09F16; */  -0x123456789.0123456789P-09F32;  -0x123456789.0123456789P-09F32x;  -0x123456789.0123456789P-09F64;  -0x123456789.0123456789P-09F64x;  -0x123456789.0123456789P-09W;  -0x123456789.0123456789P-09F128;  -0x123456789.0123456789P-09q;  /* -0x123456789.0123456789P-09q; */
    195196#endif // __GNUC_PREREQ(7,0)
     197#endif // __i386 ) || __x86_64
    196198
    197199#ifdef __CFA__
  • tests/pybin/tools.py

    r56c44dc rce55a81  
    238238# helper function to check if a files contains only a specific string
    239239def file_contains_only(file, text) :
    240         with open(file) as f:
     240        with open(file, encoding="latin-1") as f: # use latin-1 so all chars mean something.
    241241                ff = f.read().strip()
    242242                result = ff == text.strip()
  • tests/raii/.expect/ctor-autogen-ERR1.txt

    r56c44dc rce55a81  
    77        x: signed int
    88      ... returning nothing
    9 
    10       with resolved type:
    11         function
    12         ... with parameters
    13           _dst: reference to instance of struct Managed with body 1
    14           x: signed int
    15         ... returning nothing
    169
    1710      ... deleted by: ?{}: function
     
    3326
    3427
    35               with resolved type:
    36                 pointer to function
    37                 ... with parameters
    38                   intrinsic reference to signed int
    39                   intrinsic signed int
    40                 ... returning
    41                   _retval__operator_assign: signed int
    42                   ... with attributes:
    43                     Attribute with name: unused
    44 
    45 
    4628            ... to arguments
    4729              Generated Cast of:
     
    5133                  Generated Cast of:
    5234                    Variable Expression: m: reference to instance of struct Managed with body 1
    53                     with resolved type:
    54                       reference to instance of struct Managed with body 1
    5535                  ... to:
    5636                    instance of struct Managed with body 1
    57                   with resolved type:
    58                     instance of struct Managed with body 1
    59                 with resolved type:
    60                   signed int
    6137              ... to:
    62                 reference to signed int
    63               with resolved type:
    6438                reference to signed int
    6539              Generated Cast of:
    6640                constant expression (0 0: zero_t)
    67                 with resolved type:
    68                   zero_t
    6941              ... to:
    7042                signed int
    71               with resolved type:
    72                 signed int
    7343
    74             with resolved type:
    75               signed int
    7644            ... with environment:
    7745              Types:
     
    8250    Generated Cast of:
    8351      Variable Expression: x: instance of struct Managed with body 1
    84       with resolved type:
    85         instance of struct Managed with body 1
    8652    ... to:
    8753      reference to instance of struct Managed with body 1
    88     with resolved type:
    89       reference to instance of struct Managed with body 1
    9054    constant expression (123 123: signed int)
    91     with resolved type:
    92       signed int
    9355
    94   with resolved type:
    95     void
    9656... to: nothing
    97 with resolved type:
    98   void
  • tests/test.py

    r56c44dc rce55a81  
    116116        parser.add_argument('--arch', help='Test for specific architecture', type=comma_separated(str), default=None)
    117117        parser.add_argument('--continue', help='When multiple specifications are passed (debug/install/arch), sets whether or not to continue if the last specification failed', type=yes_no, default='yes', dest='continue_')
    118         parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=60)
     118        parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=120)
    119119        parser.add_argument('--global-timeout', help='Maximum cumulative duration in seconds after the ALL tests are considered to have timed out', type=int, default=7200)
    120120        parser.add_argument('--timeout-with-gdb', help='Instead of killing the command when it times out, orphan it and print process id to allow gdb to attach', type=yes_no, default="no")
     
    194194                if success(retcode):
    195195                        if settings.generating :
    196                                 # if we are ounly generating the output we still need to check that the test actually exists
     196                                # if we are only generating the output we still need to check that the test actually exists
    197197                                if no_rule(out_file, test.target()) :
    198198                                        retcode = 1
  • tests/warnings/.expect/self-assignment.txt

    r56c44dc rce55a81  
    11warnings/self-assignment.cfa:29:1 warning: self assignment of expression: Generated Cast of:
    22  Variable Expression: j: signed int
    3   with resolved type:
    4     signed int
    53... to:
    6   reference to signed int
    7 with resolved type:
    84  reference to signed int
    95warnings/self-assignment.cfa:30:1 warning: self assignment of expression: Generated Cast of:
    106  Variable Expression: s: instance of struct S with body 1
    11   with resolved type:
    12     instance of struct S with body 1
    137... to:
    14   reference to instance of struct S with body 1
    15 with resolved type:
    168  reference to instance of struct S with body 1
    179warnings/self-assignment.cfa:31:1 warning: self assignment of expression: Generated Cast of:
     
    2012  ... from aggregate:
    2113    Variable Expression: s: instance of struct S with body 1
    22     with resolved type:
    23       instance of struct S with body 1
    24   with resolved type:
    25     signed int
    2614... to:
    27   reference to signed int
    28 with resolved type:
    2915  reference to signed int
    3016warnings/self-assignment.cfa:32:1 warning: self assignment of expression: Generated Cast of:
     
    3622    ... from aggregate:
    3723      Variable Expression: t: instance of struct T with body 1
    38       with resolved type:
    39         instance of struct T with body 1
    40     with resolved type:
    41       instance of struct S with body 1
    42   with resolved type:
    43     signed int
    4424... to:
    4525  reference to signed int
    46 with resolved type:
    47   reference to signed int
  • tools/Makefile.am

    r56c44dc rce55a81  
    1818ACLOCAL_AMFLAGS  = -I automake
    1919
    20 AM_CFLAGS = -Wall -Wextra -O2 -g
     20EXTRA_DIST = build/distcc_hash build/push2dist.sh
    2121
    2222noinst_PROGRAMS = busy catchsig repeat watchdog
     23AM_CFLAGS = -Wall -Wextra -O2 -g
     24busy_LDFLAGS     = -pthread
    2325
    24 busy_SOURCES     = busy.c
    25 busy_LDFLAGS     = -pthread
    26 catchsig_SOURCES = catchsig.c
    27 repeat_SOURCES   = repeat.c
    28 watchdog_SOURCES = watchdog.c
     26nodist_busy_SOURCES     = busy.c
     27nodist_catchsig_SOURCES = catchsig.c
     28nodist_repeat_SOURCES   = repeat.c
     29nodist_watchdog_SOURCES = watchdog.c
  • tools/prettyprinter/Makefile.am

    r56c44dc rce55a81  
    3030tools_prettyprinter_PROGRAMS = pretty
    3131tools_prettyprinterdir = ../
    32 pretty_SOURCES = ${SRC}
     32nodist_pretty_SOURCES = ${SRC}
    3333pretty_LDADD = ${LEXLIB} -ldl                   # yywrap
    3434pretty_CXXFLAGS = -Wno-deprecated -Wall -DYY_NO_INPUT -O2 -g -std=c++14
Note: See TracChangeset for help on using the changeset viewer.