Changeset 056cbdb

Sep 27, 2021, 10:16:57 AM (3 weeks ago)
Thierry Delisle <tdelisle@…>
172a88d, 7ce2483
716b62c (diff), 86bd8538 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.

Merge branch 'master' of

7 edited


  • doc/theses/andrew_beach_MMath/features.tex

    r716b62c r056cbdb  
    8585A common way to organize exceptions is in a hierarchical structure.
    86 This pattern comes from object-orientated languages where the
     86This pattern comes from object-oriented languages where the
    8787exception hierarchy is a natural extension of the object hierarchy.
    131131A common feature in many programming languages is a tool to pair code
    132132(behaviour) with data.
    133 In \CFA this is done with the virtual system,
     133In \CFA, this is done with the virtual system,
    134134which allow type information to be abstracted away, recovered and allow
    135135operations to be performed on the abstract objects.
    496496For example, consider an error reading a configuration file.
    497 This is most likely a problem with the configuration file @config_error@,
    498 but the function could have been passed the wrong file name @arg_error@.
     497This is most likely a problem with the configuration file (@config_error@),
     498but the function could have been passed the wrong file name (@arg_error@).
    499499In this case the function could raise one exception and then, if it is
    500500unhandled, raise the other.
    574574For instance, a resumption used to send messages to the logger may not
    575575need to be handled at all. Putting the following default handler
    576 at the global scope can make handling the exception optional by default.
     576at the global scope can make handling that exception optional by default.
    578578void defaultResumptionHandler(log_message &) {
    908908After a coroutine stack is unwound, control returns to the @resume@ function
    909909that most recently resumed it. @resume@ reports a
    910 @CoroutineCancelled@ exception, which contains a references to the cancelled
     910@CoroutineCancelled@ exception, which contains a reference to the cancelled
    911911coroutine and the exception used to cancel it.
    912912The @resume@ function also takes the \defaultResumptionHandler{} from the
  • doc/theses/andrew_beach_MMath/implement.tex

    r716b62c r056cbdb  
    414414of a function's state with @setjmp@ and restoring that snapshot with
    415415@longjmp@. This approach bypasses the need to know stack details by simply
    416 reseting to a snapshot of an arbitrary but existing function frame on the
     416resetting to a snapshot of an arbitrary but existing function frame on the
    417417stack. It is up to the programmer to ensure the snapshot is valid when it is
    418418reset and that all required cleanup from the unwound stacks is performed.
    419 This approach is fragile and requires extra work in the surrounding code.
     419Because it does not automate or check any of this cleanup,
     420it can be easy to make mistakes and always must be handled manually.
    421422With respect to the extra work in the surrounding code,
    435436library that provides tools for stack walking, handler execution, and
    436437unwinding. What follows is an overview of all the relevant features of
    437 libunwind needed for this work, and how \CFA uses them to implement exception
    438 handling.
     438libunwind needed for this work.
     439Following that is the description of the \CFA code that uses libunwind
     440to implement termination.
    440442\subsection{libunwind Usage}
  • doc/theses/andrew_beach_MMath/intro.tex

    r716b62c r056cbdb  
    3939it returns control to that function.
    41 \input{termination}
    43 \medskip
     45% I hate these diagrams, but I can't access xfig to fix them and they are
     46% better than the alternative.
    46 \todo*{Can I make the new diagrams fit the old style?}
    4849Resumption exception handling searches the stack for a handler and then calls
    5354that preformed the raise, usually starting after the raise.
    55 \input{resumption}
    57 \medskip
     60% The other one.
    136138message as a payload\cite{Ada12}.
    138 The modern flag-ship for termination exceptions is \Cpp,
     140The modern flagship for termination exceptions -- if one exists -- is \Cpp,
    139141which added them in its first major wave of non-object-orientated features
    140142in 1990.\cite{CppHistory}
    193195included in the \Cpp standard.
    195 Since then, resumptions have been ignored in main-stream programming languages.
     197Since then, resumptions have been ignored in mainstream programming languages.
    196198However, resumption is being revisited in the context of decades of other
    197199developments in programming languages.
    217 More recently exceptions, seem to be vanishing from newer programming
     219More recently, exceptions seem to be vanishing from newer programming
    218220languages, replaced by ``panic".
    219221In Rust, a panic is just a program level abort that may be implemented by
    220222unwinding the stack like in termination exception
    222 Go's panic through is very similar to a termination, except it only supports
     224Go's panic though is very similar to a termination, except it only supports
    223225a catch-all by calling \code{Go}{recover()}, simplifying the interface at
    224226the cost of flexibility.\cite{Go:2021}
    243245through multiple functions before it is addressed.
     247Here is an example of the pattern in Bash, where commands can only  ``return"
     248numbers and most output is done through streams of text.
     250# Immediately after running a command:
     251case $? in
     253        # Success
     254        ;;
     256        # Error Code 1
     257        ;;
     259        # Error Code 2 or Error Code 3
     260        ;;
     261# Add more cases as needed.
    245265\item\emph{Special Return with Global Store}:
    246266Similar to the error codes pattern but the function itself only returns
    253273This approach avoids the multiple results issue encountered with straight
    254 error codes but otherwise has the same disadvantages and more.
     274error codes as only a single error value has to be returned,
     275but otherwise has the same disadvantages and more.
    255276Every function that reads or writes to the global store must agree on all
    256277possible errors and managing it becomes more complex with concurrency.
     279This example shows some of what has to be done to robustly handle a C
     280standard library function that reports errors this way.
     282// Now a library function can set the error.
     283int handle = open(path_name, flags);
     284if (-1 == handle) {
     285        switch (errno) {
     286    case ENAMETOOLONG:
     287                // path_name is a bad argument.
     288                break;
     289        case ENFILE:
     290                // A system resource has been exausted.
     291                break;
     292        // And many more...
     293    }
     296% cite open man page?
    258298\item\emph{Return Union}:
    265305This pattern is very popular in any functional or semi-functional language
    266306with primitive support for tagged unions (or algebraic data types).
    267 % We need listing Rust/rust to format code snippets from it.
    268 % Rust's \code{rust}{Result<T, E>}
     307Return unions can also be expressed as monads (evaluation in a context)
     308and often are in languages with special syntax for monadic evaluation,
     309such as Haskell's \code{haskell}{do} blocks.
    269311The main advantage is that an arbitrary object can be used to represent an
    270312error, so it can include a lot more information than a simple error code.
    272314execution, and if there aren't primitive tagged unions proper, usage can be
    273315hard to enforce.
     316% We need listing Rust/rust to format code snippets from it.
     317% Rust's \code{rust}{Result<T, E>}
     319This is a simple example of examining the result of a failing function in
     320Haskell, using its \code{haskell}{Either} type.
     321Examining \code{haskell}{error} further would likely involve more matching,
     322but the type of \code{haskell}{error} is user defined so there are no
     323general cases.
     325case failingFunction argA argB of
     326    Right value -> -- Use the successful computed value.
     327    Left error -> -- Handle the produced error.
     330Return unions as monads will result in the same code, but can hide most
     331of the work to propagate errors in simple cases. The code to actually handle
     332the errors, or to interact with other monads (a common case in these
     333languages) still has to be written by hand.
     335If \code{haskell}{failingFunction} is implemented with two helpers that
     336use the same error type, then it can be implemented with a \code{haskell}{do}
     339failingFunction x y = do
     340        z <- helperOne x
     341        helperTwo y z
    275344\item\emph{Handler Functions}:
    292361function calls, but cheaper (constant time) to call,
    293362they are more suited to more frequent (less exceptional) situations.
     363Although, in \Cpp and other languages that do not have checked exceptions,
     364they can actually be enforced by the type system be more reliable.
     366This is a more local example in \Cpp, using a function to provide
     367a default value for a mapping.
     369ValueT Map::key_or_default(KeyT key, ValueT(*make_default)(KeyT)) {
     370        ValueT * value = find_value(key);
     371        if (nullptr != value) {
     372                return *value;
     373        } else {
     374                return make_default(key);
     375        }
    297381Because of their cost, exceptions are rarely used for hot paths of execution.
    298382Hence, there is an element of self-fulfilling prophecy as implementation
    299 techniques have been focused on making them cheap to set-up,
     383techniques have been focused on making them cheap to set up,
    300384happily making them expensive to use in exchange.
    301385This difference is less important in higher-level scripting languages,
  • doc/theses/andrew_beach_MMath/performance.tex

    r716b62c r056cbdb  
    3737resumption exceptions. Even the older programming languages with resumption
    3838seem to be notable only for having resumption.
     39On the other hand, the functional equivalents to resumption are too new.
     40There does not seem to be any standard implementations in well-known
     41languages; so far, they seem confined to extensions and research languages.
     42% There was some maybe interesting comparison to an OCaml extension
     43% but I'm not sure how to get that working if it is interesting.
    3944Instead, resumption is compared to its simulation in other programming
    4045languages: fixup functions that are explicitly passed into a function.
    312317\CFA, \Cpp and Java.
    313318% To be exact, the Match All and Match None cases.
    314 The most likely explination is that,
     319The most likely explanation is that
    315320the generally faster languages have made ``common cases fast" at the expense
    316321of the rarer cases. Since exceptions are considered rare, they are made
    317322expensive to help speed up common actions, such as entering and leaving try
    319 Python on the other hand, while generally slower than the other languages,
    320 uses exceptions more and has not scarified their performance.
     324Python, on the other hand, while generally slower than the other languages,
     325uses exceptions more and has not sacrificed their performance.
    321326In addition, languages with high-level representations have a much
    322327easier time scanning the stack as there is less to decode.
  • doc/theses/andrew_beach_MMath/uw-ethesis-frontpgs.tex

    r716b62c r056cbdb  
    158 I would like to thank all the people who made this thesis possible.
    159 (I'm waiting until who is involved is finalized.)
     158As is tradition and his due, I would like to begin by thanking my
     159supervisor Peter Buhr. From accepting me in a first place,
     160to helping me run performance tests, I would not be here without him.
     161Also if there was an ``artist" field here he would be listed there as well,
     162he helped me a lot with the diagrams.
     164I would like to thank the readers
     165Gregor Richards and Yizhou Zhang
     166for their feedback and approval.
     167The presentation of the thesis has definitely been improved with their
     170I also thank the entire Cforall Team who built the rest of the
     171\CFA compiler. From the existing features I used in my work, to the
     172internal tooling that makes further development easier and the optimizations
     173that make running tests pass by quickly.
     174This includes: Aaron Moss, Rob Schluntz, Thierry Delisle, Michael Brooks,
     175Mubeen Zulfieqar \& Fangren Yu.
     177And thank-you Henry Xue, the co-op student who
     178converted my macro implementation of exception declarations into
     179the compiler features presented in this thesis.
     181Finally I thank my family, who are still relieved I learned how to read.
  • doc/theses/andrew_beach_MMath/uw-ethesis.bib

    r716b62c r056cbdb  
    5050    author={The Rust Team},
    5151    key={Rust Panic Macro},
    52     howpublished={\href{}{https://\\-std/\-panic/\-index.html}},
     52    howpublished={\href{}{https://\\-std/\-macro.panic.html}},
    5353    addendum={Accessed 2021-08-31},
  • libcfa/src/fstream.hfa

    r716b62c r056cbdb  
    8080void release( ofstream & );
     82void lock( ofstream & );
     83void unlock( ofstream & );
    8285struct osacquire {
    8386        ofstream & os;
Note: See TracChangeset for help on using the changeset viewer.