Changes in / [223a633:33c3ded]
- Files:
-
- 123 added
- 146 deleted
- 157 edited
-
Jenkins/FullBuild (modified) (1 diff)
-
Jenkinsfile (modified) (1 diff)
-
benchmark/Makefile.am (modified) (12 diffs)
-
benchmark/creation/JavaThread.java (modified) (1 diff)
-
benchmark/ctxswitch/JavaThread.java (modified) (1 diff)
-
benchmark/io/http/main.cfa (modified) (1 diff)
-
benchmark/io/http/worker.cfa (modified) (1 diff)
-
benchmark/io/readv.cfa (modified) (2 diffs)
-
benchmark/mutex/JavaThread.java (modified) (1 diff)
-
benchmark/readyQ/yield.cfa (modified) (2 diffs)
-
benchmark/schedint/JavaThread.java (modified) (1 diff)
-
doc/LaTeXmacros/common.tex (modified) (4 diffs)
-
doc/LaTeXmacros/lstlang.sty (modified) (3 diffs)
-
doc/bibliography/pl.bib (modified) (2 diffs)
-
doc/papers/concurrency/Paper.tex (modified) (19 diffs)
-
doc/papers/concurrency/annex/local.bib (modified) (1 diff)
-
doc/papers/concurrency/mail2 (modified) (1 diff)
-
doc/papers/concurrency/response3 (deleted)
-
doc/proposals/ZeroCostPreemption.md (deleted)
-
doc/proposals/function_type_change.md (deleted)
-
doc/refrat/refrat.tex (modified) (3 diffs)
-
doc/theses/andrew_beach_MMath/glossaries.tex (deleted)
-
doc/theses/andrew_beach_MMath/thesis.tex (modified) (1 diff)
-
doc/theses/fangren_yu_COOP_S20/Makefile (modified) (1 diff)
-
doc/theses/fangren_yu_COOP_S20/Report.tex (modified) (11 diffs)
-
doc/theses/fangren_yu_COOP_S20/cfa_developer_reference.pdf (deleted)
-
doc/theses/thierry_delisle_PhD/code/Makefile (added)
-
doc/theses/thierry_delisle_PhD/code/assert.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/bitbench/select.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/bts.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/bts_test.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/links.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/prefetch.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/process.sh (added)
-
doc/theses/thierry_delisle_PhD/code/processor.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list_fast.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/processor_list_good.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/randbit.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/Makefile (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/proto-gui/main.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/Makefile (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/cforall.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/fibre.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/pthread.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/thread.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readQ_example/thrdlib/thread.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/Makefile (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/assert.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/bitbench/select.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/bts.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/bts_test.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/links.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/prefetch.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/process.sh (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/processor.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/processor_list.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/processor_list_fast.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/processor_list_good.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/randbit.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/relaxed_list.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/relaxed_list.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/relaxed_list_layout.cpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/runperf.sh (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/scale.sh (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/snzi-packed.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/snzi.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/snzm.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/utils.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/readyQ_proto/work_stealing.hpp (deleted)
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/relaxed_list.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/relaxed_list_layout.cpp (added)
-
doc/theses/thierry_delisle_PhD/code/runperf.sh (added)
-
doc/theses/thierry_delisle_PhD/code/scale.sh (added)
-
doc/theses/thierry_delisle_PhD/code/snzi-packed.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/snzi.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/snzm.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/utils.hpp (added)
-
doc/theses/thierry_delisle_PhD/code/work_stealing.hpp (added)
-
doc/user/Makefile (modified) (1 diff)
-
doc/user/user.tex (modified) (17 diffs)
-
examples/ArrayN.c (added)
-
examples/Initialization.c (added)
-
examples/Initialization2.c (added)
-
examples/Makefile.example (added)
-
examples/Members.c (added)
-
examples/Misc.c (added)
-
examples/MiscError.c (added)
-
examples/Rank2.c (added)
-
examples/Tuple.c (added)
-
examples/abstype.c (added)
-
examples/constructors.c (added)
-
examples/forward.c (added)
-
examples/gc_no_raii/.gitignore (added)
-
examples/gc_no_raii/bug-repro/assert.c (added)
-
examples/gc_no_raii/bug-repro/blockers.tar.gz (added)
-
examples/gc_no_raii/bug-repro/blockers/explicit_cast.c (added)
-
examples/gc_no_raii/bug-repro/blockers/file_scope.c (added)
-
examples/gc_no_raii/bug-repro/blockers/recursive_realloc.c (added)
-
examples/gc_no_raii/bug-repro/crash.c (added)
-
examples/gc_no_raii/bug-repro/deref.c (added)
-
examples/gc_no_raii/bug-repro/field.c (added)
-
examples/gc_no_raii/bug-repro/find.c (added)
-
examples/gc_no_raii/bug-repro/inline.c (added)
-
examples/gc_no_raii/bug-repro/malloc.c (added)
-
examples/gc_no_raii/bug-repro/not_equal.c (added)
-
examples/gc_no_raii/bug-repro/oddtype.c (added)
-
examples/gc_no_raii/bug-repro/push_back.c (added)
-
examples/gc_no_raii/bug-repro/push_back.h (added)
-
examples/gc_no_raii/bug-repro/realloc.c (added)
-
examples/gc_no_raii/bug-repro/return.c (added)
-
examples/gc_no_raii/bug-repro/return_template.c (added)
-
examples/gc_no_raii/bug-repro/slow_malloc.c (added)
-
examples/gc_no_raii/bug-repro/static_const_local.c (added)
-
examples/gc_no_raii/bug-repro/test-assert.cpp (added)
-
examples/gc_no_raii/bug-repro/void_pointer.c (added)
-
examples/gc_no_raii/bug-repro/while.c (added)
-
examples/gc_no_raii/bug-repro/zero.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-malign.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-malloc.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-mmap.c (added)
-
examples/gc_no_raii/pool-alloc/allocate-win-valloc.c (added)
-
examples/gc_no_raii/premake4.lua (added)
-
examples/gc_no_raii/src/allocate-pool.c (added)
-
examples/gc_no_raii/src/allocate-pool.h (added)
-
examples/gc_no_raii/src/gc.h (added)
-
examples/gc_no_raii/src/gcpointers.c (added)
-
examples/gc_no_raii/src/gcpointers.h (added)
-
examples/gc_no_raii/src/internal/card_table.h (added)
-
examples/gc_no_raii/src/internal/collector.c (added)
-
examples/gc_no_raii/src/internal/collector.h (added)
-
examples/gc_no_raii/src/internal/gc_tools.h (added)
-
examples/gc_no_raii/src/internal/globals.h (added)
-
examples/gc_no_raii/src/internal/memory_pool.c (added)
-
examples/gc_no_raii/src/internal/memory_pool.h (added)
-
examples/gc_no_raii/src/internal/object_header.c (added)
-
examples/gc_no_raii/src/internal/object_header.h (added)
-
examples/gc_no_raii/src/internal/state.c (added)
-
examples/gc_no_raii/src/internal/state.h (added)
-
examples/gc_no_raii/src/test_include.c (added)
-
examples/gc_no_raii/src/tools.h (added)
-
examples/gc_no_raii/src/tools/checks.h (added)
-
examples/gc_no_raii/src/tools/print.c (added)
-
examples/gc_no_raii/src/tools/print.h (added)
-
examples/gc_no_raii/src/tools/worklist.h (added)
-
examples/gc_no_raii/test/badlll.c (added)
-
examples/gc_no_raii/test/gctest.c (added)
-
examples/gc_no_raii/test/operators.c (added)
-
examples/hashtable.cfa (added)
-
examples/hashtable2.cfa (added)
-
examples/huge.c (added)
-
examples/includes.c (added)
-
examples/index.h (added)
-
examples/io/cat.c (added)
-
examples/io/filereader.c (added)
-
examples/io/simple/client.c (added)
-
examples/io/simple/server.c (added)
-
examples/io/simple/server.cfa (added)
-
examples/io/simple/server_epoll.c (added)
-
examples/io_uring.txt (added)
-
examples/it_out.c (added)
-
examples/multicore.c (added)
-
examples/new.c (added)
-
examples/poly-bench.c (added)
-
examples/prolog.c (added)
-
examples/quad.c (added)
-
examples/s.c (added)
-
examples/simplePoly.c (added)
-
examples/simpler.c (added)
-
examples/specialize.c (added)
-
examples/square.c (added)
-
examples/twice.c (added)
-
examples/wrapper/.gitignore (added)
-
examples/wrapper/premake4.lua (added)
-
examples/wrapper/src/main.c (added)
-
examples/wrapper/src/pointer.h (added)
-
examples/zero_one.c (added)
-
libcfa/prelude/builtins.c (modified) (2 diffs)
-
libcfa/src/Makefile.am (modified) (2 diffs)
-
libcfa/src/bits/containers.hfa (modified) (1 diff)
-
libcfa/src/bits/locks.hfa (modified) (5 diffs)
-
libcfa/src/concurrency/CtxSwitch-i386.S (modified) (3 diffs)
-
libcfa/src/concurrency/alarm.cfa (modified) (1 diff)
-
libcfa/src/concurrency/clib/cfathread.cfa (deleted)
-
libcfa/src/concurrency/clib/cfathread.h (deleted)
-
libcfa/src/concurrency/coroutine.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/coroutine.hfa (modified) (3 diffs)
-
libcfa/src/concurrency/invoke.h (modified) (3 diffs)
-
libcfa/src/concurrency/io.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/io/call.cfa.in (modified) (2 diffs)
-
libcfa/src/concurrency/io/setup.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/kernel.cfa (modified) (14 diffs)
-
libcfa/src/concurrency/kernel.hfa (modified) (1 diff)
-
libcfa/src/concurrency/kernel/fwd.hfa (modified) (1 diff)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel_private.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/locks.cfa (deleted)
-
libcfa/src/concurrency/locks.hfa (deleted)
-
libcfa/src/concurrency/monitor.cfa (modified) (8 diffs)
-
libcfa/src/concurrency/mutex.cfa (modified) (8 diffs)
-
libcfa/src/concurrency/preemption.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/snzi.hfa (modified) (1 diff)
-
libcfa/src/concurrency/thread.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/thread.hfa (modified) (1 diff)
-
libcfa/src/exception.h (modified) (3 diffs)
-
libcfa/src/exception.hfa (modified) (7 diffs)
-
libcfa/src/parseargs.cfa (modified) (1 diff)
-
src/AST/Convert.cpp (modified) (7 diffs)
-
src/AST/Decl.hpp (modified) (1 diff)
-
src/AST/ForallSubstitutor.hpp (modified) (2 diffs)
-
src/AST/Pass.impl.hpp (modified) (1 diff)
-
src/AST/SymbolTable.cpp (modified) (3 diffs)
-
src/AST/SymbolTable.hpp (modified) (1 diff)
-
src/AST/Type.cpp (modified) (2 diffs)
-
src/AST/Type.hpp (modified) (1 diff)
-
src/Concurrency/Keywords.cc (modified) (6 diffs)
-
src/GenPoly/InstantiateGeneric.cc (modified) (2 diffs)
-
src/InitTweak/FixGlobalInit.cc (modified) (1 diff)
-
src/InitTweak/InitTweak.cc (modified) (1 diff)
-
src/Parser/DeclarationNode.cc (modified) (5 diffs)
-
src/Parser/lex.ll (modified) (3 diffs)
-
src/Parser/parser.yy (modified) (13 diffs)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (3 diffs)
-
src/ResolvExpr/CurrentObject.cc (modified) (2 diffs)
-
src/ResolvExpr/ResolveAssertions.cc (modified) (1 diff)
-
src/ResolvExpr/Resolver.cc (modified) (3 diffs)
-
src/ResolvExpr/SatisfyAssertions.cpp (modified) (2 diffs)
-
src/ResolvExpr/SpecCost.cc (modified) (1 diff)
-
src/ResolvExpr/Unify.cc (modified) (12 diffs)
-
src/SymTab/Autogen.cc (modified) (1 diff)
-
src/SymTab/Mangler.cc (modified) (1 diff)
-
src/SymTab/Validate.cc (modified) (3 diffs)
-
src/SynTree/AggregateDecl.cc (modified) (2 diffs)
-
src/SynTree/Declaration.h (modified) (1 diff)
-
src/SynTree/TypeDecl.cc (modified) (2 diffs)
-
src/Virtual/Tables.cc (modified) (5 diffs)
-
src/Virtual/Tables.h (modified) (1 diff)
-
src/main.cc (modified) (3 diffs)
-
tests/.expect/array.txt (modified) (1 diff)
-
tests/.expect/cast.txt (modified) (1 diff)
-
tests/.expect/const-init.txt (deleted)
-
tests/.expect/enum.txt (modified) (1 diff)
-
tests/.expect/expression.txt (modified) (1 diff)
-
tests/.expect/forall.txt (modified) (1 diff)
-
tests/.expect/heap.txt (modified) (1 diff)
-
tests/.expect/identFuncDeclarator.txt (modified) (1 diff)
-
tests/.expect/identParamDeclarator.txt (modified) (1 diff)
-
tests/.expect/init1-ERROR.txt (deleted)
-
tests/.expect/init1.txt (modified) (1 diff)
-
tests/.expect/labelledExit.txt (modified) (1 diff)
-
tests/.expect/limits.txt (modified) (1 diff)
-
tests/.expect/maybe.txt (modified) (1 diff)
-
tests/.expect/nested-types.txt (modified) (1 diff)
-
tests/.expect/numericConstants.txt (modified) (1 diff)
-
tests/.expect/operators.txt (modified) (1 diff)
-
tests/.expect/poly-cycle.txt (added)
-
tests/.expect/poly-d-cycle.txt (deleted)
-
tests/.expect/poly-o-cycle.txt (deleted)
-
tests/.expect/result.txt (modified) (1 diff)
-
tests/.expect/stdincludes.txt (modified) (1 diff)
-
tests/.expect/switch.txt (modified) (1 diff)
-
tests/.expect/typedefRedef-ERR1.txt (modified) (1 diff)
-
tests/.expect/typedefRedef.txt (modified) (1 diff)
-
tests/.expect/typeof.txt (modified) (1 diff)
-
tests/.expect/variableDeclarator.txt (modified) (1 diff)
-
tests/.expect/voidPtr.txt (modified) (1 diff)
-
tests/Makefile.am (modified) (4 diffs)
-
tests/alloc.cfa (modified) (2 diffs)
-
tests/array.cfa (modified) (2 diffs)
-
tests/bugs/196.cfa (deleted)
-
tests/builtins/.expect/sync.txt (modified) (1 diff)
-
tests/builtins/sync.cfa (modified) (2 diffs)
-
tests/cast.cfa (modified) (1 diff)
-
tests/concurrent/.expect/clib.txt (deleted)
-
tests/concurrent/.expect/cluster.txt (modified) (1 diff)
-
tests/concurrent/clib.c (deleted)
-
tests/concurrent/cluster.cfa (modified) (1 diff)
-
tests/concurrent/examples/.expect/datingService.txt (modified) (1 diff)
-
tests/concurrent/examples/datingService.cfa (modified) (2 diffs)
-
tests/concurrent/futures/.expect/basic.txt (modified) (1 diff)
-
tests/concurrent/futures/basic.cfa (modified) (1 diff)
-
tests/concurrent/park/.expect/force_preempt.txt (modified) (1 diff)
-
tests/concurrent/park/.expect/start_parked.txt (modified) (1 diff)
-
tests/concurrent/park/contention.cfa (modified) (2 diffs)
-
tests/concurrent/park/force_preempt.cfa (modified) (3 diffs)
-
tests/concurrent/park/start_parked.cfa (modified) (1 diff)
-
tests/const-init.cfa (deleted)
-
tests/enum.cfa (modified) (1 diff)
-
tests/errors/.expect/completeType.x64.txt (modified) (1 diff)
-
tests/errors/.expect/completeType.x86.txt (modified) (1 diff)
-
tests/exceptions/.expect/virtual-cast.txt (modified) (1 diff)
-
tests/exceptions/.expect/virtual-poly.txt (modified) (1 diff)
-
tests/exceptions/defaults.cfa (modified) (1 diff)
-
tests/exceptions/virtual-cast.cfa (modified) (1 diff)
-
tests/exceptions/virtual-poly.cfa (modified) (1 diff)
-
tests/expression.cfa (modified) (1 diff)
-
tests/forall.cfa (modified) (3 diffs)
-
tests/heap.cfa (modified) (2 diffs)
-
tests/identFuncDeclarator.cfa (modified) (2 diffs)
-
tests/identParamDeclarator.cfa (modified) (2 diffs)
-
tests/init1.cfa (modified) (5 diffs)
-
tests/labelledExit.cfa (modified) (2 diffs)
-
tests/limits.cfa (modified) (2 diffs)
-
tests/linking/.expect/linkerror.txt (added)
-
tests/linking/linkerror.cfa (added)
-
tests/maybe.cfa (modified) (2 diffs)
-
tests/nested-types.cfa (modified) (2 diffs)
-
tests/numericConstants.cfa (modified) (2 diffs)
-
tests/operators.cfa (modified) (1 diff)
-
tests/poly-cycle.cfa (added)
-
tests/poly-d-cycle.cfa (deleted)
-
tests/poly-o-cycle.cfa (deleted)
-
tests/pybin/tools.py (modified) (1 diff)
-
tests/raii/.expect/ctor-autogen.txt (modified) (1 diff)
-
tests/raii/.expect/init_once.txt (modified) (1 diff)
-
tests/raii/ctor-autogen.cfa (modified) (1 diff)
-
tests/raii/init_once.cfa (modified) (2 diffs)
-
tests/result.cfa (modified) (2 diffs)
-
tests/stdincludes.cfa (modified) (2 diffs)
-
tests/switch.cfa (modified) (2 diffs)
-
tests/test.py (modified) (3 diffs)
-
tests/typedefRedef.cfa (modified) (2 diffs)
-
tests/typeof.cfa (modified) (1 diff)
-
tests/variableDeclarator.cfa (modified) (8 diffs)
-
tests/voidPtr.cfa (modified) (1 diff)
-
tests/warnings/.expect/self-assignment.txt (modified) (1 diff)
-
tests/warnings/self-assignment.cfa (modified) (2 diffs)
-
tests/zombies/ArrayN.c (deleted)
-
tests/zombies/Initialization.c (deleted)
-
tests/zombies/Initialization2.c (deleted)
-
tests/zombies/Makefile.example (deleted)
-
tests/zombies/Members.c (deleted)
-
tests/zombies/Misc.c (deleted)
-
tests/zombies/MiscError.c (deleted)
-
tests/zombies/Rank2.c (deleted)
-
tests/zombies/Tuple.c (deleted)
-
tests/zombies/abstype.c (deleted)
-
tests/zombies/constructors.c (deleted)
-
tests/zombies/forward.c (deleted)
-
tests/zombies/gc_no_raii/.gitignore (deleted)
-
tests/zombies/gc_no_raii/bug-repro/assert.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/blockers.tar.gz (deleted)
-
tests/zombies/gc_no_raii/bug-repro/blockers/explicit_cast.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/blockers/file_scope.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/blockers/recursive_realloc.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/crash.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/deref.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/field.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/find.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/inline.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/malloc.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/not_equal.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/oddtype.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/push_back.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/push_back.h (deleted)
-
tests/zombies/gc_no_raii/bug-repro/realloc.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/return.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/return_template.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/slow_malloc.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/static_const_local.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/test-assert.cpp (deleted)
-
tests/zombies/gc_no_raii/bug-repro/void_pointer.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/while.c (deleted)
-
tests/zombies/gc_no_raii/bug-repro/zero.c (deleted)
-
tests/zombies/gc_no_raii/pool-alloc/allocate-malign.c (deleted)
-
tests/zombies/gc_no_raii/pool-alloc/allocate-malloc.c (deleted)
-
tests/zombies/gc_no_raii/pool-alloc/allocate-mmap.c (deleted)
-
tests/zombies/gc_no_raii/pool-alloc/allocate-win-valloc.c (deleted)
-
tests/zombies/gc_no_raii/premake4.lua (deleted)
-
tests/zombies/gc_no_raii/src/allocate-pool.c (deleted)
-
tests/zombies/gc_no_raii/src/allocate-pool.h (deleted)
-
tests/zombies/gc_no_raii/src/gc.h (deleted)
-
tests/zombies/gc_no_raii/src/gcpointers.c (deleted)
-
tests/zombies/gc_no_raii/src/gcpointers.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/card_table.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/collector.c (deleted)
-
tests/zombies/gc_no_raii/src/internal/collector.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/gc_tools.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/globals.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/memory_pool.c (deleted)
-
tests/zombies/gc_no_raii/src/internal/memory_pool.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/object_header.c (deleted)
-
tests/zombies/gc_no_raii/src/internal/object_header.h (deleted)
-
tests/zombies/gc_no_raii/src/internal/state.c (deleted)
-
tests/zombies/gc_no_raii/src/internal/state.h (deleted)
-
tests/zombies/gc_no_raii/src/test_include.c (deleted)
-
tests/zombies/gc_no_raii/src/tools.h (deleted)
-
tests/zombies/gc_no_raii/src/tools/checks.h (deleted)
-
tests/zombies/gc_no_raii/src/tools/print.c (deleted)
-
tests/zombies/gc_no_raii/src/tools/print.h (deleted)
-
tests/zombies/gc_no_raii/src/tools/worklist.h (deleted)
-
tests/zombies/gc_no_raii/test/badlll.c (deleted)
-
tests/zombies/gc_no_raii/test/gctest.c (deleted)
-
tests/zombies/gc_no_raii/test/operators.c (deleted)
-
tests/zombies/hashtable.cfa (deleted)
-
tests/zombies/hashtable2.cfa (deleted)
-
tests/zombies/huge.c (deleted)
-
tests/zombies/includes.c (deleted)
-
tests/zombies/index.h (deleted)
-
tests/zombies/io/cat.c (deleted)
-
tests/zombies/io/filereader.c (deleted)
-
tests/zombies/io/simple/client.c (deleted)
-
tests/zombies/io/simple/server.c (deleted)
-
tests/zombies/io/simple/server.cfa (deleted)
-
tests/zombies/io/simple/server_epoll.c (deleted)
-
tests/zombies/io_uring.txt (deleted)
-
tests/zombies/it_out.c (deleted)
-
tests/zombies/multicore.c (deleted)
-
tests/zombies/new.c (deleted)
-
tests/zombies/poly-bench.c (deleted)
-
tests/zombies/prolog.c (deleted)
-
tests/zombies/quad.c (deleted)
-
tests/zombies/s.c (deleted)
-
tests/zombies/simplePoly.c (deleted)
-
tests/zombies/simpler.c (deleted)
-
tests/zombies/specialize.c (deleted)
-
tests/zombies/square.c (deleted)
-
tests/zombies/structMember.cfa (modified) (2 diffs)
-
tests/zombies/twice.c (deleted)
-
tests/zombies/wrapper/.gitignore (deleted)
-
tests/zombies/wrapper/premake4.lua (deleted)
-
tests/zombies/wrapper/src/main.c (deleted)
-
tests/zombies/wrapper/src/pointer.h (deleted)
-
tests/zombies/zero_one.c (deleted)
-
tools/gdb/utils-gdb.py (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Jenkins/FullBuild
r223a633 r33c3ded 17 17 18 18 parallel ( 19 gcc_8_x86: { trigger_build( 'gcc-8', 'x86' ) },20 gcc_ 7_x86: { trigger_build( 'gcc-7', 'x86' ) },19 clang_x86: { trigger_build( 'gcc-8', 'x86' ) }, 20 gcc_5_x86: { trigger_build( 'gcc-7', 'x86' ) }, 21 21 gcc_6_x86: { trigger_build( 'gcc-6', 'x86' ) }, 22 22 gcc_9_x64: { trigger_build( 'gcc-9', 'x64' ) }, -
Jenkinsfile
r223a633 r33c3ded 392 392 break 393 393 case 'clang': 394 this.Compiler = new CC_Desc('clang', 'clang++- 10', 'gcc-9', '-flto=thin -flto-jobs=0')394 this.Compiler = new CC_Desc('clang', 'clang++-6.0', 'gcc-6', '-flto=thin -flto-jobs=0') 395 395 break 396 396 default : -
benchmark/Makefile.am
r223a633 r33c3ded 113 113 creation_cfa_generator_DURATION = 1000000000 114 114 creation_upp_coroutine_DURATION = ${creation_cfa_coroutine_eager_DURATION} 115 creation_cfa_thread_DURATION = 10000000 116 creation_upp_thread_DURATION = ${creation_cfa_thread_DURATION} 115 117 creation_DURATION = 10000000 116 118 … … 146 148 147 149 cleancsv: 148 rm -f compile.csv basic.csv ctxswitch.csv mutex.csv sched int.csv150 rm -f compile.csv basic.csv ctxswitch.csv mutex.csv scheduling.csv 149 151 150 152 jenkins$(EXEEXT): cleancsv … … 157 159 +make mutex.csv 158 160 -+make mutex.diff.csv 159 +make sched int.csv160 -+make sched int.diff.csv161 +make scheduling.csv 162 -+make scheduling.diff.csv 161 163 @DOifskipcompile@ 162 164 cat compile.csv … … 167 169 cat mutex.csv 168 170 -cat mutex.diff.csv 169 cat sched int.csv170 -cat sched int.diff.csv171 cat scheduling.csv 172 -cat scheduling.diff.csv 171 173 172 174 compile.csv: … … 198 200 $(srcdir)/fixcsv.sh $@ 199 201 200 sched int.csv:202 scheduling.csv: 201 203 echo "building $@" 202 204 echo "schedint-1,schedint-2,schedext-1,schedext-2" > $@ … … 289 291 ctxswitch-python_coroutine$(EXEEXT): 290 292 $(BENCH_V_PY)echo "#!/bin/sh" > a.out 291 echo "python3 $(srcdir)/ctxswitch/python_cor.py \"$$""@\"" >> a.out293 echo "python3.7 $(srcdir)/ctxswitch/python_cor.py" >> a.out 292 294 chmod a+x a.out 293 295 294 296 ctxswitch-nodejs_coroutine$(EXEEXT): 295 297 $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out 296 echo "nodejs $(srcdir)/ctxswitch/node_cor.js \"$$""@\"" >> a.out298 echo "nodejs $(srcdir)/ctxswitch/node_cor.js" >> a.out 297 299 chmod a+x a.out 298 300 299 301 ctxswitch-nodejs_await$(EXEEXT): 300 302 $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out 301 echo "nodejs $(srcdir)/ctxswitch/node_await.js \"$$""@\"" >> a.out303 echo "nodejs $(srcdir)/ctxswitch/node_await.js" >> a.out 302 304 chmod a+x a.out 303 305 … … 311 313 $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/ctxswitch/JavaThread.java 312 314 echo "#!/bin/sh" > a.out 313 echo "java JavaThread \"$$""@\"" >> a.out315 echo "java JavaThread" >> a.out 314 316 chmod a+x a.out 315 317 … … 353 355 $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/mutex/JavaThread.java 354 356 echo "#!/bin/sh" > a.out 355 echo "java JavaThread \"$$""@\"" >> a.out357 echo "java JavaThread" >> a.out 356 358 chmod a+x a.out 357 359 … … 385 387 $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/schedint/JavaThread.java 386 388 echo "#!/bin/sh" > a.out 387 echo "java JavaThread \"$$""@\"" >> a.out389 echo "java JavaThread" >> a.out 388 390 chmod a+x a.out 389 391 … … 452 454 creation-python_coroutine$(EXEEXT): 453 455 $(BENCH_V_PY)echo "#!/bin/sh" > a.out 454 echo "python3 $(srcdir)/creation/python_cor.py \"$$""@\"" >> a.out456 echo "python3.7 $(srcdir)/creation/python_cor.py" >> a.out 455 457 chmod a+x a.out 456 458 457 459 creation-nodejs_coroutine$(EXEEXT): 458 460 $(BENCH_V_NODEJS)echo "#!/bin/sh" > a.out 459 echo "nodejs $(srcdir)/creation/node_cor.js \"$$""@\"" >> a.out461 echo "nodejs $(srcdir)/creation/node_cor.js" >> a.out 460 462 chmod a+x a.out 461 463 … … 469 471 $(BENCH_V_JAVAC)javac -d $(builddir) $(srcdir)/creation/JavaThread.java 470 472 echo "#!/bin/sh" > a.out 471 echo "java JavaThread \"$$""@\"" >> a.out473 echo "java JavaThread" >> a.out 472 474 chmod a+x a.out 473 475 … … 490 492 491 493 compile-array$(EXEEXT): 492 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/array.cfa494 $(CFACOMPILE) -fsyntax-only -w $(testdir)/array.cfa 493 495 494 496 compile-attributes$(EXEEXT): 495 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/attributes.cfa497 $(CFACOMPILE) -fsyntax-only -w $(testdir)/attributes.cfa 496 498 497 499 compile-empty$(EXEEXT): 498 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(srcdir)/compile/empty.cfa500 $(CFACOMPILE) -fsyntax-only -w $(srcdir)/compile/empty.cfa 499 501 500 502 compile-expression$(EXEEXT): 501 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/expression.cfa503 $(CFACOMPILE) -fsyntax-only -w $(testdir)/expression.cfa 502 504 503 505 compile-io$(EXEEXT): 504 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/io1.cfa506 $(CFACOMPILE) -fsyntax-only -w $(testdir)/io1.cfa 505 507 506 508 compile-monitor$(EXEEXT): 507 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/monitor.cfa509 $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/monitor.cfa 508 510 509 511 compile-operators$(EXEEXT): 510 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/operators.cfa512 $(CFACOMPILE) -fsyntax-only -w $(testdir)/operators.cfa 511 513 512 514 compile-thread$(EXEEXT): 513 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/concurrent/thread.cfa515 $(CFACOMPILE) -fsyntax-only -w $(testdir)/concurrent/thread.cfa 514 516 515 517 compile-typeof$(EXEEXT): 516 $(CFACOMPILE) - DNO_COMPILED_PRAGMA -fsyntax-only -w $(testdir)/typeof.cfa518 $(CFACOMPILE) -fsyntax-only -w $(testdir)/typeof.cfa 517 519 518 520 ## ========================================================================================================= -
benchmark/creation/JavaThread.java
r223a633 r33c3ded 47 47 } 48 48 public static void main(String[] args) throws InterruptedException { 49 if ( args.length > 1) System.exit( 1 );50 if ( args.length == 1 ) { times = Long.parseLong(args[0]); }49 if ( args.length > 2 ) System.exit( 1 ); 50 if ( args.length == 2 ) { times = Long.parseLong(args[1]); } 51 51 52 52 for (int i = Integer.parseInt("5"); --i >= 0 ; ) { -
benchmark/ctxswitch/JavaThread.java
r223a633 r33c3ded 40 40 } 41 41 public static void main(String[] args) throws InterruptedException { 42 if ( args.length > 1) System.exit( 1 );43 if ( args.length == 1 ) { times = Long.parseLong(args[0]); }42 if ( args.length > 2 ) System.exit( 1 ); 43 if ( args.length == 2 ) { times = Long.parseLong(args[1]); } 44 44 45 45 for (int i = Integer.parseInt("5"); --i >= 0 ; ) { -
benchmark/io/http/main.cfa
r223a633 r33c3ded 125 125 workers[i].flags = 0; 126 126 } 127 unpark( workers[i] );127 unpark( workers[i] __cfaabi_dbg_ctx2 ); 128 128 } 129 129 printf("%d workers started on %d processors\n", options.clopts.nworkers, options.clopts.nprocs); -
benchmark/io/http/worker.cfa
r223a633 r33c3ded 22 22 23 23 void main( Worker & this ) { 24 park( );24 park( __cfaabi_dbg_ctx ); 25 25 /* paranoid */ assert( this.pipe[0] != -1 ); 26 26 /* paranoid */ assert( this.pipe[1] != -1 ); -
benchmark/io/readv.cfa
r223a633 r33c3ded 54 54 55 55 void main( Reader & ) { 56 park( );56 park( __cfaabi_dbg_ctx ); 57 57 /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) ); 58 58 … … 151 151 152 152 for(i; nthreads) { 153 unpark( threads[i] );153 unpark( threads[i] __cfaabi_dbg_ctx2 ); 154 154 } 155 155 wait(duration, start, end, is_tty); -
benchmark/mutex/JavaThread.java
r223a633 r33c3ded 47 47 } 48 48 public static void main(String[] args) throws InterruptedException { 49 if ( args.length > 1) System.exit( 1 );50 if ( args.length == 1 ) { times = Long.parseLong(args[0]); }49 if ( args.length > 2 ) System.exit( 1 ); 50 if ( args.length == 2 ) { times = Long.parseLong(args[1]); } 51 51 52 52 for (int n = Integer.parseInt("5"); --n >= 0 ; ) { -
benchmark/readyQ/yield.cfa
r223a633 r33c3ded 32 32 33 33 void main( Yielder & this ) { 34 park( );34 park( __cfaabi_dbg_ctx ); 35 35 /* paranoid */ assert( true == __atomic_load_n(&run, __ATOMIC_RELAXED) ); 36 36 … … 70 70 71 71 for(i; nthreads) { 72 unpark( threads[i] );72 unpark( threads[i] __cfaabi_dbg_ctx2 ); 73 73 } 74 74 wait(duration, start, end, is_tty); -
benchmark/schedint/JavaThread.java
r223a633 r33c3ded 75 75 } 76 76 public static void main(String[] args) throws InterruptedException { 77 if ( args.length > 1) System.exit( 1 );78 if ( args.length == 1 ) { times = Long.parseLong(args[0]); }77 if ( args.length > 2 ) System.exit( 1 ); 78 if ( args.length == 2 ) { times = Long.parseLong(args[1]); } 79 79 80 80 for (int n = Integer.parseInt("5"); --n >= 0 ; ) { -
doc/LaTeXmacros/common.tex
r223a633 r33c3ded 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Oct 5 09:34:46202014 %% Update Count : 46413 %% Last Modified On : Fri Sep 4 13:56:52 2020 14 %% Update Count : 383 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 55 55 \newlength{\parindentlnth} 56 56 \setlength{\parindentlnth}{\parindent} 57 58 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}} 59 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 60 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 61 62 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 63 \newlength{\columnposn} 64 \setlength{\gcolumnposn}{2.5in} 65 \setlength{\columnposn}{\gcolumnposn} 66 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}} 67 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 68 69 % allow escape sequence in lstinline 70 %\usepackage{etoolbox} 71 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 57 72 58 73 \usepackage{pslatex} % reduce size of san serif font … … 229 244 \usepackage{listings} % format program code 230 245 \usepackage{lstlang} 231 \makeatletter 232 233 \newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}} 234 \newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}} 235 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 236 237 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly 238 \newlength{\columnposn} 239 \setlength{\gcolumnposn}{2.75in} 240 \setlength{\columnposn}{\gcolumnposn} 241 \newcommand{\C}[2][\@empty]{\ifx#1\@empty\else\global\setlength{\columnposn}{#1}\global\columnposn=\columnposn\fi\hfill\makebox[\textwidth-\columnposn][l]{\lst@basicstyle{\LstCommentStyle{#2}}}} 242 \newcommand{\CRT}{\global\columnposn=\gcolumnposn} 243 244 % allow escape sequence in lstinline 245 %\usepackage{etoolbox} 246 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 247 248 % allow adding to lst literate 249 \def\addToLiterate#1{\protect\edef\lst@literate{\unexpanded\expandafter{\lst@literate}\unexpanded{#1}}} 250 \lst@Key{add to literate}{}{\addToLiterate{#1}} 251 \makeatother 252 253 \newcommand{\CFAStyle}{% 246 247 \newcommand{\CFADefaults}{% 254 248 \lstset{ 249 language=CFA, 255 250 columns=fullflexible, 256 251 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font … … 267 262 belowskip=3pt, 268 263 % replace/adjust listing characters that look bad in sanserif 269 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0. 75ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1264 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 270 265 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 271 266 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2, 272 }% lstset 273 }% CFAStyle 274 275 \ifdefined\CFALatin% extra Latin-1 escape characters 276 \lstnewenvironment{cfa}[1][]{ 277 \lstset{ 278 language=CFA, 279 moredelim=**[is][\color{red}]{®}{®}, % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 267 moredelim=**[is][\color{red}]{?}{?}, % red highlighting ?...? (registered trademark symbol) emacs: C-q M-. 280 268 moredelim=**[is][\color{blue}]{ß}{ß}, % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ 281 269 moredelim=**[is][\color{OliveGreen}]{¢}{¢}, % green highlighting ¢...¢ (cent symbol) emacs: C-q M-" 282 270 moredelim=[is][\lstset{keywords={}}]{¶}{¶}, % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 283 % replace/adjust listing characters that look bad in sanserif284 add to literate={`}{\ttfamily\upshape\hspace*{-0.1ex}`}1285 271 }% lstset 286 \lstset{#1} 287 }{} 272 }% CFADefaults 273 \newcommand{\CFAStyle}{% 274 \CFADefaults 288 275 % inline code ©...© (copyright symbol) emacs: C-q M-) 289 276 \lstMakeShortInline© % single-character for \lstinline 290 \else% regular ASCI characters 291 \lstnewenvironment{cfa}[1][]{ 292 \lstset{ 293 language=CFA, 294 escapechar=\$, % LaTeX escape in CFA code 295 moredelim=**[is][\color{red}]{@}{@}, % red highlighting @...@ 296 }% lstset 297 \lstset{#1} 298 }{} 299 % inline code @...@ (at symbol) 300 \lstMakeShortInline@ % single-character for \lstinline 301 \fi% 277 }% CFAStyle 278 279 \lstnewenvironment{cfa}[1][] 280 {\CFADefaults\lstset{#1}} 281 {} 302 282 303 283 % Local Variables: % -
doc/LaTeXmacros/lstlang.sty
r223a633 r33c3ded 8 8 %% Created On : Sat May 13 16:34:42 2017 9 9 %% Last Modified By : Peter A. Buhr 10 %% Last Modified On : Wed Sep 23 22:40:04 202011 %% Update Count : 2 410 %% Last Modified On : Tue Jan 8 14:40:33 2019 11 %% Update Count : 21 12 12 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 13 13 … … 115 115 auto, _Bool, catch, catchResume, choose, _Complex, __complex, __complex__, __const, __const__, 116 116 coroutine, disable, dtype, enable, exception, __extension__, fallthrough, fallthru, finally, 117 __float80, float80, __float128, float128, forall, ftype, generator,_Generic, _Imaginary, __imag, __imag__,117 __float80, float80, __float128, float128, forall, ftype, _Generic, _Imaginary, __imag, __imag__, 118 118 inline, __inline, __inline__, __int128, int128, __label__, monitor, mutex, _Noreturn, one_t, or, 119 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, suspend,thread,119 otype, restrict, __restrict, __restrict__, __signed, __signed__, _Static_assert, thread, 120 120 _Thread_local, throw, throwResume, timeout, trait, try, ttype, typeof, __typeof, __typeof__, 121 121 virtual, __volatile, __volatile__, waitfor, when, with, zero_t, … … 125 125 126 126 % C++ programming language 127 \lstdefinelanguage{C++}[ANSI]{C++}{ 128 morekeywords={nullptr,} 129 } 127 \lstdefinelanguage{C++}[ANSI]{C++}{} 130 128 131 129 % uC++ programming language, based on ANSI C++ -
doc/bibliography/pl.bib
r223a633 r33c3ded 1005 1005 key = {Cforall Benchmarks}, 1006 1006 author = {{\textsf{C}{$\mathbf{\forall}$} Benchmarks}}, 1007 howpublished= {\href{https:// github.com/cforall/ConcurrentBenchmarks_SPE20}{https://\-github.com/\-cforall/\-ConcurrentBenchmarks\_SPE20}},1007 howpublished= {\href{https://plg.uwaterloo.ca/~cforall/doc/CforallConcurrentBenchmarks.tar}{https://\-plg.uwaterloo.ca/\-$\sim$cforall/\-doc/\-CforallConcurrentBenchmarks.tar}}, 1008 1008 } 1009 1009 … … 1973 1973 title = {Cooperating Sequential Processes}, 1974 1974 institution = {Technological University}, 1975 address = {Eindhoven, Neth .},1975 address = {Eindhoven, Netherlands}, 1976 1976 year = 1965, 1977 1977 note = {Reprinted in \cite{Genuys68} pp. 43--112.} -
doc/papers/concurrency/Paper.tex
r223a633 r33c3ded 224 224 {} 225 225 \lstnewenvironment{C++}[1][] % use C++ style 226 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{`}{`} }\lstset{#1}}226 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 227 227 {} 228 228 \lstnewenvironment{uC++}[1][] 229 {\lstset{language=uC++,moredelim=**[is][\protect\color{red}]{`}{`} }\lstset{#1}}229 {\lstset{language=uC++,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 230 230 {} 231 231 \lstnewenvironment{Go}[1][] 232 {\lstset{language=Golang,moredelim=**[is][\protect\color{red}]{`}{`} }\lstset{#1}}232 {\lstset{language=Golang,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 233 233 {} 234 234 \lstnewenvironment{python}[1][] 235 {\lstset{language=python,moredelim=**[is][\protect\color{red}]{`}{`} }\lstset{#1}}235 {\lstset{language=python,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 236 236 {} 237 237 \lstnewenvironment{java}[1][] 238 {\lstset{language=java,moredelim=**[is][\protect\color{red}]{`}{`} }\lstset{#1}}238 {\lstset{language=java,moredelim=**[is][\protect\color{red}]{`}{`},#1}\lstset{#1}} 239 239 {} 240 240 … … 284 284 285 285 \begin{document} 286 %\linenumbers % comment out to turn off line numbering286 \linenumbers % comment out to turn off line numbering 287 287 288 288 \maketitle … … 450 450 \hline 451 451 stateful & thread & \multicolumn{1}{c|}{No} & \multicolumn{1}{c}{Yes} \\ 452 \hline 453 \hline 452 \hline 453 \hline 454 454 No & No & \textbf{1}\ \ \ @struct@ & \textbf{2}\ \ \ @mutex@ @struct@ \\ 455 \hline 455 \hline 456 456 Yes (stackless) & No & \textbf{3}\ \ \ @generator@ & \textbf{4}\ \ \ @mutex@ @generator@ \\ 457 \hline 457 \hline 458 458 Yes (stackful) & No & \textbf{5}\ \ \ @coroutine@ & \textbf{6}\ \ \ @mutex@ @coroutine@ \\ 459 \hline 459 \hline 460 460 No & Yes & \textbf{7}\ \ \ {\color{red}rejected} & \textbf{8}\ \ \ {\color{red}rejected} \\ 461 \hline 461 \hline 462 462 Yes (stackless) & Yes & \textbf{9}\ \ \ {\color{red}rejected} & \textbf{10}\ \ \ {\color{red}rejected} \\ 463 \hline 463 \hline 464 464 Yes (stackful) & Yes & \textbf{11}\ \ \ @thread@ & \textbf{12}\ \ @mutex@ @thread@ \\ 465 465 \end{tabular} … … 2896 2896 \label{s:RuntimeStructureCluster} 2897 2897 2898 A \newterm{cluster} is a collection of user and kernel threads, where the kernel threads run the user threads from the cluster's ready queue, and the operating system runs the kernel threads on the processors from its ready queue ~\cite{Buhr90a}.2898 A \newterm{cluster} is a collection of user and kernel threads, where the kernel threads run the user threads from the cluster's ready queue, and the operating system runs the kernel threads on the processors from its ready queue. 2899 2899 The term \newterm{virtual processor} is introduced as a synonym for kernel thread to disambiguate between user and kernel thread. 2900 2900 From the language perspective, a virtual processor is an actual processor (core). … … 2992 2992 \end{cfa} 2993 2993 where CPU time in nanoseconds is from the appropriate language clock. 2994 Each benchmark is performed @N@ times, where @N@ is selected so the benchmark runs in the range of 2--20 seconds for the specific programming language; 2995 each @N@ appears after the experiment name in the following tables. 2994 Each benchmark is performed @N@ times, where @N@ is selected so the benchmark runs in the range of 2--20 seconds for the specific programming language. 2996 2995 The total time is divided by @N@ to obtain the average time for a benchmark. 2997 2996 Each benchmark experiment is run 13 times and the average appears in the table. 2998 For languages with a runtime JIT (Java, Node.js, Python), a single half-hour long experiment is run to check stability;2999 all long-experiment results are statistically equivalent, \ie median/average/standard-deviation correlate with the short-experiment results, indicating the short experiments reached a steady state.3000 2997 All omitted tests for other languages are functionally identical to the \CFA tests and available online~\cite{CforallConcurrentBenchmarks}. 2998 % tar --exclude-ignore=exclude -cvhf benchmark.tar benchmark 2999 % cp -p benchmark.tar /u/cforall/public_html/doc/concurrent_benchmark.tar 3001 3000 3002 3001 \paragraph{Creation} … … 3007 3006 3008 3007 \begin{multicols}{2} 3009 \begin{cfa}[xleftmargin=0pt] 3010 `coroutine` MyCoroutine {}; 3008 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 3009 \begin{cfa} 3010 @coroutine@ MyCoroutine {}; 3011 3011 void ?{}( MyCoroutine & this ) { 3012 3012 #ifdef EAGER … … 3016 3016 void main( MyCoroutine & ) {} 3017 3017 int main() { 3018 BENCH( for ( N ) { `MyCoroutine c;`} )3018 BENCH( for ( N ) { @MyCoroutine c;@ } ) 3019 3019 sout | result; 3020 3020 } … … 3030 3030 3031 3031 \begin{tabular}[t]{@{}r*{3}{D{.}{.}{5.2}}@{}} 3032 \multicolumn{1}{@{}r}{N\hspace*{10pt}} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3033 \CFA generator (1B) & 0.6 & 0.6 & 0.0 \\ 3034 \CFA coroutine lazy (100M) & 13.4 & 13.1 & 0.5 \\ 3035 \CFA coroutine eager (10M) & 144.7 & 143.9 & 1.5 \\ 3036 \CFA thread (10M) & 466.4 & 468.0 & 11.3 \\ 3037 \uC coroutine (10M) & 155.6 & 155.7 & 1.7 \\ 3038 \uC thread (10M) & 523.4 & 523.9 & 7.7 \\ 3039 Python generator (10M) & 123.2 & 124.3 & 4.1 \\ 3040 Node.js generator (10M) & 33.4 & 33.5 & 0.3 \\ 3041 Goroutine thread (10M) & 751.0 & 750.5 & 3.1 \\ 3042 Rust tokio thread (10M) & 1860.0 & 1881.1 & 37.6 \\ 3043 Rust thread (250K) & 53801.0 & 53896.8 & 274.9 \\ 3044 Java thread (250K) & 119256.0 & 119679.2 & 2244.0 \\ 3045 % Java thread (1 000 000) & 123100.0 & 123052.5 & 751.6 \\ 3046 Pthreads thread (250K) & 31465.5 & 31419.5 & 140.4 3032 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3033 \CFA generator & 0.6 & 0.6 & 0.0 \\ 3034 \CFA coroutine lazy & 13.4 & 13.1 & 0.5 \\ 3035 \CFA coroutine eager & 144.7 & 143.9 & 1.5 \\ 3036 \CFA thread & 466.4 & 468.0 & 11.3 \\ 3037 \uC coroutine & 155.6 & 155.7 & 1.7 \\ 3038 \uC thread & 523.4 & 523.9 & 7.7 \\ 3039 Python generator & 123.2 & 124.3 & 4.1 \\ 3040 Node.js generator & 33.4 & 33.5 & 0.3 \\ 3041 Goroutine thread & 751.0 & 750.5 & 3.1 \\ 3042 Rust tokio thread & 1860.0 & 1881.1 & 37.6 \\ 3043 Rust thread & 53801.0 & 53896.8 & 274.9 \\ 3044 Java thread & 120274.0 & 120722.9 & 2356.7 \\ 3045 Pthreads thread & 31465.5 & 31419.5 & 140.4 3047 3046 \end{tabular} 3048 3047 \end{multicols} … … 3053 3052 Internal scheduling is measured using a cycle of two threads signalling and waiting. 3054 3053 Figure~\ref{f:schedint} shows the code for \CFA, with results in Table~\ref{t:schedint}. 3055 Note, the \CFA incremental cost for bulk acquire is a fixed cost for small numbers of mutex objects. 3056 User-level threading has one kernel thread, eliminating contention between the threads (direct handoff of the kernel thread). 3057 Kernel-level threading has two kernel threads allowing some contention. 3054 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects. 3055 Java scheduling is significantly greater because the benchmark explicitly creates multiple threads in order to prevent the JIT from making the program sequential, \ie removing all locking. 3058 3056 3059 3057 \begin{multicols}{2} 3060 \ setlength{\tabcolsep}{3pt}3061 \begin{cfa} [xleftmargin=0pt]3058 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 3059 \begin{cfa} 3062 3060 volatile int go = 0; 3063 `condition c;` 3064 `monitor`M {} m1/*, m2, m3, m4*/;3065 void call( M & `mutex p1/*, p2, p3, p4*/`) {3066 `signal( c );`3067 } 3068 void wait( M & `mutex p1/*, p2, p3, p4*/`) {3061 @condition c;@ 3062 @monitor@ M {} m1/*, m2, m3, m4*/; 3063 void call( M & @mutex p1/*, p2, p3, p4*/@ ) { 3064 @signal( c );@ 3065 } 3066 void wait( M & @mutex p1/*, p2, p3, p4*/@ ) { 3069 3067 go = 1; // continue other thread 3070 for ( N ) { `wait( c );`} );3068 for ( N ) { @wait( c );@ } ); 3071 3069 } 3072 3070 thread T {}; … … 3093 3091 3094 3092 \begin{tabular}{@{}r*{3}{D{.}{.}{5.2}}@{}} 3095 \multicolumn{1}{@{}r}{N\hspace*{10pt}} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3096 \CFA @signal@, 1 monitor (10M) & 364.4 & 364.2 & 4.4 \\ 3097 \CFA @signal@, 2 monitor (10M) & 484.4 & 483.9 & 8.8 \\ 3098 \CFA @signal@, 4 monitor (10M) & 709.1 & 707.7 & 15.0 \\ 3099 \uC @signal@ monitor (10M) & 328.3 & 327.4 & 2.4 \\ 3100 Rust cond. variable (1M) & 7514.0 & 7437.4 & 397.2 \\ 3101 Java @notify@ monitor (1M) & 8717.0 & 8774.1 & 471.8 \\ 3102 % Java @notify@ monitor (100 000 000) & 8634.0 & 8683.5 & 330.5 \\ 3103 Pthreads cond. variable (1M) & 5553.7 & 5576.1 & 345.6 3093 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} & \multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3094 \CFA @signal@, 1 monitor & 364.4 & 364.2 & 4.4 \\ 3095 \CFA @signal@, 2 monitor & 484.4 & 483.9 & 8.8 \\ 3096 \CFA @signal@, 4 monitor & 709.1 & 707.7 & 15.0 \\ 3097 \uC @signal@ monitor & 328.3 & 327.4 & 2.4 \\ 3098 Rust cond. variable & 7514.0 & 7437.4 & 397.2 \\ 3099 Java @notify@ monitor & 9623.0 & 9654.6 & 236.2 \\ 3100 Pthreads cond. variable & 5553.7 & 5576.1 & 345.6 3104 3101 \end{tabular} 3105 3102 \end{multicols} … … 3110 3107 External scheduling is measured using a cycle of two threads calling and accepting the call using the @waitfor@ statement. 3111 3108 Figure~\ref{f:schedext} shows the code for \CFA with results in Table~\ref{t:schedext}. 3112 Note, the \CFA incremental cost for bulk acquire isa fixed cost for small numbers of mutex objects.3109 Note, the incremental cost of bulk acquire for \CFA, which is largely a fixed cost for small numbers of mutex objects. 3113 3110 3114 3111 \begin{multicols}{2} 3115 \ setlength{\tabcolsep}{5pt}3112 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 3116 3113 \vspace*{-16pt} 3117 \begin{cfa} [xleftmargin=0pt]3118 `monitor`M {} m1/*, m2, m3, m4*/;3119 void call( M & `mutex p1/*, p2, p3, p4*/`) {}3120 void wait( M & `mutex p1/*, p2, p3, p4*/`) {3121 for ( N ) { `waitfor( call : p1/*, p2, p3, p4*/ );`}3114 \begin{cfa} 3115 @monitor@ M {} m1/*, m2, m3, m4*/; 3116 void call( M & @mutex p1/*, p2, p3, p4*/@ ) {} 3117 void wait( M & @mutex p1/*, p2, p3, p4*/@ ) { 3118 for ( N ) { @waitfor( call : p1/*, p2, p3, p4*/ );@ } 3122 3119 } 3123 3120 thread T {}; … … 3136 3133 \columnbreak 3137 3134 3138 \vspace*{-1 8pt}3135 \vspace*{-16pt} 3139 3136 \captionof{table}{External-scheduling comparison (nanoseconds)} 3140 3137 \label{t:schedext} 3141 3138 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 3142 \multicolumn{1}{@{} r}{N\hspace*{10pt}} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\3143 \CFA @waitfor@, 1 monitor (10M)& 367.1 & 365.3 & 5.0 \\3144 \CFA @waitfor@, 2 monitor (10M)& 463.0 & 464.6 & 7.1 \\3145 \CFA @waitfor@, 4 monitor (10M)& 689.6 & 696.2 & 21.5 \\3146 \uC \lstinline[language=uC++]|_Accept| monitor (10M)& 328.2 & 329.1 & 3.4 \\3147 Go \lstinline[language=Golang]|select| channel (10M)& 365.0 & 365.5 & 1.23139 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3140 \CFA @waitfor@, 1 monitor & 367.1 & 365.3 & 5.0 \\ 3141 \CFA @waitfor@, 2 monitor & 463.0 & 464.6 & 7.1 \\ 3142 \CFA @waitfor@, 4 monitor & 689.6 & 696.2 & 21.5 \\ 3143 \uC \lstinline[language=uC++]|_Accept| monitor & 328.2 & 329.1 & 3.4 \\ 3144 Go \lstinline[language=Golang]|select| channel & 365.0 & 365.5 & 1.2 3148 3145 \end{tabular} 3149 3146 \end{multicols} … … 3158 3155 3159 3156 \begin{multicols}{2} 3160 \ setlength{\tabcolsep}{3pt}3161 \begin{cfa} [xleftmargin=0pt]3162 `monitor`M {} m1/*, m2, m3, m4*/;3163 call( M & `mutex p1/*, p2, p3, p4*/`) {}3157 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 3158 \begin{cfa} 3159 @monitor@ M {} m1/*, m2, m3, m4*/; 3160 call( M & @mutex p1/*, p2, p3, p4*/@ ) {} 3164 3161 int main() { 3165 3162 BENCH( for( N ) call( m1/*, m2, m3, m4*/ ); ) … … 3176 3173 \label{t:mutex} 3177 3174 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 3178 \multicolumn{1}{@{}r}{N\hspace*{10pt}} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3179 test-and-test-set lock (50M) & 19.1 & 18.9 & 0.4 \\ 3180 \CFA @mutex@ function, 1 arg. (50M) & 48.3 & 47.8 & 0.9 \\ 3181 \CFA @mutex@ function, 2 arg. (50M) & 86.7 & 87.6 & 1.9 \\ 3182 \CFA @mutex@ function, 4 arg. (50M) & 173.4 & 169.4 & 5.9 \\ 3183 \uC @monitor@ member rtn. (50M) & 54.8 & 54.8 & 0.1 \\ 3184 Goroutine mutex lock (50M) & 34.0 & 34.0 & 0.0 \\ 3185 Rust mutex lock (50M) & 33.0 & 33.2 & 0.8 \\ 3186 Java synchronized method (50M) & 31.0 & 30.9 & 0.5 \\ 3187 % Java synchronized method (10 000 000 000) & 31.0 & 30.2 & 0.9 \\ 3188 Pthreads mutex Lock (50M) & 31.0 & 31.1 & 0.4 3175 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3176 test-and-test-set lock & 19.1 & 18.9 & 0.4 \\ 3177 \CFA @mutex@ function, 1 arg. & 48.3 & 47.8 & 0.9 \\ 3178 \CFA @mutex@ function, 2 arg. & 86.7 & 87.6 & 1.9 \\ 3179 \CFA @mutex@ function, 4 arg. & 173.4 & 169.4 & 5.9 \\ 3180 \uC @monitor@ member rtn. & 54.8 & 54.8 & 0.1 \\ 3181 Goroutine mutex lock & 34.0 & 34.0 & 0.0 \\ 3182 Rust mutex lock & 33.0 & 33.2 & 0.8 \\ 3183 Java synchronized method & 31.0 & 31.0 & 0.0 \\ 3184 Pthreads mutex Lock & 31.0 & 31.1 & 0.4 3189 3185 \end{tabular} 3190 3186 \end{multicols} … … 3205 3201 % To: "Peter A. Buhr" <pabuhr@plg2.cs.uwaterloo.ca> 3206 3202 % Date: Fri, 24 Jan 2020 13:49:18 -0500 3207 % 3203 % 3208 3204 % I can also verify that the previous version, which just tied a bunch of promises together, *does not* go back to the 3209 3205 % event loop at all in the current version of Node. Presumably they're taking advantage of the fact that the ordering of … … 3215 3211 3216 3212 \begin{multicols}{2} 3217 \begin{cfa}[xleftmargin=0pt] 3218 `coroutine` C {}; 3219 void main( C & ) { for () { `suspend;` } } 3213 \lstset{language=CFA,moredelim=**[is][\color{red}]{@}{@},deletedelim=**[is][]{`}{`}} 3214 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3215 @coroutine@ C {}; 3216 void main( C & ) { for () { @suspend;@ } } 3220 3217 int main() { // coroutine test 3221 3218 C c; 3222 BENCH( for ( N ) { `resume( c );`} )3219 BENCH( for ( N ) { @resume( c );@ } ) 3223 3220 sout | result; 3224 3221 } 3225 3222 int main() { // thread test 3226 BENCH( for ( N ) { `yield();`} )3223 BENCH( for ( N ) { @yield();@ } ) 3227 3224 sout | result; 3228 3225 } … … 3237 3234 \label{t:ctx-switch} 3238 3235 \begin{tabular}{@{}r*{3}{D{.}{.}{3.2}}@{}} 3239 \multicolumn{1}{@{}r}{N\hspace*{10pt}} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3240 C function (10B) & 1.8 & 1.8 & 0.0 \\ 3241 \CFA generator (5B) & 1.8 & 2.0 & 0.3 \\ 3242 \CFA coroutine (100M) & 32.5 & 32.9 & 0.8 \\ 3243 \CFA thread (100M) & 93.8 & 93.6 & 2.2 \\ 3244 \uC coroutine (100M) & 50.3 & 50.3 & 0.2 \\ 3245 \uC thread (100M) & 97.3 & 97.4 & 1.0 \\ 3246 Python generator (100M) & 40.9 & 41.3 & 1.5 \\ 3247 Node.js await (5M) & 1852.2 & 1854.7 & 16.4 \\ 3248 Node.js generator (100M) & 33.3 & 33.4 & 0.3 \\ 3249 Goroutine thread (100M) & 143.0 & 143.3 & 1.1 \\ 3250 Rust async await (100M) & 32.0 & 32.0 & 0.0 \\ 3251 Rust tokio thread (100M) & 143.0 & 143.0 & 1.7 \\ 3252 Rust thread (25M) & 332.0 & 331.4 & 2.4 \\ 3253 Java thread (100M) & 405.0 & 415.0 & 17.6 \\ 3254 % Java thread ( 100 000 000) & 413.0 & 414.2 & 6.2 \\ 3255 % Java thread (5 000 000 000) & 415.0 & 415.2 & 6.1 \\ 3256 Pthreads thread (25M) & 334.3 & 335.2 & 3.9 3236 \multicolumn{1}{@{}c}{} & \multicolumn{1}{c}{Median} &\multicolumn{1}{c}{Average} & \multicolumn{1}{c@{}}{Std Dev} \\ 3237 C function & 1.8 & 1.8 & 0.0 \\ 3238 \CFA generator & 1.8 & 2.0 & 0.3 \\ 3239 \CFA coroutine & 32.5 & 32.9 & 0.8 \\ 3240 \CFA thread & 93.8 & 93.6 & 2.2 \\ 3241 \uC coroutine & 50.3 & 50.3 & 0.2 \\ 3242 \uC thread & 97.3 & 97.4 & 1.0 \\ 3243 Python generator & 40.9 & 41.3 & 1.5 \\ 3244 Node.js await & 1852.2 & 1854.7 & 16.4 \\ 3245 Node.js generator & 33.3 & 33.4 & 0.3 \\ 3246 Goroutine thread & 143.0 & 143.3 & 1.1 \\ 3247 Rust async await & 32.0 & 32.0 & 0.0 \\ 3248 Rust tokio thread & 143.0 & 143.0 & 1.7 \\ 3249 Rust thread & 332.0 & 331.4 & 2.4 \\ 3250 Java thread & 405.0 & 415.0 & 17.6 \\ 3251 Pthreads thread & 334.3 & 335.2 & 3.9 3257 3252 \end{tabular} 3258 3253 \end{multicols} … … 3263 3258 Languages using 1:1 threading based on pthreads can at best meet or exceed, due to language overhead, the pthread results. 3264 3259 Note, pthreads has a fast zero-contention mutex lock checked in user space. 3265 Languages with M:N threading have better performance than 1:1 because there is no operating-system interactions (context-switching or locking). 3266 As well, for locking experiments, M:N threading has less contention if only one kernel thread is used. 3260 Languages with M:N threading have better performance than 1:1 because there is no operating-system interactions. 3267 3261 Languages with stackful coroutines have higher cost than stackless coroutines because of stack allocation and context switching; 3268 3262 however, stackful \uC and \CFA coroutines have approximately the same performance as stackless Python and Node.js generators. 3269 3263 The \CFA stackless generator is approximately 25 times faster for suspend/resume and 200 times faster for creation than stackless Python and Node.js generators. 3270 The Node.js context-switch is costly when asynchronous await must enter the event engine because a promise is not fulfilled.3271 Finally, the benchmark results correlate across programming languages with and without JIT, indicating the JIT has completed any runtime optimizations.3272 3264 3273 3265 … … 3327 3319 3328 3320 The authors recognize the design assistance of Aaron Moss, Rob Schluntz, Andrew Beach, and Michael Brooks; David Dice for commenting and helping with the Java benchmarks; and Gregor Richards for helping with the Node.js benchmarks. 3329 This research is funded by the NSERC/Waterloo-Huawei (\url{http://www.huawei.com}) Joint Innovation Lab. %, and Peter Buhr is partially funded by the Natural Sciences and Engineering Research Council of Canada.3321 This research is funded by a grant from Waterloo-Huawei (\url{http://www.huawei.com}) Joint Innovation Lab. %, and Peter Buhr is partially funded by the Natural Sciences and Engineering Research Council of Canada. 3330 3322 3331 3323 {% -
doc/papers/concurrency/annex/local.bib
r223a633 r33c3ded 59 59 @manual{Cpp-Transactions, 60 60 keywords = {C++, Transactional Memory}, 61 title = {Tech . Spec.for C++ Extensions for Transactional Memory},61 title = {Technical Specification for C++ Extensions for Transactional Memory}, 62 62 organization= {International Standard ISO/IEC TS 19841:2015 }, 63 63 publisher = {American National Standards Institute}, -
doc/papers/concurrency/mail2
r223a633 r33c3ded 959 959 Software: Practice and Experience Editorial Office 960 960 961 962 963 Date: Wed, 2 Sep 2020 20:55:34 +0000964 From: Richard Jones <onbehalfof@manuscriptcentral.com>965 Reply-To: R.E.Jones@kent.ac.uk966 To: tdelisle@uwaterloo.ca, pabuhr@uwaterloo.ca967 Subject: Software: Practice and Experience - Decision on Manuscript ID968 SPE-19-0219.R2969 970 02-Sep-2020971 972 Dear Dr Buhr,973 974 Many thanks for submitting SPE-19-0219.R2 entitled "Advanced Control-flow and Concurrency in Cforall" to Software: Practice and Experience. The paper has now been reviewed and the comments of the referees are included at the bottom of this letter. I apologise for the length of time it has taken to get these.975 976 Both reviewers consider this paper to be close to acceptance. However, before I can accept this paper, I would like you address the comments of Reviewer 2, particularly with regard to the description of the adaptation Java harness to deal with warmup. I would expect to see a convincing argument that the computation has reached a steady state. I would also like you to provide the values for N for each benchmark run. This should be very straightforward for you to do. There are a couple of papers on steady state that you may wish to consult (though I am certainly not pushing my own work).977 978 1) Barrett, Edd; Bolz-Tereick, Carl Friedrich; Killick, Rebecca; Mount, Sarah and Tratt, Laurence. Virtual Machine Warmup Blows Hot and Cold. OOPSLA 2017. https://doi.org/10.1145/3133876979 Virtual Machines (VMs) with Just-In-Time (JIT) compilers are traditionally thought to execute programs in two phases: the initial warmup phase determines which parts of a program would most benefit from dynamic compilation, before JIT compiling those parts into machine code; subsequently the program is said to be at a steady state of peak performance. Measurement methodologies almost always discard data collected during the warmup phase such that reported measurements focus entirely on peak performance. We introduce a fully automated statistical approach, based on changepoint analysis, which allows us to determine if a program has reached a steady state and, if so, whether that represents peak performance or not. Using this, we show that even when run in the most controlled of circumstances, small, deterministic, widely studied microbenchmarks often fail to reach a steady state of peak performance on a variety of common VMs. Repeating our experiment on 3 different machines, we found that at most 43.5% of pairs consistently reach a steady state of peak performance.980 981 2) Kalibera, Tomas and Jones, Richard. Rigorous Benchmarking in Reasonable Time. ISMM 2013. https://doi.org/10.1145/2555670.2464160982 Experimental evaluation is key to systems research. Because modern systems are complex and non-deterministic, good experimental methodology demands that researchers account for uncertainty. To obtain valid results, they are expected to run many iterations of benchmarks, invoke virtual machines (VMs) several times, or even rebuild VM or benchmark binaries more than once. All this repetition costs time to complete experiments. Currently, many evaluations give up on sufficient repetition or rigorous statistical methods, or even run benchmarks only in training sizes. The results reported often lack proper variation estimates and, when a small difference between two systems is reported, some are simply unreliable.In contrast, we provide a statistically rigorous methodology for repetition and summarising results that makes efficient use of experimentation time. Time efficiency comes from two key observations. First, a given benchmark on a given platform is typically prone to much less non-determinism than the common worst-case of published corner-case studies. Second, repetition is most needed where most uncertainty arises (whether between builds, between executions or between iterations). We capture experimentation cost with a novel mathematical model, which we use to identify the number of repetitions at each level of an experiment necessary and sufficient to obtain a given level of precision.We present our methodology as a cookbook that guides researchers on the number of repetitions they should run to obtain reliable results. We also show how to present results with an effect size confidence interval. As an example, we show how to use our methodology to conduct throughput experiments with the DaCapo and SPEC CPU benchmarks on three recent platforms.983 984 You have 42 days from the date of this email to submit your revision. If you are unable to complete the revision within this time, please contact me to request a short extension.985 986 You can upload your revised manuscript and submit it through your Author Center. Log into https://mc.manuscriptcentral.com/spe and enter your Author Center, where you will find your manuscript title listed under "Manuscripts with Decisions".987 988 When submitting your revised manuscript, you will be able to respond to the comments made by the referee(s) in the space provided. You can use this space to document any changes you make to the original manuscript.989 990 If you would like help with English language editing, or other article preparation support, Wiley Editing Services offers expert help with English Language Editing, as well as translation, manuscript formatting, and figure formatting at www.wileyauthors.com/eeo/preparation. You can also check out our resources for Preparing Your Article for general guidance about writing and preparing your manuscript at www.wileyauthors.com/eeo/prepresources.991 992 Once again, thank you for submitting your manuscript to Software: Practice and Experience. I look forward to receiving your revision.993 994 Sincerely,995 Richard996 997 Prof. Richard Jones998 Editor, Software: Practice and Experience999 R.E.Jones@kent.ac.uk1000 1001 Referee(s)' Comments to Author:1002 1003 Reviewing: 11004 1005 Comments to the Author1006 Overall, I felt that this draft was an improvement on previous drafts and I don't have further changes to request.1007 1008 I appreciated the new language to clarify the relationship of external and internal scheduling, for example, as well as the new measurements of Rust tokio. Also, while I still believe that the choice between thread/generator/coroutine and so forth could be made crisper and clearer, the current draft of Section 2 did seem adequate to me in terms of specifying the considerations that users would have to take into account to make the choice.1009 1010 1011 Reviewing: 21012 1013 Comments to the Author1014 First: let me apologise for the delay on this review. I'll blame the global pandemic combined with my institution's senior management's counterproductive decisions for taking up most of my time and all of my energy.1015 1016 At this point, reading the responses, I think we've been around the course enough times that further iteration is unlikely to really improve the paper any further, so I'm happy to recommend acceptance. My main comments are that there were some good points in the responses to *all* the reviews and I strongly encourage the authors to incorporate those discursive responses into the final paper so they may benefit readers as well as reviewers. I agree with the recommendations of reviewer #2 that the paper could usefully be split in to two, which I think I made to a previous revision, but I'm happy to leave that decision to the Editor.1017 1018 Finally, the paper needs to describe how the Java harness was adapted to deal with warmup; why the computation has warmed up and reached a steady state - similarly for js and Python. The tables should also give the "N" chosen for each benchmark run.1019 1020 minor points1021 * don't start sentences with "However"1022 * most downloaded isn't an "Award"1023 1024 1025 1026 Date: Thu, 1 Oct 2020 05:34:29 +00001027 From: Richard Jones <onbehalfof@manuscriptcentral.com>1028 Reply-To: R.E.Jones@kent.ac.uk1029 To: pabuhr@uwaterloo.ca1030 Subject: Revision reminder - SPE-19-0219.R21031 1032 01-Oct-20201033 1034 Dear Dr Buhr1035 1036 SPE-19-0219.R21037 1038 This is a reminder that your opportunity to revise and re-submit your manuscript will expire 14 days from now. If you require more time please contact me directly and I may grant an extension to this deadline, otherwise the option to submit a revision online, will not be available.1039 1040 If your article is of potential interest to the general public, (which means it must be timely, groundbreaking, interesting and impact on everyday society) then please e-mail ejp@wiley.co.uk explaining the public interest side of the research. Wiley will then investigate the potential for undertaking a global press campaign on the article.1041 1042 I look forward to receiving your revision.1043 1044 Sincerely,1045 1046 Prof. Richard Jones1047 Editor, Software: Practice and Experience1048 1049 https://mc.manuscriptcentral.com/spe1050 1051 1052 1053 Date: Tue, 6 Oct 2020 15:29:41 +00001054 From: Mayank Roy Chowdhury <onbehalfof@manuscriptcentral.com>1055 Reply-To: speoffice@wiley.com1056 To: tdelisle@uwaterloo.ca, pabuhr@uwaterloo.ca1057 Subject: SPE-19-0219.R3 successfully submitted1058 1059 06-Oct-20201060 1061 Dear Dr Buhr,1062 1063 Your manuscript entitled "Advanced Control-flow and Concurrency in Cforall" has been successfully submitted online and is presently being given full consideration for publication in Software: Practice and Experience.1064 1065 Your manuscript number is SPE-19-0219.R3. Please mention this number in all future correspondence regarding this submission.1066 1067 You can view the status of your manuscript at any time by checking your Author Center after logging into https://mc.manuscriptcentral.com/spe. If you have difficulty using this site, please click the 'Get Help Now' link at the top right corner of the site.1068 1069 1070 Thank you for submitting your manuscript to Software: Practice and Experience.1071 1072 Sincerely,1073 1074 Software: Practice and Experience Editorial Office1075 -
doc/refrat/refrat.tex
r223a633 r33c3ded 11 11 %% Created On : Wed Apr 6 14:52:25 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Oct 5 09:02:53 202014 %% Update Count : 1 1013 %% Last Modified On : Wed Jan 31 17:30:23 2018 14 %% Update Count : 108 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 30 30 \usepackage{upquote} % switch curled `'" to straight 31 31 \usepackage{calc} 32 \usepackage{xspace} 32 33 \usepackage{varioref} % extended references 34 \usepackage{listings} % format program code 33 35 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 34 36 \usepackage{latexsym} % \Box glyph 35 37 \usepackage{mathptmx} % better math font with "times" 36 38 \usepackage[usenames]{color} 37 \newcommand{\CFALatin}{} 39 \input{common} % common CFA document macros 40 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 41 \usepackage{breakurl} 42 \renewcommand{\UrlFont}{\small\sf} 43 44 \usepackage[pagewise]{lineno} 45 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 46 \usepackage[firstpage]{draftwatermark} 47 \SetWatermarkLightness{0.9} 48 49 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore 50 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR 51 % AFTER HYPERREF. 52 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 53 54 \setlength{\topmargin}{-0.45in} % move running title into header 55 \setlength{\headsep}{0.25in} 56 57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 59 \CFAStyle % use default CFA format-style 60 \lstnewenvironment{C++}[1][] % use C++ style 61 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®}#1}} 62 {} 63 38 64 % inline code ©...© (copyright symbol) emacs: C-q M-) 39 65 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. … … 43 69 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 44 70 % math escape $...$ (dollar symbol) 45 \input{common} % common CFA document macros46 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}47 \usepackage{breakurl}48 \renewcommand{\UrlFont}{\small\sf}49 50 \usepackage[pagewise]{lineno}51 \renewcommand{\linenumberfont}{\scriptsize\sffamily}52 \usepackage[firstpage]{draftwatermark}53 \SetWatermarkLightness{0.9}54 55 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore56 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR57 % AFTER HYPERREF.58 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}59 60 \setlength{\topmargin}{-0.45in} % move running title into header61 \setlength{\headsep}{0.25in}62 71 63 72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 64 73 65 \CFAStyle % use default CFA format-style66 \lstnewenvironment{C++}[1][] % use C++ style67 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®},#1}}68 {}69 70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%71 72 74 % Names used in the document. 73 \newcommand{\Version}{\input{ build/version}}75 \newcommand{\Version}{\input{../../version}} 74 76 \newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}} 75 77 \newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}} -
doc/theses/andrew_beach_MMath/thesis.tex
r223a633 r33c3ded 34 34 \usepackage[toc,abbreviations]{glossaries-extra} 35 35 36 % Define all the glossaries. 37 \input{glossaries} 36 % Main glossary entries -- definitions of relevant terminology 37 \newglossaryentry{computer} 38 { 39 name=computer, 40 description={A programmable machine that receives input data, 41 stores and manipulates the data, and provides 42 formatted output} 43 } 44 45 % Nomenclature glossary entries -- New definitions, or unusual terminology 46 \newglossary*{nomenclature}{Nomenclature} 47 \newglossaryentry{dingledorf} 48 { 49 type=nomenclature, 50 name=dingledorf, 51 description={A person of supposed average intelligence who makes incredibly 52 brainless misjudgments} 53 } 54 55 % List of Abbreviations (abbreviations are from the glossaries-extra package) 56 \newabbreviation{aaaaz}{AAAAZ}{American Association of Amature Astronomers 57 and Zoologists} 58 59 % List of Symbols 60 \newglossary*{symbols}{List of Symbols} 61 \newglossaryentry{rvec} 62 { 63 name={$\mathbf{v}$}, 64 sort={label}, 65 type=symbols, 66 description={Random vector: a location in n-dimensional Cartesian space, where 67 each dimensional component is determined by a random process} 68 } 38 69 39 70 % Generate the glossaries defined above. -
doc/theses/fangren_yu_COOP_S20/Makefile
r223a633 r33c3ded 46 46 # File Dependencies # 47 47 48 48 49 ${DOCUMENT} : ${BASE}.ps 49 50 ps2pdf $< -
doc/theses/fangren_yu_COOP_S20/Report.tex
r223a633 r33c3ded 1 \documentclass[twoside,1 1pt]{article}1 \documentclass[twoside,12pt]{article} 2 2 3 3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 11 11 \usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt]{subfig} 12 12 \renewcommand{\thesubfigure}{\alph{subfigure})} 13 \usepackage[flushmargin]{footmisc} % support label/reference in footnote14 13 \usepackage{latexsym} % \Box glyph 15 14 \usepackage{mathptmx} % better math font with "times" 16 \usepackage[toc]{appendix} % article does not have appendix17 15 \usepackage[usenames]{color} 18 16 \input{common} % common CFA document macros 19 17 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 20 18 \usepackage{breakurl} 21 \urlstyle{sf}22 23 % reduce spacing24 \setlist[itemize]{topsep=5pt,parsep=0pt}% global25 \setlist[enumerate]{topsep=5pt,parsep=0pt}% global26 19 27 20 \usepackage[pagewise]{lineno} … … 33 26 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 34 27 \newcommand{\NOTE}{\textbf{NOTE}} 35 \newcommand{\TODO}[1]{{\color{Purple}#1}}36 28 37 29 \setlength{\topmargin}{-0.45in} % move running title into header … … 40 32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 41 33 42 \CFA Style % CFA code-style for all languages34 \CFADefaults 43 35 \lstset{ 44 language=C++,moredelim=**[is][\color{red}]{@}{@} % make C++ the default language 36 language=C++, % make C++ the default language 37 escapechar=\$, % LaTeX escape in CFA code 38 moredelim=**[is][\color{red}]{`}{`}, 45 39 }% lstset 40 \lstMakeShortInline@% 46 41 \lstnewenvironment{C++}[1][] % use C++ style 47 {\lstset{language=C++,moredelim=**[is][\color{red}]{@}{@}}\lstset{#1}}{} 42 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{`}{`},#1}} 43 {} 48 44 49 45 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 88 84 \section{Overview} 89 85 90 @cfa-cc@ is the reference compiler for the \CFA programming language, which is a non-object-oriented extension to C. 91 \CFA attempts to introduce productive modern programming language features to C while maintaining as much backward-compatibility as possible, so that most existing C programs can seamlessly work with \CFA. 92 93 Since the \CFA project dates back to the early 2000s, and only restarted in the past few years, there is a significant amount of legacy code in the current compiler codebase with little documentation. 94 The lack of documentation makes it difficult to develop new features from the current implementation and diagnose problems. 95 96 Currently, the \CFA team is also facing poor compiler performance. 97 For the development of a new programming language, writing standard libraries is an important component. 98 The slow compiler causes building of the library files to take tens of minutes, making iterative development and testing almost impossible. 99 There is an ongoing effort to rewrite the core data-structure of the compiler to overcome the performance issue, but many bugs have appeared during this work, and lack of documentation is hampering debugging. 100 101 This developer's reference manual begins the documentation and should be continuously im\-proved until it eventually covers the entire compiler codebase. 102 For now, the focus is mainly on the parts being rewritten, and also the primary performance bottleneck, namely the resolution algorithm. 103 Its aimed is to provide new project developers with guidance in understanding the codebase, and clarify the purpose and behaviour of certain functions that are not mentioned in the previous \CFA research papers~\cite{Bilson03,Ditchfield92,Moss19}. 86 cfa-cc is the reference compiler for the \CFA programming language, which is a non- 87 object-oriented extension to C. 88 \CFA attempts to introduce productive modern programming language features to C 89 while maintaining as much backward-compatibility as possible, so that most existing C 90 programs can seamlessly work with \CFA. 91 92 Since the \CFA project was dated back to the early 2000s, and only restarted in the past 93 few years, there is a significant amount of legacy code in the current compiler codebase, 94 with little proper documentation available. This becomes a difficulty while developing new 95 features based on the previous implementations, and especially while diagnosing 96 problems. 97 98 Currently, the \CFA team is also facing another problem: bad compiler performance. For 99 the development of a new programming language, writing a standard library is an 100 important part. The incompetence of the compiler causes building the library files to take 101 tens of minutes, making iterative development and testing almost impossible. There is 102 ongoing effort to rewrite the core data structure of the compiler to overcome the 103 performance issue, but many bugs may appear during the work, and lack of documentation 104 makes debugging extremely difficult. 105 106 This developer's reference will be continuously improved and eventually cover the 107 compiler codebase. For now, the focus is mainly on the parts being rewritten, and also the 108 performance bottleneck, namely the resolution algorithm. It is aimed to provide new 109 developers to the project enough guidance and clarify the purposes and behavior of certain 110 functions which are not mentioned in the previous \CFA research papers. 104 111 105 112 106 113 \section{Compiler Framework} 107 114 108 \CFA source code is first transformed into an abstract syntax tree (AST) by the parser before analyzed by the compiler.109 110 111 115 \subsection{AST Representation} 112 116 113 114 There are 4 major categories of AST nodes used by the compiler, along with some derived structures. 115 116 \subsubsection{Declaration Nodes} 117 Source code input is first transformed into abstract syntax tree (AST) representation by the 118 parser before analyzed by the compiler. 119 120 There are 4 major categories of AST nodes used by the compiler, along with some derived 121 structures. 122 123 \subsubsection{Declaration nodes} 117 124 118 125 A declaration node represents either of: 119 126 \begin{itemize} 120 127 \item 121 type declaration: @struct@, @union@, @typedef@ or type parameter (see \VRef[Appendix]{s:KindsTypeParameters})122 \item 123 variable declaration124 \item 125 function declaration128 Type declaration: struct, union, typedef or type parameter (see Appendix A.3) 129 \item 130 Variable declaration 131 \item 132 Function declaration 126 133 \end{itemize} 127 134 Declarations are introduced by standard C declarations, with the usual scoping rules. 128 In addition, declarations can also be qualified by the \lstinline[language=CFA]@forall@ clause (which is the origin of \CFA's name): 135 In addition, declarations can also be introduced by the forall clause (which is the origin 136 of \CFA's name): 129 137 \begin{cfa} 130 forall ( <$\emph{TypeParameterList}$> | <$\emph{AssertionList}$>)138 forall (<$\emph{TypeParameterList}$> | <$\emph{AssertionList}$>) 131 139 $\emph{declaration}$ 132 140 \end{cfa} 133 Type parameters in \CFA are similar to \CC template type parameters. 134 The \CFAdeclaration141 Type parameters in \CFA are similar to \CC template type parameters. The \CFA 142 declaration 135 143 \begin{cfa} 136 144 forall (dtype T) ... 137 145 \end{cfa} 138 behaves similarly tothe \CC template declaration146 behaves similarly as the \CC template declaration 139 147 \begin{C++} 140 148 template <typename T> ... 141 149 \end{C++} 142 150 143 Assertions are a distinctive feature of \CFA, similar to \emph{interfaces} in D and Go, and \emph{traits} in Rust. 144 Contrary to the \CC template where arbitrary functions and operators can be used in a template definition, in a \CFA parametric function, operations on parameterized types must be declared in assertions. 151 Assertions are a distinctive feature of \CFA: contrary to the \CC template where 152 arbitrary functions and operators can be used in a template definition, in a \CFA 153 parametric function, operations on parameterized types must be declared in assertions. 154 145 155 Consider the following \CC template: 146 156 \begin{C++} 147 @template@ forall<typename T> T foo( T t) {148 return t + t * t;157 template <typename T> int foo(T t) { 158 return bar(t) + baz(t); 149 159 } 150 160 \end{C++} 151 where there are no explicit requirements on the type @T@. 152 Therefore, the \CC compiler must deduce what operators are required during textual (macro) expansion of the template at each usage. 153 As a result, templates cannot be compiled. 154 \CFA assertions specify restrictions on type parameters: 161 Unless bar and baz are also parametric functions taking any argument type, they must be 162 declared in the assertions, or otherwise the code will not compile: 155 163 \begin{cfa} 156 forall ( dtype T | @{ T ?+?( T, T ); T ?*?( T, T ) }@ ) int foo ( T t) {157 return t + t * t;164 forall (dtype T | { int bar(T); int baz(t); }) int foo (T t) { 165 return bar(t) + baz(t); 158 166 } 159 167 \end{cfa} 160 Assertions are written using the usual \CFA function declaration syntax. 161 Only types with operators ``@+@'' and ``@*@'' work with this function, and the function prototype is sufficient to allow separate compilation. 162 163 Type parameters and assertions are used in the following compiler data-structures. 164 165 166 \subsubsection{Type Nodes} 167 168 Type nodes represent the type of an object or expression. 169 Named types reference the corresponding type declarations. 170 The type of a function is its function pointer type (same as standard C). 171 With the addition of type parameters, named types may contain a list of parameter values (actual parameter types). 172 173 174 \subsubsection{Statement Nodes} 175 176 Statement nodes represent the executable statements in the program, including basic expression statements, control flows and blocks. 168 Assertions are written using the usual function declaration syntax. The scope of type 169 parameters and assertions is the following declaration. 170 171 \subsubsection{Type nodes} 172 173 A type node represents the type of an object or expression. 174 Named types reference the corresponding type declarations. The type of a function is its 175 function pointer type (same as standard C). 176 With the addition of type parameters, named types may contain a list of parameter values 177 (actual parameter types). 178 179 \subsubsection{Statement nodes} 180 181 Statement nodes represent the statements in the program, including basic expression 182 statements, control flows and blocks. 177 183 Local declarations (within a block statement) are represented as declaration statements. 178 184 179 180 \subsubsection{Expression Nodes} 181 182 Some expressions are represented differently before and after the resolutionstage:185 \subsubsection{Expression nodes} 186 187 Some expressions are represented differently in the compiler before and after resolution 188 stage: 183 189 \begin{itemize} 184 190 \item 185 Name expressions: @NameExpr@ pre-resolution, @VariableExpr@ post-resolution 186 \item 187 Member expressions: @UntypedMemberExpr@ pre-resolution, @MemberExpr@ post-resolution 188 \item 189 \begin{sloppypar} 190 Function call expressions (including overloadable operators): @UntypedExpr@ pre-resolution, @ApplicationExpr@ post-resolution 191 \end{sloppypar} 191 Name expressions: NameExpr pre-resolution, VariableExpr post-resolution 192 \item 193 Member expressions: UntypedMemberExpr pre-resolution, MemberExpr post-resolution 194 \item 195 Function call expressions (including overloadable operators): UntypedExpr pre-resolution, ApplicationExpr post-resolution 192 196 \end{itemize} 193 The pre-resolution representation contains only the symbols.194 Post-resolution linksthem to the actual variable and function declarations.197 The pre-resolution representations contain only the symbols. Post-resolution results link 198 them to the actual variable and function declarations. 195 199 196 200 197 201 \subsection{Compilation Passes} 198 202 199 Compilation steps are implemented as passes, which follows a general structural recursion pattern on the syntax tree. 200 201 The basic workflow of compilation passes follows preorder and postorder traversal on the AST data-structure, implemented with visitor pattern, and can be loosely described with the following pseudocode: 202 \begin{C++} 203 Pass::visit( node_t node ) { 204 previsit( node ); 205 if ( visit_children ) 203 Compilation steps are implemented as passes, which follows a general structural recursion 204 pattern on the syntax tree. 205 206 The basic work flow of compilation passes follows preorder and postorder traversal on 207 tree data structure, implemented with visitor pattern, and can be loosely described with 208 the following pseudocode: 209 \begin{C++} 210 Pass::visit (node_t node) { 211 previsit(node); 212 if (visit_children) 206 213 for each child of node: 207 child.accept( this);208 postvisit( node);214 child.accept(this); 215 postvisit(node); 209 216 } 210 217 \end{C++} 211 Operations in @previsit@ happen in preorder (top to bottom) and operations in @postvisit@ happen in postorder (bottom to top). 212 The precise order of recursive operations on child nodes can be found in @Common/PassVisitor.impl.h@ (old) and @AST/Pass.impl.hpp@ (new). 213 214 Implementations of compilation passes follow certain conventions: 218 Operations in previsit() happen in preorder (top to bottom) and operations in 219 postvisit() happen in postorder (bottom to top). The precise order of recursive 220 operations on child nodes can be found in @Common/PassVisitor.impl.h@ (old) and 221 @AST/Pass.impl.hpp@ (new). 222 Implementations of compilation passes need to follow certain conventions: 215 223 \begin{itemize} 216 224 \item 217 Passes \textbf{should not} directly override the visit method (Non-virtual Interface principle); 218 if a pass desires different recursion behaviour, it should set @visit_children@ to false and perform recursive calls manually within previsit or postvisit procedures. 219 To enable this option, inherit from the @WithShortCircuiting@ mixin. 220 \item 221 previsit may mutate the node but \textbf{must not} change the node type or return @nullptr@. 222 \item 223 postvisit may mutate the node, reconstruct it to a different node type, or delete it by returning @nullptr@. 225 Passes \textbf{should not} directly override the visit method (Non-virtual Interface 226 principle); if a pass desires different recursion behavior, it should set 227 @visit_children@ to false and perform recursive calls manually within previsit or 228 postvisit procedures. To enable this option, inherit from @WithShortCircuiting@ mixin. 229 \item 230 previsit may mutate the node but \textbf{must not} change the node type or return null. 231 \item 232 postvisit may mutate the node, reconstruct it to a different node type, or delete it by 233 returning null. 224 234 \item 225 235 If the previsit or postvisit method is not defined for a node type, the step is skipped. 226 If the return type is declared as @void@, the original node is returned by default.227 These behaviours are controlled by template specialization rules; 228 see @Common/PassVisitor.proto.h@ (old) and @AST/@ @Pass.proto.hpp@ (new) for details.236 If the return type is declared as void, the original node is returned by default. These 237 behaviors are controlled by template specialization rules; see 238 @Common/PassVisitor.proto.h@ (old) and @AST/Pass.proto.hpp@ (new) for details. 229 239 \end{itemize} 230 240 Other useful mixin classes for compilation passes include: 231 241 \begin{itemize} 232 242 \item 233 @WithGuards@ allows saving and restoring variable values automatically upon entering/exiting the current node. 234 \item 235 @WithVisitorRef@ creates a wrapped entity for the current pass (the actual argument passed to recursive calls internally) for explicit recursion, usually used together with @WithShortCircuiting@. 236 \item 237 @WithSymbolTable@ gives a managed symbol table with built-in scoping-rule handling (\eg on entering and exiting a block statement) 243 WithGuards allows saving values of variables and restore automatically upon exiting 244 the current node. 245 \item 246 WithVisitorRef creates a wrapped entity of current pass (the actual argument 247 passed to recursive calls internally) for explicit recursion, usually used together 248 with WithShortCircuiting. 249 \item 250 WithSymbolTable gives a managed symbol table with built-in scoping rule handling 251 (\eg on entering and exiting a block statement) 238 252 \end{itemize} 239 \NOTE: If a pass extends the functionality of another existing pass, due to \CC overloading resolution rules, it \textbf{must} explicitly introduce the inherited previsit and postvisit procedures to its own scope, or otherwise they are not picked up by template resolution: 253 \NOTE: If a pass extends the functionality of another existing pass, due to \CC overloading 254 resolution rules, it \textbf{must} explicitly introduce the inherited previsit and postvisit procedures 255 to its own scope, or otherwise they will not be picked up by template resolution: 240 256 \begin{C++} 241 257 class Pass2: public Pass1 { 242 @using Pass1::previsit;@243 @using Pass1::postvisit;@258 using Pass1::previsit; 259 using Pass1::postvisit; 244 260 // new procedures 245 261 } … … 247 263 248 264 249 \subsection{Data Structure Change (new-ast)} 250 251 It has been observed that excessive copying of syntax tree structures accounts for a majority of computation cost and significantly slows down the compiler. 252 In the previous implementation of the syntax tree, every internal node has a unique parent; 253 therefore all copies are required to duplicate the entire subtree. 254 A new, experimental re-implementation of the syntax tree (source under directory @AST/@ hereby referred to as ``new-ast'') attempts to overcome this issue with a functional approach that allows sharing of common sub-structures and only makes copies when necessary. 255 256 The core of new-ast is a customized implementation of smart pointers, similar to @std::shared_ptr@ and @std::weak_ptr@ in the \CC standard library. 257 Reference counting is used to detect sharing and allowing certain optimizations. 258 For a purely functional (immutable) data-structure, all mutations are modelled by shallow copies along the path of mutation. 265 \subsection{Data Structure Change WIP (new-ast)} 266 267 It has been observed that excessive copying of syntax tree structures accounts for a 268 majority of computation cost and significantly slows down the compiler. In the previous 269 implementation of the syntax tree, every internal node has a unique parent; therefore all 270 copies are required to duplicate everything down to the bottom. A new, experimental 271 re-implementation of the syntax tree (source under directory AST/ hereby referred to as 272 ``new-ast'') attempts to overcome this issue with a functional approach that allows sharing 273 of common sub-structures and only makes copies when necessary. 274 275 The core of new-ast is a customized implementation of smart pointers, similar to 276 @std::shared_ptr@ and @std::weak_ptr@ in \CC standard library. Reference counting is 277 used to detect sharing and allows optimization. For a purely functional (a.k.a. immutable) 278 data structure, all mutations are modelled by shallow copies along the path of mutation. 259 279 With reference counting optimization, unique nodes are allowed to be mutated in place. 260 This however, may potentially introduce some complications and bugs; 261 a few issues are discussed near the end of this section. 262 263 264 \subsubsection{Source: \lstinline{AST/Node.hpp}} 265 266 Class @ast::Node@ is the base class of all new-ast node classes, which implements reference counting mechanism. 267 Two different counters are recorded: ``strong'' reference count for number of nodes semantically owning it; 268 ``weak'' reference count for number of nodes holding a mere reference and only need to observe changes. 269 Class @ast::ptr_base@ is the smart pointer implementation and also takes care of resource management. 270 271 Direct access through the smart pointer is read-only. 272 A mutable access should be obtained by calling @shallowCopy@ or mutate as below. 273 274 Currently, the weak pointers are only used to reference declaration nodes from a named type, or a variable expression. 275 Since declaration nodes are intended to denote unique entities in the program, weak pointers always point to unique (unshared) nodes. 276 This property may change in the future, and weak references to shared nodes may introduce some problems; 280 This however, may potentially introduce some complications and bugs; a few issues are 281 discussed near the end of this section. 282 283 \subsubsection{Source: AST/Node.hpp} 284 285 class @ast::Node@ is the base class of all new-ast node classes, which implements 286 reference counting mechanism. Two different counters are recorded: ``strong'' reference 287 count for number of nodes semantically owning it; ``weak'' reference count for number of 288 nodes holding a mere reference and only need to observe changes. 289 class @ast::ptr_base@ is the smart pointer implementation and also takes care of 290 resource management. 291 292 Direct access through the smart pointer is read-only. A mutable access should be obtained 293 by calling shallowCopy or mutate as below. 294 295 Currently, the weak pointers are only used to reference declaration nodes from a named 296 type, or a variable expression. Since declaration nodes are intended to denote unique 297 entities in the program, weak pointers always point to unique (unshared) nodes. This may 298 change in the future, and weak references to shared nodes may introduce some problems; 277 299 see mutate function below. 278 300 279 All node classes should always use smart pointers in structure definitions versus raw pointers. 280 Function 301 All node classes should always use smart pointers in the structure and should not use raw 302 pointers. 303 281 304 \begin{C++} 282 305 void ast::Node::increment(ref_type ref) 283 306 \end{C++} 284 increments this node's strong or weak reference count. 285 Function 307 Increments this node's strong or weak reference count. 286 308 \begin{C++} 287 309 void ast::Node::decrement(ref_type ref, bool do_delete = true) 288 310 \end{C++} 289 decrements this node's strong or weak reference count. 290 If strong reference count reaches zero, the node is deleted. 291 \NOTE: Setting @do_delete@ to false may result in a detached node. 292 Subsequent code should manually delete the node or assign it to a strong pointer to prevent memory leak. 293 311 Decrements this node's strong or weak reference count. If strong reference count reaches 312 zero, the node is deleted by default. 313 \NOTE: Setting @do_delete@ to false may result in a detached node. Subsequent code should 314 manually delete the node or assign it to a strong pointer to prevent memory leak. 294 315 Reference counting functions are internally called by @ast::ptr_base@. 295 Function296 316 \begin{C++} 297 317 template<typename node_t> 298 318 node_t * shallowCopy(const node_t * node) 299 319 \end{C++} 300 returns a mutable, shallow copy of node: all child pointers are pointing to the same child nodes. 301 Function 320 Returns a mutable, shallow copy of node: all child pointers are pointing to the same child 321 nodes. 302 322 \begin{C++} 303 323 template<typename node_t> 304 324 node_t * mutate(const node_t * node) 305 325 \end{C++} 306 returns a mutable pointer to the same node, if the node is unique (strong reference count is 1); 307 otherwise, it returns @shallowCopy(node)@. 308 It is an error to mutate a shared node that is weak-referenced. 309 Currently this does not happen. 310 A problem may appear once weak pointers to shared nodes (\eg expression nodes) are used; 311 special care is needed. 312 313 \NOTE: This naive uniqueness check may not be sufficient in some cases. 314 A discussion of the issue is presented at the end of this section. 315 Functions 326 If node is unique (strong reference count is 1), returns a mutable pointer to the same node. 327 Otherwise, returns shallowCopy(node). 328 It is an error to mutate a shared node that is weak-referenced. Currently this does not 329 happen. The problem may appear once weak pointers to shared nodes (\eg expression 330 nodes) are used; special care will be needed. 331 332 \NOTE: This naive uniqueness check may not be sufficient in some cases. A discussion of the 333 issue is presented at the end of this section. 316 334 \begin{C++} 317 335 template<typename node_t, typename parent_t, typename field_t, typename assn_t> 318 const node_t * mutate_field(const node_t * node, field_t parent_t::* field, assn_t && val)336 const node_t * mutate_field(const node_t * node, field_t parent_t::*field, assn_t && val) 319 337 \end{C++} 320 338 \begin{C++} … … 324 342 field_t && val) 325 343 \end{C++} 326 are helpers for mutating a field on a node using pointer to a member function (creates shallow copy when necessary). 327 328 329 \subsubsection{Issue: Undetected Sharing}330 331 The @mutate@ behavio ur described above has a problem: deeper shared nodes may be344 Helpers for mutating a field on a node using pointer to member (creates shallow copy 345 when necessary). 346 347 \subsubsection{Issue: Undetected sharing} 348 349 The @mutate@ behavior described above has a problem: deeper shared nodes may be 332 350 mistakenly considered as unique. \VRef[Figure]{f:DeepNodeSharing} shows how the problem could arise: 333 351 \begin{figure} … … 337 355 \label{f:DeepNodeSharing} 338 356 \end{figure} 339 Given the tree rooted at P1, which is logically the chain P1-A-B, and P2 is irrelevant, assume @mutate(B)@ is called. 340 The algorithm considers B as unique since it is only directly owned by A. 341 However, the other tree P2-A-B indirectly shares the node B and is therefore wrongly mutated. 342 343 To partly address this problem, if the mutation is called higher up the tree, a chain mutation helper can be used. 344 345 \subsubsection{Source: \lstinline{AST/Chain.hpp}} 346 347 Function 357 Suppose that we are working on the tree rooted at P1, which 358 is logically the chain P1-A-B and P2 is irrelevant, and then 359 mutate(B) is called. The algorithm considers B as unique since 360 it is only directly owned by A. However, the other tree P2-A-B 361 indirectly shares the node B and is therefore wrongly mutated. 362 363 To partly address this problem, if the mutation is called higher up the tree, a chain 364 mutation helper can be used: 365 366 \subsubsection{Source: AST/Chain.hpp} 367 348 368 \begin{C++} 349 369 template<typename node_t, Node::ref_type ref_t> 350 370 auto chain_mutate(ptr_base<node_t, ref_t> & base) 351 371 \end{C++} 352 returns a chain mutator handle that takes pointer-to-member to go down the tree, while creating shallow copies as necessary; 353 see @struct _chain_mutator@ in the source code for details. 354 355 For example, in the above diagram, if mutation of B is wanted while at P1, the call using @chain_mutate@ looks like the following: 372 This function returns a chain mutator handle which takes pointer-to-member to go down 373 the tree while creating shallow copies as necessary; see @struct _chain_mutator@ in the 374 source code for details. 375 376 For example, in the above diagram, if mutation of B is wanted while at P1, the call using 377 @chain_mutate@ looks like the following: 356 378 \begin{C++} 357 379 chain_mutate(P1.a)(&A.b) = new_value_of_b; 358 380 \end{C++} 359 \NOTE: if some node in chain mutate is shared (therefore shallow copied), it implies that every node further down is also copied, thus correctly executing the functional mutation algorithm. 360 This example code creates copies of both A and B and performs mutation on the new nodes, so that the other tree P2-A-B is untouched. 361 However, if a pass traverses down to node B and performs mutation, for example, in @postvisit(B)@, information on sharing higher up is lost. 362 Since the new-ast structure is only in experimental use with the resolver algorithm, which mostly rebuilds the tree bottom-up, this issue does not actually happen. 363 It should be addressed in the future when other compilation passes are migrated to new-ast and many of them contain procedural mutations, where it might cause accidental mutations to other logically independent trees (\eg common sub-expression) and become a bug. 364 365 381 Note that if some node in chain mutate is shared (therefore shallow copied), it implies that 382 every node further down will also be copied, thus correctly executing the functional 383 mutation algorithm. This example code creates copies of both A and B and performs 384 mutation on the new nodes, so that the other tree P2-A-B is untouched. 385 However, if a pass traverses down to node B and performs mutation, for example, in 386 @postvisit(B)@, information on sharing higher up is lost. Since the new-ast structure is only in 387 experimental use with the resolver algorithm, which mostly rebuilds the tree bottom-up, 388 this issue does not actually happen. It should be addressed in the future when other 389 compilation passes are migrated to new-ast and many of them contain procedural 390 mutations, where it might cause accidental mutations to other logically independent trees 391 (\eg common sub-expression) and become a bug. 392 393 394 \vspace*{20pt} % FIX ME, spacing problem with this heading ??? 366 395 \section{Compiler Algorithm Documentation} 367 396 368 This compiler algorithm documentation covers most of the resolver, data structures used in variable and expression resolution, and a few directly related passes. 369 Later passes involving code generation are not included yet; 370 documentation for those will be done latter. 371 397 This documentation currently covers most of the resolver, data structures used in variable 398 and expression resolution, and a few directly related passes. Later passes involving code 399 generation is not included yet; documentation for those will be done afterwards. 372 400 373 401 \subsection{Symbol Table} 374 402 375 \NOTE: For historical reasons, the symbol-table data-structure is called @indexer@ in the old implementation. 376 Hereby, the name is changed to @SymbolTable@. 377 The symbol table stores a mapping from names to declarations, implements a similar name-space separation rule, and provides the same scoping rules as standard C.\footnote{ISO/IEC 9899:1999, Sections 6.2.1 and 6.2.3.} 378 The difference in name-space rule is that @typedef@ aliases are no longer considered ordinary identifiers. 379 In addition to C tag-types (@struct@, @union@, @enum@), \CFA introduces another tag type, @trait@, which is a named collection of assertions. 380 381 382 \subsubsection{Source: \lstinline{AST/SymbolTable.hpp}} 383 384 Function 403 \NOTE: For historical reasons, the symbol table data structure was called ``indexer'' in the 404 old implementation. Hereby we will be using the name SymbolTable everywhere. 405 The symbol table stores a mapping from names to declarations and implements a similar 406 name space separation rule, and the same scoping rules in standard C.\footnote{ISO/IEC 9899:1999, Sections 6.2.1 and 6.2.3} The difference in 407 name space rule is that typedef aliases are no longer considered ordinary identifiers. 408 In addition to C tag types (struct, union, enum), \CFA introduces another tag type, trait, 409 which is a named collection of assertions. 410 411 \subsubsection{Source: AST/SymbolTable.hpp} 412 413 \subsubsection{Source: SymTab/Indexer.h} 414 385 415 \begin{C++} 386 416 SymbolTable::addId(const DeclWithType * decl) 387 417 \end{C++} 388 provides name mangling of identifiers, since \CFA allows overloading of variables and functions. 389 The mangling scheme is closely based on the Itanium \CC ABI,\footnote{\url{https://itanium-cxx-abi.github.io/cxx-abi/abi.html}, Section 5.1} while making adaptations to \CFA specific features, mainly assertions and overloaded variables by type. 390 391 Naming conflicts are handled by mangled names; 392 lookup by name returns a list of declarations with the sameidentifier name.393 Functions 418 Since \CFA allows overloading of variables and functions, ordinary identifier names need 419 to be mangled. The mangling scheme is closely based on the Itanium \CC ABI,\footnote{\url{https://itanium-cxx-abi.github.io/cxx-abi/abi.html}, Section 5.1} while 420 making adaptations to \CFA specific features, mainly assertions and overloaded variables 421 by type. Naming conflicts are handled by mangled names; lookup by name returns a list of 422 declarations with the same literal identifier name. 423 394 424 \begin{C++} 395 425 SymbolTable::addStruct(const StructDecl * decl) … … 398 428 SymbolTable::addTrait(const TraitDecl * decl) 399 429 \end{C++} 400 add a tag-type declaration to the symbol table. 401 Function 430 Adds a tag type declaration to the symbol table. 402 431 \begin{C++} 403 432 SymbolTable::addType(const NamedTypeDecl * decl) 404 433 \end{C++} 405 adds a @typedef@ alias to the symbol table. 406 407 \textbf{C Incompatibility Note}: Since \CFA allows using @struct@, @union@ and @enum@ type-names without a prefix keyword, as in \CC, @typedef@ names and tag-type names cannot be disambiguated by syntax rules. 408 Currently the compiler puts them together and disallows collision. 409 The following program is valid C but invalid \CFA (and \CC): 434 Adds a typedef alias to the symbol table. 435 436 \textbf{C Incompatibility Note}: Since Cforall allows using struct, union and enum type names 437 without the keywords, typedef names and tag type names cannot be disambiguated by 438 syntax rules. Currently the compiler puts them together and disallows collision. The 439 following program is valid C but not valid Cforall: 410 440 \begin{C++} 411 441 struct A {}; 412 typedef int A; // gcc: ok, cfa: Cannot redefine typedef A413 struct A sa; // C disambiguates via struct prefix414 A ia;415 \end{C++}416 In practices, such usage is extremely rare, and hence, this change (as in \CC) has minimal impact on existing C programs.417 The declaration418 \begin{C++}419 struct A {};420 typedef struct A A; // A is an alias for struct A421 A a;422 struct A b;423 \end{C++}424 is not an error because the alias name is identical to the original.425 Finally, the following program is allowed in \CFA:426 \begin{C++}427 442 typedef int A; 428 void A(); // name mangled 443 // gcc: ok, cfa: Cannot redefine typedef A 444 \end{C++} 445 In actual practices however, such usage is extremely rare, and typedef struct A A; is 446 not considered an error, but silently discarded. Therefore, we expect this change to have 447 minimal impact on existing C programs. 448 Meanwhile, the following program is allowed in Cforall: 449 \begin{C++} 450 typedef int A; 451 void A(); 429 452 // gcc: A redeclared as different kind of symbol, cfa: ok 430 453 \end{C++} 431 because the function name is mangled.432 433 454 434 455 \subsection{Type Environment and Unification} 435 456 436 The following core ideas underlie the parametric type-resolution algorithm. 437 A type environment organizes type parameters into \textbf{equivalent classes} and maps them to actual types. 438 Unification is the algorithm that takes two (possibly parametric) types and parameter mappings, and attempts to produce a common type by matching information in the type environments. 457 The core of parametric type resolution algorithm. 458 Type Environment organizes type parameters in \textbf{equivalent classes} and maps them to 459 actual types. Unification is the algorithm that takes two (possibly parametric) types and 460 parameter mappings and attempts to produce a common type by matching the type 461 environments. 439 462 440 463 The unification algorithm is recursive in nature and runs in two different modes internally: 441 464 \begin{itemize} 442 465 \item 443 Exact unification mode requires equivalent parameters to match perfectly. 444 \item 445 Inexact unification mode allows equivalent parameters to be converted to a common type. 466 \textbf{Exact} unification mode requires equivalent parameters to match perfectly; 467 \item 468 \textbf{Inexact} unification mode allows equivalent parameters to be converted to a 469 common type. 446 470 \end{itemize} 447 For a pair of matching parameters (actually, their equivalent classes), if either side is open (not bound to a concrete type yet), they are combined. 448 449 Within the inexact mode, types are allowed to differ on their cv-qualifiers (\eg @const@, @volatile@, \etc); 450 additionally, if a type never appear either in a parameter list or as the base type of a pointer, it may also be widened (\ie safely converted). 451 As \CFA currently does not implement subclassing as in object-oriented languages, widening conversions are only on the primitive types, \eg conversion from @int@ to @long int@. 452 453 The need for two unification modes comes from the fact that parametric types are considered compatible only if all parameters are exactly the same (not just compatible). 454 Pointer types also behaves similarly; 455 in fact, they may be viewed as a primitive kind of parametric types. 456 @int *@ and @long *@ are different types, just like @vector(int)@ and @vector(long)@ are, for the parametric type @*(T)@ / @vector(T)@, respectively. 457 458 The resolver uses the following @public@ functions:\footnote{ 459 Actual code also tracks assertions on type parameters; those extra arguments are omitted here for conciseness.} 460 461 462 \subsubsection{Source: \lstinline{ResolvExpr/Unify.cc}} 463 464 Function 465 \begin{C++} 466 bool unify(const Type * type1, const Type * type2, TypeEnvironment & env, 467 OpenVarSet & openVars, const SymbolTable & symtab, Type *& commonType) 468 \end{C++} 469 returns a boolean indicating if the unification succeeds or fails after attempting to unify @type1@ and @type2@ within current type environment. 470 If the unify succeeds, @env@ is modified by combining the equivalence classes of matching parameters in @type1@ and @type2@, and their common type is written to @commonType@. 471 If the unify fails, nothing changes. 472 Functions 473 \begin{C++} 474 bool typesCompatible(const Type * type1, const Type * type2, const SymbolTable & symtab, 475 const TypeEnvironment & env) 476 bool typesCompatibleIgnoreQualifiers(const Type * type1, const Type * type2, 477 const SymbolTable & symtab, const TypeEnvironment & env) 478 \end{C++} 479 return a boolean indicating if types @type1@ and @type2@ can possibly be the same type. 480 The second version ignores the outermost cv-qualifiers if present.\footnote{ 481 In \lstinline@const int * const@, only the second \lstinline@const@ is ignored.} 482 These function have no side effects. 483 484 \NOTE: No attempt is made to widen the types (exact unification is used), although the function names may suggest otherwise, \eg @typesCompatible(int, long)@ returns false. 471 For a pair of matching parameters (actually, their equivalent classes), if either side is open 472 (not bound to a concrete type yet), they are simply combined. 473 474 Within inexact mode, types are allowed to differ on their cv-qualifiers; additionally, if a 475 type never appear either in parameter list or as the base type of a pointer, it may also be 476 widened (i.e. safely converted). As Cforall currently does not implement subclassing similar 477 to object-oriented languages, widening conversions are on primitive types only, for 478 example the conversion from int to long. 479 480 The need for two unification modes come from the fact that parametric types are 481 considered compatible only if all parameters are exactly the same (not just compatible). 482 Pointer types also behaves similarly; in fact, they may be viewed as a primitive kind of 483 parametric types. @int*@ and @long*@ are different types, just like @vector(int)@ and 484 @vector(long)@ are, for the parametric type @vector(T)@. 485 486 The resolver should use the following ``@public@'' functions:\footnote{ 487 Actual code also tracks assertions on type parameters; those extra arguments are omitted here for 488 conciseness.} 489 490 491 \subsubsection{Source: ResolvExpr/Unify.cc} 492 493 \begin{C++} 494 bool unify(const Type *type1, const Type *type2, TypeEnvironment &env, 495 OpenVarSet &openVars, const SymbolTable &symtab, Type *&commonType) 496 \end{C++} 497 Attempts to unify @type1@ and @type2@ with current type environment. 498 499 If operation succeeds, @env@ is modified by combining the equivalence classes of matching 500 parameters in @type1@ and @type2@, and their common type is written to commonType. 501 502 If operation fails, returns false. 503 \begin{C++} 504 bool typesCompatible(const Type * type1, const Type * type2, const 505 SymbolTable &symtab, const TypeEnvironment &env) 506 bool typesCompatibleIgnoreQualifiers(const Type * type1, const Type * 507 type2, const SymbolTable &symtab, const TypeEnvironment &env) 508 \end{C++} 509 510 Determines if type1 and type2 can possibly be the same type. The second version ignores 511 the outermost cv-qualifiers if present.\footnote{ 512 In const \lstinline@int * const@, only the second \lstinline@const@ is ignored.} 513 514 The call has no side effect. 515 516 \NOTE: No attempts are made to widen the types (exact unification is used), although the 517 function names may suggest otherwise. E.g. @typesCompatible(int, long)@ returns false. 485 518 486 519 487 520 \subsection{Expression Resolution} 488 521 489 The design of the current version of expression resolver is outlined in the Ph.D.\ thesis by Aaron Moss~\cite{Moss19}. 522 The design of the current version of expression resolver is outlined in the Ph.D. Thesis from 523 Aaron Moss~\cite{Moss19}. 524 490 525 A summary of the resolver algorithm for each expression type is presented below. 491 526 492 All overloadable operators are modelled as function calls. 493 For a function call, interpretations of the function and arguments are found recursively. 494 Then the followingsteps produce a filtered list of valid interpretations:527 All overloadable operators are modelled as function calls. For a function call, 528 interpretations of the function and arguments are found recursively. Then the following 529 steps produce a filtered list of valid interpretations: 495 530 \begin{enumerate} 496 531 \item 497 From all possible combinations of interpretations of the function and arguments, those where argument types may be converted to function parameter types are considered valid. 532 From all possible combinations of interpretations of the function and arguments, 533 those where argument types may be converted to function parameter types are 534 considered valid. 498 535 \item 499 536 Valid interpretations with the minimum sum of argument costs are kept. 500 537 \item 501 \label{p:argcost} 502 Argument costs are then discarded; the actual cost for the function call expression is the sum of conversion costs from the argument types to parameter types. 503 \item 504 \label{p:returntype} 505 For each return type, the interpretations with satisfiable assertions are then sorted by actual cost computed in step~\ref{p:argcost}. 506 If for a given type, the minimum cost interpretations are not unique, that return type is ambiguous. 507 If the minimum cost interpretation is unique but contains an ambiguous argument, it is also ambiguous. 538 Argument costs are then discarded; the actual cost for the function call expression is 539 the sum of conversion costs from the argument types to parameter types. 540 \item 541 For each return type, the interpretations with satisfiable assertions are then sorted 542 by actual cost computed in step 3. If for a given type, the minimum cost 543 interpretations are not unique, it is said that for that return type the interpretation 544 is ambiguous. If the minimum cost interpretation is unique but contains an 545 ambiguous argument, it is also considered ambiguous. 508 546 \end{enumerate} 509 Therefore, for each return type, the resolver produces :547 Therefore, for each return type, the resolver produces either of: 510 548 \begin{itemize} 511 549 \item 512 no alternatives513 \item 514 asingle valid alternative515 \item 516 an ambiguous alternative550 No alternatives 551 \item 552 A single valid alternative 553 \item 554 An ambiguous alternative 517 555 \end{itemize} 518 \NOTE: an ambiguous alternative may be discarded at the parent expressions because a different return type matches better for the parent expressions. 519 520 The \emph{non}-overloadable expressions in \CFA are: cast expressions, address-of (unary @&@) expressions, short-circuiting logical expressions (@&&@, @||@) and ternary conditional expression (@?:@). 521 522 For a cast expression, the convertible argument types are kept. 523 Then the result is selected by lowest argument cost, and further by lowest conversion cost to target type. 524 If the lowest cost is still not unique or an ambiguous argument interpretation is selected, the cast expression is ambiguous. 525 In an expression statement, the top level expression is implicitly cast to @void@. 556 Note that an ambiguous alternative may be discarded at the parent expressions because a 557 different return type matches better for the parent expressions. 558 559 The non-overloadable expressions in Cforall are: cast expressions, address-of (unary @&@) 560 expressions, short-circuiting logical expressions (@&&@, @||@) and ternary conditional 561 expression (@?:@). 562 563 For a cast expression, the convertible argument types are kept. Then the result is selected 564 by lowest argument cost, and further by lowest conversion cost to target type. If the lowest 565 cost is still not unique, or an ambiguous argument interpretation is selected, the cast 566 expression is ambiguous. In an expression statement, the top level expression is implicitly 567 cast to void. 526 568 527 569 For an address-of expression, only lvalue results are kept and the minimum cost is selected. 528 570 529 For logical expressions @&&@ and @||@, arguments are implicitly cast to @bool@, and follow the rules fr cast expression above. 530 531 For the ternary conditional expression, the condition is implicitly cast to @bool@, and the branch expressions must have compatible types. 532 Each pair of compatible branch expression types produce a possible interpretation, and the cost is defined as the sum of the expression costs plus the sum of conversion costs to the common type. 533 534 535 \subsection{Conversion and Application Cost} 536 537 There were some unclear parts in the previous documentation in the cost system, as described in the Moss thesis~\cite{Moss19}, section 4.1.2. 538 Some clarification are presented in this section. 539 540 \begin{enumerate} 541 \item 542 Conversion to a type denoted by parameter may incur additional cost if the match is not exact. 543 For example, if a function is declared to accept @(T, T)@ and receives @(int, long)@, @T@ is deducted @long@ and an additional widening conversion cost is added for @int@ to @T@. 544 545 \item 546 The specialization level of a function is the sum of the least depth of an appearance of a type parameter (counting pointers, references and parameterized types), plus the number of assertions. 547 A higher specialization level is favoured if argument conversion costs are equal. 548 549 \item 550 Coercion of pointer types is only allowed in explicit cast expressions; 551 the only allowed implicit pointer casts are adding qualifiers to the base type and cast to @void*@, and these counts as safe conversions. 552 Note that implicit cast from @void *@ to other pointer types is no longer valid, as opposed to standard C. 553 \end{enumerate} 571 For logical expressions @&&@ and @||@, arguments are implicitly cast to bool, and follow the rule 572 of cast expression as above. 573 574 For the ternary conditional expression, the condition is implicitly cast to bool, and the 575 branch expressions must have compatible types. Each pair of compatible branch 576 expression types produce a possible interpretation, and the cost is defined as the sum of 577 expression costs plus the sum of conversion costs to the common type. 578 579 TODO: Write a specification for expression costs. 554 580 555 581 556 582 \subsection{Assertion Satisfaction} 557 583 558 The resolver tries to satisfy assertions on expressions only when it is needed: either while selecting from multiple alternatives of a same result type for a function call (step \ref{p:returntype} of resolving function calls) or upon reaching the top level of an expression statement. 559 560 Unsatisfiable alternatives are discarded. 561 Satisfiable alternatives receive \textbf{implicit parameters}: in \CFA, parametric functions may be separately compiled, as opposed to \CC templates which are only compiled at instantiation. 562 Given the parametric function-definition: 584 The resolver tries to satisfy assertions on expressions only when it is needed: either while 585 selecting from multiple alternatives of a same result type for a function call (step 4 of 586 resolving function calls), or upon reaching the top level of an expression statement. 587 588 Unsatisfiable alternatives are discarded. Satisfiable alternatives receive \textbf{implicit 589 parameters}: in Cforall, parametric functions are designed such that they can be compiled 590 separately, as opposed to \CC templates which are only compiled at instantiation. Given a 591 parametric function definition: 563 592 \begin{C++} 564 593 forall (otype T | {void foo(T);}) 565 594 void bar (T t) { foo(t); } 566 595 \end{C++} 567 the function @bar@ does not know which @foo@ to call when compiled without knowing the call site, so it requests a function pointer to be passed as an extra argument. 568 At the call site, implicit parameters are automatically inserted by the compiler. 569 570 Implementation of implicit parameters is discussed in \VRef[Appendix]{s:ImplementationParametricFunctions}. 596 The function bar does not know which @foo@ to call when compiled without knowing the call 597 site, so it requests a function pointer to be passed as an extra argument. At the call site, 598 implicit parameters are automatically inserted by the compiler. 599 600 \textbf{TODO}: Explain how recursive assertion satisfaction and polymorphic recursion work. 601 571 602 572 603 \section{Tests} … … 574 605 \subsection{Test Suites} 575 606 576 Automatic test suites are located under the @tests/@ directory. 577 A test case consists of an input CFA source file (suffix @.cfa@), and an expected output file located in the @tests/.expect/@ directory, with the same file name ending with suffix @.txt@. 578 For example, the test named @tests/tuple/tupleCast.cfa@ has the following files, for example: 607 Automatic test suites are located under the @tests/@ directory. A test case consists of an 608 input CFA source file (name ending with @.cfa@), and an expected output file located 609 in @.expect/@ directory relative to the source file, with the same file name ending with @.txt@. 610 So a test named @tuple/tupleCast@ has the following files, for example: 579 611 \begin{C++} 580 612 tests/ 581 tuple/ 582 .expect/ 583 tupleCast.txt 584 tupleCast.cfa 585 \end{C++} 586 If compilation fails, the error output is compared to the expect file. 587 If the compilation succeeds but does not generate an executable, the compilation output is compared to the expect file. 588 If the compilation succeeds and generates an executable, the executable is run and its output is compared to the expect file. 589 To run the tests, execute the test script @test.py@ under the @tests/@ directory, with a list of test names to be run, or @--all@ (or @make all-tests@) to run all tests. 590 The test script reports test cases fail/success, compilation time and program run time. 591 To see all the options available for @test.py@ using the @--help@ option. 613 .. tuple/ 614 ...... .expect/ 615 .......... tupleCast.txt 616 ...... tupleCast.cfa 617 \end{C++} 618 If compilation fails, the error output is compared to the expect file. If compilation succeeds, 619 the built program is run and its output compared to the expect file. 620 To run the tests, execute the test script @test.py@ under the @tests/@ directory, with a list of 621 test names to be run, or @--all@ to run all tests. The test script reports test cases 622 fail/success, compilation time and program run time. 592 623 593 624 594 625 \subsection{Performance Reports} 595 626 596 To turn on performance reports, pass the @-XCFA -S@ flag to the compiler. 597 Three kinds of performance reports are available: 627 To turn on performance reports, pass @-S@ flag to the compiler. 628 629 3 kinds of performance reports are available: 598 630 \begin{enumerate} 599 631 \item … … 607 639 @Common/Stats/Counter.h@. 608 640 \end{enumerate} 609 It is suggested to run performance tests with optimization (@g++@ flag @-O3@). 610 611 612 \appendix 613 \section{Appendix} 614 615 \subsection{Kinds of Type Parameters} 616 \label{s:KindsTypeParameters} 617 618 A type parameter in a @forall@ clause has 3 kinds: 619 \begin{enumerate}[listparindent=0pt] 620 \item 621 @dtype@: any data type (built-in or user defined) that is not a concrete type. 622 623 A non-concrete type is an incomplete type such as an opaque type or pointer/reference with an implicit (pointer) size and implicitly generated reference and dereference operations. 624 \item 625 @otype@: any data type (built-in or user defined) that is concrete type. 626 627 A concrete type is a complete type, \ie types that can be used to create a variable, which also implicitly asserts the existence of default and copy constructors, assignment, and destructor\footnote{\CFA implements the same automatic resource management (RAII) semantics as \CC.}. 628 % \item 629 % @ftype@: any function type. 630 % 631 % @ftype@ provides two purposes: 632 % \begin{itemize} 633 % \item 634 % Differentiate function pointer from data pointer because (in theory) some systems have different sizes for these pointers. 635 % \item 636 % Disallow a function pointer to match an overloaded data pointer, since variables and functions can have the same names. 637 % \end{itemize} 638 639 \item 640 @ttype@: tuple (variadic) type. 641 642 Restricted to the type for the last parameter in a function, it provides a type-safe way to implement variadic functions. 643 Note however, that it has certain restrictions, as described in the implementation section below. 644 \end{enumerate} 645 646 647 \subsection{GNU C Nested Functions} 648 649 \CFA is designed to be mostly compatible with GNU C, an extension to ISO C99 and C11 standards. The \CFA compiler also implements some language features by GCC extensions, most notably nested functions. 650 651 In ISO C, function definitions are not allowed to be nested. GCC allows nested functions with full lexical scoping. The following example is taken from GCC documentation\footnote{\url{https://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html}}: 652 \begin{C++} 653 void bar( int * array, int offset, int size ) { 654 int access( int * array, int index ) { return array[index + offset]; } 655 int i; 656 /* ... */ 657 for ( i = 0; i < size; i++ ) 658 /* ... */ access (array, i) /* ... */ 659 } 660 \end{C++} 661 GCC nested functions behave identically to \CC lambda functions with default by-reference capture (stack-allocated, lifetime ends upon exiting the declared block), while also possible to be passed as arguments with standard function pointer types. 662 663 664 \subsection{Implementation of Parametric Functions} 665 \label{s:ImplementationParametricFunctions} 666 667 \CFA implements parametric functions using the implicit parameter approach: required assertions are passed to the callee by function pointers; 668 size of a parametric type must also be known if referenced directly (\ie not as a pointer). 669 670 The implementation is similar to the one from Scala\footnote{\url{https://www.scala-lang.org/files/archive/spec/2.13/07-implicits.html}}, with some notable differences in resolution: 671 \begin{enumerate} 672 \item 673 All types, variables, and functions are candidates of implicit parameters 674 \item 675 The parameter (assertion) name must match the actual declarations. 676 \end{enumerate} 677 678 For example, the \CFA function declaration 679 \begin{cfa} 680 forall( otype T | { int foo( T, int ); } ) 681 int bar(T); 682 \end{cfa} 683 after implicit parameter expansion, has the actual signature\footnote{\textbf{otype} also requires the type to have constructor and destructor, which are the first two function pointers preceding the one for \textbf{foo}.} 684 \begin{C++} 685 int bar( T, size_t, void (*)(T&), void (*)(T&), int (*)(T, int) ); 686 \end{C++} 687 The implicit parameter approach has an apparent issue: when the satisfying declaration is also parametric, it may require its own implicit parameters too. 688 That also causes the supplied implicit parameter to have a different \textbf{actual} type than the \textbf{nominal} type, so it cannot be passed directly. 689 Therefore, a wrapper with matching actual type must be created, and it is here where GCC nested functions are used internally by the compiler. 690 691 Consider the following program: 692 \begin{cfa} 693 int assertion(int); 694 695 forall( otype T | { int assertion(T); } ) 696 void foo(T); 697 698 forall(otype T | { void foo(T); } ) 699 void bar(T t) { 700 foo(t); 701 } 702 \end{cfa} 703 The \CFA compiler translates the program to non-parametric form\footnote{In the final code output, \lstinline@T@ needs to be replaced by an opaque type, and arguments must be accessed by a frame pointer offset table, due to the unknown sizes. The presented code here is simplified for better understanding.} 704 \begin{C++} 705 // ctor, dtor and size arguments are omitted 706 void foo(T, int (*)(T)); 707 708 void bar(T t, void (*foo)(T)) { 709 foo(t); 710 } 711 \end{C++} 712 However, when @bar(1)@ is called, @foo@ cannot be directly provided as an argument: 713 \begin{C++} 714 bar(1, foo); // WRONG: foo has different actual type 715 \end{C++} 716 and an additional step is required: 717 \begin{C++} 718 { 719 void _foo_wrapper(int t) { 720 foo( t, assertion ); 721 } 722 bar( 1, _foo_wrapper ); 723 } 724 \end{C++} 725 Nested assertions and implicit parameter creation may continue indefinitely. 726 This issue is a limitation of implicit parameter implementation. 727 In particular, polymorphic variadic recursion must be structural (\ie the number of arguments decreases in any possible recursive calls), otherwise code generation gets into an infinite loop. 728 The \CFA compiler sets a limit on assertion depth and reports an error if assertion resolution does not terminate within the limit (as for \lstinline[language=C++]@templates@ in \CC). 641 It is suggested to run performance tests with optimized build (@g++@ flag @-O3@) 642 729 643 730 644 \bibliographystyle{plain} -
doc/user/Makefile
r223a633 r33c3ded 55 55 56 56 ${DOCUMENT} : ${BASE}.ps 57 ps2pdf -dPDFSETTINGS=/prepress$<57 ps2pdf $< 58 58 59 59 ${BASE}.ps : ${BASE}.dvi -
doc/user/user.tex
r223a633 r33c3ded 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Mon Oct 5 08:57:29202014 %% Update Count : 39 9813 %% Last Modified On : Fri Mar 6 13:34:52 2020 14 %% Update Count : 3924 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 30 30 \usepackage{upquote} % switch curled `'" to straight 31 31 \usepackage{calc} 32 \usepackage{xspace} 32 33 \usepackage{varioref} % extended references 33 \usepackage[labelformat=simple,aboveskip=0pt,farskip=0pt]{subfig} 34 \renewcommand{\thesubfigure}{\alph{subfigure})} 34 \usepackage{listings} % format program code 35 35 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 36 36 \usepackage{latexsym} % \Box glyph 37 37 \usepackage{mathptmx} % better math font with "times" 38 38 \usepackage[usenames]{color} 39 \newcommand{\CFALatin}{} 39 \input{common} % common CFA document macros 40 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref} 41 \usepackage{breakurl} 42 43 \usepackage[pagewise]{lineno} 44 \renewcommand{\linenumberfont}{\scriptsize\sffamily} 45 \usepackage[firstpage]{draftwatermark} 46 \SetWatermarkLightness{0.9} 47 48 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore 49 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR 50 % AFTER HYPERREF. 51 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}} 52 53 \setlength{\topmargin}{-0.45in} % move running title into header 54 \setlength{\headsep}{0.25in} 55 56 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 57 58 \CFAStyle % use default CFA format-style 59 \lstnewenvironment{C++}[1][] % use C++ style 60 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®},#1}} 61 {} 62 40 63 % inline code ©...© (copyright symbol) emacs: C-q M-) 41 64 % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. … … 45 68 % keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^ 46 69 % math escape $...$ (dollar symbol) 47 \input{common} % common CFA document macros48 \usepackage[dvips,plainpages=false,pdfpagelabels,pdfpagemode=UseNone,colorlinks=true,pagebackref=true,linkcolor=blue,citecolor=blue,urlcolor=blue,pagebackref=true,breaklinks=true]{hyperref}49 \usepackage{breakurl}50 51 \renewcommand\footnoterule{\kern -3pt\rule{0.3\linewidth}{0.15pt}\kern 2pt}52 53 \usepackage[pagewise]{lineno}54 \renewcommand{\linenumberfont}{\scriptsize\sffamily}55 \usepackage[firstpage]{draftwatermark}56 \SetWatermarkLightness{0.9}57 58 % Default underscore is too low and wide. Cannot use lstlisting "literate" as replacing underscore59 % removes it as a variable-name character so keywords in variables are highlighted. MUST APPEAR60 % AFTER HYPERREF.61 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}62 63 \setlength{\topmargin}{-0.45in} % move running title into header64 \setlength{\headsep}{0.25in}65 66 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%67 68 \CFAStyle % use default CFA format-style69 \lstnewenvironment{C++}[1][] % use C++ style70 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®},#1}}71 {}72 73 \newsavebox{\myboxA}74 \newsavebox{\myboxB}75 70 76 71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 84 79 \newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}} 85 80 \newcommand{\KWC}{K-W C\xspace} 81 82 \newsavebox{\LstBox} 86 83 87 84 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% … … 256 253 257 254 The signature feature of \CFA is \emph{\Index{overload}able} \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name): 258 \begin{ cfa}255 \begin{lstlisting} 259 256 ®forall( otype T )® T identity( T val ) { return val; } 260 257 int forty_two = identity( 42 ); §\C{// T is bound to int, forty\_two == 42}§ 261 \end{ cfa}258 \end{lstlisting} 262 259 % extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions. 263 260 \CFA{}\hspace{1pt}'s polymorphism was originally formalized by \Index*{Glen Ditchfield}\index{Ditchfield, Glen}~\cite{Ditchfield92}, and first implemented by \Index*{Richard Bilson}\index{Bilson, Richard}~\cite{Bilson03}. … … 278 275 \begin{comment} 279 276 A simple example is leveraging the existing type-unsafe (©void *©) C ©bsearch© to binary search a sorted floating array: 280 \begin{ cfa}277 \begin{lstlisting} 281 278 void * bsearch( const void * key, const void * base, size_t dim, size_t size, 282 279 int (* compar)( const void *, const void * )); … … 287 284 double key = 5.0, vals[10] = { /* 10 sorted floating values */ }; 288 285 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); §\C{// search sorted array}§ 289 \end{ cfa}286 \end{lstlisting} 290 287 which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers: 291 \begin{ cfa}288 \begin{lstlisting} 292 289 forall( otype T | { int ?<?( T, T ); } ) T * bsearch( T key, const T * arr, size_t size ) { 293 290 int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ } … … 300 297 double * val = bsearch( 5.0, vals, 10 ); §\C{// selection based on return type}§ 301 298 int posn = bsearch( 5.0, vals, 10 ); 302 \end{ cfa}299 \end{lstlisting} 303 300 The nested function ©comp© provides the hidden interface from typed \CFA to untyped (©void *©) C, plus the cast of the result. 304 301 Providing a hidden ©comp© function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope. … … 308 305 \CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations. 309 306 For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©: 310 \begin{ cfa}307 \begin{lstlisting} 311 308 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 312 309 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 313 310 double * dp = malloc(); 314 311 struct S {...} * sp = malloc(); 315 \end{ cfa}312 \end{lstlisting} 316 313 where the return type supplies the type/size of the allocation, which is impossible in most type systems. 317 314 \end{comment} … … 946 943 the same level as a ©case© clause; the target label may be case ©default©, but only associated 947 944 with the current ©switch©/©choose© statement. 945 946 947 \subsection{Loop Control} 948 949 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}). 950 \begin{itemize} 951 \item 952 The loop index is polymorphic in the type of the comparison value N (when the start value is implicit) or the start value M. 953 \item 954 An empty conditional implies comparison value of ©1© (true). 955 \item 956 A comparison N is implicit up-to exclusive range [0,N©®)®©. 957 \item 958 A comparison ©=© N is implicit up-to inclusive range [0,N©®]®©. 959 \item 960 The up-to range M ©~©\index{~@©~©} N means exclusive range [M,N©®)®©. 961 \item 962 The up-to range M ©~=©\index{~=@©~=©} N means inclusive range [M,N©®]®©. 963 \item 964 The down-to range M ©-~©\index{-~@©-~©} N means exclusive range [N,M©®)®©. 965 \item 966 The down-to range M ©-~=©\index{-~=@©-~=©} N means inclusive range [N,M©®]®©. 967 \item 968 ©0© is the implicit start value; 969 \item 970 ©1© is the implicit increment value. 971 \item 972 The up-to range uses operator ©+=© for increment; 973 \item 974 The down-to range uses operator ©-=© for decrement. 975 \item 976 ©@© means put nothing in this field. 977 \item 978 ©:© means start another index. 979 \end{itemize} 948 980 949 981 \begin{figure} … … 1054 1086 1055 1087 1056 \subsection{Loop Control}1057 1058 The ©for©/©while©/©do-while© loop-control allows empty or simplified ranges (see Figure~\ref{f:LoopControlExamples}).1059 \begin{itemize}1060 \item1061 The loop index is polymorphic in the type of the comparison value N (when the start value is implicit) or the start value M.1062 \item1063 An empty conditional implies comparison value of ©1© (true).1064 \item1065 A comparison N is implicit up-to exclusive range [0,N©®)®©.1066 \item1067 A comparison ©=© N is implicit up-to inclusive range [0,N©®]®©.1068 \item1069 The up-to range M ©~©\index{~@©~©} N means exclusive range [M,N©®)®©.1070 \item1071 The up-to range M ©~=©\index{~=@©~=©} N means inclusive range [M,N©®]®©.1072 \item1073 The down-to range M ©-~©\index{-~@©-~©} N means exclusive range [N,M©®)®©.1074 \item1075 The down-to range M ©-~=©\index{-~=@©-~=©} N means inclusive range [N,M©®]®©.1076 \item1077 ©0© is the implicit start value;1078 \item1079 ©1© is the implicit increment value.1080 \item1081 The up-to range uses operator ©+=© for increment;1082 \item1083 The down-to range uses operator ©-=© for decrement.1084 \item1085 ©@© means put nothing in this field.1086 \item1087 ©:© means start another index.1088 \end{itemize}1089 1090 1091 1088 %\subsection{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}} 1092 1089 \subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}} … … 1098 1095 for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement. 1099 1096 \VRef[Figure]{f:MultiLevelExit} shows ©continue© and ©break© indicating the specific control structure, and the corresponding C program using only ©goto© and labels. 1100 The innermost loop has 8exit points, which cause continuation or termination of one or more of the 7 \Index{nested control-structure}s.1097 The innermost loop has 7 exit points, which cause continuation or termination of one or more of the 7 \Index{nested control-structure}s. 1101 1098 1102 1099 \begin{figure} 1103 \centering 1104 \begin{lrbox}{\myboxA} 1105 \begin{cfa}[tabsize=3] 1106 ®Compound:® { 1107 ®Try:® try { 1108 ®For:® for ( ... ) { 1109 ®While:® while ( ... ) { 1110 ®Do:® do { 1111 ®If:® if ( ... ) { 1112 ®Switch:® switch ( ... ) { 1113 case 3: 1114 ®break Compound®; 1115 ®break Try®; 1116 ®break For®; /* or */ ®continue For®; 1117 ®break While®; /* or */ ®continue While®; 1118 ®break Do®; /* or */ ®continue Do®; 1119 ®break If®; 1120 ®break Switch®; 1121 } // switch 1122 } else { 1123 ... ®break If®; ... // terminate if 1124 } // if 1125 } while ( ... ); // do 1126 } // while 1127 } // for 1128 } ®finally® { // always executed 1129 } // try 1100 \begin{tabular}{@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} 1101 \multicolumn{1}{@{\hspace{\parindentlnth}}c@{\hspace{\parindentlnth}}}{\textbf{\CFA}} & \multicolumn{1}{@{\hspace{\parindentlnth}}c}{\textbf{C}} \\ 1102 \begin{cfa} 1103 ®LC:® { 1104 ... §declarations§ ... 1105 ®LS:® switch ( ... ) { 1106 case 3: 1107 ®LIF:® if ( ... ) { 1108 ®LF:® for ( ... ) { 1109 ®LW:® while ( ... ) { 1110 ... break ®LC®; ... 1111 ... break ®LS®; ... 1112 ... break ®LIF®; ... 1113 ... continue ®LF;® ... 1114 ... break ®LF®; ... 1115 ... continue ®LW®; ... 1116 ... break ®LW®; ... 1117 } // while 1118 } // for 1119 } else { 1120 ... break ®LIF®; ... 1121 } // if 1122 } // switch 1130 1123 } // compound 1131 1124 \end{cfa} 1132 \end{lrbox} 1133 1134 \begin{lrbox}{\myboxB} 1135 \begin{cfa}[tabsize=3] 1125 & 1126 \begin{cfa} 1136 1127 { 1137 1138 ®ForC:® for ( ... ) { 1139 ®WhileC:® while ( ... ) { 1140 ®DoC:® do { 1141 if ( ... ) { 1142 switch ( ... ) { 1143 case 3: 1144 ®goto Compound®; 1145 ®goto Try®; 1146 ®goto ForB®; /* or */ ®goto ForC®; 1147 ®goto WhileB®; /* or */ ®goto WhileC®; 1148 ®goto DoB®; /* or */ ®goto DoC®; 1149 ®goto If®; 1150 ®goto Switch®; 1151 } ®Switch:® ; 1152 } else { 1153 ... ®goto If®; ... // terminate if 1154 } ®If:®; 1155 } while ( ... ); ®DoB:® ; 1156 } ®WhileB:® ; 1157 } ®ForB:® ; 1158 1159 1160 } ®Compound:® ; 1161 \end{cfa} 1162 \end{lrbox} 1163 1164 \subfloat[\CFA]{\label{f:CFibonacci}\usebox\myboxA} 1165 \hspace{2pt} 1166 \vrule 1167 \hspace{2pt} 1168 \subfloat[C]{\label{f:CFAFibonacciGen}\usebox\myboxB} 1128 ... §declarations§ ... 1129 switch ( ... ) { 1130 case 3: 1131 if ( ... ) { 1132 for ( ... ) { 1133 while ( ... ) { 1134 ... goto ®LC®; ... 1135 ... goto ®LS®; ... 1136 ... goto ®LIF®; ... 1137 ... goto ®LFC®; ... 1138 ... goto ®LFB®; ... 1139 ... goto ®LWC®; ... 1140 ... goto ®LWB®; ... 1141 ®LWC®: ; } ®LWB:® ; 1142 ®LFC:® ; } ®LFB:® ; 1143 } else { 1144 ... goto ®LIF®; ... 1145 } ®L3:® ; 1146 } ®LS:® ; 1147 } ®LC:® ; 1148 \end{cfa} 1149 & 1150 \begin{cfa} 1151 1152 1153 1154 1155 1156 1157 1158 // terminate compound 1159 // terminate switch 1160 // terminate if 1161 // continue loop 1162 // terminate loop 1163 // continue loop 1164 // terminate loop 1165 1166 1167 1168 // terminate if 1169 1170 1171 1172 \end{cfa} 1173 \end{tabular} 1169 1174 \caption{Multi-level Exit} 1170 1175 \label{f:MultiLevelExit} … … 1421 1426 try { 1422 1427 f(...); 1423 } catch( E e ; §boolean-predicate§ ) { §\C {// termination handler}§1428 } catch( E e ; §boolean-predicate§ ) { §\C[8cm]{// termination handler}§ 1424 1429 // recover and continue 1425 } catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler} §1430 } catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler}\CRT§ 1426 1431 // repair and return 1427 1432 } finally { … … 3486 3491 For implicit formatted input, the common case is reading a sequence of values separated by whitespace, where the type of an input constant must match with the type of the input variable. 3487 3492 \begin{cquote} 3488 \begin{lrbox}{\ myboxA}3493 \begin{lrbox}{\LstBox} 3489 3494 \begin{cfa}[aboveskip=0pt,belowskip=0pt] 3490 3495 int x; double y char z; … … 3492 3497 \end{lrbox} 3493 3498 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{3em}}l@{}} 3494 \multicolumn{1}{@{}l@{}}{\usebox\ myboxA} \\3499 \multicolumn{1}{@{}l@{}}{\usebox\LstBox} \\ 3495 3500 \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CFA}} & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{Python}} \\ 3496 3501 \begin{cfa}[aboveskip=0pt,belowskip=0pt] … … 6667 6672 For example, an initial alignment and fill capability are preserved during a resize copy so the copy has the same alignment and extended storage is filled. 6668 6673 Without sticky properties it is dangerous to use ©realloc©, resulting in an idiom of manually performing the reallocation to maintain correctness. 6669 \begin{cfa}6670 6671 \end{cfa}6672 6674 6673 6675 \CFA memory management extends allocation to support constructors for initialization of allocated storage, \eg in … … 6719 6721 6720 6722 // §\CFA§ safe general allocation, fill, resize, alignment, array 6721 T * alloc( void );§\indexc{alloc}§ §\C[3.5in]{// variable, T size}§ 6722 T * alloc( size_t dim ); §\C{// array[dim], T size elements}§ 6723 T * alloc( T ptr[], size_t dim ); §\C{// realloc array[dim], T size elements}§ 6724 6725 T * alloc_set( char fill );§\indexc{alloc_set}§ §\C{// variable, T size, fill bytes with value}§ 6726 T * alloc_set( T fill ); §\C{// variable, T size, fill with value}§ 6727 T * alloc_set( size_t dim, char fill ); §\C{// array[dim], T size elements, fill bytes with value}§ 6728 T * alloc_set( size_t dim, T fill ); §\C{// array[dim], T size elements, fill elements with value}§ 6729 T * alloc_set( size_t dim, const T fill[] ); §\C{// array[dim], T size elements, fill elements with array}§ 6730 T * alloc_set( T ptr[], size_t dim, char fill ); §\C{// realloc array[dim], T size elements, fill bytes with value}§ 6731 6732 T * alloc_align( size_t align ); §\C{// aligned variable, T size}§ 6733 T * alloc_align( size_t align, size_t dim ); §\C{// aligned array[dim], T size elements}§ 6734 T * alloc_align( T ptr[], size_t align ); §\C{// realloc new aligned array}§ 6735 T * alloc_align( T ptr[], size_t align, size_t dim ); §\C{// realloc new aligned array[dim]}§ 6736 6737 T * alloc_align_set( size_t align, char fill ); §\C{// aligned variable, T size, fill bytes with value}§ 6738 T * alloc_align_set( size_t align, T fill ); §\C{// aligned variable, T size, fill with value}§ 6739 T * alloc_align_set( size_t align, size_t dim, char fill ); §\C{// aligned array[dim], T size elements, fill bytes with value}§ 6740 T * alloc_align_set( size_t align, size_t dim, T fill ); §\C{// aligned array[dim], T size elements, fill elements with value}§ 6741 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); §\C{// aligned array[dim], T size elements, fill elements with array}§ 6742 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); §\C{// realloc new aligned array[dim], fill new bytes with value}§ 6723 T * alloc( void );§\indexc{alloc}§ 6724 T * alloc( size_t dim ); 6725 T * alloc( T ptr[], size_t dim ); 6726 T * alloc_set( char fill );§\indexc{alloc_set}§ 6727 T * alloc_set( T fill ); 6728 T * alloc_set( size_t dim, char fill ); 6729 T * alloc_set( size_t dim, T fill ); 6730 T * alloc_set( size_t dim, const T fill[] ); 6731 T * alloc_set( T ptr[], size_t dim, char fill ); 6732 6733 T * alloc_align( size_t align ); 6734 T * alloc_align( size_t align, size_t dim ); 6735 T * alloc_align( T ptr[], size_t align ); // aligned realloc array 6736 T * alloc_align( T ptr[], size_t align, size_t dim ); // aligned realloc array 6737 T * alloc_align_set( size_t align, char fill ); 6738 T * alloc_align_set( size_t align, T fill ); 6739 T * alloc_align_set( size_t align, size_t dim, char fill ); 6740 T * alloc_align_set( size_t align, size_t dim, T fill ); 6741 T * alloc_align_set( size_t align, size_t dim, const T fill[] ); 6742 T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); 6743 6743 6744 6744 // §\CFA§ safe initialization/copy, i.e., implicit size specification -
libcfa/prelude/builtins.c
r223a633 r33c3ded 10 10 // Created On : Fri Jul 21 16:21:03 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Oct 9 18:26:19202013 // Update Count : 1 1012 // Last Modified On : Mon Jul 13 21:10:02 2020 13 // Update Count : 109 14 14 // 15 15 … … 94 94 // universal typed pointer constant 95 95 static inline forall( dtype DT ) DT * intptr( uintptr_t addr ) { return (DT *)addr; } 96 static inline forall( ftype FT ) FT * intptr( uintptr_t addr ) { return (FT *)addr; }97 96 98 97 #if defined(__SIZEOF_INT128__) -
libcfa/src/Makefile.am
r223a633 r33c3ded 88 88 inst_thread_headers_nosrc = \ 89 89 bits/random.hfa \ 90 concurrency/clib/cfathread.h \91 90 concurrency/invoke.h \ 92 91 concurrency/kernel/fwd.hfa … … 104 103 concurrency/alarm.cfa \ 105 104 concurrency/alarm.hfa \ 106 concurrency/clib/cfathread.cfa \107 105 concurrency/CtxSwitch-@ARCHITECTURE@.S \ 108 106 concurrency/invoke.c \ -
libcfa/src/bits/containers.hfa
r223a633 r33c3ded 157 157 tail = &get_next( *val ); 158 158 *tail = 1p; 159 }160 161 T * peek( __queue(T) & this ) {162 verify(*this.tail == 1p);163 T * head = this.head;164 if( head != 1p ) {165 verify(*this.tail == 1p);166 return head;167 }168 verify(*this.tail == 1p);169 return 0p;170 159 } 171 160 -
libcfa/src/bits/locks.hfa
r223a633 r33c3ded 164 164 165 165 struct $thread; 166 extern void park( void);167 extern void unpark( struct $thread * this );166 extern void park( __cfaabi_dbg_ctx_param ); 167 extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 ); 168 168 static inline struct $thread * active_thread (); 169 169 … … 191 191 /* paranoid */ verify( expected == 0p ); 192 192 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 193 park( );193 park( __cfaabi_dbg_ctx ); 194 194 return true; 195 195 } … … 210 210 else { 211 211 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 212 unpark( expected );212 unpark( expected __cfaabi_dbg_ctx2 ); 213 213 return true; 214 214 } … … 244 244 /* paranoid */ verify( expected == 0p ); 245 245 if(__atomic_compare_exchange_n(&this.ptr, &expected, active_thread(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 246 park( );246 park( __cfaabi_dbg_ctx ); 247 247 /* paranoid */ verify( this.ptr == 1p ); 248 248 return true; … … 256 256 struct $thread * got = __atomic_exchange_n( &this.ptr, 1p, __ATOMIC_SEQ_CST); 257 257 if( got == 0p ) return false; 258 unpark( got );258 unpark( got __cfaabi_dbg_ctx2 ); 259 259 return true; 260 260 } -
libcfa/src/concurrency/CtxSwitch-i386.S
r223a633 r33c3ded 10 10 // Created On : Tue Dec 6 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 6 18:23:37202013 // Update Count : 512 // Last Modified On : Sun Aug 16 08:46:22 2020 13 // Update Count : 4 14 14 // 15 15 … … 35 35 36 36 // Copy the "from" context argument from the stack to register eax 37 // Return address is at 0(%esp), with parameters following .37 // Return address is at 0(%esp), with parameters following 38 38 39 39 movl 4(%esp),%eax … … 50 50 movl %ebp,FP_OFFSET(%eax) 51 51 52 // Copy the "to" context argument from the stack to register eax . Having53 // pushed 3 words (= 12 bytes) on the stack, the argument is now at54 // 8 + 12 = 20(%esp).52 // Copy the "to" context argument from the stack to register eax 53 // Having pushed three words (= 12 bytes) on the stack, the 54 // argument is now at 8 + 12 = 20(%esp) 55 55 56 56 movl 20(%esp),%eax -
libcfa/src/concurrency/alarm.cfa
r223a633 r33c3ded 130 130 131 131 register_self( &node ); 132 park( );132 park( __cfaabi_dbg_ctx ); 133 133 134 134 /* paranoid */ verify( !node.set ); -
libcfa/src/concurrency/coroutine.cfa
r223a633 r33c3ded 47 47 48 48 //----------------------------------------------------------------------------- 49 FORALL_DATA_INSTANCE(CoroutineCancelled, (dtype coroutine_t), (coroutine_t)) 49 FORALL_DATA_INSTANCE(CoroutineCancelled, 50 (dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) 50 51 51 52 struct __cfaehm_node { … … 58 59 void mark_exception(CoroutineCancelled(T) *) {} 59 60 60 forall(dtype T )61 forall(dtype T | sized(T)) 61 62 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) { 62 63 dst->the_coroutine = src->the_coroutine; … … 76 77 exception_t * except = (exception_t *)(1 + (__cfaehm_node *)desc->cancellation); 77 78 78 // TODO: Remove explitate vtable set once trac#186 is fixed.79 79 CoroutineCancelled(T) except; 80 except.virtual_table = &get_exception_vtable(&except);81 80 except.the_coroutine = &cor; 82 81 except.the_exception = except; … … 92 91 93 92 // minimum feasible stack size in bytes 94 static const size_t MinStackSize = 1000; 93 #define MinStackSize 1000 95 94 extern size_t __page_size; // architecture pagesize HACK, should go in proper runtime singleton 96 95 -
libcfa/src/concurrency/coroutine.hfa
r223a633 r33c3ded 22 22 //----------------------------------------------------------------------------- 23 23 // Exception thrown from resume when a coroutine stack is cancelled. 24 FORALL_DATA_EXCEPTION(CoroutineCancelled, (dtype coroutine_t), (coroutine_t)) ( 24 // Should not have to be be sized (see trac #196). 25 FORALL_DATA_EXCEPTION(CoroutineCancelled, 26 (dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) ( 25 27 coroutine_t * the_coroutine; 26 28 exception_t * the_exception; … … 28 30 29 31 forall(dtype T) 32 void mark_exception(CoroutineCancelled(T) *); 33 34 forall(dtype T | sized(T)) 30 35 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src); 31 36 … … 37 42 // Anything that implements this trait can be resumed. 38 43 // Anything that is resumed is a coroutine. 39 trait is_coroutine(dtype T | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) { 44 trait is_coroutine(dtype T | sized(T) 45 | is_resumption_exception(CoroutineCancelled(T)) 46 | VTABLE_ASSERTION(CoroutineCancelled, (T))) { 40 47 void main(T & this); 41 48 $coroutine * get_coroutine(T & this); -
libcfa/src/concurrency/invoke.h
r223a633 r33c3ded 93 93 94 94 }; 95 // Wrapper for gdb96 struct cfathread_coroutine_t { struct $coroutine debug; };97 95 98 96 static inline struct __stack_t * __get_stack( struct $coroutine * cor ) { … … 131 129 struct __condition_node_t * dtor_node; 132 130 }; 133 // Wrapper for gdb134 struct cfathread_monitor_t { struct $monitor debug; };135 131 136 132 struct __monitor_group_t { … … 190 186 } node; 191 187 192 #if defined( __CFA_WITH_VERIFY__ ) 193 unsigned long long canary; 188 #ifdef __CFA_DEBUG__ 189 // previous function to park/unpark the thread 190 const char * park_caller; 191 int park_result; 192 enum __Coroutine_State park_state; 193 bool park_stale; 194 const char * unpark_caller; 195 int unpark_result; 196 enum __Coroutine_State unpark_state; 197 bool unpark_stale; 194 198 #endif 195 199 }; 196 // Wrapper for gdb197 struct cfathread_thread_t { struct $thread debug; };198 200 199 201 #ifdef __CFA_DEBUG__ -
libcfa/src/concurrency/io.cfa
r223a633 r33c3ded 69 69 if( block ) { 70 70 enable_interrupts( __cfaabi_dbg_ctx ); 71 park( );71 park( __cfaabi_dbg_ctx ); 72 72 disable_interrupts(); 73 73 } … … 97 97 98 98 if(nextt) { 99 unpark( nextt );99 unpark( nextt __cfaabi_dbg_ctx2 ); 100 100 enable_interrupts( __cfaabi_dbg_ctx ); 101 101 return true; … … 134 134 int ret = 0; 135 135 if( need_sys_to_submit || need_sys_to_complete ) { 136 ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, 0, flags, (sigset_t *)0p, _NSIG / 8);136 ret = syscall( __NR_io_uring_enter, ring.fd, to_submit, 0, flags, 0p, _NSIG / 8); 137 137 if( ret < 0 ) { 138 138 switch((int)errno) { -
libcfa/src/concurrency/io/call.cfa.in
r223a633 r33c3ded 47 47 #include "kernel/fwd.hfa" 48 48 49 static const __u8 REGULAR_FLAGS = 0 50 #if defined(CFA_HAVE_IOSQE_FIXED_FILE) 51 | IOSQE_FIXED_FILE 52 #endif 53 #if defined(CFA_HAVE_IOSQE_IO_DRAIN) 54 | IOSQE_IO_DRAIN 55 #endif 56 #if defined(CFA_HAVE_IOSQE_ASYNC) 57 | IOSQE_ASYNC 58 #endif 59 ; 60 61 static const __u32 LINK_FLAGS = 0 62 #if defined(CFA_HAVE_IOSQE_IO_LINK) 63 | IOSQE_IO_LINK 64 #endif 65 #if defined(CFA_HAVE_IOSQE_IO_HARDLINK) 66 | IOSQE_IO_HARDLINK 67 #endif 68 ; 69 70 static const __u32 SPLICE_FLAGS = 0 71 #if defined(CFA_HAVE_SPLICE_F_FD_IN_FIXED) 72 | SPLICE_F_FD_IN_FIXED 73 #endif 74 ; 49 #if defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC) 50 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN | IOSQE_ASYNC) 51 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_ASYNC) 52 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_ASYNC) 53 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) && defined(CFA_HAVE_IOSQE_IO_DRAIN) 54 #define REGULAR_FLAGS (IOSQE_FIXED_FILE | IOSQE_IO_DRAIN) 55 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN) && defined(CFA_HAVE_IOSQE_ASYNC) 56 #define REGULAR_FLAGS (IOSQE_IO_DRAIN | IOSQE_ASYNC) 57 #elif defined(CFA_HAVE_IOSQE_FIXED_FILE) 58 #define REGULAR_FLAGS (IOSQE_FIXED_FILE) 59 #elif defined(CFA_HAVE_IOSQE_IO_DRAIN) 60 #define REGULAR_FLAGS (IOSQE_IO_DRAIN) 61 #elif defined(CFA_HAVE_IOSQE_ASYNC) 62 #define REGULAR_FLAGS (IOSQE_ASYNC) 63 #else 64 #define REGULAR_FLAGS (0) 65 #endif 66 67 #if defined(CFA_HAVE_IOSQE_IO_LINK) && defined(CFA_HAVE_IOSQE_IO_HARDLINK) 68 #define LINK_FLAGS (IOSQE_IO_LINK | IOSQE_IO_HARDLINK) 69 #elif defined(CFA_HAVE_IOSQE_IO_LINK) 70 #define LINK_FLAGS (IOSQE_IO_LINK) 71 #elif defined(CFA_HAVE_IOSQE_IO_HARDLINK) 72 #define LINK_FLAGS (IOSQE_IO_HARDLINK) 73 #else 74 #define LINK_FLAGS (0) 75 #endif 76 77 #if defined(CFA_HAVE_SPLICE_F_FD_IN_FIXED) 78 #define SPLICE_FLAGS (SPLICE_F_FD_IN_FIXED) 79 #else 80 #define SPLICE_FLAGS (0) 81 #endif 75 82 76 83 extern [* struct io_uring_sqe, __u32] __submit_alloc( struct __io_data & ring, __u64 data ); … … 340 347 # CFA_HAVE_IORING_OP_MADVISE 341 348 Call('MADVISE', 'int madvise(void *addr, size_t length, int advice)', { 342 'addr': ' (__u64)addr',349 'addr': 'addr', 343 350 'len': 'length', 344 351 'fadvise_advice': 'advice' -
libcfa/src/concurrency/io/setup.cfa
r223a633 r33c3ded 147 147 static void * iopoll_loop( __attribute__((unused)) void * args ) { 148 148 __processor_id_t id; 149 id.full_proc = false;150 149 id.id = doregister(&id); 151 150 __cfaabi_dbg_print_safe( "Kernel : IO poller thread starting\n" ); … … 247 246 thrd.link.next = 0p; 248 247 thrd.link.prev = 0p; 248 __cfaabi_dbg_debug_do( thrd.unpark_stale = true ); 249 249 250 250 // Fixup the thread state … … 266 266 267 267 // unpark the fast io_poller 268 unpark( &thrd );268 unpark( &thrd __cfaabi_dbg_ctx2 ); 269 269 } 270 270 else { … … 275 275 } 276 276 } else { 277 unpark( &thrd );277 unpark( &thrd __cfaabi_dbg_ctx2 ); 278 278 } 279 279 -
libcfa/src/concurrency/kernel.cfa
r223a633 r33c3ded 237 237 $coroutine * proc_cor = get_coroutine(this->runner); 238 238 239 // Update global state 240 kernelTLS.this_thread = thrd_dst; 241 239 242 // set state of processor coroutine to inactive 240 243 verify(proc_cor->state == Active); … … 246 249 thrd_dst->state = Active; 247 250 248 // Update global state 249 kernelTLS.this_thread = thrd_dst; 251 __cfaabi_dbg_debug_do( 252 thrd_dst->park_stale = true; 253 thrd_dst->unpark_stale = true; 254 ) 250 255 251 256 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 252 257 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst ); 253 /* paranoid */ verify( thrd_dst->context.SP );254 258 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); // add escape condition if we are setting up the processor 255 259 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit) || thrd_dst->curr_cor == proc_cor, "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); // add escape condition if we are setting up the processor 256 /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );257 258 259 260 260 261 // set context switch to the thread that the processor is executing 262 verify( thrd_dst->context.SP ); 261 263 __cfactx_switch( &proc_cor->context, &thrd_dst->context ); 262 264 // when __cfactx_switch returns we are back in the processor coroutine 263 265 264 /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_dst->canary );265 266 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) > ((uintptr_t)__get_stack(thrd_dst->curr_cor)->limit), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too large.\n", thrd_dst ); 266 267 /* paranoid */ verifyf( ((uintptr_t)thrd_dst->context.SP) < ((uintptr_t)__get_stack(thrd_dst->curr_cor)->base ), "ERROR : Destination $thread %p has been corrupted.\n StackPointer too small.\n", thrd_dst ); 267 /* paranoid */ verify( thrd_dst->context.SP );268 268 /* paranoid */ verify( kernelTLS.this_thread == thrd_dst ); 269 269 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 270 270 271 // Reset global state272 kernelTLS.this_thread = 0p;273 271 274 272 // We just finished running a thread, there are a few things that could have happened. … … 288 286 // The thread has halted, it should never be scheduled/run again 289 287 // We may need to wake someone up here since 290 unpark( this->destroyer );288 unpark( this->destroyer __cfaabi_dbg_ctx2 ); 291 289 this->destroyer = 0p; 292 290 break RUNNING; … … 298 296 // set state of processor coroutine to active and the thread to inactive 299 297 int old_ticket = __atomic_fetch_sub(&thrd_dst->ticket, 1, __ATOMIC_SEQ_CST); 298 __cfaabi_dbg_debug_do( thrd_dst->park_result = old_ticket; ) 300 299 switch(old_ticket) { 301 300 case 1: … … 314 313 // Just before returning to the processor, set the processor coroutine to active 315 314 proc_cor->state = Active; 315 kernelTLS.this_thread = 0p; 316 316 317 317 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); … … 334 334 __x87_store; 335 335 #endif 336 /* paranoid */ verify( proc_cor->context.SP ); 337 /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary ); 336 verify( proc_cor->context.SP ); 338 337 __cfactx_switch( &thrd_src->context, &proc_cor->context ); 339 /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd_src->canary );340 338 #if defined( __i386 ) || defined( __x86_64 ) 341 339 __x87_load; … … 369 367 /* paranoid */ #endif 370 368 /* paranoid */ verifyf( thrd->link.next == 0p, "Expected null got %p", thrd->link.next ); 371 /* paranoid */ verify( 0x0D15EA5E0D15EA5E == thrd->canary );372 373 369 374 370 if (thrd->preempted == __NO_PREEMPTION) thrd->state = Ready; … … 407 403 408 404 // KERNEL ONLY unpark with out disabling interrupts 409 void __unpark( struct __processor_id_t * id, $thread * thrd ) { 405 void __unpark( struct __processor_id_t * id, $thread * thrd __cfaabi_dbg_ctx_param2 ) { 406 // record activity 407 __cfaabi_dbg_record_thrd( *thrd, false, caller ); 408 410 409 int old_ticket = __atomic_fetch_add(&thrd->ticket, 1, __ATOMIC_SEQ_CST); 410 __cfaabi_dbg_debug_do( thrd->unpark_result = old_ticket; thrd->unpark_state = thrd->state; ) 411 411 switch(old_ticket) { 412 412 case 1: … … 426 426 } 427 427 428 void unpark( $thread * thrd ) {428 void unpark( $thread * thrd __cfaabi_dbg_ctx_param2 ) { 429 429 if( !thrd ) return; 430 430 431 431 disable_interrupts(); 432 __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd );432 __unpark( (__processor_id_t*)kernelTLS.this_processor, thrd __cfaabi_dbg_ctx_fwd2 ); 433 433 enable_interrupts( __cfaabi_dbg_ctx ); 434 434 } 435 435 436 void park( void) {436 void park( __cfaabi_dbg_ctx_param ) { 437 437 /* paranoid */ verify( kernelTLS.preemption_state.enabled ); 438 438 disable_interrupts(); 439 439 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 440 440 /* paranoid */ verify( kernelTLS.this_thread->preempted == __NO_PREEMPTION ); 441 442 // record activity 443 __cfaabi_dbg_record_thrd( *kernelTLS.this_thread, true, caller ); 441 444 442 445 returnToKernel(); … … 518 521 disable_interrupts(); 519 522 /* paranoid */ verify( ! kernelTLS.preemption_state.enabled ); 520 post( this->idle );523 bool ret = post( this->idle ); 521 524 enable_interrupts( __cfaabi_dbg_ctx ); 522 525 } … … 646 649 // atomically release spin lock and block 647 650 unlock( lock ); 648 park( );651 park( __cfaabi_dbg_ctx ); 649 652 return true; 650 653 } … … 667 670 668 671 // make new owner 669 unpark( thrd );672 unpark( thrd __cfaabi_dbg_ctx2 ); 670 673 671 674 return thrd != 0p; … … 678 681 count += diff; 679 682 for(release) { 680 unpark( pop_head( waiting ) );683 unpark( pop_head( waiting ) __cfaabi_dbg_ctx2 ); 681 684 } 682 685 … … 694 697 this.prev_thrd = kernelTLS.this_thread; 695 698 } 699 700 void __cfaabi_dbg_record_thrd($thread & this, bool park, const char prev_name[]) { 701 if(park) { 702 this.park_caller = prev_name; 703 this.park_stale = false; 704 } 705 else { 706 this.unpark_caller = prev_name; 707 this.unpark_stale = false; 708 } 709 } 696 710 } 697 711 ) -
libcfa/src/concurrency/kernel.hfa
r223a633 r33c3ded 48 48 // Processor id, required for scheduling threads 49 49 struct __processor_id_t { 50 unsigned id:24; 51 bool full_proc:1; 50 unsigned id; 52 51 53 52 #if !defined(__CFA_NO_STATISTICS__) -
libcfa/src/concurrency/kernel/fwd.hfa
r223a633 r33c3ded 118 118 119 119 extern "Cforall" { 120 extern void park( void);121 extern void unpark( struct $thread * this );120 extern void park( __cfaabi_dbg_ctx_param ); 121 extern void unpark( struct $thread * this __cfaabi_dbg_ctx_param2 ); 122 122 static inline struct $thread * active_thread () { return TL_GET( this_thread ); } 123 123 -
libcfa/src/concurrency/kernel/startup.cfa
r223a633 r33c3ded 451 451 link.next = 0p; 452 452 link.prev = 0p; 453 #if defined( __CFA_WITH_VERIFY__ )454 canary = 0x0D15EA5E0D15EA5E;455 #endif456 453 457 454 node.next = 0p; … … 473 470 this.name = name; 474 471 this.cltr = &_cltr; 475 full_proc = true;472 id = -1u; 476 473 destroyer = 0p; 477 474 do_terminate = false; -
libcfa/src/concurrency/kernel_private.hfa
r223a633 r33c3ded 64 64 65 65 // KERNEL ONLY unpark with out disabling interrupts 66 void __unpark( struct __processor_id_t *, $thread * thrd );66 void __unpark( struct __processor_id_t *, $thread * thrd __cfaabi_dbg_ctx_param2 ); 67 67 68 68 static inline bool __post(single_sem & this, struct __processor_id_t * id) { … … 77 77 else { 78 78 if(__atomic_compare_exchange_n(&this.ptr, &expected, 0p, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 79 __unpark( id, expected );79 __unpark( id, expected __cfaabi_dbg_ctx2 ); 80 80 return true; 81 81 } -
libcfa/src/concurrency/monitor.cfa
r223a633 r33c3ded 122 122 123 123 unlock( this->lock ); 124 park( );124 park( __cfaabi_dbg_ctx ); 125 125 126 126 __cfaabi_dbg_print_safe( "Kernel : %10p Entered mon %p\n", thrd, this); … … 201 201 // Release the next thread 202 202 /* paranoid */ verifyf( urgent->owner->waiting_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this ); 203 unpark( urgent->owner->waiting_thread );203 unpark( urgent->owner->waiting_thread __cfaabi_dbg_ctx2 ); 204 204 205 205 // Park current thread waiting 206 park( );206 park( __cfaabi_dbg_ctx ); 207 207 208 208 // Some one was waiting for us, enter … … 222 222 223 223 // Park current thread waiting 224 park( );224 park( __cfaabi_dbg_ctx ); 225 225 226 226 /* paranoid */ verifyf( kernelTLS.this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", kernelTLS.this_thread, this->owner, this->recursion, this ); … … 264 264 //We need to wake-up the thread 265 265 /* paranoid */ verifyf( !new_owner || new_owner == this->owner, "Expected owner to be %p, got %p (m: %p)", new_owner, this->owner, this ); 266 unpark( new_owner );266 unpark( new_owner __cfaabi_dbg_ctx2 ); 267 267 } 268 268 … … 493 493 // Wake the threads 494 494 for(int i = 0; i < thread_count; i++) { 495 unpark( threads[i] );495 unpark( threads[i] __cfaabi_dbg_ctx2 ); 496 496 } 497 497 498 498 // Everything is ready to go to sleep 499 park( );499 park( __cfaabi_dbg_ctx ); 500 500 501 501 // We are back, restore the owners and recursions … … 575 575 576 576 // unpark the thread we signalled 577 unpark( signallee );577 unpark( signallee __cfaabi_dbg_ctx2 ); 578 578 579 579 //Everything is ready to go to sleep 580 park( );580 park( __cfaabi_dbg_ctx ); 581 581 582 582 … … 679 679 680 680 // unpark the thread we signalled 681 unpark( next );681 unpark( next __cfaabi_dbg_ctx2 ); 682 682 683 683 //Everything is ready to go to sleep 684 park( );684 park( __cfaabi_dbg_ctx ); 685 685 686 686 // We are back, restore the owners and recursions … … 724 724 725 725 //Everything is ready to go to sleep 726 park( );726 park( __cfaabi_dbg_ctx ); 727 727 728 728 -
libcfa/src/concurrency/mutex.cfa
r223a633 r33c3ded 42 42 append( blocked_threads, kernelTLS.this_thread ); 43 43 unlock( lock ); 44 park( );44 park( __cfaabi_dbg_ctx ); 45 45 } 46 46 else { … … 65 65 this.is_locked = (this.blocked_threads != 0); 66 66 unpark( 67 pop_head( this.blocked_threads ) 67 pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2 68 68 ); 69 69 unlock( this.lock ); … … 97 97 append( blocked_threads, kernelTLS.this_thread ); 98 98 unlock( lock ); 99 park( );99 park( __cfaabi_dbg_ctx ); 100 100 } 101 101 } … … 124 124 owner = thrd; 125 125 recursion_count = (thrd ? 1 : 0); 126 unpark( thrd );126 unpark( thrd __cfaabi_dbg_ctx2 ); 127 127 } 128 128 unlock( lock ); … … 142 142 lock( lock __cfaabi_dbg_ctx2 ); 143 143 unpark( 144 pop_head( this.blocked_threads ) 144 pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2 145 145 ); 146 146 unlock( lock ); … … 151 151 while(this.blocked_threads) { 152 152 unpark( 153 pop_head( this.blocked_threads ) 153 pop_head( this.blocked_threads ) __cfaabi_dbg_ctx2 154 154 ); 155 155 } … … 161 161 append( this.blocked_threads, kernelTLS.this_thread ); 162 162 unlock( this.lock ); 163 park( );163 park( __cfaabi_dbg_ctx ); 164 164 } 165 165 … … 170 170 unlock(l); 171 171 unlock(this.lock); 172 park( );172 park( __cfaabi_dbg_ctx ); 173 173 lock(l); 174 174 } -
libcfa/src/concurrency/preemption.cfa
r223a633 r33c3ded 274 274 kernelTLS.this_stats = this->curr_cluster->stats; 275 275 #endif 276 __unpark( id, this );276 __unpark( id, this __cfaabi_dbg_ctx2 ); 277 277 } 278 278 … … 411 411 static void * alarm_loop( __attribute__((unused)) void * args ) { 412 412 __processor_id_t id; 413 id.full_proc = false;414 413 id.id = doregister(&id); 415 414 -
libcfa/src/concurrency/snzi.hfa
r223a633 r33c3ded 36 36 static inline void depart( __snzi_node_t & ); 37 37 38 static const int __snzi_half = -1; 38 #define __snzi_half -1 39 39 40 40 //-------------------------------------------------- -
libcfa/src/concurrency/thread.cfa
r223a633 r33c3ded 39 39 link.prev = 0p; 40 40 link.preferred = -1; 41 #if defined( __CFA_WITH_VERIFY__ )42 canary = 0x0D15EA5E0D15EA5E;43 #endif44 41 45 42 node.next = 0p; … … 51 48 52 49 void ^?{}($thread& this) with( this ) { 53 #if defined( __CFA_WITH_VERIFY__ )54 canary = 0xDEADDEADDEADDEAD;55 #endif56 50 unregister(curr_cluster, this); 57 51 ^self_cor{}; -
libcfa/src/concurrency/thread.hfa
r223a633 r33c3ded 88 88 //---------- 89 89 // Park thread: block until corresponding call to unpark, won't block if unpark is already called 90 void park( void);90 void park( __cfaabi_dbg_ctx_param ); 91 91 92 92 //---------- 93 93 // Unpark a thread, if the thread is already blocked, schedule it 94 94 // if the thread is not yet block, signal that it should rerun immediately 95 void unpark( $thread * this );95 void unpark( $thread * this __cfaabi_dbg_ctx_param2 ); 96 96 97 97 forall( dtype T | is_thread(T) ) 98 static inline void unpark( T & this ) { if(!&this) return; unpark( get_thread( this ));}98 static inline void unpark( T & this __cfaabi_dbg_ctx_param2 ) { if(!&this) return; unpark( get_thread( this ) __cfaabi_dbg_ctx_fwd2 );} 99 99 100 100 //---------- -
libcfa/src/exception.h
r223a633 r33c3ded 76 76 // implemented in the .c file either so they all have to be inline. 77 77 78 trait is_exception(dtype exceptT , dtype virtualT) {78 trait is_exception(dtype exceptT) { 79 79 /* The first field must be a pointer to a virtual table. 80 * That virtual table must be a decendent of the base exception virtual tab le.80 * That virtual table must be a decendent of the base exception virtual tab$ 81 81 */ 82 v irtualT const & get_exception_vtable(exceptT *);83 // Always returns the virtual table for this type (associated types hack).82 void mark_exception(exceptT *); 83 // This is never used and should be a no-op. 84 84 }; 85 85 86 trait is_termination_exception(dtype exceptT , dtype virtualT | is_exception(exceptT, virtualT)) {86 trait is_termination_exception(dtype exceptT | is_exception(exceptT)) { 87 87 void defaultTerminationHandler(exceptT &); 88 88 }; 89 89 90 trait is_resumption_exception(dtype exceptT , dtype virtualT | is_exception(exceptT, virtualT)) {90 trait is_resumption_exception(dtype exceptT | is_exception(exceptT)) { 91 91 void defaultResumptionHandler(exceptT &); 92 92 }; 93 93 94 forall(dtype exceptT , dtype virtualT | is_termination_exception(exceptT, virtualT))94 forall(dtype exceptT | is_termination_exception(exceptT)) 95 95 static inline void $throw(exceptT & except) { 96 96 __cfaehm_throw_terminate( … … 100 100 } 101 101 102 forall(dtype exceptT , dtype virtualT | is_resumption_exception(exceptT, virtualT))102 forall(dtype exceptT | is_resumption_exception(exceptT)) 103 103 static inline void $throwResume(exceptT & except) { 104 104 __cfaehm_throw_resume( … … 108 108 } 109 109 110 forall(dtype exceptT , dtype virtualT | is_exception(exceptT, virtualT))110 forall(dtype exceptT | is_exception(exceptT)) 111 111 static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) { 112 112 __cfaehm_cancel_stack( (exception_t *)&except ); 113 113 } 114 114 115 forall(dtype exceptT , dtype virtualT | is_exception(exceptT, virtualT))115 forall(dtype exceptT | is_exception(exceptT)) 116 116 static inline void defaultTerminationHandler(exceptT & except) { 117 117 return cancel_stack( except ); 118 118 } 119 119 120 forall(dtype exceptT , dtype virtualT | is_exception(exceptT, virtualT))120 forall(dtype exceptT | is_exception(exceptT)) 121 121 static inline void defaultResumptionHandler(exceptT & except) { 122 122 throw except; -
libcfa/src/exception.hfa
r223a633 r33c3ded 95 95 // visible anywhere you use the instantiation of the exception is used. 96 96 #define POLY_VTABLE_DECLARATION(exception_name, ...) \ 97 VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(exception_name(__VA_ARGS__) *); \97 void mark_exception(exception_name(__VA_ARGS__) *); \ 98 98 extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) 99 99 … … 125 125 #define VTABLE_ASSERTION(exception_name, parameters) \ 126 126 { VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); } 127 128 // IS_EXCEPTION(exception_name [, (...parameters)])129 // IS_RESUMPTION_EXCEPTION(exception_name [, (parameters...)])130 // IS_TERMINATION_EXCEPTION(exception_name [, (parameters...)])131 // Create an assertion that exception_name, possibly with the qualifing parameters, is the given132 // kind of exception with the standard vtable with the same parameters if applicable.133 #define IS_EXCEPTION(...) _IS_EXCEPTION(is_exception, __VA_ARGS__, , ~)134 #define IS_RESUMPTION_EXCEPTION(...) _IS_EXCEPTION(is_resumption_exception, __VA_ARGS__, , ~)135 #define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)136 127 137 128 // All internal helper macros begin with an underscore. … … 169 160 170 161 #define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \ 171 forall(_UNPACK assertions | \ 172 is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \ 162 forall(_UNPACK assertions | VTABLE_ASSERTION(exception_name, parameters) ) \ 173 163 void ?{}(exception_name parameters & this) 174 164 175 165 #define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \ 176 166 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \ 177 (this).virtual_table = &get_exception_vtable(&this); \167 VTABLE_INIT(this, exception_name); \ 178 168 } 179 169 … … 195 185 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \ 196 186 struct exception_name; \ 187 void mark_exception(exception_name *); \ 197 188 VTABLE_TYPE(exception_name); \ 198 VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \199 189 extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \ 200 190 VTABLE_TYPE(exception_name) { \ … … 207 197 208 198 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \ 209 VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \ 210 return VTABLE_NAME(exception_name); \ 211 } \ 199 void mark_exception(exception_name *) {} \ 212 200 void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \ 213 201 *this = *other; \ … … 230 218 231 219 #define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \ 232 extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \ 233 VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \ 234 exception_name(__VA_ARGS__) *) { \ 235 return VTABLE_NAME(exception_name); \ 236 } \ 220 void mark_exception(exception_name(__VA_ARGS__) *) {} \ 237 221 void _GLUE2(exception_name,_copy)( \ 238 222 exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \ … … 243 227 _GLUE2(exception_name,_copy), ^?{}, \ 244 228 _CLOSE 245 246 #define _IS_EXCEPTION(kind, exception_name, parameters, ...) \247 kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters) -
libcfa/src/parseargs.cfa
r223a633 r33c3ded 25 25 #include "limits.hfa" 26 26 27 extern int cfa_args_argc __attribute__((weak));28 extern char ** cfa_args_argv __attribute__((weak));29 extern char ** cfa_args_envp __attribute__((weak));27 extern int cfa_args_argc; 28 extern char ** cfa_args_argv; 29 extern char ** cfa_args_envp; 30 30 31 31 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn)); 32 32 33 33 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) { 34 if( 0p != &cfa_args_argc ) { 35 parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left ); 36 } 37 else { 38 char * temp = ""; 39 parse_args(0, &temp, options, opt_count, usage, left ); 40 } 34 parse_args(cfa_args_argc, cfa_args_argv, options, opt_count, usage, left ); 41 35 } 42 36 -
src/AST/Convert.cpp
r223a633 r33c3ded 177 177 const ast::DeclWithType * visit( const ast::FunctionDecl * node ) override final { 178 178 if ( inCache( node ) ) return nullptr; 179 180 // function decl contains real variables that the type must use.181 // the structural change means function type in and out of decl182 // must be handled **differently** on convert back to old.183 auto ftype = new FunctionType(184 cv(node->type),185 (bool)node->type->isVarArgs186 );187 ftype->returnVals = get<DeclarationWithType>().acceptL(node->returns);188 ftype->parameters = get<DeclarationWithType>().acceptL(node->params);189 190 ftype->forall = get<TypeDecl>().acceptL( node->type->forall );191 192 visitType(node->type, ftype);193 194 179 auto decl = new FunctionDecl( 195 180 node->name, 196 181 Type::StorageClasses( node->storage.val ), 197 182 LinkageSpec::Spec( node->linkage.val ), 198 ftype, 199 //get<FunctionType>().accept1( node->type ), 183 get<FunctionType>().accept1( node->type ), 200 184 {}, 201 185 get<Attribute>().acceptL( node->attributes ), … … 1168 1152 1169 1153 const ast::Type * visit( const ast::FunctionType * node ) override final { 1170 static std::string dummy_paramvar_prefix = "__param_";1171 static std::string dummy_returnvar_prefix = "__retval_";1172 1173 1154 auto ty = new FunctionType { 1174 1155 cv( node ), 1175 1156 (bool)node->isVarArgs 1176 1157 }; 1177 auto returns = get<Type>().acceptL(node->returns); 1178 auto params = get<Type>().acceptL(node->params); 1179 1180 int ret_index = 0; 1181 for (auto t: returns) { 1182 // xxx - LinkageSpec shouldn't matter but needs to be something 1183 ObjectDecl * dummy = new ObjectDecl(dummy_returnvar_prefix + std::to_string(ret_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1184 ty->returnVals.push_back(dummy); 1185 } 1186 int param_index = 0; 1187 for (auto t: params) { 1188 ObjectDecl * dummy = new ObjectDecl(dummy_paramvar_prefix + std::to_string(param_index++), {}, LinkageSpec::C, nullptr, t, nullptr); 1189 ty->parameters.push_back(dummy); 1190 } 1191 1192 // ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1193 // ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1158 ty->returnVals = get<DeclarationWithType>().acceptL( node->returns ); 1159 ty->parameters = get<DeclarationWithType>().acceptL( node->params ); 1194 1160 ty->forall = get<TypeDecl>().acceptL( node->forall ); 1195 1161 return visitType( node, ty ); … … 1408 1374 ast::Node * node = nullptr; 1409 1375 /// cache of nodes that might be referenced by readonly<> for de-duplication 1410 /// in case that some nodes are dropped by conversion (due to possible structural change) 1411 /// use smart pointers in cache value to prevent accidental invalidation. 1412 /// at conversion stage, all created nodes are guaranteed to be unique, therefore 1413 /// const_casting out of smart pointers is permitted. 1414 std::unordered_map< const BaseSyntaxNode *, ast::ptr<ast::Node> > cache = {}; 1376 std::unordered_map< const BaseSyntaxNode *, ast::Node * > cache = {}; 1415 1377 1416 1378 // Local Utilities: … … 1485 1447 auto it = cache.find( old ); 1486 1448 if ( it == cache.end() ) return false; 1487 node = const_cast<ast::Node *>(it->second.get());1449 node = it->second; 1488 1450 return true; 1489 1451 } … … 1524 1486 virtual void visit( const FunctionDecl * old ) override final { 1525 1487 if ( inCache( old ) ) return; 1526 auto paramVars = GET_ACCEPT_V(type->parameters, DeclWithType);1527 auto returnVars = GET_ACCEPT_V(type->returnVals, DeclWithType);1528 auto forall = GET_ACCEPT_V(type->forall, TypeDecl);1529 1530 // function type is now derived from parameter decls instead of storing them1531 auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type));1532 ftype->params.reserve(paramVars.size());1533 ftype->returns.reserve(returnVars.size());1534 1535 for (auto & v: paramVars) {1536 ftype->params.emplace_back(v->get_type());1537 }1538 for (auto & v: returnVars) {1539 ftype->returns.emplace_back(v->get_type());1540 }1541 ftype->forall = std::move(forall);1542 visitType(old->type, ftype);1543 1544 1488 auto decl = new ast::FunctionDecl{ 1545 1489 old->location, 1546 1490 old->name, 1547 // GET_ACCEPT_1(type, FunctionType), 1548 std::move(paramVars), 1549 std::move(returnVars), 1491 GET_ACCEPT_1(type, FunctionType), 1550 1492 {}, 1551 1493 { old->storageClasses.val }, … … 1554 1496 { old->get_funcSpec().val } 1555 1497 }; 1556 1557 decl->type = ftype;1558 1498 cache.emplace( old, decl ); 1559 1560 1499 decl->withExprs = GET_ACCEPT_V(withExprs, Expr); 1561 1500 decl->stmts = GET_ACCEPT_1(statements, CompoundStmt); … … 2576 2515 cv( old ) 2577 2516 }; 2578 auto returnVars = GET_ACCEPT_V(returnVals, DeclWithType); 2579 auto paramVars = GET_ACCEPT_V(parameters, DeclWithType); 2580 // ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2581 // ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2582 for (auto & v: returnVars) { 2583 ty->returns.emplace_back(v->get_type()); 2584 } 2585 for (auto & v: paramVars) { 2586 ty->params.emplace_back(v->get_type()); 2587 } 2517 ty->returns = GET_ACCEPT_V( returnVals, DeclWithType ); 2518 ty->params = GET_ACCEPT_V( parameters, DeclWithType ); 2588 2519 ty->forall = GET_ACCEPT_V( forall, TypeDecl ); 2589 2520 visitType( old, ty ); -
src/AST/Decl.hpp
r223a633 r33c3ded 124 124 class FunctionDecl : public DeclWithType { 125 125 public: 126 std::vector<ptr<DeclWithType>> params;127 std::vector<ptr<DeclWithType>> returns;128 // declared type, derived from parameter declarations129 126 ptr<FunctionType> type; 130 127 ptr<CompoundStmt> stmts; 131 128 std::vector< ptr<Expr> > withExprs; 132 129 133 FunctionDecl( const CodeLocation & loc, const std::string & name, 134 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 130 FunctionDecl( const CodeLocation & loc, const std::string & name, FunctionType * type, 135 131 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 136 132 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}) 137 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),133 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), 138 134 stmts( stmts ) {} 139 135 -
src/AST/ForallSubstitutor.hpp
r223a633 r33c3ded 33 33 } 34 34 35 template<typename node_t >36 std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {37 std::vector<ptr<node_t>> n;38 n.reserve(o.size());39 for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }40 return n;41 }42 43 /*44 45 35 /// Substitute parameter/return type 46 36 std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) { … … 58 48 return n; 59 49 } 60 61 */62 50 }; 63 51 -
src/AST/Pass.impl.hpp
r223a633 r33c3ded 465 465 __pass::symtab::addId( core, 0, func ); 466 466 VISIT( 467 // parameter declarations are now directly here468 maybe_accept( node, &FunctionDecl::params );469 maybe_accept( node, &FunctionDecl::returns );470 // foralls are still in function type471 467 maybe_accept( node, &FunctionDecl::type ); 472 468 // function body needs to have the same scope as parameters - CompoundStmt will not enter -
src/AST/SymbolTable.cpp
r223a633 r33c3ded 335 335 } 336 336 337 /*338 337 void SymbolTable::addFunctionType( const FunctionType * ftype ) { 339 338 addTypes( ftype->forall ); … … 341 340 addIds( ftype->params ); 342 341 } 343 */344 342 345 343 void SymbolTable::lazyInitScope() { … … 370 368 assert( ! params.empty() ); 371 369 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 372 const Type * base = InitTweak::getPointerBase( params.front() );370 const Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 373 371 assert( base ); 374 372 return Mangle::mangle( base ); -
src/AST/SymbolTable.hpp
r223a633 r33c3ded 145 145 146 146 /// convenience function for adding all of the declarations in a function type to the indexer 147 //void addFunctionType( const FunctionType * ftype );147 void addFunctionType( const FunctionType * ftype ); 148 148 149 149 private: -
src/AST/Type.cpp
r223a633 r33c3ded 102 102 // --- FunctionType 103 103 104 105 104 FunctionType::FunctionType( const FunctionType & o ) 106 105 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(), … … 113 112 114 113 namespace { 115 bool containsTtype( const std::vector<ptr< Type>> & l ) {114 bool containsTtype( const std::vector<ptr<DeclWithType>> & l ) { 116 115 if ( ! l.empty() ) { 117 return Tuples::isTtype( l.back() );116 return Tuples::isTtype( l.back()->get_type() ); 118 117 } 119 118 return false; -
src/AST/Type.hpp
r223a633 r33c3ded 302 302 class FunctionType final : public ParameterizedType { 303 303 public: 304 // std::vector<ptr<DeclWithType>> returns; 305 // std::vector<ptr<DeclWithType>> params; 306 307 std::vector<ptr<Type>> returns; 308 std::vector<ptr<Type>> params; 304 std::vector<ptr<DeclWithType>> returns; 305 std::vector<ptr<DeclWithType>> params; 309 306 310 307 /// Does the function accept a variable number of arguments following the arguments specified -
src/Concurrency/Keywords.cc
r223a633 r33c3ded 66 66 bool needs_main, AggregateDecl::Aggregate cast_target ) : 67 67 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), 68 context_error( context_error ), exception_name( exception_name ), 69 vtable_name( getVTableName( exception_name ) ), 68 context_error( context_error ), vtable_name( getVTableName( exception_name ) ), 70 69 needs_main( needs_main ), cast_target( cast_target ) {} 71 70 … … 90 89 const std::string getter_name; 91 90 const std::string context_error; 92 const std::string exception_name;93 91 const std::string vtable_name; 94 92 bool needs_main; … … 97 95 StructDecl * type_decl = nullptr; 98 96 FunctionDecl * dtor_decl = nullptr; 99 StructDecl * except_decl = nullptr;100 97 StructDecl * vtable_decl = nullptr; 101 98 }; … … 379 376 else if ( is_target(decl) ) { 380 377 handle( decl ); 381 }382 else if ( !except_decl && exception_name == decl->name && decl->body ) {383 except_decl = decl;384 378 } 385 379 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) { … … 404 398 assert( struct_type ); 405 399 406 std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) }; 407 ObjectDecl * vtable_object = Virtual::makeVtableInstance( 408 vtable_decl->makeInst( poly_args ), struct_type, nullptr ); 409 declsToAddAfter.push_back( vtable_object ); 410 declsToAddAfter.push_back( Virtual::makeGetExceptionFunction( 411 vtable_object, except_decl->makeInst( std::move( poly_args ) ) 412 ) ); 400 declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, { 401 new TypeExpr( struct_type->clone() ), 402 }, struct_type, nullptr ) ); 413 403 } 414 404 … … 444 434 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) { 445 435 if ( vtable_decl ) { 446 std::list< Expression * > poly_args ={436 declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, { 447 437 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 448 }; 449 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 450 vtable_decl->makeInst( poly_args ), 451 except_decl->makeInst( poly_args ) 452 ) ); 453 declsToAddBefore.push_back( Virtual::makeVtableForward( 454 vtable_decl->makeInst( move( poly_args ) ) ) ); 438 } ) ); 455 439 // Its only an error if we want a vtable and don't have one. 456 440 } else if ( ! vtable_name.empty() ) { -
src/GenPoly/InstantiateGeneric.cc
r223a633 r33c3ded 172 172 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 173 173 /// Set of types which are dtype-only generic (and therefore have static layout) 174 std::set<AggregateDecl *> dtypeStatics;174 ScopedSet< AggregateDecl* > dtypeStatics; 175 175 /// Namer for concrete types 176 176 UniqueName typeNamer; … … 505 505 void GenericInstantiator::beginScope() { 506 506 instantiations.beginScope(); 507 dtypeStatics.beginScope(); 507 508 } 508 509 509 510 void GenericInstantiator::endScope() { 510 511 instantiations.endScope(); 512 dtypeStatics.endScope(); 511 513 } 512 514 -
src/InitTweak/FixGlobalInit.cc
r223a633 r33c3ded 112 112 } // if 113 113 if ( Statement * ctor = ctorInit->ctor ) { 114 // Translation 1: Add this attribute on the global declaration:115 // __attribute__((section (".data#")))116 // which makes gcc put the global in the data section,117 // so that the global is writeable (via a const cast) in the init function.118 // The trailing # is an injected assembly comment, to suppress the "a" in119 // .section .data,"a"120 // .section .data#,"a"121 // to avoid assembler warning "ignoring changed section attributes for .data"122 Type *strLitT = new PointerType( Type::Qualifiers( ),123 new BasicType( Type::Qualifiers( ), BasicType::Char ) );124 std::list< Expression * > attr_params;125 attr_params.push_back(126 new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );127 objDecl->attributes.push_back(new Attribute("section", attr_params));128 // Translation 2: Move the initizliation off the global declaration,129 // into the startup function.130 114 initStatements.push_back( ctor ); 131 115 objDecl->init = nullptr; -
src/InitTweak/InitTweak.cc
r223a633 r33c3ded 1026 1026 if ( ftype->params.size() != 2 ) return false; 1027 1027 1028 const ast::Type * t1 = getPointerBase( ftype->params.front() );1028 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() ); 1029 1029 if ( ! t1 ) return false; 1030 const ast::Type * t2 = ftype->params.back() ;1030 const ast::Type * t2 = ftype->params.back()->get_type(); 1031 1031 1032 1032 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); -
src/Parser/DeclarationNode.cc
r223a633 r33c3ded 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Oct 8 08:03:38202013 // Update Count : 113 512 // Last Modified On : Tue Jun 9 20:26:55 2020 13 // Update Count : 1134 14 14 // 15 15 … … 1016 1016 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1017 1017 dwt->location = cur->location; 1018 * out++ = dwt;1018 * out++ = dwt; 1019 1019 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1020 1020 // e.g., int foo(struct S) {} … … 1022 1022 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1023 1023 obj->location = cur->location; 1024 * out++ = obj;1024 * out++ = obj; 1025 1025 delete agg; 1026 1026 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { … … 1029 1029 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1030 1030 obj->location = cur->location; 1031 * out++ = obj;1031 * out++ = obj; 1032 1032 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1033 1033 // e.g., int foo(enum E) {} … … 1035 1035 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1036 1036 obj->location = cur->location; 1037 * out++ = obj;1037 * out++ = obj; 1038 1038 } // if 1039 1039 } catch( SemanticErrorException & e ) { -
src/Parser/lex.ll
r223a633 r33c3ded 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Tue Oct 6 18:15:41202013 * Update Count : 7 4312 * Last Modified On : Sat Feb 15 11:05:50 2020 13 * Update Count : 737 14 14 */ 15 15 … … 62 62 #define IDENTIFIER_RETURN() RETURN_VAL( typedefTable.isKind( yytext ) ) 63 63 64 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef64 #ifdef HAVE_KEYWORDS_FLOATXX // GCC >= 7 => keyword, otherwise typedef 65 65 #define FLOATXX(v) KEYWORD_RETURN(v); 66 66 #else … … 292 292 __restrict__ { KEYWORD_RETURN(RESTRICT); } // GCC 293 293 return { KEYWORD_RETURN(RETURN); } 294 /* resume { KEYWORD_RETURN(RESUME); } // CFA */294 /* resume { KEYWORD_RETURN(RESUME); } // CFA */ 295 295 short { KEYWORD_RETURN(SHORT); } 296 296 signed { KEYWORD_RETURN(SIGNED); } -
src/Parser/parser.yy
r223a633 r33c3ded 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Oct 9 18:09:09202013 // Update Count : 4 61412 // Last Modified On : Thu May 28 12:11:45 2020 13 // Update Count : 4500 14 14 // 15 15 … … 204 204 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 205 205 } else { 206 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed ." ); return nullptr;206 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 207 207 } // if 208 208 } else { 209 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed ." ); return nullptr;209 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 210 210 } // if 211 211 } // forCtrl … … 278 278 %token OTYPE FTYPE DTYPE TTYPE TRAIT // CFA 279 279 %token SIZEOF OFFSETOF 280 // %token RESUME // CFA281 %token SUSPEND // CFA280 // %token RESUME // CFA 281 %token SUSPEND // CFA 282 282 %token ATTRIBUTE EXTENSION // GCC 283 283 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN … … 329 329 %type<en> conditional_expression constant_expression assignment_expression assignment_expression_opt 330 330 %type<en> comma_expression comma_expression_opt 331 %type<en> argument_expression_list_opt argument_expression default_initialize_opt331 %type<en> argument_expression_list_opt argument_expression default_initialize_opt 332 332 %type<ifctl> if_control_expression 333 333 %type<fctl> for_control_expression for_control_expression_list … … 370 370 %type<decl> assertion assertion_list assertion_list_opt 371 371 372 %type<en> bit_subrange_size_opt bit_subrange_size372 %type<en> bit_subrange_size_opt bit_subrange_size 373 373 374 374 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 793 793 | '(' aggregate_control '&' ')' cast_expression // CFA 794 794 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 795 // VIRTUAL cannot be opt because of look ahead issues 795 796 | '(' VIRTUAL ')' cast_expression // CFA 796 797 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); } … … 919 920 | unary_expression assignment_operator assignment_expression 920 921 { 921 //if ( $2 == OperKinds::AtAssn ) {922 //SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;923 //} else {922 if ( $2 == OperKinds::AtAssn ) { 923 SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 924 } else { 924 925 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); 925 //} // if926 } // if 926 927 } 927 928 | unary_expression '=' '{' initializer_list_opt comma_opt '}' … … 1675 1676 1676 1677 typedef_expression: 1677 // deprecatedGCC, naming expression type: typedef name = exp; gives a name to the type of an expression1678 // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression 1678 1679 TYPEDEF identifier '=' assignment_expression 1679 1680 { 1680 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1681 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1682 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1681 1683 } 1682 1684 | typedef_expression pop ',' push identifier '=' assignment_expression 1683 1685 { 1684 SemanticError( yylloc, "Typedef expression is deprecated, use typeof(...) instead." ); $$ = nullptr; 1685 } 1686 ; 1686 // $$ = DeclarationNode::newName( 0 ); // unimplemented 1687 SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr; 1688 } 1689 ; 1690 1691 //c_declaration: 1692 // declaring_list pop ';' 1693 // | typedef_declaration pop ';' 1694 // | typedef_expression pop ';' // GCC, naming expression type 1695 // | sue_declaration_specifier pop ';' 1696 // ; 1697 // 1698 //declaring_list: 1699 // // A semantic check is required to ensure asm_name only appears on declarations with implicit or explicit static 1700 // // storage-class 1701 // declarator asm_name_opt initializer_opt 1702 // { 1703 // typedefTable.addToEnclosingScope( IDENTIFIER ); 1704 // $$ = ( $2->addType( $1 ))->addAsmName( $3 )->addInitializer( $4 ); 1705 // } 1706 // | declaring_list ',' attribute_list_opt declarator asm_name_opt initializer_opt 1707 // { 1708 // typedefTable.addToEnclosingScope( IDENTIFIER ); 1709 // $$ = $1->appendList( $1->cloneBaseType( $4->addAsmName( $5 )->addInitializer( $6 ) ) ); 1710 // } 1711 // ; 1687 1712 1688 1713 c_declaration: … … 1690 1715 { $$ = distAttr( $1, $2 ); } 1691 1716 | typedef_declaration 1692 | typedef_expression // deprecatedGCC, naming expression type1717 | typedef_expression // GCC, naming expression type 1693 1718 | sue_declaration_specifier 1694 1719 ; … … 2069 2094 { yyy = true; $$ = AggregateDecl::Union; } 2070 2095 | EXCEPTION // CFA 2071 // { yyy = true; $$ = AggregateDecl::Exception; } 2072 { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2096 { yyy = true; $$ = AggregateDecl::Exception; } 2073 2097 ; 2074 2098 … … 2412 2436 // Overloading: function, data, and operator identifiers may be overloaded. 2413 2437 // 2414 // Type declarations: " otype" is used to generate new types for declaring objects. Similarly, "dtype" is used for object2438 // Type declarations: "type" is used to generate new types for declaring objects. Similarly, "dtype" is used for object 2415 2439 // and incomplete types, and "ftype" is used for function types. Type declarations with initializers provide 2416 2440 // definitions of new types. Type declarations with storage class "extern" provide opaque types. … … 2441 2465 type_class identifier_or_type_name 2442 2466 { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); } 2443 type_initializer_opt assertion_list_opt2467 type_initializer_opt assertion_list_opt 2444 2468 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } 2445 2469 | type_specifier identifier_parameter_declarator … … 2468 2492 assertion 2469 2493 | assertion_list assertion 2470 { $$ = $1 ->appendList( $2 ); }2494 { $$ = $1 ? $1->appendList( $2 ) : $2; } 2471 2495 ; 2472 2496 -
src/ResolvExpr/CandidateFinder.cpp
r223a633 r33c3ded 188 188 189 189 // mark conversion cost and also specialization cost of param type 190 //const ast::Type * paramType = (*param)->get_type();190 const ast::Type * paramType = (*param)->get_type(); 191 191 cand->expr = ast::mutate_field_index( 192 192 appExpr, &ast::ApplicationExpr::args, i, 193 193 computeExpressionConversionCost( 194 args[i], *param, symtab, cand->env, convCost ) );195 convCost.decSpec( specCost( *param) );194 args[i], paramType, symtab, cand->env, convCost ) ); 195 convCost.decSpec( specCost( paramType ) ); 196 196 ++param; // can't be in for-loop update because of the continue 197 197 } … … 698 698 if ( targetType && ! targetType->isVoid() && ! funcType->returns.empty() ) { 699 699 // attempt to narrow based on expected target type 700 const ast::Type * returnType = funcType->returns.front() ;700 const ast::Type * returnType = funcType->returns.front()->get_type(); 701 701 if ( ! unify( 702 702 returnType, targetType, funcEnv, funcNeed, funcHave, funcOpen, symtab ) … … 712 712 std::size_t genStart = 0; 713 713 714 // xxx - how to handle default arg after change to ftype representation? 715 if (const ast::VariableExpr * varExpr = func->expr.as<ast::VariableExpr>()) { 716 if (const ast::FunctionDecl * funcDecl = varExpr->var.as<ast::FunctionDecl>()) { 717 // function may have default args only if directly calling by name 718 // must use types on candidate however, due to RenameVars substitution 719 auto nParams = funcType->params.size(); 720 721 for (size_t i=0; i<nParams; ++i) { 722 auto obj = funcDecl->params[i].strict_as<ast::ObjectDecl>(); 723 if (!instantiateArgument( 724 funcType->params[i], obj->init, args, results, genStart, symtab)) return; 725 } 726 goto endMatch; 727 } 728 } 729 for ( const auto & param : funcType->params ) { 714 for ( const ast::DeclWithType * param : funcType->params ) { 715 auto obj = strict_dynamic_cast< const ast::ObjectDecl * >( param ); 730 716 // Try adding the arguments corresponding to the current parameter to the existing 731 717 // matches 732 // no default args for indirect calls733 718 if ( ! instantiateArgument( 734 param, nullptr, args, results, genStart, symtab ) ) return; 735 } 736 737 endMatch: 719 obj->type, obj->init, args, results, genStart, symtab ) ) return; 720 } 721 738 722 if ( funcType->isVarArgs ) { 739 723 // append any unused arguments to vararg pack -
src/ResolvExpr/CurrentObject.cc
r223a633 r33c3ded 594 594 class SimpleIterator final : public MemberIterator { 595 595 CodeLocation location; 596 const Type *type = nullptr;596 readonly< Type > type = nullptr; 597 597 public: 598 598 SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {} … … 630 630 class ArrayIterator final : public MemberIterator { 631 631 CodeLocation location; 632 const ArrayType *array = nullptr;633 const Type *base = nullptr;632 readonly< ArrayType > array = nullptr; 633 readonly< Type > base = nullptr; 634 634 size_t index = 0; 635 635 size_t size = 0; -
src/ResolvExpr/ResolveAssertions.cc
r223a633 r33c3ded 277 277 const DeclarationWithType * candidate = cdata.id; 278 278 279 // ignore deleted candidates. 280 // NOTE: this behavior is different from main resolver. 281 // further investigations might be needed to determine 282 // if we should implement the same rule here 283 // (i.e. error if unique best match is deleted) 284 if (candidate->isDeleted) continue; 285 286 // build independent unification context. for candidate 279 // build independent unification context for candidate 287 280 AssertionSet have, newNeed; 288 281 TypeEnvironment newEnv{ resn.alt.env }; -
src/ResolvExpr/Resolver.cc
r223a633 r33c3ded 1223 1223 template<typename Iter> 1224 1224 inline bool nextMutex( Iter & it, const Iter & end ) { 1225 while ( it != end && ! (*it)-> is_mutex() ) { ++it; }1225 while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; } 1226 1226 return it != end; 1227 1227 } … … 1638 1638 // Check if the argument matches the parameter type in the current 1639 1639 // scope 1640 //ast::ptr< ast::Type > paramType = (*param)->get_type();1640 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1641 1641 if ( 1642 1642 ! unify( 1643 arg->expr->result, *param, resultEnv, need, have, open,1643 arg->expr->result, paramType, resultEnv, need, have, open, 1644 1644 symtab ) 1645 1645 ) { … … 1648 1648 ss << "candidate function not viable: no known conversion " 1649 1649 "from '"; 1650 ast::print( ss, *param);1650 ast::print( ss, (*param)->get_type() ); 1651 1651 ss << "' to '"; 1652 1652 ast::print( ss, arg->expr->result ); -
src/ResolvExpr/SatisfyAssertions.cpp
r223a633 r33c3ded 170 170 const ast::DeclWithType * candidate = cdata.id; 171 171 172 // ignore deleted candidates.173 // NOTE: this behavior is different from main resolver.174 // further investigations might be needed to determine175 // if we should implement the same rule here176 // (i.e. error if unique best match is deleted)177 if (candidate->isDeleted) continue;178 179 172 // build independent unification context for candidate 180 173 ast::AssertionSet have, newNeed; … … 325 318 if ( ! func ) continue; 326 319 327 for ( const a uto ¶m : func->params ) {328 cost.decSpec( specCost( param ) );320 for ( const ast::DeclWithType * param : func->params ) { 321 cost.decSpec( specCost( param->get_type() ) ); 329 322 } 330 323 -
src/ResolvExpr/SpecCost.cc
r223a633 r33c3ded 178 178 void previsit( const ast::FunctionType * fty ) { 179 179 int minCount = std::numeric_limits<int>::max(); 180 updateMinimumPresent( minCount, fty->params, type_deref);181 updateMinimumPresent( minCount, fty->returns, type_deref);180 updateMinimumPresent( minCount, fty->params, decl_type ); 181 updateMinimumPresent( minCount, fty->returns, decl_type ); 182 182 // Add another level to minCount if set. 183 183 count = toNoneOrInc( minCount ); -
src/ResolvExpr/Unify.cc
r223a633 r33c3ded 395 395 396 396 template< typename Iterator1, typename Iterator2 > 397 bool unify TypeList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) {397 bool unifyDeclList( Iterator1 list1Begin, Iterator1 list1End, Iterator2 list2Begin, Iterator2 list2End, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, const SymTab::Indexer &indexer ) { 398 398 auto get_type = [](DeclarationWithType * dwt){ return dwt->get_type(); }; 399 399 for ( ; list1Begin != list1End && list2Begin != list2End; ++list1Begin, ++list2Begin ) { … … 489 489 || flatOther->isTtype() 490 490 ) { 491 if ( unify TypeList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {492 if ( unify TypeList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {491 if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 492 if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 493 493 494 494 // the original types must be used in mark assertions, since pointer comparisons are used … … 784 784 785 785 /// returns flattened version of `src` 786 static std::vector< ast::ptr< ast:: Type > > flattenList(787 const std::vector< ast::ptr< ast:: Type > > & src, ast::TypeEnvironment & env786 static std::vector< ast::ptr< ast::DeclWithType > > flattenList( 787 const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env 788 788 ) { 789 std::vector< ast::ptr< ast:: Type > > dst;789 std::vector< ast::ptr< ast::DeclWithType > > dst; 790 790 dst.reserve( src.size() ); 791 for ( const a uto &d : src ) {791 for ( const ast::DeclWithType * d : src ) { 792 792 ast::Pass<TtypeExpander_new> expander{ env }; 793 793 // TtypeExpander pass is impure (may mutate nodes in place) 794 794 // need to make nodes shared to prevent accidental mutation 795 ast::ptr<ast:: Type> dc = d->accept(expander);796 auto types = flatten( dc );795 ast::ptr<ast::DeclWithType> dc = d->accept(expander); 796 auto types = flatten( dc->get_type() ); 797 797 for ( ast::ptr< ast::Type > & t : types ) { 798 798 // outermost const, volatile, _Atomic qualifiers in parameters should not play … … 803 803 // requirements than a non-mutex function 804 804 remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic ); 805 dst.emplace_back( t);805 dst.emplace_back( new ast::ObjectDecl{ dc->location, "", t } ); 806 806 } 807 807 } … … 811 811 /// Creates a tuple type based on a list of DeclWithType 812 812 template< typename Iter > 813 static ast::ptr< ast::Type > tupleFrom Types( Iter crnt, Iter end ) {813 static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) { 814 814 std::vector< ast::ptr< ast::Type > > types; 815 815 while ( crnt != end ) { 816 816 // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure 817 817 // that this results in a flat tuple 818 flatten( *crnt, types );818 flatten( (*crnt)->get_type(), types ); 819 819 820 820 ++crnt; … … 825 825 826 826 template< typename Iter > 827 static bool unify TypeList(827 static bool unifyDeclList( 828 828 Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env, 829 829 ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open, … … 831 831 ) { 832 832 while ( crnt1 != end1 && crnt2 != end2 ) { 833 const ast::Type * t1 = *crnt1;834 const ast::Type * t2 = *crnt2;833 const ast::Type * t1 = (*crnt1)->get_type(); 834 const ast::Type * t2 = (*crnt2)->get_type(); 835 835 bool isTuple1 = Tuples::isTtype( t1 ); 836 836 bool isTuple2 = Tuples::isTtype( t2 ); … … 840 840 // combine remainder of list2, then unify 841 841 return unifyExact( 842 t1, tupleFrom Types( crnt2, end2 ), env, need, have, open,842 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 843 843 noWiden(), symtab ); 844 844 } else if ( ! isTuple1 && isTuple2 ) { 845 845 // combine remainder of list1, then unify 846 846 return unifyExact( 847 tupleFrom Types( crnt1, end1 ), t2, env, need, have, open,847 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 848 848 noWiden(), symtab ); 849 849 } … … 860 860 if ( crnt1 != end1 ) { 861 861 // try unifying empty tuple with ttype 862 const ast::Type * t1 = *crnt1;862 const ast::Type * t1 = (*crnt1)->get_type(); 863 863 if ( ! Tuples::isTtype( t1 ) ) return false; 864 864 return unifyExact( 865 t1, tupleFrom Types( crnt2, end2 ), env, need, have, open,865 t1, tupleFromDecls( crnt2, end2 ), env, need, have, open, 866 866 noWiden(), symtab ); 867 867 } else if ( crnt2 != end2 ) { 868 868 // try unifying empty tuple with ttype 869 const ast::Type * t2 = *crnt2;869 const ast::Type * t2 = (*crnt2)->get_type(); 870 870 if ( ! Tuples::isTtype( t2 ) ) return false; 871 871 return unifyExact( 872 tupleFrom Types( crnt1, end1 ), t2, env, need, have, open,872 tupleFromDecls( crnt1, end1 ), t2, env, need, have, open, 873 873 noWiden(), symtab ); 874 874 } … … 877 877 } 878 878 879 static bool unify TypeList(880 const std::vector< ast::ptr< ast:: Type > > & list1,881 const std::vector< ast::ptr< ast:: Type > > & list2,879 static bool unifyDeclList( 880 const std::vector< ast::ptr< ast::DeclWithType > > & list1, 881 const std::vector< ast::ptr< ast::DeclWithType > > & list2, 882 882 ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have, 883 883 const ast::OpenVarSet & open, const ast::SymbolTable & symtab 884 884 ) { 885 return unify TypeList(885 return unifyDeclList( 886 886 list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open, 887 887 symtab ); … … 928 928 ) return; 929 929 930 if ( ! unify TypeList( params, params2, tenv, need, have, open, symtab ) ) return;931 if ( ! unify TypeList(930 if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return; 931 if ( ! unifyDeclList( 932 932 func->returns, func2->returns, tenv, need, have, open, symtab ) ) return; 933 933 … … 1232 1232 ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) { 1233 1233 if ( func->returns.empty() ) return new ast::VoidType{}; 1234 if ( func->returns.size() == 1 ) return func->returns[0] ;1234 if ( func->returns.size() == 1 ) return func->returns[0]->get_type(); 1235 1235 1236 1236 std::vector<ast::ptr<ast::Type>> tys; 1237 for ( const a uto &decl : func->returns ) {1238 tys.emplace_back( decl );1237 for ( const ast::DeclWithType * decl : func->returns ) { 1238 tys.emplace_back( decl->get_type() ); 1239 1239 } 1240 1240 return new ast::TupleType{ std::move(tys) }; -
src/SymTab/Autogen.cc
r223a633 r33c3ded 339 339 } catch ( SemanticErrorException & ) { 340 340 // okay if decl does not resolve - that means the function should not be generated 341 // delete dcl; 342 delete dcl->statements; 343 dcl->statements = nullptr; 344 dcl->isDeleted = true; 345 definitions.push_back( dcl ); 346 indexer.addId( dcl ); 341 delete dcl; 347 342 } 348 343 } -
src/SymTab/Mangler.cc
r223a633 r33c3ded 551 551 GuardValue( inFunctionType ); 552 552 inFunctionType = true; 553 if (functionType->returns.empty()) mangleName << Encoding::void_t; 554 else accept_each( functionType->returns, *visitor ); 553 std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns ); 554 if (returnTypes.empty()) mangleName << Encoding::void_t; 555 else accept_each( returnTypes, *visitor ); 555 556 mangleName << "_"; 556 accept_each( functionType->params, *visitor ); 557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params ); 558 accept_each( paramTypes, *visitor ); 557 559 mangleName << "_"; 558 560 } -
src/SymTab/Validate.cc
r223a633 r33c3ded 1384 1384 /// Replaces enum types by int, and function/array types in function parameter and return 1385 1385 /// lists by appropriate pointers 1386 /*1387 1386 struct EnumAndPointerDecay_new { 1388 1387 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) { … … 1435 1434 } 1436 1435 }; 1437 */1438 1436 1439 1437 /// expand assertions from a trait instance, performing appropriate type variable substitutions … … 1839 1837 const ast::Type * validateType( 1840 1838 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1841 //ast::Pass< EnumAndPointerDecay_new > epc;1839 ast::Pass< EnumAndPointerDecay_new > epc; 1842 1840 ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab }; 1843 1841 ast::Pass< ForallPointerDecay_new > fpd{ loc }; 1844 1842 1845 return type->accept( lrt )->accept( fpd );1843 return type->accept( epc )->accept( lrt )->accept( fpd ); 1846 1844 } 1847 1845 -
src/SynTree/AggregateDecl.cc
r223a633 r33c3ded 21 21 #include "Common/utility.h" // for printAll, cloneAll, deleteAll 22 22 #include "Declaration.h" // for AggregateDecl, TypeDecl, Declaration 23 #include "Expression.h"24 23 #include "Initializer.h" 25 24 #include "LinkageSpec.h" // for Spec, linkageName, Cforall … … 89 88 const char * StructDecl::typeString() const { return aggrString( kind ); } 90 89 91 StructInstType * StructDecl::makeInst( std::list< Expression * > const & new_parameters ) {92 std::list< Expression * > copy_parameters;93 cloneAll( new_parameters, copy_parameters );94 return makeInst( move( copy( copy_parameters ) ) );95 }96 97 StructInstType * StructDecl::makeInst( std::list< Expression * > && new_parameters ) {98 assert( parameters.size() == new_parameters.size() );99 StructInstType * type = new StructInstType( noQualifiers, this );100 type->parameters = std::move( new_parameters );101 return type;102 }103 104 90 const char * UnionDecl::typeString() const { return aggrString( Union ); } 105 91 -
src/SynTree/Declaration.h
r223a633 r33c3ded 306 306 bool is_thread () { return kind == Thread ; } 307 307 308 // Make a type instance of this declaration.309 StructInstType * makeInst( std::list< Expression * > const & parameters );310 StructInstType * makeInst( std::list< Expression * > && parameters );311 312 308 virtual StructDecl * clone() const override { return new StructDecl( *this ); } 313 309 virtual void accept( Visitor & v ) override { v.visit( this ); } -
src/SynTree/TypeDecl.cc
r223a633 r33c3ded 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Oct 8 18:18:55 202013 // Update Count : 2 212 // Last Modified On : Fri Dec 13 15:26:14 2019 13 // Update Count : 21 14 14 // 15 15 … … 21 21 #include "Type.h" // for Type, Type::StorageClasses 22 22 23 TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : 24 Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) { 23 TypeDecl::TypeDecl( const std::string & name, Type::StorageClasses scs, Type * type, Kind kind, bool sized, Type * init ) : Parent( name, scs, type ), kind( kind ), sized( kind == Ttype || sized ), init( init ) { 25 24 } 26 25 -
src/Virtual/Tables.cc
r223a633 r33c3ded 14 14 // 15 15 16 #include <SynTree/Attribute.h>17 16 #include <SynTree/Declaration.h> 18 17 #include <SynTree/Expression.h> 19 #include <SynTree/Statement.h>20 18 #include <SynTree/Type.h> 21 19 … … 40 38 } 41 39 40 // Fuse base polymorphic declaration and forall arguments into a new type. 41 static StructInstType * vtableInstType( 42 StructDecl * polyDecl, std::list< Expression * > && parameters ) { 43 assert( parameters.size() == polyDecl->parameters.size() ); 44 StructInstType * type = new StructInstType( 45 Type::Qualifiers( /* Type::Const */ ), polyDecl ); 46 type->parameters = std::move( parameters ); 47 return type; 48 } 49 42 50 static ObjectDecl * makeVtableDeclaration( 43 51 StructInstType * type, Initializer * init ) { … … 58 66 59 67 ObjectDecl * makeVtableForward( StructInstType * type ) { 60 assert( type );61 68 return makeVtableDeclaration( type, nullptr ); 62 69 } 63 70 71 ObjectDecl * makeVtableForward( 72 StructDecl * polyDecl, std::list< Expression * > && parameters ) { 73 return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) ); 74 } 75 64 76 ObjectDecl * makeVtableInstance( 65 StructInstType * vtableType, Type * objectType, Initializer * init ) { 66 assert( vtableType ); 67 assert( objectType ); 77 StructInstType * vtableType, Type * vobject_type, Initializer * init ) { 68 78 StructDecl * vtableStruct = vtableType->baseStruct; 69 79 // Build the initialization … … 82 92 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) ); 83 93 } else if ( std::string( "size" ) == field->name ) { 84 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );94 inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) ); 85 95 } else if ( std::string( "align" ) == field->name ) { 86 inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );96 inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) ); 87 97 } else { 88 98 inits.push_back( new SingleInit( new NameExpr( field->name ) ) ); … … 98 108 } 99 109 100 namespace { 101 std::string const functionName = "get_exception_vtable"; 102 } 103 104 FunctionDecl * makeGetExceptionForward( 105 Type * vtableType, Type * exceptType ) { 106 assert( vtableType ); 107 assert( exceptType ); 108 FunctionType * type = new FunctionType( noQualifiers, false ); 109 vtableType->tq.is_const = true; 110 type->returnVals.push_back( new ObjectDecl( 111 "_retvalue", 112 noStorageClasses, 113 LinkageSpec::Cforall, 114 nullptr, 115 new ReferenceType( noQualifiers, vtableType ), 116 nullptr, 117 { new Attribute("unused") } 118 ) ); 119 type->parameters.push_back( new ObjectDecl( 120 "__unused", 121 noStorageClasses, 122 LinkageSpec::Cforall, 123 nullptr, 124 new PointerType( noQualifiers, exceptType ), 125 nullptr, 126 { new Attribute("unused") } 127 ) ); 128 return new FunctionDecl( 129 functionName, 130 noStorageClasses, 131 LinkageSpec::Cforall, 132 type, 133 nullptr 134 ); 135 } 136 137 FunctionDecl * makeGetExceptionFunction( 138 ObjectDecl * vtableInstance, Type * exceptType ) { 139 assert( vtableInstance ); 140 assert( exceptType ); 141 FunctionDecl * func = makeGetExceptionForward( 142 vtableInstance->type->clone(), exceptType ); 143 func->statements = new CompoundStmt( { 144 new ReturnStmt( new VariableExpr( vtableInstance ) ), 145 } ); 146 return func; 110 ObjectDecl * makeVtableInstance( 111 StructDecl * polyDecl, std::list< Expression * > && parameters, 112 Type * vobject, Initializer * init ) { 113 return makeVtableInstance( 114 vtableInstType( polyDecl, std::move( parameters ) ), vobject, init ); 147 115 } 148 116 -
src/Virtual/Tables.h
r223a633 r33c3ded 27 27 bool isVTableInstanceName( std::string const & name ); 28 28 29 ObjectDecl * makeVtableForward( StructInstType * vtableType ); 30 /* Create a forward declaration of a vtable of the given type. 31 * vtableType node is consumed. 29 /// Converts exceptions into regular structures. 30 //void ( std::list< Declaration * > & translationUnit ); 31 32 ObjectDecl * makeVtableForward( StructInstType * ); 33 ObjectDecl * makeVtableForward( StructDecl *, std::list< Expression * > && ); 34 /* Create a forward definition of a vtable of the given type. 35 * 36 * Instead of the virtual table type you may provide the declaration and all 37 * the forall parameters. 32 38 */ 33 39 34 ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType, 35 Initializer * init = nullptr ); 40 ObjectDecl * makeVtableInstance( StructInstType *, Type *, Initializer * ); 41 ObjectDecl * makeVtableInstance( 42 StructDecl *, std::list< Expression * > &&, Type *, Initializer * ); 36 43 /* Create an initialized definition of a vtable. 37 * vtableType and init (if provided) nodes are consumed. 38 */ 39 40 // Some special code for how exceptions interact with virtual tables. 41 FunctionDecl * makeGetExceptionForward( Type * vtableType, Type * exceptType ); 42 /* Create a forward declaration of the exception virtual function 43 * linking the vtableType to the exceptType. Both nodes are consumed. 44 */ 45 46 FunctionDecl * makeGetExceptionFunction( 47 ObjectDecl * vtableInstance, Type * exceptType ); 48 /* Create the definition of the exception virtual function. 49 * exceptType node is consumed. 44 * 45 * The parameters are the virtual table type (or the base declaration and the 46 * forall parameters), the object type and optionally an initializer. 47 * 48 * Instead of the virtual table type you may provide the declaration and all 49 * the forall parameters. 50 50 */ 51 51 -
src/main.cc
r223a633 r33c3ded 9 9 // Author : Peter Buhr and Rob Schluntz 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu Oct 8 18:17:46202013 // Update Count : 63 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue May 19 12:03:00 2020 13 // Update Count : 634 14 14 // 15 15 … … 451 451 452 452 453 static const char optstring[] = ":c:ghlLmNnpd OAP:S:twW:D:";453 static const char optstring[] = ":c:ghlLmNnpdP:S:twW:D:"; 454 454 455 455 enum { PreludeDir = 128 }; … … 478 478 479 479 static const char * description[] = { 480 "diagnostic color: never, always, or auto.", // -c481 "wait for gdb to attach", // -g482 "print help message", // -h483 "generate libcfa.c", // -l484 "generate line marks", // -L485 "do not replace main", // -m486 "do not generate line marks", // -N487 "do not read prelude", // -n480 "diagnostic color: never, always, or auto.", // -c 481 "wait for gdb to attach", // -g 482 "print help message", // -h 483 "generate libcfa.c", // -l 484 "generate line marks", // -L 485 "do not replace main", // -m 486 "do not generate line marks", // -N 487 "do not read prelude", // -n 488 488 "generate prototypes for prelude functions", // -p 489 " only print deterministic output",// -d490 "Use the old-ast", // -O491 "Use the new-ast", // -A492 "print", // -P489 "don't print output that isn't deterministic", // -d 490 "Use the old-ast", // -O 491 "Use the new-ast", // -A 492 "print", // -P 493 493 "<directory> prelude directory for debug/nodebug", // no flag 494 494 "<option-list> enable profiling information:\n counters,heap,time,all,none", // -S 495 "building cfa standard lib", // -t496 "", // -w497 "", // -W498 "", // -D495 "building cfa standard lib", // -t 496 "", // -w 497 "", // -W 498 "", // -D 499 499 }; // description 500 500 -
tests/.expect/array.txt
r223a633 r33c3ded 1 array.cfa: In function '_X4mainFi___1':2 array.cfa:55:9: note: #pragma message: Compiled -
tests/.expect/cast.txt
r223a633 r33c3ded 1 cast.cfa: In function '_X4mainFi_iPPKc__1':2 cast.cfa:18:9: note: #pragma message: Compiled -
tests/.expect/enum.txt
r223a633 r33c3ded 1 done -
tests/.expect/expression.txt
r223a633 r33c3ded 1 expression.cfa: In function '_X4mainFi___1':2 expression.cfa:89:9: note: #pragma message: Compiled -
tests/.expect/forall.txt
r223a633 r33c3ded 1 forall.cfa: In function '_X4mainFi___1':2 forall.cfa:218:9: note: #pragma message: Compiled -
tests/.expect/heap.txt
r223a633 r33c3ded 1 done -
tests/.expect/identFuncDeclarator.txt
r223a633 r33c3ded 1 identFuncDeclarator.cfa: In function '_X4mainFi___1':2 identFuncDeclarator.cfa:116:9: note: #pragma message: Compiled -
tests/.expect/identParamDeclarator.txt
r223a633 r33c3ded 1 done -
tests/.expect/init1.txt
r223a633 r33c3ded 1 init1.cfa: In function '_X4mainFi___1': 2 init1.cfa:136:9: note: #pragma message: Compiled 1 error: No reasonable alternatives for expression Untyped Init Expression 2 Name: rx InitAlternative: reference to signed int 3 error: No reasonable alternatives for expression Untyped Init Expression 4 Name: px InitAlternative: pointer to signed int 5 error: No reasonable alternatives for expression Untyped Init Expression 6 Name: crx InitAlternative: reference to float 7 error: No reasonable alternatives for expression Untyped Init Expression 8 Name: cpx InitAlternative: pointer to float 9 init1.cfa:94:1 error: No reasonable alternatives for expression Generated Cast of: 10 Name: rx 11 ... to: 12 reference to signed int 13 init1.cfa:97:1 error: No reasonable alternatives for expression Applying untyped: 14 Name: ?{} 15 ...to: 16 Generated Cast of: 17 Variable Expression: _retval_f_py: pointer to signed int 18 ... to: 19 reference to pointer to signed int 20 Name: px 21 22 init1.cfa:104:1 error: No reasonable alternatives for expression Generated Cast of: 23 Name: crx 24 ... to: 25 reference to float 26 init1.cfa:107:1 error: No reasonable alternatives for expression Applying untyped: 27 Name: ?{} 28 ...to: 29 Generated Cast of: 30 Variable Expression: _retval_f_py2: pointer to float 31 ... to: 32 reference to pointer to float 33 Name: cpx 34 35 init1.cfa:114:1 error: No reasonable alternatives for expression Generated Cast of: 36 Name: s 37 ... to: 38 reference to instance of type T (not function type) 39 init1.cfa:118:1 error: No reasonable alternatives for expression Applying untyped: 40 Name: ?{} 41 ...to: 42 Generated Cast of: 43 Variable Expression: _retval_anycvt: pointer to instance of type T (not function type) 44 ... to: 45 reference to pointer to instance of type T (not function type) 46 Name: s 47 -
tests/.expect/labelledExit.txt
r223a633 r33c3ded 1 labelledExit.cfa: In function '_X4mainFi_iPPKc__1':2 labelledExit.cfa:183:9: note: #pragma message: Compiled -
tests/.expect/limits.txt
r223a633 r33c3ded 1 limits.cfa: In function '_X4mainFi_iPPKc__1':2 limits.cfa:154:9: note: #pragma message: Compiled -
tests/.expect/maybe.txt
r223a633 r33c3ded 1 done -
tests/.expect/nested-types.txt
r223a633 r33c3ded 1 nested-types.cfa: In function '_X4mainFi___1':2 nested-types.cfa:102:9: note: #pragma message: Compiled -
tests/.expect/numericConstants.txt
r223a633 r33c3ded 1 numericConstants.cfa: In function '_X4mainFi___1':2 numericConstants.cfa:68:9: note: #pragma message: Compiled -
tests/.expect/operators.txt
r223a633 r33c3ded 1 done -
tests/.expect/result.txt
r223a633 r33c3ded 1 done -
tests/.expect/stdincludes.txt
r223a633 r33c3ded 1 stdincludes.cfa: In function '_X4mainFi___1':2 stdincludes.cfa:52:9: note: #pragma message: Compiled -
tests/.expect/switch.txt
r223a633 r33c3ded 1 switch.cfa: In function '_X4mainFi___1':2 switch.cfa:105:9: note: #pragma message: Compiled -
tests/.expect/typedefRedef-ERR1.txt
r223a633 r33c3ded 1 1 typedefRedef.cfa:4:1 error: Cannot redefine typedef: Foo 2 typedefRedef.cfa: 59:1 error: Cannot redefine typedef: ARR2 typedefRedef.cfa:60:1 error: Cannot redefine typedef: ARR -
tests/.expect/typedefRedef.txt
r223a633 r33c3ded 1 typedefRedef.cfa: In function '_X4mainFi___1':2 typedefRedef.cfa:71:9: note: #pragma message: Compiled -
tests/.expect/typeof.txt
r223a633 r33c3ded 1 done -
tests/.expect/variableDeclarator.txt
r223a633 r33c3ded 1 variableDeclarator.cfa: In function '_X4mainFi_iPPKc__1':2 variableDeclarator.cfa:182:9: note: #pragma message: Compiled -
tests/.expect/voidPtr.txt
r223a633 r33c3ded 1 done -
tests/Makefile.am
r223a633 r33c3ded 11 11 ## Created On : Sun May 31 09:08:15 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Fri Oct 9 23:13:07 202014 ## Update Count : 8613 ## Last Modified On : Tue Nov 20 11:18:51 2018 14 ## Update Count : 68 15 15 ############################################################################### 16 16 … … 40 40 -fdebug-prefix-map=$(abspath ${abs_srcdir})= \ 41 41 -fdebug-prefix-map=/tmp= \ 42 -fno-diagnostics-show-caret \43 42 -g \ 44 43 -Wall \ … … 53 52 54 53 # adjust CC to current flags 55 CC = LC_ALL=C$(if $(DISTCC_CFA_PATH),distcc $(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS})54 CC = $(if $(DISTCC_CFA_PATH),distcc $(DISTCC_CFA_PATH) ${ARCH_FLAGS},$(TARGET_CFA) ${DEBUG_FLAGS} ${ARCH_FLAGS}) 56 55 CFACC = $(CC) 57 56 … … 134 133 $(CFACOMPILETEST) -CFA -XCFA -p -c -fsyntax-only -o $(abspath ${@}) 135 134 135 # Use for tests where the make command is expected to succeed but the expected.txt should be compared to stderr 136 EXPECT_STDERR = builtins/sync warnings/self-assignment 137 $(EXPECT_STDERR): % : %.cfa $(CFACCBIN) 138 $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@}) 139 136 140 #------------------------------------------------------------------------------ 137 141 # CUSTOM TARGET 138 142 #------------------------------------------------------------------------------ 139 # tests that just validate syntax and compiler output should be compared to stderr 140 CFACOMPILE_SYNTAX = $(CFACOMPILETEST) -Wno-unused-variable -Wno-unused-label -c -fsyntax-only -o $(abspath ${@}) 141 142 SYNTAX_ONLY_CODE = expression typedefRedef variableDeclarator switch numericConstants identFuncDeclarator forall \ 143 init1 limits nested-types stdincludes cast labelledExit array builtins/sync warnings/self-assignment 144 $(SYNTAX_ONLY_CODE): % : %.cfa $(CFACCBIN) 145 $(CFACOMPILE_SYNTAX) 146 $(if $(test), cp $(test) $(abspath ${@}), ) 143 # tests that just validate syntax 144 expression : expression.cfa $(CFACCBIN) 145 $(CFACOMPILETEST) -c -fsyntax-only 2> $(abspath ${@}) 147 146 148 147 # expected failures 149 # use custom target since they require a custom define *and* have a name that doesn't match the file148 # use custom target since they require a custom define and custom dependencies 150 149 alloc-ERROR : alloc.cfa $(CFACCBIN) 151 $(CFACOMPILE_SYNTAX) -DERR1 152 -cp $(test) $(abspath ${@}) 153 154 init1-ERROR : init1.cfa $(CFACCBIN) 155 $(CFACOMPILE_SYNTAX) -DERR1 156 -cp $(test) $(abspath ${@}) 150 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 157 151 158 152 typedefRedef-ERR1 : typedefRedef.cfa $(CFACCBIN) 159 $(CFACOMPILE_SYNTAX) -DERR1 160 -cp $(test) $(abspath ${@}) 153 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 161 154 162 155 nested-types-ERR1 : nested-types.cfa $(CFACCBIN) 163 $(CFACOMPILE_SYNTAX) -DERR1 164 -cp $(test) $(abspath ${@}) 156 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 165 157 166 158 nested-types-ERR2 : nested-types.cfa $(CFACCBIN) 167 $(CFACOMPILE_SYNTAX) -DERR2 168 -cp $(test) $(abspath ${@}) 159 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 169 160 170 161 raii/memberCtors-ERR1 : raii/memberCtors.cfa $(CFACCBIN) 171 $(CFACOMPILE_SYNTAX) -DERR1 172 -cp $(test) $(abspath ${@}) 162 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 173 163 174 164 raii/ctor-autogen-ERR1 : raii/ctor-autogen.cfa $(CFACCBIN) 175 $(CFACOMPILE_SYNTAX) -DERR1 176 -cp $(test) $(abspath ${@}) 165 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 177 166 178 167 raii/dtor-early-exit-ERR1 : raii/dtor-early-exit.cfa $(CFACCBIN) 179 $(CFACOMPILE_SYNTAX) -DERR1 180 -cp $(test) $(abspath ${@}) 168 $(CFACOMPILETEST) -DERR1 -c -fsyntax-only -o $(abspath ${@}) 181 169 182 170 raii/dtor-early-exit-ERR2 : raii/dtor-early-exit.cfa $(CFACCBIN) 183 $(CFACOMPILE_SYNTAX) -DERR2 184 -cp $(test) $(abspath ${@}) 171 $(CFACOMPILETEST) -DERR2 -c -fsyntax-only -o $(abspath ${@}) 185 172 186 173 # Exception Tests -
tests/alloc.cfa
r223a633 r33c3ded 10 10 // Created On : Wed Feb 3 07:56:22 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Oct 9 23:03:11202013 // Update Count : 43 112 // Last Modified On : Fri Aug 14 16:59:59 2020 13 // Update Count : 430 14 14 // 15 15 … … 362 362 ip = memset( stp, 10 ); 363 363 ip = memcpy( &st1, &st ); 364 #endif // ERR1364 #endif 365 365 } // main 366 366 -
tests/array.cfa
r223a633 r33c3ded 1 // -*- Mode: C -*- 2 // 1 // -*- Mode: C -*- 2 // 3 3 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 4 // 5 5 // The contents of this file are covered under the licence agreement in the 6 6 // file "LICENCE" distributed with Cforall. 7 // 7 // 8 8 // array.cfa -- test array declarations 9 // 9 // 10 10 // Author : Peter A. Buhr 11 11 // Created On : Tue Feb 19 21:18:06 2019 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Sun Sep 27 09:05:40 202014 // Update Count : 415 // 13 // Last Modified On : Tue Feb 19 21:18:46 2019 14 // Update Count : 1 15 // 16 16 17 int a1[ 0];17 int a1[]; 18 18 //int a2[*]; 19 19 //double a4[3.0]; 20 20 21 int m1[ 0][3];21 int m1[][3]; 22 22 //int m2[*][*]; 23 23 int m4[3][3]; … … 49 49 } 50 50 51 int main() { 52 #if !defined(NO_COMPILED_PRAGMA) 53 #pragma message( "Compiled" ) // force non-empty .expect file 54 #endif 55 } 51 int main() {} 56 52 57 53 // Local Variables: // -
tests/builtins/.expect/sync.txt
r223a633 r33c3ded 1 builtins/sync.cfa: In function '_X4mainFi___1':2 builtins/sync.cfa:358:9: note: #pragma message: Compiled -
tests/builtins/sync.cfa
r223a633 r33c3ded 66 66 #if defined(__SIZEOF_INT128__) 67 67 { __int128 ret; ret = __sync_fetch_and_nand(vplll, vlll); } 68 { __int128 ret; ret = __sync_fetch_and_nand_16(vplll, vlll); } 68 69 #endif 69 70 … … 354 355 355 356 int main() { 356 #pragma message( "Compiled" ) // force non-empty .expect file357 return 0; 357 358 } -
tests/cast.cfa
r223a633 r33c3ded 13 13 14 14 //Dummy main 15 int main( int argc, char const * argv[] ) { 16 #pragma message( "Compiled" ) // force non-empty .expect file 15 int main(int argc, char const *argv[]) 16 { 17 return 0; 17 18 } -
tests/concurrent/.expect/cluster.txt
r223a633 r33c3ded 1 done -
tests/concurrent/cluster.cfa
r223a633 r33c3ded 32 32 } 33 33 } 34 printf( "done\n" ); // non-empty .expect file34 return 0; 35 35 } -
tests/concurrent/examples/.expect/datingService.txt
r223a633 r33c3ded 1 done -
tests/concurrent/examples/datingService.cfa
r223a633 r33c3ded 10 10 // Created On : Mon Oct 30 12:56:20 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 15:42:25 202013 // Update Count : 4012 // Last Modified On : Fri Jun 21 11:32:34 2019 13 // Update Count : 38 14 14 // 15 15 … … 108 108 if ( girlck[ boyck[i] ] != boyck[ girlck[i] ] ) abort(); 109 109 } // for 110 111 printf( "done\n" ); // non-empty .expect file112 110 } // main 113 111 -
tests/concurrent/futures/.expect/basic.txt
r223a633 r33c3ded 1 done -
tests/concurrent/futures/basic.cfa
r223a633 r33c3ded 91 91 } 92 92 } 93 printf( "done\n" ); // non-empty .expect file94 95 93 } -
tests/concurrent/park/.expect/force_preempt.txt
r223a633 r33c3ded 1 done -
tests/concurrent/park/.expect/start_parked.txt
r223a633 r33c3ded 1 done -
tests/concurrent/park/contention.cfa
r223a633 r33c3ded 21 21 if(blocked[idx]) { 22 22 Thread * thrd = __atomic_exchange_n(&blocked[idx], 0p, __ATOMIC_SEQ_CST); 23 unpark( *thrd );23 unpark( *thrd __cfaabi_dbg_ctx2 ); 24 24 } else { 25 25 Thread * thrd = __atomic_exchange_n(&blocked[idx], &this, __ATOMIC_SEQ_CST); 26 unpark( *thrd );27 park( );26 unpark( *thrd __cfaabi_dbg_ctx2 ); 27 park( __cfaabi_dbg_ctx ); 28 28 } 29 29 } … … 41 41 int idx = myrand() % blocked_size; 42 42 Thread * thrd = __atomic_exchange_n(&blocked[idx], 0p, __ATOMIC_SEQ_CST); 43 unpark( *thrd );43 unpark( *thrd __cfaabi_dbg_ctx2 ); 44 44 yield( myrand() % 20 ); 45 45 } -
tests/concurrent/park/force_preempt.cfa
r223a633 r33c3ded 30 30 31 31 // Unpark this thread, don't force a yield 32 unpark( this );32 unpark( this __cfaabi_dbg_ctx2 ); 33 33 assert(mask == 0xCAFEBABA); 34 34 … … 43 43 // Park this thread, 44 44 assert(mask == (id_hash ^ 0xCAFEBABA)); 45 park( );45 park( __cfaabi_dbg_ctx ); 46 46 assert(mask == (id_hash ^ 0xCAFEBABA)); 47 47 … … 57 57 Waiter waiters[5]; 58 58 } 59 printf( "done\n" ); // non-empty .expect file60 59 } -
tests/concurrent/park/start_parked.cfa
r223a633 r33c3ded 3 3 thread Parker {}; 4 4 void main( Parker & ) { 5 park();5 park( __cfaabi_dbg_ctx ); 6 6 } 7 7 8 8 int main() { 9 for(1000) { 10 Parker parker; 11 unpark( parker ); 12 } 13 printf( "done\n" ); // non-empty .expect file 9 for(1000) { 10 Parker parker; 11 unpark( parker __cfaabi_dbg_ctx2 ); 12 } 14 13 } -
tests/enum.cfa
r223a633 r33c3ded 26 26 //Dummy main 27 27 int main(int argc, char const *argv[]) { 28 printf( "done\n" ); // non-empty .expect file29 28 } -
tests/errors/.expect/completeType.x64.txt
r223a633 r33c3ded 132 132 ?=?: pointer to function 133 133 ... with parameters 134 reference to instance of type _1 10_0_T (not function type)135 instance of type _1 10_0_T (not function type)134 reference to instance of type _109_0_T (not function type) 135 instance of type _109_0_T (not function type) 136 136 ... returning 137 _retval__operator_assign: instance of type _1 10_0_T (not function type)137 _retval__operator_assign: instance of type _109_0_T (not function type) 138 138 ... with attributes: 139 139 Attribute with name: unused -
tests/errors/.expect/completeType.x86.txt
r223a633 r33c3ded 132 132 ?=?: pointer to function 133 133 ... with parameters 134 reference to instance of type _10 9_0_T (not function type)135 instance of type _10 9_0_T (not function type)134 reference to instance of type _108_0_T (not function type) 135 instance of type _108_0_T (not function type) 136 136 ... returning 137 _retval__operator_assign: instance of type _10 9_0_T (not function type)137 _retval__operator_assign: instance of type _108_0_T (not function type) 138 138 ... with attributes: 139 139 Attribute with name: unused -
tests/exceptions/.expect/virtual-cast.txt
r223a633 r33c3ded 1 done -
tests/exceptions/.expect/virtual-poly.txt
r223a633 r33c3ded 1 done -
tests/exceptions/defaults.cfa
r223a633 r33c3ded 55 55 56 56 void unhandled_test(void) { 57 forall(dtype T , dtype V | is_exception(T, V))57 forall(dtype T | is_exception(T)) 58 58 void defaultTerminationHandler(T &) { 59 59 throw (unhandled_exception){}; -
tests/exceptions/virtual-cast.cfa
r223a633 r33c3ded 74 74 free(tri); 75 75 free(top); 76 printf( "done\n" ); // non-empty .expect file77 76 } -
tests/exceptions/virtual-poly.cfa
r223a633 r33c3ded 77 77 mono_poly_test(); 78 78 poly_poly_test(); 79 printf( "done\n" ); // non-empty .expect file80 79 } -
tests/expression.cfa
r223a633 r33c3ded 8 8 9 9 int main() { 10 int a[3] = { 0, 0, 0 };11 S s = { 3 }, * ps = &s;12 [int] t = { 3 };13 * [int] pt = &t;14 int i = 1, j = 2;10 int a[3] = { 0, 0, 0 }; 11 S s = { 3 }, * ps = &s; 12 [int] t = { 3 }; 13 * [int] pt = &t; 14 int i = 1, j = 2; 15 15 16 // operators16 // operators 17 17 18 !i;19 ~i;20 +i;21 -i;22 *ps;23 ++ps;24 --ps;25 ps++;26 ps--;18 !i; 19 ~i; 20 +i; 21 -i; 22 *ps; 23 ++ps; 24 --ps; 25 ps++; 26 ps--; 27 27 28 i + j;29 i - j;30 i * j;28 i + j; 29 i - j; 30 i * j; 31 31 32 i / j;33 i % j;34 i ^ j;35 i & j;36 i | j;37 i < j;38 i > j;39 i = j;32 i / j; 33 i % j; 34 i ^ j; 35 i & j; 36 i | j; 37 i < j; 38 i > j; 39 i = j; 40 40 41 i == j;42 i != j;43 i << j;44 i >> j;45 i <= j;46 i >= j;47 i && j;48 i || j;49 ps->i;41 i == j; 42 i != j; 43 i << j; 44 i >> j; 45 i <= j; 46 i >= j; 47 i && j; 48 i || j; 49 ps->i; 50 50 51 i *= j;52 i /= j;53 i %= j;54 i += j;55 i -= j;56 i &= j;57 i |= j;58 i ^= j;59 i <<= j;60 i >>= j;51 i *= j; 52 i /= j; 53 i %= j; 54 i += j; 55 i -= j; 56 i &= j; 57 i |= j; 58 i ^= j; 59 i <<= j; 60 i >>= j; 61 61 62 i ? i : j;62 i ? i : j; 63 63 64 // postfix function call64 // postfix function call 65 65 66 (3 + 4)`mary; 67 ({3 + 4;})`mary; 68 [3, 4]`mary; 69 3`mary; 70 a[0]`mary; 71 a[0]`mary`mary; 72 s{0}`mary; 73 a[3]`jane++; 74 jack(3)`mary; 75 s.i`mary; 76 t.0`mary; 77 s.[i]`mary; 78 ps->i`mary; 79 pt->0`mary; 80 ps->[i]`mary; 81 i++`mary; 82 i--`mary; 83 (S){2}`mary; 84 (S)@{2}`mary; 85 86 #if !defined(NO_COMPILED_PRAGMA) 87 #pragma message( "Compiled" ) // force non-empty .expect file 88 #endif 66 (3 + 4)`mary; 67 ({3 + 4;})`mary; 68 [3, 4]`mary; 69 3`mary; 70 a[0]`mary; 71 a[0]`mary`mary; 72 s{0}`mary; 73 a[3]`jane++; 74 jack(3)`mary; 75 s.i`mary; 76 t.0`mary; 77 s.[i]`mary; 78 ps->i`mary; 79 pt->0`mary; 80 ps->[i]`mary; 81 i++`mary; 82 i--`mary; 83 (S){2}`mary; 84 (S)@{2}`mary; 89 85 } // main -
tests/forall.cfa
r223a633 r33c3ded 10 10 // Created On : Wed May 9 08:48:15 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:43:20 202013 // Update Count : 3 512 // Last Modified On : Tue Mar 19 08:29:38 2019 13 // Update Count : 32 14 14 // 15 15 … … 158 158 } 159 159 forall( otype T ) inline static { 160 int RT9( T ) { T t; return 3;}160 int RT9( T ) { T t; } 161 161 } 162 162 … … 213 213 // w3 g3; 214 214 215 int main( void ) { 216 #pragma message( "Compiled" ) // force non-empty .expect file 217 } 215 int main( void ) {} 218 216 219 217 // Local Variables: // -
tests/heap.cfa
r223a633 r33c3ded 10 10 // Created On : Tue Nov 6 17:54:56 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 15:21:52202013 // Update Count : 7 312 // Last Modified On : Mon Sep 7 18:37:41 2020 13 // Update Count : 72 14 14 // 15 15 … … 485 485 // checkFreeOn(); 486 486 // malloc_stats(); 487 printf( "done\n" ); // non-empty .expect file488 487 } 489 488 -
tests/identFuncDeclarator.cfa
r223a633 r33c3ded 10 10 // Created On : Wed Aug 17 08:36:34 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:20:46 202013 // Update Count : 512 // Last Modified On : Tue Nov 6 17:56:33 2018 13 // Update Count : 3 14 14 // 15 15 … … 111 111 int (* (* const f80)(int))(); 112 112 int (* const(* const f81)(int))(); 113 114 #pragma message( "Compiled" ) // force non-empty .expect file115 113 } 116 114 -
tests/identParamDeclarator.cfa
r223a633 r33c3ded 10 10 // Created On : Wed Aug 17 08:37:56 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 14:31:08 202013 // Update Count : 412 // Last Modified On : Tue Nov 6 17:56:44 2018 13 // Update Count : 3 14 14 // 15 15 … … 158 158 159 159 int main( int argc, char const *argv[] ) { // dummy main 160 printf( "done\n" ); // non-empty .expect file160 return 0; 161 161 } 162 162 -
tests/init1.cfa
r223a633 r33c3ded 9 9 // Author : Michael Brooks 10 10 // Created On : Thu Jul 16 22:00:00 2020 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun Oct 11 10:26:50 202013 // Update Count : 811 // Last Modified By : Michael Brooks 12 // Last Modified On : Thu Jul 16 22:00:00 2020 13 // Update Count : 1 14 14 // 15 15 … … 41 41 const float * cpx2 = cpx; 42 42 43 // FIX ME: Code gen not producing correct cast.44 #pragma GCC diagnostic push45 #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"46 int (* fp)( int ) = 0p;47 fp = 0p;48 #pragma GCC diagnostic pop49 50 43 // 51 44 // unsound initializations 52 45 // 53 46 54 #ifdef ERR155 47 // mismatched referenced type 56 48 int & ry = rx; … … 60 52 float & ry2 = crx; 61 53 float * py2 = cpx; 62 #endif // ERR163 54 } 64 55 … … 99 90 // 100 91 101 #ifdef ERR1102 92 int & f_ry() { 103 93 float & rx = *0p; … … 129 119 return s; // mismatched referenced type 130 120 } 131 #endif // ERR1132 133 int main() {134 #pragma message( "Compiled" ) // force non-empty .expect file135 } -
tests/labelledExit.cfa
r223a633 r33c3ded 10 10 // Created On : Wed Aug 10 07:29:39 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 09:01:34202013 // Update Count : 1212 // Last Modified On : Wed Feb 5 16:49:48 2020 13 // Update Count : 9 14 14 // 15 15 … … 179 179 180 180 int main( int argc, char const *argv[] ) { 181 #pragma message( "Compiled" ) // force non-empty .expect file181 /* code */ 182 182 } 183 183 -
tests/limits.cfa
r223a633 r33c3ded 10 10 // Created On : Tue May 10 20:44:20 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:45:43 202013 // Update Count : 1012 // Last Modified On : Tue Nov 6 17:57:55 2018 13 // Update Count : 8 14 14 // 15 16 // Note: For testing the ability to load the constants defined in libcfa/src/limits.cfa,17 // see discussion in test const-init.18 15 19 16 #include <limits.hfa> … … 150 147 151 148 int main(int argc, char const *argv[]) { 152 #pragma message( "Compiled" ) // force non-empty .expect file 149 //DUMMY 150 return 0; 153 151 } 154 152 -
tests/maybe.cfa
r223a633 r33c3ded 10 10 // Created On : Thr May 25 16:02:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 15:13:28 202013 // Update Count : 212 // Last Modified On : Thu Jul 20 15:24:07 2017 13 // Update Count : 1 14 14 // 15 15 … … 65 65 //checkNamedConstructors(); 66 66 checkSetters(); 67 printf( "done\n" ); // non-empty .expect file68 67 } -
tests/nested-types.cfa
r223a633 r33c3ded 10 10 // Created On : Mon Jul 9 10:20:03 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:48:59202013 // Update Count : 612 // Last Modified On : Wed Feb 12 18:21:15 2020 13 // Update Count : 3 14 14 // 15 15 16 16 typedef int N; 17 17 struct A { 18 forall(otype T)19 struct N {20 T x;21 };18 forall(otype T) 19 struct N { 20 T x; 21 }; 22 22 }; 23 23 24 24 struct S { 25 struct T {26 int i;27 typedef int Bar;28 };29 T x;25 struct T { 26 int i; 27 typedef int Bar; 28 }; 29 T x; 30 30 31 // struct U;32 typedef T Bar;33 typedef int Baz;31 // struct U; 32 typedef T Bar; 33 typedef int Baz; 34 34 }; 35 35 … … 65 65 66 66 int main() { 67 // access nested struct68 S.T x;67 // access nested struct 68 S.T x; 69 69 70 {71 struct S {72 int i;73 struct Z {74 double d;75 };76 };70 { 71 struct S { 72 int i; 73 struct Z { 74 double d; 75 }; 76 }; 77 77 78 S.Z z;// gets local S79 .S.T y;// lookup at global scope only78 S.Z z; // gets local S 79 .S.T y; // lookup at global scope only 80 80 81 const volatile .S.T q;81 const volatile .S.T q; 82 82 #if ERR1 83 T err1;// error: no T in scope83 T err1; // error: no T in scope 84 84 #endif 85 85 #if ERR2 86 .Z err2;// error: no Z in global scope87 .S.Baz.Bar err3;// error: .S.Baz => int, int is not aggregate and should not appear left of the dot88 .S.Z err4;// error: no Z in global S86 .Z err2; // error: no Z in global scope 87 .S.Baz.Bar err3; // error: .S.Baz => int, int is not aggregate and should not appear left of the dot 88 .S.Z err4; // error: no Z in global S 89 89 #endif 90 }90 } 91 91 92 // U.S un;92 // U.S un; 93 93 94 S.Bar y;95 S.Baz x;96 S.T.Bar z;94 S.Bar y; 95 S.Baz x; 96 S.T.Bar z; 97 97 98 // A.N(int) x; // xxx - should not be an error, but currently is. 99 100 #pragma message( "Compiled" ) // force non-empty .expect file 98 // A.N(int) x; // xxx - should not be an error, but currently is. 101 99 } 102 100 -
tests/numericConstants.cfa
r223a633 r33c3ded 10 10 // Created On : Wed May 24 22:10:36 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 07:55:22 202013 // Update Count : 712 // Last Modified On : Tue Feb 5 08:58:16 2019 13 // Update Count : 5 14 14 // 15 15 … … 63 63 0x_ff.ffp0; // hex real 64 64 0x_1.ffff_ffff_p_128_l; 65 66 #pragma message( "Compiled" ) // force non-empty .expect file67 65 } // main 68 66 -
tests/operators.cfa
r223a633 r33c3ded 31 31 int main(int argc, char const *argv[]) { 32 32 /* code */ 33 printf( "done\n" ); // non-empty .expect file33 return 0; 34 34 } 35 35 -
tests/pybin/tools.py
r223a633 r33c3ded 88 88 raise 89 89 90 def is_empty(fname):91 if not os.path.isfile(fname):92 return True93 94 if os.stat(fname).st_size == 0:95 return True96 97 return False98 99 90 def is_ascii(fname): 100 91 if settings.dry_run: 101 92 print("is_ascii: %s" % fname) 102 return (True, "")93 return True 103 94 104 95 if not os.path.isfile(fname): 105 return (False, "No file")106 107 code, out = sh("file ",fname, output_file=subprocess.PIPE)96 return False 97 98 code, out = sh("file %s" % fname, output_file=subprocess.PIPE) 108 99 if code != 0: 109 return (False, "'file EXPECT' failed with code {}".format(code))100 return False 110 101 111 102 match = re.search(".*: (.*)", out) 112 103 113 104 if not match: 114 return (False, "Unreadable file type: '{}'".format(out)) 115 116 if "ASCII text" in match.group(1): 117 return (True, "") 118 119 return (False, "File type should be 'ASCII text', was '{}'".format(match.group(1))) 105 return False 106 107 return match.group(1).startswith("ASCII text") 120 108 121 109 def is_exe(fname): -
tests/raii/.expect/ctor-autogen.txt
r223a633 r33c3ded 1 done -
tests/raii/.expect/init_once.txt
r223a633 r33c3ded 1 done -
tests/raii/ctor-autogen.cfa
r223a633 r33c3ded 151 151 identity(gcs); 152 152 identity(gcu); 153 printf( "done\n" ); // non-empty .expect file154 153 } -
tests/raii/init_once.cfa
r223a633 r33c3ded 10 10 // Created On : Tue Jun 14 15:43:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 15:36:39 202013 // Update Count : 512 // Last Modified On : Fri Mar 22 13:41:26 2019 13 // Update Count : 4 14 14 // 15 15 … … 188 188 static_variable(); 189 189 } 190 printf( "done\n" ); // non-empty .expect file191 190 } 192 191 -
tests/result.cfa
r223a633 r33c3ded 10 10 // Created On : Thr May 25 16:50:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Sep 25 15:22:59 202013 // Update Count : 212 // Last Modified On : Thu Jul 20 15:24:12 2017 13 // Update Count : 1 14 14 // 15 15 … … 66 66 checkGetters(); 67 67 checkSetters(); 68 printf( "done\n" ); // non-empty .expect file69 68 } -
tests/stdincludes.cfa
r223a633 r33c3ded 10 10 // Created On : Tue Aug 29 08:26:14 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:51:38 202013 // Update Count : 812 // Last Modified On : Tue Nov 6 18:00:53 2018 13 // Update Count : 6 14 14 // 15 15 … … 47 47 #include <wctype.h> 48 48 49 int main() { 50 #pragma message( "Compiled" ) // force non-empty .expect file 51 } 49 int main() {} 52 50 53 51 // Local Variables: // -
tests/switch.cfa
r223a633 r33c3ded 10 10 // Created On : Tue Jul 12 06:50:22 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 08:35:02 202013 // Update Count : 4312 // Last Modified On : Tue Nov 6 18:01:34 2018 13 // Update Count : 37 14 14 // 15 15 … … 100 100 j = 5; 101 101 } // choose 102 103 #pragma message( "Compiled" ) // force non-empty .expect file104 102 } // main 105 103 -
tests/test.py
r223a633 r33c3ded 173 173 test.prepare() 174 174 175 # ----------176 # MAKE177 # ----------178 175 # build, skipping to next test on error 179 176 with Timed() as comp_dur: 180 177 make_ret, _ = make( test.target(), output_file=subprocess.DEVNULL, error=out_file, error_file = err_file ) 181 178 182 # ---------- 183 # RUN 184 # ---------- 179 run_dur = None 185 180 # run everything in a temp directory to make sure core file are handled properly 186 run_dur = None187 181 with tempdir(): 188 182 # if the make command succeeds continue otherwise skip to diff … … 262 256 make('clean', output_file=subprocess.DEVNULL, error=subprocess.DEVNULL) 263 257 264 # create the executor for our jobs 265 pool = multiprocessing.Pool(jobs) 258 # since python prints stacks by default on a interrupt, redo the interrupt handling to be silent 259 def worker_init(): 260 def sig_int(signal_num, frame): 261 pass 262 263 signal.signal(signal.SIGINT, sig_int) 264 265 # create the executor for our jobs and handle the signal properly 266 pool = multiprocessing.Pool(jobs, worker_init) 266 267 267 268 failed = False 269 270 def stop(x, y): 271 print("Tests interrupted by user", file=sys.stderr) 272 sys.exit(1) 273 signal.signal(signal.SIGINT, stop) 268 274 269 275 # for each test to run … … 354 360 failed = 0 355 361 356 # check if the expected files aren't empty357 if not options.regenerate_expected:358 for t in tests:359 if is_empty(t.expect()):360 print('WARNING: test "{}" has empty .expect file'.format(t.target()), file=sys.stderr)361 362 362 # for each build configurations, run the test 363 363 with Timed() as total_dur: -
tests/typedefRedef.cfa
r223a633 r33c3ded 27 27 typedef int ARR[]; 28 28 typedef int ARR[]; 29 #ifdef ERR1 30 // if a typedef has an array dimension, it can only be redefined to the same dimension 29 // #ifdef ERR1 30 // if a typedef has an array dimension, 31 // it can only be redefined to the same dimension 31 32 typedef int ARR[2]; 32 #endif33 // #endif 33 34 34 35 typedef int X; … … 53 54 54 55 int main() { 55 typedef int ARR[sz];56 typedef int ARR[sz]; 56 57 57 // can't redefine typedef which is VLA58 // can't redefine typedef which is VLA 58 59 #if ERR1 59 typedef int ARR[sz];60 typedef int ARR[sz]; 60 61 #endif 61 62 62 Foo *x;63 Foo *x; 63 64 64 typedef struct Bar Foo;65 Foo *y;65 typedef struct Bar Foo; 66 Foo *y; 66 67 67 typedef int *** pt; 68 69 #pragma message( "Compiled" ) // force non-empty .expect file 68 typedef int *** pt; 70 69 } -
tests/typeof.cfa
r223a633 r33c3ded 1 1 int main() { 2 int *v1; 3 typeof(v1) v2; 4 typeof(*v1) v3[4]; 5 char *v4[4]; 6 typeof(typeof(char *)[4]) v5; 7 typeof (int *) v6; 8 typeof( int ( int, int p ) ) *v7; 9 typeof( [int] ( int, int p ) ) *v8; 10 (typeof(v1)) v2; // cast with typeof 11 printf( "done\n" ); // non-empty .expect file 2 int *v1; 3 typeof(v1) v2; 4 typeof(*v1) v3[4]; 5 char *v4[4]; 6 typeof(typeof(char *)[4]) v5; 7 typeof (int *) v6; 8 typeof( int ( int, int p ) ) *v7; 9 typeof( [int] ( int, int p ) ) *v8; 10 (typeof(v1)) v2; // cast with typeof 12 11 } -
tests/variableDeclarator.cfa
r223a633 r33c3ded 10 10 // Created On : Wed Aug 17 08:41:42 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 07:46:17 202013 // Update Count : 1312 // Last Modified On : Tue Nov 6 18:02:16 2018 13 // Update Count : 2 14 14 // 15 15 … … 18 18 int (f2); 19 19 20 int * f3;21 int ** f4;22 int * const * f5;20 int *f3; 21 int **f4; 22 int * const *f5; 23 23 int * const * const f6; 24 24 25 int * (f7);26 int ** (f8);27 int * const * (f9);25 int *(f7); 26 int **(f8); 27 int * const *(f9); 28 28 int * const * const (f10); 29 29 30 int (* f11);31 int (** f12);32 int (* const * f13);30 int (*f11); 31 int (**f12); 32 int (* const *f13); 33 33 int (* const * const f14); 34 34 35 int f15[ 0];35 int f15[]; 36 36 int f16[10]; 37 int (f17[ 0]);37 int (f17[]); 38 38 int (f18[10]); 39 39 40 int * f19[0];41 int * f20[10];42 int ** f21[0];43 int ** f22[10];44 int * const * f23[0];45 int * const * f24[10];46 int * const * const f25[ 0];40 int *f19[]; 41 int *f20[10]; 42 int **f21[]; 43 int **f22[10]; 44 int * const *f23[]; 45 int * const *f24[10]; 46 int * const * const f25[]; 47 47 int * const * const f26[10]; 48 48 49 int *(f27[ 0]);49 int *(f27[]); 50 50 int *(f28[10]); 51 int **(f29[ 0]);51 int **(f29[]); 52 52 int **(f30[10]); 53 int * const *(f31[ 0]);53 int * const *(f31[]); 54 54 int * const *(f32[10]); 55 int * const * const (f33[ 0]);55 int * const * const (f33[]); 56 56 int * const * const (f34[10]); 57 57 58 int (* f35)[];59 int (* f36)[10];60 int (** f37)[];61 int (** f38)[10];62 int (* const * f39)[];63 int (* const * f40)[10];58 int (*f35)[]; 59 int (*f36)[10]; 60 int (**f37)[]; 61 int (**f38)[10]; 62 int (* const *f39)[]; 63 int (* const *f40)[10]; 64 64 int (* const * const f41)[]; 65 65 int (* const * const f42)[10]; 66 66 67 int f43[ 0][3];67 int f43[][3]; 68 68 int f44[3][3]; 69 int (f45[ 0])[3];69 int (f45[])[3]; 70 70 int (f46[3])[3]; 71 int ((f47[ 0]))[3];71 int ((f47[]))[3]; 72 72 int ((f48[3]))[3]; 73 73 74 int * f49[0][3];75 int * f50[3][3];76 int ** f51[0][3];77 int ** f52[3][3];78 int * const * f53[0][3];79 int * const * f54[3][3];80 int * const * const f55[ 0][3];74 int *f49[][3]; 75 int *f50[3][3]; 76 int **f51[][3]; 77 int **f52[3][3]; 78 int * const *f53[][3]; 79 int * const *f54[3][3]; 80 int * const * const f55[][3]; 81 81 int * const * const f56[3][3]; 82 82 83 int (* f57[0][3]);84 int (* f58[3][3]);85 int (** f59[0][3]);86 int (** f60[3][3]);87 int (* const * f61[0][3]);88 int (* const * f62[3][3]);89 int (* const * const f63[ 0][3]);83 int (*f57[][3]); 84 int (*f58[3][3]); 85 int (**f59[][3]); 86 int (**f60[3][3]); 87 int (* const *f61[][3]); 88 int (* const *f62[3][3]); 89 int (* const * const f63[][3]); 90 90 int (* const * const f64[3][3]); 91 91 … … 93 93 int (f66)(int); 94 94 95 int * f67(int);96 int ** f68(int);97 int * const * f69(int);95 int *f67(int); 96 int **f68(int); 97 int * const *f69(int); 98 98 int * const * const f70(int); 99 99 … … 104 104 int * const * const (f74)(int); 105 105 106 int (* f75)(int);107 int (** f76)(int);108 int (* const * f77)(int);106 int (*f75)(int); 107 int (**f76)(int); 108 int (* const *f77)(int); 109 109 int (* const * const f78)(int); 110 110 111 int (*(* f79)(int))();111 int (*(*f79)(int))(); 112 112 int (*(* const f80)(int))(); 113 113 int (* const(* const f81)(int))(); … … 119 119 //int fe2()[]; // returning an array 120 120 //int fe3()(); // returning a function 121 //int (* fe4)()(); // returning a function122 //int ((* fe5())())[]; // returning an array121 //int (*fe4)()(); // returning a function 122 //int ((*fe5())())[]; // returning an array 123 123 124 #ifdef __CFA__125 124 // Cforall extensions 126 125 … … 130 129 const * const * int cf6; 131 130 132 [ 0] int cf15;131 [] int cf15; 133 132 [10] int cf16; 134 133 135 [ 0] * int cf19;134 [] * int cf19; 136 135 [10] * int cf20; 137 int ** cf21[0];136 int **cf21[]; 138 137 [10] * * int cf22; 139 [ 0] * const * int cf23;138 [] * const * int cf23; 140 139 [10] * const * int cf24; 141 [ 0] const * const * int cf25;140 [] const * const * int cf25; 142 141 [10] const * const * int cf26; 143 142 … … 151 150 const * const * [10] int cf42; 152 151 153 [ 0][3] int cf43;152 [][3] int cf43; 154 153 [3][3] int cf44; 155 154 156 [ 0][3] * int cf49;155 [][3] * int cf49; 157 156 [3][3] * int cf50; 158 [ 0][3] * * int cf51;157 [][3] * * int cf51; 159 158 [3][3] * * int cf52; 160 [ 0][3] const * int cf53;159 [][3] const * int cf53; 161 160 [3][3] * const * int cf54; 162 [ 0][3] const * const * int cf55;161 [][3] const * const * int cf55; 163 162 [3][3] const * const * int cf56; 164 163 … … 174 173 175 174 *[]*[]* [ *[]*[] int ]( *[]*[] int, *[]*[] int ) v3; 176 #endif // __CFA__177 175 178 176 //Dummy main 179 int main( int argc, char const * argv[] ) { 180 #pragma message( "Compiled" ) // force non-empty .expect file 177 int main(int argc, char const *argv[]) 178 { 179 return 0; 181 180 } 182 181 -
tests/voidPtr.cfa
r223a633 r33c3ded 13 13 if ( ! a ) { 14 14 abort(); 15 } 16 printf( "done\n" ); // non-empty .expect file 15 } 17 16 } 18 17 -
tests/warnings/.expect/self-assignment.txt
r223a633 r33c3ded 24 24 ... to: 25 25 reference to signed int 26 warnings/self-assignment.cfa: In function '_X4mainFi___1':27 warnings/self-assignment.cfa:36:9: note: #pragma message: Compiled -
tests/warnings/self-assignment.cfa
r223a633 r33c3ded 10 10 // Created On : Thu Mar 1 13:53:57 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Sep 27 09:24:34 202013 // Update Count : 612 // Last Modified On : Wed Feb 20 07:56:17 2019 13 // Update Count : 3 14 14 // 15 15 … … 31 31 s.i = s.i; 32 32 t.s.i = t.s.i; 33 34 #pragma message( "Compiled" ) // force non-empty .expect file35 33 } 36 34 37 35 // Local Variables: // 38 36 // tab-width: 4 // 39 // compile-command: "cfa self-assignment.cfa" //37 // compile-command: "cfa dtor-early-exit" // 40 38 // End: // -
tests/zombies/structMember.cfa
r223a633 r33c3ded 53 53 // C useless declarations 54 54 55 #ifdef ERROR56 55 int; 57 56 TD; … … 71 70 W(int); 72 71 W(int).X; 73 #endif // ERROR74 72 }; 75 73 -
tools/gdb/utils-gdb.py
r223a633 r33c3ded 44 44 STACK = [] 45 45 46 # A global variable to keep all system task name 47 SysTask_Name = ["uLocalDebuggerReader", "uLocalDebugger", "uProcessorTask", "uBootTask", "uSystemTask", 48 "uProcessorTask", "uPthread", "uProfiler"] 49 46 50 not_supported_error_msg = "Not a supported command for this language" 47 51 … … 97 101 return cluster_root 98 102 99 def get_sched_lock():100 """101 Return: gdb.Value of __scheduler_lock102 """103 lock = gdb.parse_and_eval('_X16__scheduler_lockPS20__scheduler_RWLock_t_1')104 if lock.address == 0x0:105 print('No scheduler lock, program terminated')106 return lock107 108 def all_clusters():109 if not is_cforall():110 return None111 112 cluster_root = get_cluster_root()113 if cluster_root.address == 0x0:114 return115 116 curr = cluster_root117 ret = [curr]118 119 while True:120 curr = curr['_X4nodeS26__cluster____dbg_node_cltr_1']['_X4nextPS7cluster_1']121 if curr == cluster_root:122 break123 124 ret.append(curr)125 126 return ret127 128 def all_processors():129 if not is_cforall():130 return None131 132 cfa_t = get_cfa_types()133 134 # get processors from registration to the RWlock135 lock = get_sched_lock()136 137 #get number of elements138 count = lock['_X5readyVj_1']139 140 #find all the procs141 raw_procs = [lock['_X4dataPS21__scheduler_lock_id_t_1'][i]['_X6handleVPS16__processor_id_t_1'] for i in range(count)]142 143 # pre cast full procs144 procs = [p.cast(cfa_t.processor_ptr) for p in raw_procs if p['_X9full_procb_1']]145 146 # sort procs by clusters147 return sorted(procs, key=lambda p: p['_X4cltrPS7cluster_1'])148 149 def tls_for_pthread(pthrd):150 prev = gdb.selected_thread()151 inf = gdb.selected_inferior()152 153 thrd = inf.thread_from_thread_handle( pthrd )154 thrd.switch()155 tls = gdb.parse_and_eval('&_X9kernelTLSS16KernelThreadData_1')156 157 prev.switch()158 return tls159 160 def tls_for_proc(proc):161 return tls_for_pthread(proc['_X13kernel_threadm_1'])162 163 def thread_for_pthread(pthrd):164 return tls_for_pthread(pthrd)['_X11this_threadVPS7$thread_1']165 166 def thread_for_proc(proc):167 return tls_for_proc(proc)['_X11this_threadVPS7$thread_1']168 169 170 171 103 def find_curr_thread(): 172 104 # btstr = gdb.execute('bt', to_string = True).splitlines() … … 176 108 # return btstr[0].split('this=',1)[1].split(',')[0].split(')')[0] 177 109 return None 110 111 def all_clusters(): 112 if not is_cforall(): 113 return None 114 115 cluster_root = get_cluster_root() 116 if cluster_root.address == 0x0: 117 return 118 119 curr = cluster_root 120 ret = [curr] 121 122 while True: 123 curr = curr['_X4nodeS26__cluster____dbg_node_cltr_1']['_X4nextPS7cluster_1'] 124 if curr == cluster_root: 125 break 126 127 ret.append(curr) 128 129 return ret 130 178 131 179 132 def lookup_cluster(name = None): … … 286 239 """Cforall: Display currently known processors 287 240 Usage: 288 info processors : print out all the processors 241 info processors : print out all the processors in the Main Cluster 242 info processors all : print out all processors in all clusters 289 243 info processors <cluster_name> : print out all processors in a given cluster 290 244 """ … … 293 247 super(Processors, self).__init__('info processors', gdb.COMMAND_USER) 294 248 295 def print_processor(self, processor): 296 should_stop = processor['_X12do_terminateVb_1'] 297 if not should_stop: 298 midle = processor['_X6$linksS7$dlinks_S9processor__1']['_X4nextS9$mgd_link_Y13__tE_generic___1']['_X4elemPY13__tE_generic__1'] != 0x0 299 end = processor['_X6$linksS7$dlinks_S9processor__1']['_X4nextS9$mgd_link_Y13__tE_generic___1']['_X10terminatorPv_1'] != 0x0 300 301 status = 'Idle' if midle or end else 'Active' 302 else: 249 def print_processor(self, name, status, pending, address): 250 print('{:>20} {:>11} {:>13} {:>20}'.format(name, status, pending, address)) 251 252 def iterate_procs(self, root, active): 253 if root == 0x0: 254 return 255 256 cfa_t = get_cfa_types() 257 curr = root 258 259 while True: 260 processor = curr 261 should_stop = processor['_X12do_terminateVb_1'] 303 262 stop_count = processor['_X10terminatedS9semaphore_1']['_X5counti_1'] 304 status_str = 'Last Thread' if stop_count >= 0 else 'Terminating' 305 status = '{}({},{})'.format(status_str, should_stop, stop_count) 306 307 print('{:>20} {:>11} {:<7} {:<}'.format( 308 processor['_X4namePKc_1'].string(), 309 status, 310 str(processor['_X18pending_preemptionb_1']), 311 str(processor) 312 )) 313 tls = tls_for_proc( processor ) 314 thrd = tls['_X11this_threadVPS7$thread_1'] 315 if thrd != 0x0: 316 tname = '{} {}'.format(thrd['self_cor']['name'].string(), str(thrd)) 317 else: 318 tname = None 319 320 print('{:>20} {}'.format('Thread', tname)) 321 print('{:>20} {}'.format('TLS', tls)) 263 if not should_stop: 264 status = 'Active' if active else 'Idle' 265 else: 266 status_str = 'Last Thread' if stop_count >= 0 else 'Terminating' 267 status = '{}({},{})'.format(status_str, should_stop, stop_count) 268 269 self.print_processor(processor['_X4namePKc_1'].string(), 270 status, str(processor['_X18pending_preemptionb_1']), str(processor) 271 ) 272 273 curr = curr['_X4nodeS28__processor____dbg_node_proc_1']['_X4nextPS9processor_1'] 274 275 if curr == root or curr == 0x0: 276 break 322 277 323 278 #entry point from gdb … … 327 282 328 283 if not arg: 284 clusters = [lookup_cluster(None)] 285 elif arg == "all": 329 286 clusters = all_clusters() 330 287 else: … … 335 292 return 336 293 337 procs = all_processors() 338 339 print('{:>20} {:>11} {:<7} {}'.format('Processor', '', 'Pending', 'Object')) 340 print('{:>20} {:>11} {:<7} {}'.format('Name', 'Status', 'Yield', 'Address')) 341 cl = None 342 for p in procs: 343 # if this is a different cluster print it 344 if cl != p['_X4cltrPS7cluster_1']: 345 if cl: 346 print() 347 cl = p['_X4cltrPS7cluster_1'] 348 print('Cluster {}'.format(cl['_X4namePKc_1'].string())) 349 350 # print the processor information 351 self.print_processor(p) 294 cfa_t = get_cfa_types() 295 for cluster in clusters: 296 print('Cluster: "{}"({})'.format(cluster['_X4namePKc_1'].string(), cluster.cast(cfa_t.cluster_ptr))) 297 298 active_root = cluster.cast(cfa_t.cluster_ptr) \ 299 ['_X5procsS8__dllist_S9processor__1'] \ 300 ['_X4headPY15__TYPE_generic__1'] \ 301 .cast(cfa_t.processor_ptr) 302 303 idle_root = cluster.cast(cfa_t.cluster_ptr) \ 304 ['_X5idlesS8__dllist_S9processor__1'] \ 305 ['_X4headPY15__TYPE_generic__1'] \ 306 .cast(cfa_t.processor_ptr) 307 308 if idle_root != 0x0 or active_root != 0x0: 309 self.print_processor('Name', 'Status', 'Pending Yield', 'Address') 310 self.iterate_procs(active_root, True) 311 self.iterate_procs(idle_root, False) 312 else: 313 print("No processors on cluster") 352 314 353 315 print()
Note:
See TracChangeset
for help on using the changeset viewer.