# Changeset ce55a81

Ignore:
Timestamp:
Sep 4, 2020, 2:14:10 PM (2 years ago)
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:
66 edited
8 moved

Unmodified
Removed
• ## .gitignore

 r56c44dc **/Makefile **/Makefile.in **/Makefile.dist.in /version

• ## doc/LaTeXmacros/common.tex


• ## doc/theses/thierry_delisle_PhD/comp_II/Makefile

 r56c44dc ## Define the text source files. SOURCES = ${addsuffix .tex, \ comp_II \ } FIGURES =${addsuffix .tex, \ base \ empty \ emptybit \ emptytree \ emptytls \ resize \ system \ } PICTURES = ${addsuffix .pstex, \ base \ empty \ system \ } ## Define the documents that need to be made. all: comp_II.pdf presentation.pdf comp_II.pdf:${FIGURES} ${PICTURES} presentation.pdf: presentationstyle.sty base.dark.pstex empty.dark.pstex system.dark.pstex DOCUMENT = comp_II.pdf DOCUMENT = comp_II.pdf presentation.pdf BASE =${basename ${DOCUMENT}} # File Dependencies #${DOCUMENT} : ${BASE}.ps %.pdf : build/%.ps |${Build} ps2pdf $<${BASE}.ps : ${BASE}.dvi dvips${Build}/$< -o$@ build/%.ps : build/%.dvi | ${Build} dvips$< -o $@${BASE}.dvi : Makefile ${GRAPHS}${PROGRAMS} ${PICTURES}${FIGURES} ${SOURCES} \${Macros}/common.tex ${Macros}/indexstyle ../../../bibliography/pl.bib \ local.bib glossary.tex |${Build} build/%.dvi : %.tex Makefile | ${Build} # Must have *.aux file containing citations for bibtex if [ ! -r${basename $@}.aux ] ; then${LaTeX} ${basename$@}.tex ; fi -${BibTeX}${Build}/${basename$@} if [ ! -r ${basename$@}.aux ] ; then ${LaTeX}$< ; fi -${BibTeX}${basename $@} # Some citations reference others so run again to resolve these citations${LaTeX} ${basename$@}.tex -${BibTeX}${Build}/${basename$@} ${LaTeX}$< -${BibTeX}${basename $@} # Make index from *.aux entries and input index at end of document makeglossaries -q -s${Build}/${basename$@}.ist ${Build}/${basename $@} -makeglossaries -q -s${basename $@}.ist${basename $@} # Run again to finish citations${LaTeX} ${basename$@}.tex ${LaTeX}$< ## Define the default recipes. mkdir -p ${Build} %.tex : img/%.fig${Build} %.tex : img/%.fig | ${Build} fig2dev -L eepic$< > ${Build}/$@ fig2dev -L pstex_t -p ${Build}/$@ $< >${Build}/$@_t ## pstex with inverted colors %.dark.pstex : img/%.fig Makefile |${Build} fig2dev -L pstex $< >${Build}/$@ sed -i 's/\/col-1 {0 setgray} bind def/\/col-1 {1 setgray} bind def/g'${Build}/$@ 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}/$@ 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}/$@ fig2dev -L pstex_t -p${Build}/$@$< > ${Build}/$@_t # Local Variables: # # compile-command: "make" #
• ## doc/theses/thierry_delisle_PhD/comp_II/comp_II.tex

 r56c44dc It aims to add high-productivity features while maintaining the predictable performance of C. As such, concurrency in \CFA\cite{Delisle19} aims to offer simple and safe high-level tools while still allowing performant code. \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. \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. As such, the \CFA \newterm{scheduler} is a preemptive user-level scheduler that maps \glspl{uthrd} onto \glspl{kthrd}. and the cost of scheduling, \ie deciding which thread to run next among all the threads ready to run. \end{enumerate} 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. 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. 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 third fixed thread before scheduling.}, while the scheduling cost can vary based on the system state. 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. The more threads switch, the more the administration cost of scheduling becomes noticeable. It is therefore important to build a scheduler with the lowest possible cost and latency. While the illusion of simultaneity is easier to reason about, it can break down if the scheduler allows too much unfairness. Therefore, the scheduler should offer as much fairness as needed to guarantee eventual progress, but use unfairness to help performance. 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. In practice, threads must wait in turn but there can be advantages to unfair scheduling, similar to the express cash register at a grocery store. The goal of this research is to produce a scheduler that is simple for programmers to understand and offers good performance. \end{quote} For a general purpose scheduler, it is impossible to produce an optimal algorithm as it would require knowledge of the future behaviour of threads. 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}. For a general-purpose scheduler, it is impossible to produce an optimal algorithm as it would require knowledge of the future behaviour of threads. 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 worse than \emph{X}. For this proposal, the performance is evaluated using the second approach to allow \CFA programmers to rely on scheduling performance. Because 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. To achieve the \CFA scheduling goal includes: \begin{enumerate} \item producing a scheduling strategy with sufficient fairness guarantees, \item creating an abstraction layer over the operating system to handle kernel-threads spinning unnecessarily, \item scheduling blocking I/O operations, \item and writing sufficient library tools to allow developers to indirectly use the scheduler, either through tuning knobs or replacing the default scheduler. \item producing a scheduling strategy with sufficient fairness guarantees, \item creating an abstraction layer over the operating system to handle kernel-threads spinning unnecessarily, \item scheduling blocking I/O operations, \item and writing sufficient library tools to allow developers to indirectly use the scheduler, either through tuning knobs or replacing the default scheduler. \end{enumerate} \paragraph{Correctness} As with any other concurrent data structure or algorithm, the correctness requirement is paramount. The 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. Since \CFA concurrency has no spurious wakeup, this definition of correctness also means the scheduler should have no spurious wakeup. Since \CFA concurrency has no spurious wake up, this definition of correctness also means the scheduler should have no spurious wake up. The \CFA scheduler must be correct. The \CFA scheduler should offer good performance for all three metrics. \paragraph{Fairness} Like performance, this requirement has several aspect : eventual progress, predictability and performance reliability. \paragraph{Fairness} Like performance, this requirement has several aspects : eventual progress, predictability and performance reliability. \newterm{Eventual progress} guarantees every scheduled thread is eventually run, \ie prevent starvation. 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. \newterm{Predictability} and \newterm{reliability} means similar workloads achieve similar performance and programmer execution intuition is respected. For example, a thread that yields aggressively should not run more often then other tasks. 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. \newterm{Predictability} and \newterm{reliability} mean similar workloads achieve similar performance and programmer execution intuition is respected. For example, a thread that yields aggressively should not run more often than other tasks. While this is intuitive, it does not hold true for many work-stealing or feedback based schedulers. The \CFA scheduler must guarantee eventual progress and should be predictable and offer reliable performance. \begin{enumerate} \item Threads live long enough for useful feedback information to be to gathered. \item Threads live long enough for useful feedback information to be gathered. \item Threads belong to multiple users so fairness across threads is insufficient. \end{enumerate} Since \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. Scheduling strategies based on feedback cannot be effective in these cases because there is no opportunity to measure the metrics that underlie the algorithm. 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. 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. In the context of operating systems, these concerns can be overshadowed by a more pressing concern : security. In the case of the \CFA scheduler, every thread runs in the same user space and is controlled by the same user. Fairness across users is therefore a given and it is then possible to safely ignore the possibility that threads are malevolent. 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. 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. Since 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. Another broad category of schedulers are priority schedulers. In these scheduling strategies, threads have priorities and the runtime schedules the threads with the highest priority before scheduling other threads. Threads with equal priority are scheduled using a secondary strategy, often something simple like round-robin or FIFO. Threads with equal priority are scheduled using a secondary strategy, often something simple like round robin or FIFO. A 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. This 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. An important observation is that threads do not need to have explicit priorities for problems to occur. 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. 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. For example, a popular scheduling strategy that suffers from implicit priorities is work stealing. \newterm{Work stealing} is generally presented as follows: \subsection{Schedulers without feedback or priorities} 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. This 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. The simplest fairness guarantee is FIFO ordering, \ie threads scheduled first run first. However, enforcing FIFO ordering generally conflicts with scalability across multiple processors because of the additional synchronization. Pushing 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. Popping is done by selecting two queues at random and popping from the queue with the oldest timestamp. A higher number of underlying queues leads to less contention on each queue and therefore better performance. A higher number of underlying queues lead to less contention on each queue and therefore better performance. In a loaded system, it is highly likely the queues are non-empty, \ie several tasks are on each of the underlying queues. This means that selecting a queue at random to pop from is highly likely to yield a queue with available items. \begin{figure} \begin{center} \input{base} \input{base.pstex_t} \end{center} \caption{Relaxed FIFO list at the base of the scheduler: an array of strictly FIFO lists. The timestamp is in all nodes and cell arrays.} The timestamp is in all nodes and cell arrays.} \label{fig:base} \end{figure} \begin{figure} \begin{center} \input{empty} \input{empty.pstex_t} \end{center} \caption{More empty'' state of the queue: the array contains many empty cells.} Overall performance is therefore influenced by the contention on the underlying queues and pop performance is influenced by the item density. This leads to four performance cases for the centralized ready-queue, as depicted in Table~\ref{tab:perfcases}. This leads to four performance cases for the centralized ready queue, as depicted in Table~\ref{tab:perfcases}. The 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. The number of threads (many or few) refers to the number of user threads ready to be run. Sparse 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. Similarly, other sparse schemes need to read multiple cachelines to acquire all the information needed.}. 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. 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. 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. The fact that these solutions have these fundamental limits suggest to me a better solution that attempts to combine these properties in an interesting way. Also, the lock discussed in Section~\ref{sec:resize} allows for solutions that adapt to the number of processors, which could also prove useful. How much scalability is actually needed is highly debatable. \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. \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. As such, the single atomic instruction on a shared cacheline may be sufficiently performant. I 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. Using this prototype I ran preliminary performance experiments that confirm the expected performance in Table~\ref{tab:perfcases}. Using this prototype, I ran preliminary performance experiments that confirm the expected performance in Table~\ref{tab:perfcases}. However, 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. \begin{figure} \begin{center} \input{system} \input{system.pstex_t} \end{center} \caption{Global structure of the \CFA runtime system.} This assumption is made both in the design of the proposed scheduler as well as in the original design of the \CFA runtime system. As such, the proposed scheduler must honour the correctness of this behaviour but does not have any performance objectives with regard to resizing a cluster. 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. 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 periods of times. However, as mentioned in Section~\ref{sec:queue}, contention on the underlying queues can have a direct impact on performance. The number of underlying queues must therefore be adjusted as the number of processors grows or shrinks. This description effectively matches with the description of a reader-writer lock, infrequent but invasive updates among frequent read operations. In 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. Writes on the other hand would add or remove inner queues, invalidating references to the array of inner queues in a process. Writes, on the other hand, would add or remove inner queues, invalidating references to the array of inner queues in a process. Therefore, 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. \paragraph{Objectives and Existing Work} The lock must offer scalability and performance on par with the actual ready-queue in order not to introduce a new bottleneck. The lock must offer scalability and performance on par with the actual ready queue in order not to introduce a new bottleneck. I have already built a lock that fits the desired requirements and preliminary testing show scalability and performance that exceed the target. As such, I do not consider this lock to be a risk for this project. give back unneeded CPU time associated with a process to other user processors executing on the computer, \item and reduce energy consumption in cases where more idle kernel-threads translate to idle CPUs, which can cycle down. and reduce energy consumption in cases where more idle kernel-threads translate into idle CPUs, which can cycle down. \end{enumerate} Support 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. This 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. The waking-up operation sees the blocked process and signals it, but the blocking process is racing to sleep so the signal is missed. 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. In 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. Individual 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). However, 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. Another important issue is avoiding kernel threads sleeping and waking frequently because there is a significant operating-system cost. This scenario happens when a program oscillates between high and low activity, needing most and then less processors. This scenario happens when a program oscillates between high and low activity, needing most and then fewer processors. A possible partial solution is to order the processors so that the one which most recently went to sleep is woken up. This allows other sleeping processors to reach deeper sleep state (when these are available) while keeping hot'' processors warmer. A 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. 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. Furthermore, transitions from sleeping to awake and vice-versa also add unnecessary latency. Processors that are unnecessarily unblocked lead to unnecessary contention, CPU usage, and power consumption, while too many sleeping processors can lead to suboptimal throughput. Furthermore, transitions from sleeping to awake and vice versa also add unnecessary latency. There 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}. It is preferable to block the user thread performing the I/O and reuse the underlying kernel-thread to run other ready user threads. This 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. As such, there are three components needed to implemented support for asynchronous I/O: As such, there are three components needed to implement support for asynchronous I/O: \begin{enumerate} \item It is sufficient to make one work in the complex context of the \CFA runtime. \uC uses the $select$\cite{select} as its interface, which handles ttys, pipes and sockets, but not disk. $select$ entails significant complexity and is being replaced in UNIX operating-systems, which make it a less interesting alternative. $select$ entails significant complexity and is being replaced in UNIX operating systems, which make it a less interesting alternative. Another popular interface is $epoll$\cite{epoll}, which is supposed to be cheaper than $select$. However, $epoll$ also does not handle the file system and anectodal evidence suggest it has problem with linux pipes and $TTY$s. However, $epoll$ also does not handle the file system and anecdotal evidence suggest it has problems with Linux pipes and $TTY$s. A popular cross-platform alternative is $libuv$\cite{libuv}, which offers asynchronous sockets and asynchronous file system operations (among other features). However, 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. A very recent alternative that I am investigating is $io_uring$\cite{io_uring}. It claims to address some of the issues with $epoll$ and my early investigating suggest that the claim is accurate. $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. It claims to address some of the issues with $epoll$ and my early investigating suggests that the claim is accurate. $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. I believe this approach allows for fewer problems, \eg the manpage for $open$\cite{open} states: \begin{quote} Note that [the $O_NONBLOCK$ flag] has no effect for regular files and block devices; that is, I/O operations will (briefly) block when device activity is required, regardless of whether $O_NONBLOCK$ is set. 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. Note that [the $O_NONBLOCK$ flag] has no effect for regular files and block devices; that is, I/O operations will (briefly) block when device activity is required, regardless of whether $O_NONBLOCK$ is set. Since $O_NONBLOCK$ semantics might eventually be implemented, applications should not depend upon blocking behaviour when specifying this flag for regular files and block devices. \end{quote} This makes approach based on $epoll$/$select$ less reliable since they may not work for every file descriptors. 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. 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. However, only a small subset of the features are available in Ubuntu as of April 2020\cite{wiki:ubuntu-linux}, which will limit performance comparisons. I do not believe this will affect the comparison result. \section{Discussion} I believe that runtime system and scheduling are still open topics. 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. 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 widely available system language offers modern threading facilities. I believe the proposed work offers a novel runtime and scheduling package, where existing work only offers fragments that users must assemble themselves when possible. \hline November 2020 & March 2021   & Completion of the implementation. \\ \hline March 2021 & April 2021  & Final Performance experiments. \\ \hline May 2021 & August 2021 & Thesis writing and defense. \\ \hline May 2021 & August 2021 & Thesis writing and defence. \\ \hline \end{tabular}
• ## doc/theses/thierry_delisle_PhD/comp_II/img/base.fig

 r56c44dc #FIG 3.2  Produced by xfig version 3.2.5c #FIG 3.2  Produced by xfig version 3.2.7b Landscape Center Inches Letter Letter 100.00 Single 1 3 0 1 0 0 50 -1 20 0.000 1 0.0000 6975 4200 20 20 6975 4200 6995 4200 -6 6 2400 2100 3000 2700 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 2400 300 300 2700 2400 3000 2400 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2400 2475 3000 2475 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 2650 TS\001 -6 6 2400 3000 3000 3600 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 3300 300 300 2700 3300 3000 3300 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2400 3375 3000 3375 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 3550 TS\001 -6 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3900 2400 300 300 3900 2400 4200 2400 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3900 3300 300 300 3900 3300 4200 3300 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6300 3300 300 300 6300 3300 6600 3300 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4509 3302 300 300 4509 3302 4809 3302 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 3300 300 300 2700 3300 3000 3300 1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2700 2400 300 300 2700 2400 3000 2400 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3000 3900 3000 4500 1 1 1.00 45.00 90.00 6300 4200 6300 3600 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 0 1 -1 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 45.00 90.00 2700 4200 2700 3600 1 1 1.00 45.00 90.00 4500 4200 4500 3600 4 2 0 50 -1 0 12 0.0000 2 180 660 2100 4200 Array of\001 4 2 0 50 -1 0 12 0.0000 2 165 600 2100 4425 Queues\001 4 2 0 50 -1 0 12 0.0000 2 135 645 2100 3075 Threads\001 4 2 0 50 -1 0 12 0.0000 2 180 525 2100 2850 Ready\001 4 1 0 50 -1 0 11 0.0000 2 120 210 2700 4450 TS\001 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2400 3375 3000 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2400 2475 3000 2475 4 2 -1 50 -1 0 12 0.0000 2 135 630 2100 3075 Threads\001 4 2 -1 50 -1 0 12 0.0000 2 165 450 2100 2850 Ready\001 4 1 -1 50 -1 0 11 0.0000 2 135 180 2700 4450 TS\001 4 2 -1 50 -1 0 12 0.0000 2 165 720 2100 4200 Array of\001 4 2 -1 50 -1 0 12 0.0000 2 150 540 2100 4425 Queues\001 4 1 -1 50 -1 0 11 0.0000 2 135 180 2700 3550 TS\001 4 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 #FIG 3.2  Produced by xfig version 3.2.5c #FIG 3.2  Produced by xfig version 3.2.7b Landscape Center Inches Letter Letter 100.00 Single 1 1 1.00 45.00 90.00 2700 4200 2700 3600 4 2 0 50 -1 0 12 0.0000 2 180 660 2100 4200 Array of\001 4 2 0 50 -1 0 12 0.0000 2 165 600 2100 4425 Queues\001 4 2 0 50 -1 0 12 0.0000 2 135 645 2100 3075 Threads\001 4 2 0 50 -1 0 12 0.0000 2 180 525 2100 2850 Ready\001 4 2 -1 50 -1 0 12 0.0000 2 165 720 2100 4200 Array of\001 4 2 -1 50 -1 0 12 0.0000 2 150 540 2100 4425 Queues\001 4 2 -1 50 -1 0 12 0.0000 2 135 630 2100 3075 Threads\001 4 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 Center Inches Letter Letter 100.00 Single 4 1 -1 0 0 0 10 0.0000 2 105 990 2175 3525 Discrete-event\001 4 1 -1 0 0 0 10 0.0000 2 135 795 2175 4350 preemption\001 4 0 -1 0 0 0 10 0.0000 2 150 1290 2325 4875 genrator/coroutine\001 4 0 -1 0 0 0 10 0.0000 2 150 1290 2325 4875 generator/coroutine\001 4 0 -1 0 0 0 10 0.0000 2 120 270 4050 4875 task\001 4 0 -1 0 0 0 10 0.0000 2 105 450 7050 4875 cluster\001
• ## driver/cfa.cc

 r56c44dc // Created On       : Tue Aug 20 13:44:49 2002 // Last Modified By : Peter A. Buhr // Last Modified On : Thu Aug 20 23:43:59 2020 // Update Count     : 436 // Last Modified On : Wed Sep  2 17:59:20 2020 // Update Count     : 438 // #endif // __x86_64__ args[nargs++] = "-ldl"; args[nargs++] = "-lrt"; args[nargs++] = "-lm"; } // if

• ## src/AST/Convert.cpp

 r56c44dc new KeywordCastExpr( get().accept1(node->arg), castTarget castTarget, {node->concrete_target.field, node->concrete_target.getter} ) ); old->location, GET_ACCEPT_1(arg, Expr), castTarget castTarget, {old->concrete_target.field, old->concrete_target.getter} ) );
• ## src/AST/Copy.hpp

 r56c44dc #include "Stmt.hpp" #include "Type.hpp" #include #include namespace ast {
• ## src/AST/Expr.hpp

 r56c44dc public: ptr arg; struct Concrete { std::string field; std::string getter; Concrete() = default; Concrete(const Concrete &) = default; }; ast::AggregateDecl::Aggregate target; Concrete concrete_target; KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t ) : Expr( loc ), arg( a ), target( t ) {} KeywordCastExpr( const CodeLocation & loc, const Expr * a, ast::AggregateDecl::Aggregate t, const Concrete & ct ) : Expr( loc ), arg( a ), target( t ), concrete_target( ct ) {} /// Get a name for the target type
• ## src/AST/Pass.hpp

 r56c44dc // // Several additional features are available through inheritance // | PureVisitor           - makes the visitor pure, it never modifies nodes in place and always //                           clones nodes it needs to make changes to // | WithTypeSubstitution  - provides polymorphic const TypeSubstitution * env for the //                           current expression /// Keep track of the polymorphic const TypeSubstitution * env for the current expression /// If used the visitor will always clone nodes. struct PureVisitor {}; struct WithConstTypeSubstitution { const TypeSubstitution * env = nullptr;
• ## src/AST/Pass.impl.hpp

 r56c44dc namespace ast { template node_t * shallowCopy( const node_t * node ); namespace __pass { // Check if this is either a null pointer or a pointer to an empty container static inline bool empty( T * ptr ) { return !ptr || ptr->empty(); } template< typename core_t, typename node_t > static inline node_t* mutate(const node_t *node) { return std::is_base_of::value ? ::ast::shallowCopy(node) : ::ast::mutate(node); } if( __pass::differs(old_val, new_val) ) { auto new_parent = mutate(parent); auto new_parent = __pass::mutate(parent); new_parent->*child = new_val; parent = new_parent; if ( node->forall.empty() ) return; node_t * mut = mutate( node ); node_t * mut = __pass::mutate( node ); mut->forall = subs->clone( node->forall, *this ); node = mut; if(mutated) { auto n = mutate(node); auto n = __pass::mutate(node); n->clauses = std::move( new_clauses ); node = n; auto nval = call_accept( node->field ); \ if(nval != node->field ) { \ auto nparent = mutate(node); \ auto nparent = __pass::mutate(node); \ nparent->field = nval; \ node = nparent; \ if(mutated) { auto n = mutate(node); auto n = __pass::mutate(node); n->associations = std::move( new_kids ); node = n; } if (mutated) { auto new_node = mutate( node ); auto new_node = __pass::mutate( node ); new_node->typeEnv.swap( new_map ); node = new_node; } if (mutated) { auto new_node = mutate( node ); auto new_node = __pass::mutate( node ); new_node->varEnv.swap( new_map ); node = new_node;
• ## src/AST/Pass.proto.hpp

 r56c44dc template class Pass; struct PureVisitor; namespace __pass {
• ## src/AST/Print.cpp

 r56c44dc #include "Type.hpp" #include "TypeSubstitution.hpp" #include "CompilationState.h" #include "Common/utility.h" // for group_iterate if ( node->result ) { os << endl << indent << "... with resolved type:" << endl; ++indent; os << indent; node->result->accept( *this ); --indent; if (!deterministic_output) { os << endl << indent << "... with resolved type:" << endl; ++indent; os << indent; node->result->accept( *this ); --indent; } }
• ## src/AST/TypeSubstitution.hpp

 r56c44dc template< typename SynTreeClass > struct ApplyResult { // const SynTreeClass * node; ast::ptr node; int count; // definitition must happen after PassVisitor is included so that WithGuards can be used struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef { struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef, public PureVisitor { static size_t traceId; assert( input ); Pass sub( *this, false ); input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) ); input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); return { input, sub.core.subCount }; } assert( input ); Pass sub( *this, true ); input = strict_dynamic_cast< const SynTreeClass * >( deepCopy(input)->accept( sub ) ); input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); return { input, sub.core.subCount }; }

• ## src/CodeTools/module.mk

 r56c44dc ############################################################################### SRC += CodeTools/DeclStats.cc \ SRC += \ CodeTools/DeclStats.cc \ CodeTools/DeclStats.h \ CodeTools/ResolvProtoDump.cc \ CodeTools/TrackLoc.cc CodeTools/ResolvProtoDump.h \ CodeTools/TrackLoc.cc \ CodeTools/TrackLoc.h

• ## src/GenPoly/module.mk

 r56c44dc SRC += GenPoly/Box.cc \ GenPoly/Box.h \ GenPoly/ErasableScopedMap.h \ GenPoly/FindFunction.cc \ GenPoly/FindFunction.h \ GenPoly/GenPoly.cc \ GenPoly/GenPoly.h \ GenPoly/InstantiateGeneric.cc \ GenPoly/InstantiateGeneric.h \ GenPoly/Lvalue.cc \ GenPoly/Lvalue.h \ GenPoly/ScopedSet.h \ GenPoly/ScrubTyVars.cc \ GenPoly/Lvalue.cc \ GenPoly/ScrubTyVars.h \ GenPoly/Specialize.cc \ GenPoly/FindFunction.cc \ GenPoly/InstantiateGeneric.cc GenPoly/Specialize.h SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/GenPoly.h GenPoly/Lvalue.cc GenPoly/Lvalue.h
• ## src/InitTweak/module.mk

 r56c44dc ############################################################################### SRC += InitTweak/GenInit.cc \ SRC += \ InitTweak/FixGlobalInit.cc \ InitTweak/FixGlobalInit.h \ InitTweak/FixInit.cc \ InitTweak/FixGlobalInit.cc \ InitTweak/InitTweak.cc InitTweak/FixInit.h \ InitTweak/GenInit.cc \ InitTweak/GenInit.h \ InitTweak/InitTweak.cc \ InitTweak/InitTweak.h SRCDEMANGLE += InitTweak/GenInit.cc \ InitTweak/InitTweak.cc SRCDEMANGLE += \ InitTweak/GenInit.cc \ InitTweak/GenInit.h \ InitTweak/InitTweak.cc \ InitTweak/InitTweak.h
• ## src/Makefile.am

 r56c44dc SRC = main.cc \ CompilationState.cc \ CompilationState.h \ MakeLibCfa.cc \ CompilationState.cc MakeLibCfa.h SRCDEMANGLE = CompilationState.cc ___driver_cfa_cpp_SOURCES = $(SRC) ___driver_cfa_cpp_LDADD = -ldl$(LIBPROFILER) $(LIBTCMALLOC) EXTRA_DIST = include/cassert include/optional BasicTypes-gen.cc AM_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 Parser/ExpressionNode.cc \ Parser/InitializerNode.cc \ Parser/lex.ll \ Parser/ParseNode.cc \ Parser/ParseNode.h \ Parser/parser.yy \ Parser/ParserTypes.h \ Parser/parserutility.cc \ Parser/parserutility.h \ Parser/StatementNode.cc \ Parser/TypeData.cc \ Parser/TypeData.h \ Parser/TypedefTable.cc \ Parser/lex.ll \ Parser/parser.yy \ Parser/parserutility.cc Parser/TypedefTable.h MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
• ## src/ResolvExpr/CandidateFinder.cpp

 r56c44dc } void postvisit( const ast::KeywordCastExpr * castExpr ) { const auto & loc = castExpr->location; assertf( castExpr->result, "Cast target should have been set in Validate." ); auto ref = castExpr->result.strict_as(); auto inst = ref->base.strict_as(); auto target = inst->base.get(); CandidateFinder finder{ symtab, tenv }; auto pick_alternatives = [target, this](CandidateList & found, bool expect_ref) { for(auto & cand : found) { const ast::Type * expr = cand->expr->result.get(); if(expect_ref) { auto res = dynamic_cast(expr); if(!res) { continue; } expr = res->base.get(); } if(auto insttype = dynamic_cast(expr)) { auto td = cand->env.lookup(insttype->name); if(!td) { continue; } expr = td->bound.get(); } if(auto base = dynamic_cast(expr)) { if(base->base == target) { candidates.push_back( std::move(cand) ); reason.code = NoReason; } } } }; try { // Attempt 1 : turn (thread&)X into ($thread&)X.__thrd // Clone is purely for memory management std::unique_ptr tech1 { new ast::UntypedMemberExpr(loc, new ast::NameExpr(loc, castExpr->concrete_target.field), castExpr->arg) }; // don't prune here, since it's guaranteed all alternatives will have the same type finder.find( tech1.get(), ResolvMode::withoutPrune() ); pick_alternatives(finder.candidates, false); return; } catch(SemanticErrorException & ) {} // Fallback : turn (thread&)X into ($thread&)get_thread(X) std::unique_ptr fallback { ast::UntypedExpr::createDeref(loc,  new ast::UntypedExpr(loc, new ast::NameExpr(loc, castExpr->concrete_target.getter), { castExpr->arg })) }; // don't prune here, since it's guaranteed all alternatives will have the same type finder.find( fallback.get(), ResolvMode::withoutPrune() ); pick_alternatives(finder.candidates, true); // Whatever happens here, we have no more fallbacks } void postvisit( const ast::UntypedMemberExpr * memberExpr ) { CandidateFinder aggFinder{ symtab, tenv };
• ## src/ResolvExpr/Unify.cc

 r56c44dc /// If this isn't done when satifying ttype assertions, then argument lists can have /// different size and structure when they should be compatible. struct TtypeExpander_new : public ast::WithShortCircuiting { struct TtypeExpander_new : public ast::WithShortCircuiting, public ast::PureVisitor { ast::TypeEnvironment & tenv; // TtypeExpander pass is impure (may mutate nodes in place) // need to make nodes shared to prevent accidental mutation ast::ptr dc = d; dc = dc->accept( expander ); ast::ptr dc = d->accept(expander); auto types = flatten( dc->get_type() ); for ( ast::ptr< ast::Type > & t : types ) { ast::Pass expander{ tenv }; ast::ptr tuplec = tuple; ast::ptr tuple2c = tuple2; const ast::Type * flat = tuplec->accept( expander ); const ast::Type * flat2 = tuple2c->accept( expander ); const ast::Type * flat = tuple->accept( expander ); const ast::Type * flat2 = tuple2->accept( expander ); auto types = flatten( flat );

• ## src/SynTree/Expression.cc

 r56c44dc #include "Type.h"                    // for Type, BasicType, Type::Qualifiers #include "TypeSubstitution.h"        // for TypeSubstitution #include "CompilationState.h"        // for deterministic_output #include "GenPoly/Lvalue.h" if ( result ) { os << std::endl << indent << "with resolved type:" << std::endl; os << (indent+1); result->print( os, indent+1 ); if (!deterministic_output) { os << std::endl << indent << "with resolved type:" << std::endl; os << (indent+1); result->print( os, indent+1 ); } } } KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) { } KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) { } KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ) : Expression(), arg(arg), target( target ) {} KeywordCastExpr::KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target, const KeywordCastExpr::Concrete & concrete_target ) : Expression(), arg(arg), target( target ), concrete_target(concrete_target) {} KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {} KeywordCastExpr::~KeywordCastExpr() {
• ## src/SynTree/Expression.h

 r56c44dc KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target ); KeywordCastExpr( Expression * arg, AggregateDecl::Aggregate target, const Concrete & concrete_target ); KeywordCastExpr( const KeywordCastExpr & other ); virtual ~KeywordCastExpr();
• ## src/SynTree/module.mk

 r56c44dc SynTree/ApplicationExpr.cc \ SynTree/ArrayType.cc \ SynTree/Attribute.cc \ SynTree/Attribute.h \ SynTree/AttrType.cc \ SynTree/Attribute.cc \ SynTree/BaseSyntaxNode.h \ SynTree/BasicType.cc \ SynTree/CommaExpr.cc \ SynTree/CompoundStmt.cc \ SynTree/Constant.cc \ SynTree/Constant.h \ SynTree/Declaration.cc \ SynTree/Declaration.h \ SynTree/DeclarationWithType.cc \ SynTree/DeclReplacer.cc \ SynTree/DeclReplacer.h \ SynTree/DeclStmt.cc \ SynTree/Declaration.cc \ SynTree/DeclarationWithType.cc \ SynTree/Expression.cc \ SynTree/Expression.h \ SynTree/FunctionDecl.cc \ SynTree/FunctionType.cc \ SynTree/Initializer.cc \ SynTree/Initializer.h \ SynTree/Label.h \ SynTree/LinkageSpec.cc \ SynTree/LinkageSpec.h \ SynTree/Mutator.h \ SynTree/NamedTypeDecl.cc \ SynTree/ObjectDecl.cc \ SynTree/ReferenceType.cc \ SynTree/Statement.cc \ SynTree/Statement.h \ SynTree/SynTree.h \ SynTree/TupleExpr.cc \ SynTree/TupleType.cc \ SynTree/TypeDecl.cc \ SynTree/TypeExpr.cc \ SynTree/Type.h \ SynTree/TypeofType.cc \ SynTree/TypeSubstitution.cc \ SynTree/TypeofType.cc \ SynTree/TypeSubstitution.h \ SynTree/VarArgsType.cc \ SynTree/Visitor.h \ SynTree/VoidType.cc \ SynTree/ZeroOneType.cc
• ## src/Tuples/module.mk

 r56c44dc ############################################################################### SRC += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \ Tuples/Tuples.cc SRCDEMANGLE += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \ Tuples/Tuples.cc SRC_TUPLES = \ Tuples/Explode.cc \ Tuples/Explode.h \ Tuples/TupleAssignment.cc \ Tuples/TupleExpansion.cc \ Tuples/Tuples.cc \ Tuples/Tuples.h SRC += $(SRC_TUPLES) SRCDEMANGLE +=$(SRC_TUPLES)
• ## src/Validate/module.mk

 r56c44dc ############################################################################### SRC += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc SRCDEMANGLE += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc SRC += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h SRCDEMANGLE += Validate/HandleAttributes.cc Validate/HandleAttributes.h Validate/FindSpecialDecls.cc Validate/FindSpecialDecls.h
• ## src/Virtual/module.mk

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

 r56c44dc alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped: alloc.cfa:361:1 error: No reasonable alternatives for expression Applying untyped: Name: ?=? ...to: Name: stp with resolved type: unsigned long int alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped: alloc.cfa:362:1 error: No reasonable alternatives for expression Applying untyped: Name: ?=? ...to: Name: stp constant expression (10 10: signed int) with resolved type: signed int alloc.cfa:364:1 error: No reasonable alternatives for expression Applying untyped: alloc.cfa:363:1 error: No reasonable alternatives for expression Applying untyped: Name: ?=? ...to:

• ## tests/.expect/castError.txt

 r56c44dc Name: f ... to: char with resolved type: char Alternatives are: Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of: ... returning nothing with resolved type: pointer to function accepting unspecified arguments ... returning nothing ... to: char with resolved type: char (types: Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of: Variable Expression: f: double with resolved type: double ... to: char with resolved type: char (types: Cost ( 1, 0, 0, 0, 0, 0, 0 ): Explicit Cast of: Variable Expression: f: signed int with resolved type: signed int ... to: char with resolved type: char (types: Comma Expression: constant expression (3 3: signed int) with resolved type: signed int Name: v ... to: nothing with resolved type: void  Alternatives are: ... to: nothing Alternatives are: Cost ( 0, 0, 2, 0, 0, 0, 0 ): Generated Cast of: Comma Expression: constant expression (3 3: signed int) with resolved type: signed int Variable Expression: v: unsigned char with resolved type: unsigned char with resolved type: unsigned char ... to: nothing with resolved type: void (types: void Comma Expression: constant expression (3 3: signed int) with resolved type: signed int Variable Expression: v: signed short int with resolved type: signed short int with resolved type: signed short int ... to: nothing with resolved type: void (types: void char with resolved type: instance of struct S with body 1 ... with parameters char
• ## tests/.expect/init1.txt

 r56c44dc ... to: reference to signed int with resolved type: reference to signed int init1.cfa:97:1 error: No reasonable alternatives for expression Applying untyped: Name: ?{} Generated Cast of: Variable Expression: _retval_f_py: pointer to signed int with resolved type: pointer to signed int ... to: reference to pointer to signed int with resolved type: reference to pointer to signed int Name: px ... to: reference to float with resolved type: reference to float init1.cfa:107:1 error: No reasonable alternatives for expression Applying untyped: Name: ?{} Generated Cast of: Variable Expression: _retval_f_py2: pointer to float with resolved type: pointer to float ... to: reference to pointer to float with resolved type: reference to pointer to float Name: cpx ... to: reference to instance of type T (not function type) with resolved type: reference to instance of type T (not function type) init1.cfa:118:1 error: No reasonable alternatives for expression Applying untyped: Name: ?{} Generated Cast of: Variable Expression: _retval_anycvt: pointer to instance of type T (not function type) with resolved type: pointer to instance of type T (not function type) ... to: reference to pointer to instance of type T (not function type) with resolved type: reference to pointer to instance of type T (not function type) Name: s
• ## tests/Makefile.am

 r56c44dc avl_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 # automake doesn't know we still need C/CPP rules so pretend like we have a C program _dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp nodist__dummy_hack_SOURCES = .dummy_hack.c .dummy_hackxx.cpp #----------------------------------------------------------------------------------------------------------------
• ## tests/alloc.cfa

 r56c44dc free( ip ); ip = alloc_set( fill );                                                         // CFA alloc, fill ip = alloc( fillfill );                                                                // CFA alloc, fill printf( "CFA alloc, fill %08x\n", *ip ); free( ip ); ip = alloc_set( 3 );                                                            // CFA alloc, fill ip = alloc( 3fill );                                                           // CFA alloc, fill printf( "CFA alloc, fill %d\n", *ip ); free( ip ); free( ip ); ip = alloc_set( 2 * dim, fill );                                        // CFA array alloc, fill ip = alloc( 2 * dim, fillfill );                                       // CFA array alloc, fill printf( "CFA array alloc, fill %#hhx\n", fill ); for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); } free( ip ); ip = alloc_set( 2 * dim, 0xdeadbeef );                          // CFA array alloc, fill ip = alloc( 2 * dim, ((int)0xdeadbeef)fill );                          // CFA array alloc, fill printf( "CFA array alloc, fill %#hhx\n", 0xdeadbeef ); for ( i; 2 * dim ) { printf( "%#x ", ip[i] ); } // do not free ip1 = alloc_set( 2 * dim, ip, 2 * dim );                                // CFA array alloc, fill ip1 = alloc( 2 * dim, [ip, 2 * dim]fill );                             // CFA array alloc, fill printf( "CFA array alloc, fill from array\n" ); for ( i; 2 * dim ) { printf( "%#x %#x, ", ip[i], ip1[i] ); } printf( "\n" ); ip = alloc( ip, dim );                                                          // CFA realloc array alloc ip = alloc( dim, iprealloc );                                                          // CFA realloc array alloc for ( i; dim ) { ip[i] = 0xdeadbeef; } printf( "CFA realloc array alloc\n" ); // do not free ip = alloc( ip, 2 * dim );                                                      // CFA realloc array alloc ip = alloc( 2 * dim, iprealloc );                                                      // CFA realloc array alloc for ( i; dim ~ 2 * dim ) { ip[i] = 0x1010101; }         // fill upper part printf( "CFA realloc array alloc\n" ); // do not free ip = alloc( ip, dim );                                                          // CFA realloc array alloc ip = alloc( dim, iprealloc );                                                          // CFA realloc array alloc printf( "CFA realloc array alloc\n" ); for ( i; dim ) { printf( "%#x ", ip[i] ); } // do not free ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill ip = alloc( 3 * dim, iprealloc, fillfill );                           // CFA realloc array alloc, fill printf( "CFA realloc array alloc, fill\n" ); for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); } // do not free ip = alloc_set( ip, dim, fill );                                        // CFA realloc array alloc, fill ip = alloc( dim, iprealloc, fillfill );                                       // CFA realloc array alloc, fill printf( "CFA realloc array alloc, fill\n" ); for ( i; dim ) { printf( "%#x ", ip[i] ); } // do not free ip = alloc_set( ip, 3 * dim, fill );                            // CFA realloc array alloc, fill ip = alloc( 3 * dim, iprealloc, fillfill );                           // CFA realloc array alloc, fill printf( "CFA realloc array alloc, fill\n" ); for ( i; 3 * dim ) { printf( "%#x ", ip[i] ); } // do not free #if 0 // FIX ME ip = alloc_set( ip, 5 * dim, 5 );                                       // CFA realloc array alloc, 5 ip = alloc( 5 * dim, iprealloc, 5fill );                                      // CFA realloc array alloc, 5 printf( "CFA realloc array alloc, 5\n" ); for ( i; 5 * dim ) { printf( "%#x ", ip[i] ); } // do not free ip = alloc_set( ip, dim, 5 );                                           // CFA realloc array alloc, 5 ip = alloc( dim, iprealloc, 5fill );                                          // CFA realloc array alloc, 5 printf( "CFA realloc array alloc, 5\n" ); for ( i; dim ) { printf( "%#x ", ip[i] ); } // do not free ip = alloc_set( ip, 5 * dim, 5 );                                       // CFA realloc array alloc, 5 ip = alloc( 5 * dim, iprealloc, 5fill );                                      // CFA realloc array alloc, 5 printf( "CFA realloc array alloc, 5\n" ); for ( i; 5 * dim ) { printf( "%#x ", ip[i] ); } ip = alloc(); *ip = 5; double * dp = alloc( ip ); double * dp = alloc( ipresize ); *dp = 5.5; S * sp = alloc( dp ); S * sp = alloc( dpresize ); *sp = (S){ {0, 1, 2, 3, 4} }; ip = alloc( sp ); ip = alloc( spresize ); *ip = 3; free( ip ); ip = alloc( 5 ); for ( i; 5 ) { ip[i] = 5; } dp = alloc( ip, 5 ); dp = alloc( 5, ipresize ); for ( i; 5 ) { dp[i] = 5.5; } sp = alloc( dp, 5 ); sp = alloc( 5, dpresize ); for ( i; 5 ) { sp[i] = (S){ {0, 1, 2, 3, 4} }; } ip = alloc( sp, 3 ); ip = alloc( 3, spresize ); for ( i; 3 ) { ip[i] = 3; } ip = alloc( ip, 7 ); ip = alloc( 7, iprealloc ); for ( i; 7 ) { ip[i] = 7; } ip = alloc( ip, 7, false ); ip = alloc( 7, ipresize ); for ( i; 7 ) { ip[i] = 7; } free( ip ); free( stp ); stp = &(*alloc_align( Alignment)){ 42, 42.5 };          // CFA alloc_align stp = &(*alloc( Alignmentalign)){ 42, 42.5 };          // CFA alloc_align assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA alloc_align %d %g\n", stp->x, stp->y ); free( stp ); stp = &(*alloc_align( Alignment )){ 42, 42.5 };         // CFA alloc_align stp = &(*alloc( Alignmentalign )){ 42, 42.5 };         // CFA alloc_align assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA alloc_align %d %g\n", stp->x, stp->y ); free( stp ); stp = alloc_align_set( Alignment, fill );                       // CFA memalign, fill stp = alloc( Alignmentalign, fillfill );                      // CFA memalign, fill assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA alloc_align fill %#x %a\n", stp->x, stp->y ); free( stp ); stp = alloc_align_set( Alignment, (Struct){ 42, 42.5 } ); // CFA memalign, fill stp = alloc( Alignmentalign, (Struct){ 42, 42.5 }fill ); // CFA memalign, fill assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA alloc_align fill %d %g\n", stp->x, stp->y ); // do not free stp = &(*alloc_align( stp, 4096 )){ 42, 42.5 };         // CFA realign stp = &(*alloc( stprealloc, 4096align )){ 42, 42.5 };         // CFA realign assert( (uintptr_t)stp % 4096 == 0 ); printf( "CFA alloc_align %d %g\n", stp->x, stp->y ); printf( "\n" ); stp = alloc_align( Alignment, dim );                // CFA array memalign stp = alloc( dim, Alignmentalign );                // CFA array memalign assert( (uintptr_t)stp % Alignment == 0 ); for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; } free( stp ); stp = alloc_align_set( Alignment, dim, fill );          // CFA array memalign, fill stp = alloc( dim, Alignmentalign, fillfill );         // CFA array memalign, fill assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA array alloc_align, fill\n" ); free( stp ); stp = alloc_align_set( Alignment, dim, (Struct){ 42, 42.5 } ); // CFA array memalign, fill stp = alloc( dim, Alignmentalign, ((Struct){ 42, 42.5 })fill ); // CFA array memalign, fill assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA array alloc_align, fill\n" ); // do not free stp1 = alloc_align_set( Alignment, dim, stp, dim );     // CFA array memalign, fill stp1 = alloc( dim, Alignmentalign, [stp, dim]fill );  // CFA array memalign, fill assert( (uintptr_t)stp % Alignment == 0 ); printf( "CFA array alloc_align, fill array\n" ); free( stp1 ); stp = alloc_align( stp, 4096, dim );                            // CFA aligned realloc array stp = alloc( dim, stprealloc, 4096`align );                            // CFA aligned realloc array assert( (uintptr_t)stp % 4096 == 0 ); for ( i; dim ) { stp[i] = (Struct){ 42, 42.5 }; } for ( i; dim ) { printf( "%#x %a, ", sta1[i].x, sta1[i].y ); } printf( "\n" ); // new, non-array types
• ## tests/concurrent/examples/boundedBufferEXT.cfa

 r56c44dc // // Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo // // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. } enum { Prods = 4, Cons = 5 }; Producer * prods[Prods]; Consumer * cons[Cons]; int main() { Buffer(int) buffer; enum { Prods = 4, Cons = 5 }; Producer * prods[Prods]; Consumer * cons[Cons]; int sums[Cons]; int i;
• ## tests/errors/.expect/completeType.x64.txt

 r56c44dc Name: x ... to: nothing with resolved type: void  Alternatives are: ... to: nothing Alternatives are: Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: Application of with resolved type: pointer to forall _90_4_DT: data type function ... with parameters intrinsic pointer to instance of type _90_4_DT (not function type) ... returning _retval__operator_deref: reference to instance of type _90_4_DT (not function type) ... with attributes: Attribute with name: unused ... to arguments Variable Expression: x: pointer to instance of struct A with body 0 with resolved type: pointer to instance of struct A with body 0 with resolved type: reference to instance of struct A with body 0 ... to: nothing with resolved type: void (types: void with resolved type: pointer to forall _90_4_DT: data type function ... with parameters intrinsic pointer to instance of type _90_4_DT (not function type) ... returning _retval__operator_deref: reference to instance of type _90_4_DT (not function type) ... with attributes: Attribute with name: unused ... to arguments Variable Expression: x: pointer to instance of struct B with body 1 with resolved type: pointer to instance of struct B with body 1 with resolved type: reference to instance of struct B with body 1 ... to: nothing with resolved type: void (types: void ... returning nothing with resolved type: pointer to forall _109_0_T: sized data type ... with assertions ?=?: pointer to function ... with parameters reference to instance of type _109_0_T (not function type) instance of type _109_0_T (not function type) ... returning _retval__operator_assign: instance of type _109_0_T (not function type) ... with attributes: Attribute with name: unused ?{}: pointer to function ... with parameters reference to instance of type _109_0_T (not function type) ... returning nothing ?{}: pointer to function ... with parameters reference to instance of type _109_0_T (not function type) instance of type _109_0_T (not function type) ... returning nothing ^?{}: pointer to function ... with parameters reference to instance of type _109_0_T (not function type) ... returning nothing function ... with parameters pointer to instance of type _109_0_T (not function type) ... returning nothing ... to arguments Variable Expression: z: pointer to instance of type T (not function type) with resolved type: pointer to instance of type T (not function type) with resolved type: void (types: void
• ## tests/errors/.expect/completeType.x86.txt

 r56c44dc Name: x ... to: nothing with resolved type: void  Alternatives are: ... to: nothing Alternatives are: Cost ( 0, 1, 2, 0, 1, -1, 0 ): Generated Cast of: Application of with resolved type: pointer to forall _89_4_DT: data type function ... with parameters intrinsic pointer to instance of type _89_4_DT (not function type) ... returning _retval__operator_deref: reference to instance of type _89_4_DT (not function type) ... with attributes: Attribute with name: unused ... to arguments Variable Expression: x: pointer to instance of struct A with body 0 with resolved type: pointer to instance of struct A with body 0 with resolved type: reference to instance of struct A with body 0 ... to: nothing with resolved type: void (types: void with resolved type: pointer to forall _89_4_DT: data type function ... with parameters intrinsic pointer to instance of type _89_4_DT (not function type) ... returning _retval__operator_deref: reference to instance of type _89_4_DT (not function type) ... with attributes: Attribute with name: unused ... to arguments Variable Expression: x: pointer to instance of struct B with body 1 with resolved type: pointer to instance of struct B with body 1 with resolved type: reference to instance of struct B with body 1 ... to: nothing with resolved type: void (types: void ... returning nothing with resolved type: pointer to forall _108_0_T: sized data type ... with assertions ?=?: pointer to function ... with parameters reference to instance of type _108_0_T (not function type) instance of type _108_0_T (not function type) ... returning _retval__operator_assign: instance of type _108_0_T (not function type) ... with attributes: Attribute with name: unused ?{}: pointer to function ... with parameters reference to instance of type _108_0_T (not function type) ... returning nothing ?{}: pointer to function ... with parameters reference to instance of type _108_0_T (not function type) instance of type _108_0_T (not function type) ... returning nothing ^?{}: pointer to function ... with parameters reference to instance of type _108_0_T (not function type) ... returning nothing function ... with parameters pointer to instance of type _108_0_T (not function type) ... returning nothing ... to arguments Variable Expression: z: pointer to instance of type T (not function type) with resolved type: pointer to instance of type T (not function type) with resolved type: void (types: void
• ## tests/literals.cfa

 r56c44dc // Created On       : Sat Sep  9 16:34:38 2017 // Last Modified By : Peter A. Buhr // Last Modified On : Thu Aug 20 13:51:12 2020 // Update Count     : 225 // Last Modified On : Sat Aug 29 10:57:56 2020 // Update Count     : 226 // -0X0123456789.0123456789P-09;  -0X0123456789.0123456789P-09f;  -0X0123456789.0123456789P-09l;  -0X0123456789.0123456789P-09F;  -0X0123456789.0123456789P-09L; #if defined( __i386 ) || defined( __x86_64 ) #if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7 // floating with length, gcc f16/f128x unsupported and no prelude code for any _FloatXXx, so they work by conversion to long double /* -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; */ #endif // __GNUC_PREREQ(7,0) #endif // __i386 ) || __x86_64 #ifdef __CFA__
• ## tests/pybin/tools.py

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

 r56c44dc x: signed int ... returning nothing with resolved type: function ... with parameters _dst: reference to instance of struct Managed with body 1 x: signed int ... returning nothing ... deleted by: ?{}: function with resolved type: pointer to function ... with parameters intrinsic reference to signed int intrinsic signed int ... returning _retval__operator_assign: signed int ... with attributes: Attribute with name: unused ... to arguments Generated Cast of: Generated Cast of: Variable Expression: m: reference to instance of struct Managed with body 1 with resolved type: reference to instance of struct Managed with body 1 ... to: instance of struct Managed with body 1 with resolved type: instance of struct Managed with body 1 with resolved type: signed int ... to: reference to signed int with resolved type: reference to signed int Generated Cast of: constant expression (0 0: zero_t) with resolved type: zero_t ... to: signed int with resolved type: signed int with resolved type: signed int ... with environment: Types: Generated Cast of: Variable Expression: x: instance of struct Managed with body 1 with resolved type: instance of struct Managed with body 1 ... to: reference to instance of struct Managed with body 1 with resolved type: reference to instance of struct Managed with body 1 constant expression (123 123: signed int) with resolved type: signed int with resolved type: void ... to: nothing with resolved type: void
• ## tests/test.py

 r56c44dc parser.add_argument('--arch', help='Test for specific architecture', type=comma_separated(str), default=None) 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_') parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=60) parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=120) 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) 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") if success(retcode): if settings.generating : # if we are ounly generating the output we still need to check that the test actually exists # if we are only generating the output we still need to check that the test actually exists if no_rule(out_file, test.target()) : retcode = 1
• ## tests/warnings/.expect/self-assignment.txt

 r56c44dc warnings/self-assignment.cfa:29:1 warning: self assignment of expression: Generated Cast of: Variable Expression: j: signed int with resolved type: signed int ... to: reference to signed int with resolved type: reference to signed int warnings/self-assignment.cfa:30:1 warning: self assignment of expression: Generated Cast of: Variable Expression: s: instance of struct S with body 1 with resolved type: instance of struct S with body 1 ... to: reference to instance of struct S with body 1 with resolved type: reference to instance of struct S with body 1 warnings/self-assignment.cfa:31:1 warning: self assignment of expression: Generated Cast of: ... from aggregate: Variable Expression: s: instance of struct S with body 1 with resolved type: instance of struct S with body 1 with resolved type: signed int ... to: reference to signed int with resolved type: reference to signed int warnings/self-assignment.cfa:32:1 warning: self assignment of expression: Generated Cast of: ... from aggregate: Variable Expression: t: instance of struct T with body 1 with resolved type: instance of struct T with body 1 with resolved type: instance of struct S with body 1 with resolved type: signed int ... to: reference to signed int with resolved type: reference to signed int
• ## tools/Makefile.am

 r56c44dc ACLOCAL_AMFLAGS  = -I automake AM_CFLAGS = -Wall -Wextra -O2 -g EXTRA_DIST = build/distcc_hash build/push2dist.sh noinst_PROGRAMS = busy catchsig repeat watchdog AM_CFLAGS = -Wall -Wextra -O2 -g busy_LDFLAGS     = -pthread busy_SOURCES     = busy.c busy_LDFLAGS     = -pthread catchsig_SOURCES = catchsig.c repeat_SOURCES   = repeat.c watchdog_SOURCES = watchdog.c nodist_busy_SOURCES     = busy.c nodist_catchsig_SOURCES = catchsig.c nodist_repeat_SOURCES   = repeat.c nodist_watchdog_SOURCES = watchdog.c
• ## tools/prettyprinter/Makefile.am

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