Changes in / [d83b266:c86ee4c]


Ignore:
Files:
13 deleted
70 edited

Legend:

Unmodified
Added
Removed
  • benchmark/rmit.py

    rd83b266 rc86ee4c  
    138138        # ================================================================================
    139139        # Identify the commands to run
    140         command = './' + options.command[0]
    141         if options.candidates:
    142                 commands = [command + "-" + c for c in options.candidates]
    143         else:
    144                 commands = [command]
     140        commands = ["./" + options.command[0] + "-" + c for c in options.candidates]
    145141        for c in commands:
    146142                if not os.path.isfile(c):
  • doc/theses/andrew_beach_MMath/code/cond-catch.cfa

    rd83b266 rc86ee4c  
    1919                throw_exception();
    2020        } catch (empty_exception * exc ; should_catch) {
    21                 asm volatile ("# catch block (conditional)");
     21                // ...
    2222        }
    2323}
     
    3737                        cond_catch();
    3838                } catch (empty_exception * exc) {
    39                         asm volatile ("# catch block (unconditional)");
     39                        // ...
    4040                }
    4141        }
  • doc/theses/andrew_beach_MMath/code/cond-catch.cpp

    rd83b266 rc86ee4c  
    1919                throw_exception();
    2020        } catch (EmptyException & exc) {
    21                 if (!should_catch) {
     21                if (should_catch) {
    2222                        throw;
    2323                }
    24                 asm volatile ("# catch block (conditional)");
    2524        }
    2625}
     
    4039                        cond_catch();
    4140                } catch (EmptyException &) {
    42                         asm volatile ("# catch block (unconditional)");
     41                        // ...
    4342                }
    4443    }
  • doc/theses/andrew_beach_MMath/code/cond-fixup.cfa

    rd83b266 rc86ee4c  
    1212
    1313void throw_exception() {
    14         throwResume (empty_exception){&empty_vt};
     14        throw (empty_exception){&empty_vt};
    1515}
    1616
     
    1818        try {
    1919                throw_exception();
    20         } catchResume (empty_exception * exc ; should_catch) {
    21                 asm volatile ("# fixup block (conditional)");
     20        } catch (empty_exception * exc ; should_catch) {
     21                // ...
    2222        }
    2323}
     
    3636                try {
    3737                        cond_catch();
    38                 } catchResume (empty_exception * exc) {
    39                         asm volatile ("# fixup block (unconditional)");
     38                } catch (empty_exception * exc) {
     39                        // ...
    4040                }
    4141        }
  • doc/theses/andrew_beach_MMath/code/cross-catch.cfa

    rd83b266 rc86ee4c  
    77EHM_EXCEPTION(not_raised_exception)();
    88
    9 EHM_VIRTUAL_TABLE(not_raised_exception, not_vt);
    10 
    119int main(int argc, char * argv[]) {
    1210        unsigned int times = 1;
    13         volatile bool should_throw = false;
     11        unsigned int total_frames = 1;
    1412        if (1 < argc) {
    1513                times = strtol(argv[1], 0p, 10);
     14        }
     15        if (2 < argc) {
     16                total_frames = strtol(argv[2], 0p, 10);
    1617        }
    1718
     
    1920        for (unsigned int count = 0 ; count < times ; ++count) {
    2021                try {
    21                         asm volatile ("# try block");
    22                         if (should_throw) {
    23                                 throw (not_raised_exception){&not_vt};
    24                         }
     22                        // ...
    2523                } catch (not_raised_exception *) {
    26                         asm volatile ("# catch block");
     24                        // ...
    2725                }
    2826        }
  • doc/theses/andrew_beach_MMath/code/cross-catch.cpp

    rd83b266 rc86ee4c  
    1111int main(int argc, char * argv[]) {
    1212        unsigned int times = 1;
    13         volatile bool should_throw = false;
    1413        if (1 < argc) {
    1514                times = strtol(argv[1], nullptr, 10);
     
    1918        for (unsigned int count = 0 ; count < times ; ++count) {
    2019                try {
    21                         asm volatile ("# try block");
    22                         if (should_throw) {
    23                                 throw NotRaisedException();
    24                         }
     20                        // ...
    2521                } catch (NotRaisedException &) {
    26                         asm volatile ("# catch block");
     22                        // ...
    2723                }
    2824        }
  • doc/theses/andrew_beach_MMath/code/cross-finally.cfa

    rd83b266 rc86ee4c  
    55#include <stdlib.hfa>
    66
    7 EHM_EXCEPTION(not_raised_exception)();
    8 
    9 EHM_VIRTUAL_TABLE(not_raised_exception, not_vt);
    10 
    117int main(int argc, char * argv[]) {
    128        unsigned int times = 1;
    13         volatile bool should_throw = false;
     9        unsigned int total_frames = 1;
    1410        if (1 < argc) {
    1511                times = strtol(argv[1], 0p, 10);
     12        }
     13        if (2 < argc) {
     14                total_frames = strtol(argv[2], 0p, 10);
    1615        }
    1716
    1817        Time start_time = timeHiRes();
    1918        for (unsigned int count = 0 ; count < times ; ++count) {
    20                 try {
    21                         asm volatile ("# try block");
    22                         if (should_throw) {
    23                                 throw (not_raised_exception){&not_vt};
    24                         }
     19                 try {
     20                        // ...
    2521                } finally {
    26                         asm volatile ("# finally block");
     22                        // ...
    2723                }
    2824        }
  • doc/theses/andrew_beach_MMath/code/cross-resume.cfa

    rd83b266 rc86ee4c  
    2020        for (unsigned int count = 0 ; count < times ; ++count) {
    2121                try {
    22                         asm volatile ("");
     22                        // ...
    2323                } catchResume (not_raised_exception *) {
    24                         asm volatile ("");
     24                        // ...
    2525                }
    2626        }
  • doc/theses/andrew_beach_MMath/code/resume-detor.cfa

    rd83b266 rc86ee4c  
    1212
    1313void ^?{}(WithDestructor & this) {
    14         asm volatile ("# destructor body");
     14    // ...
    1515}
    1616
    1717void unwind_destructor(unsigned int frames) {
    18         if (frames) {
     18    if (frames) {
    1919
    20                 WithDestructor object;
    21                 unwind_destructor(frames - 1);
    22         } else {
    23                 throwResume (empty_exception){&empty_vt};
    24         }
     20        WithDestructor object;
     21        unwind_destructor(frames - 1);
     22    } else {
     23        throwResume (empty_exception){&empty_vt};
     24    }
    2525}
    2626
     
    3636
    3737        Time start_time = timeHiRes();
    38         for (int count = 0 ; count < times ; ++count) {
    39                 try {
    40                         unwind_destructor(total_frames);
    41                 } catchResume (empty_exception *) {
    42                         asm volatile ("# fixup block");
    43                 }
    44         }
     38    for (int count = 0 ; count < times ; ++count) {
     39        try {
     40            unwind_destructor(total_frames);
     41        } catchResume (empty_exception *) {
     42            // ...
     43        }
     44    }
    4545        Time end_time = timeHiRes();
    4646        sout | "Run-Time (ns): " | (end_time - start_time)`ns;
  • doc/theses/andrew_beach_MMath/code/resume-empty.cfa

    rd83b266 rc86ee4c  
    1313                unwind_empty(frames - 1);
    1414        } else {
    15                 throwResume (empty_exception){&empty_vt};
     15                throw (empty_exception){&empty_vt};
    1616        }
    1717}
     
    3131                try {
    3232                        unwind_empty(total_frames);
    33                 } catchResume (empty_exception *) {
    34                         asm volatile ("# fixup block");
     33                } catch (empty_exception *) {
     34                        // ...
    3535                }
    3636        }
  • doc/theses/andrew_beach_MMath/code/resume-finally.cfa

    rd83b266 rc86ee4c  
    1414                        unwind_finally(frames - 1);
    1515                } finally {
    16                         asm volatile ("# finally block");
     16                        // ...
    1717                }
    1818        } else {
     
    3636                        unwind_finally(total_frames);
    3737                } catchResume (empty_exception *) {
    38                         asm volatile ("# fixup block");
     38                        // ...
    3939                }
    4040        }
  • doc/theses/andrew_beach_MMath/code/resume-other.cfa

    rd83b266 rc86ee4c  
    1616                        unwind_other(frames - 1);
    1717                } catchResume (not_raised_exception *) {
    18                         asm volatile ("# fixup block (stack)");
     18                        // ...
    1919                }
    2020        } else {
     
    3838                        unwind_other(total_frames);
    3939                } catchResume (empty_exception *) {
    40                         asm volatile ("# fixup block (base)");
     40                        // ...
    4141                }
    4242        }
  • doc/theses/andrew_beach_MMath/code/test.sh

    rd83b266 rc86ee4c  
    11#!/usr/bin/env bash
    22
    3 # Usage:
    4 # test.sh LANGUAGE TEST
    5 #   Run the TEST in LANGUAGE.
    6 # test.sh -b SOURCE_FILE...
    7 #   Build a test from SOURCE_FILE(s).
    8 # test.sh -v LANGUAGE TEST FILE
    9 #   View the result from TEST in LANGUAGE stored in FILE.
     3# Usage: LANGUAGE TEST | -b SOURCE_FILE
    104
    115readonly ITERATIONS=1000000 # 1 000 000, one million
     
    2418        *.cfa)
    2519                # Requires a symbolic link.
    26                 mmake "${1%.cfa}" "$1" ./cfa -DNDEBUG -nodebug -O3 "$1" -o "${1%.cfa}"
     20                mmake "${1%.cfa}" "$1" ./cfa "$1" -o "${1%.cfa}"
    2721                ;;
    2822        *.cpp)
    29                 mmake "${1%.cpp}-cpp" "$1" g++ -DNDEBUG -O3 "$1" -o "${1%.cpp}-cpp"
     23                mmake "${1%.cpp}-cpp" "$1" g++ "$1" -o "${1%.cpp}-cpp"
    3024                ;;
    3125        *.java)
     
    4438        done
    4539        exit 0
    46 elif [ "-v" = "$1" -a 4 = "$#" ]; then
    47     TEST_LANG="$2"
    48     TEST_CASE="$3"
    49     VIEW_FILE="$4"
    50 elif [ 2 -eq "$#" ]; then
    51         TEST_LANG="$1"
    52         TEST_CASE="$2"
    53 else
    54         echo "Unknown call pattern." >&2
    55         exit 2
    5640fi
    5741
     
    6246}
    6347
    64 case "$TEST_CASE" in
     48case "$2" in
    6549cond-match-all)
    6650        CFAT="./cond-catch $ITERATIONS 1"
     
    6852        CPP="./cond-catch-cpp $ITERATIONS 1"
    6953        JAVA="java CondCatch $ITERATIONS 1"
    70         PYTHON="./cond_catch.py $ITERATIONS 1"
    7154        ;;
    7255cond-match-none)
     
    7558        CPP="./cond-catch-cpp $ITERATIONS 0"
    7659        JAVA="java CondCatch $ITERATIONS 0"
    77         PYTHON="./cond_catch.py $ITERATIONS 0"
    7860        ;;
    7961cross-catch)
     
    8264        CPP="./cross-catch-cpp $ITERATIONS"
    8365        JAVA="java CrossCatch $ITERATIONS"
    84         PYTHON="./cross_catch.py $ITERATIONS"
    8566        ;;
    8667cross-finally)
     
    8970        CPP=unsupported
    9071        JAVA="java CrossFinally $ITERATIONS"
    91         PYTHON="./cross_finally.py $ITERATIONS"
    9272        ;;
    9373raise-detor)
     
    9676        CPP="./throw-detor-cpp $ITERATIONS $STACK_HEIGHT"
    9777        JAVA=unsupported
    98         PYTHON=unsupported
    9978        ;;
    10079raise-empty)
     
    10382        CPP="./throw-empty-cpp $ITERATIONS $STACK_HEIGHT"
    10483        JAVA="java ThrowEmpty $ITERATIONS $STACK_HEIGHT"
    105         PYTHON="./throw_empty.py $ITERATIONS $STACK_HEIGHT"
    10684        ;;
    10785raise-finally)
     
    11088        CPP=unsupported
    11189        JAVA="java ThrowFinally $ITERATIONS $STACK_HEIGHT"
    112         PYTHON="./throw_finally.py $ITERATIONS $STACK_HEIGHT"
    11390        ;;
    11491raise-other)
     
    11794        CPP="./throw-other-cpp $ITERATIONS $STACK_HEIGHT"
    11895        JAVA="java ThrowOther $ITERATIONS $STACK_HEIGHT"
    119         PYTHON="./throw_other.py $ITERATIONS $STACK_HEIGHT"
    12096        ;;
    12197*)
    122         echo "No such test: $TEST_CASE" >&2
     98        echo "No such test." >&2
    12399        exit 2
    124100        ;;
    125101esac
    126102
    127 case "$TEST_LANG" in
    128 cfa-t) CALL="$CFAT";;
    129 cfa-r) CALL="$CFAR";;
    130 cpp) CALL="$CPP";;
    131 java) CALL="$JAVA";;
    132 python) CALL="$PYTHON";;
    133 *)
    134         echo "No such language: $TEST_LANG" >&2
    135         exit 2
    136         ;;
     103case "$1" in
     104cfa-t) echo $CFAT; $CFAT;;
     105cfa-r) echo $CFAR; $CFAR;;
     106cpp) echo $CPP; $CPP;;
     107java) echo $JAVA; $JAVA;;
    137108esac
    138 
    139 echo $CALL
    140 
    141 if [ -n "$VIEW_FILE" ]; then
    142     grep -A 1 -B 0 "$CALL" "$VIEW_FILE" | sed -n -e 's!Run-Time (ns): !!;T;p'
    143     exit
    144 fi
    145 
    146 $CALL
  • doc/theses/andrew_beach_MMath/code/throw-detor.cfa

    rd83b266 rc86ee4c  
    1212
    1313void ^?{}(WithDestructor & this) {
    14         asm volatile ("# destructor body");
     14        // ...
    1515}
    1616
     
    3939                        unwind_destructor(total_frames);
    4040                } catch (empty_exception *) {
    41                         asm volatile ("# catch block");
     41                        // ...
    4242                }
    4343        }
  • doc/theses/andrew_beach_MMath/code/throw-detor.cpp

    rd83b266 rc86ee4c  
    1010
    1111struct WithDestructor {
    12         ~WithDestructor() {
    13                 asm volatile ("# destructor body");
    14         }
     12        ~WithDestructor() {}
    1513};
    1614
     
    3937                        unwind_destructor(total_frames);
    4038                } catch (EmptyException &) {
    41                         asm volatile ("# catch block");
     39                        // ...
    4240                }
    4341        }
  • doc/theses/andrew_beach_MMath/code/throw-empty.cfa

    rd83b266 rc86ee4c  
    3232                        unwind_empty(total_frames);
    3333                } catch (empty_exception *) {
    34                         asm volatile ("# catch block");
     34                        // ...
    3535                }
    3636        }
  • doc/theses/andrew_beach_MMath/code/throw-empty.cpp

    rd83b266 rc86ee4c  
    3232                        unwind_empty(total_frames);
    3333                } catch (EmptyException &) {
    34                         asm volatile ("# catch block");
     34                        // ...
    3535                }
    3636        }
  • doc/theses/andrew_beach_MMath/code/throw-finally.cfa

    rd83b266 rc86ee4c  
    1414                        unwind_finally(frames - 1);
    1515                } finally {
    16                         asm volatile ("# finally block");
     16                        // ...
    1717                }
    1818        } else {
     
    3636                        unwind_finally(total_frames);
    3737                } catch (empty_exception *) {
    38                         asm volatile ("# catch block");
     38                        // ...
    3939                }
    4040        }
  • doc/theses/andrew_beach_MMath/code/throw-other.cfa

    rd83b266 rc86ee4c  
    1616                        unwind_other(frames - 1);
    1717                } catch (not_raised_exception *) {
    18                         asm volatile ("# catch block (stack)");
     18                        // ...
    1919                }
    2020        } else {
     
    3838                        unwind_other(total_frames);
    3939                } catch (empty_exception *) {
    40                         asm volatile ("# catch block (base)");
     40                        // ...
    4141                }
    4242        }
  • doc/theses/andrew_beach_MMath/code/throw-other.cpp

    rd83b266 rc86ee4c  
    1616                        unwind_other(frames - 1);
    1717                } catch (NotRaisedException &) {
    18                         asm volatile ("# catch block (stack)");
     18                        // ...
    1919                }
    2020        } else {
     
    3838                        unwind_other(total_frames);
    3939                } catch (EmptyException &) {
    40                         asm volatile ("# catch block (base)");
     40                        // ...
    4141                }
    4242        }
  • doc/theses/andrew_beach_MMath/intro.tex

    rd83b266 rc86ee4c  
    107107
    108108Exception handling is not a new concept,
    109 with papers on the subject dating back 70s.\cite{Goodenough}
    110 
    111 Early exceptions were often treated as signals. They carried no information
    112 except their identity. Ada still uses this system.
    113 
    114 The modern flag-ship for termination exceptions is \Cpp,
     109with papers on the subject dating back 70s.
     110
     111Their were popularised by \Cpp,
    115112which added them in its first major wave of non-object-orientated features
    116113in 1990.
    117114% https://en.cppreference.com/w/cpp/language/history
    118 \Cpp has the ability to use any value of any type as an exception.
    119 However that seems to immediately pushed aside for classes inherited from
    120 \code{C++}{std::exception}.
    121 Although there is a special catch-all syntax it does not allow anything to
    122 be done with the caught value becuase nothing is known about it.
    123 So instead a base type is defined with some common functionality (such as
    124 the ability to describe the reason the exception was raised) and all
    125 exceptions have that functionality.
    126 This seems to be the standard now, as the garentied functionality is worth
    127 any lost flexibility from limiting it to a single type.
    128 
    129 Java was the next popular language to use exceptions.
    130 Its exception system largely reflects that of \Cpp, except that requires
    131 you throw a child type of \code{Java}{java.lang.Throwable}
    132 and it uses checked exceptions.
     115
     116Java was the next popular language to use exceptions. It is also the most
     117popular language with checked exceptions.
    133118Checked exceptions are part of the function interface they are raised from.
    134119This includes functions they propogate through, until a handler for that
     
    146131Resumption exceptions have been much less popular.
    147132Although resumption has a history as old as termination's, very few
    148 programming languages have implemented them.
     133programming languages have implement them.
    149134% http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/parc/techReports/
    150135%   CSL-79-3_Mesa_Language_Manual_Version_5.0.pdf
    151 Mesa is one programming languages that did. Experiance with Mesa
    152 is quoted as being one of the reasons resumptions were not
     136Mesa is one programming languages that did and experiance with that
     137languages is quoted as being one of the reasons resumptions were not
    153138included in the \Cpp standard.
    154139% https://en.wikipedia.org/wiki/Exception_handling
    155 Since then resumptions have been ignored in the main-stream.
    156 
    157 All of this does call into question the use of resumptions, is
    158 something largely rejected decades ago worth revisiting now?
    159 Yes, even if it was the right call at the time there have been decades
    160 of other developments in computer science that have changed the situation
    161 since then.
    162 Some of these developments, such as in functional programming's resumption
    163 equivalent: algebraic effects\cite{Zhang19}, are directly related to
    164 resumptions as well.
    165 A complete rexamination of resumptions is beyond a single paper, but it is
    166 enough to try them again in \CFA.
    167 % Especially considering how much easier they are to implement than
    168 % termination exceptions.
    169 
    170 %\subsection
    171 Functional languages tend to use other solutions for their primary error
    172 handling mechanism, exception-like constructs still appear.
    173 Termination appears in error construct, which marks the result of an
    174 expression as an error, the result of any expression that tries to use it as
    175 an error, and so on until an approprate handler is reached.
    176 Resumption appears in algebric effects, where a function dispatches its
    177 side-effects to its caller for handling.
     140\todo{A comment about why we did include them when they are so unpopular
     141might be approprate.}
     142
     143%\subsection
     144Functional languages, tend to use solutions like the return union, but some
     145exception-like constructs still appear.
     146
     147For instance Haskell's built in error mechanism can make the result of any
     148expression, including function calls. Any expression that examines an
     149error value will in-turn produce an error. This continues until the main
     150function produces an error or until it is handled by one of the catch
     151functions.
    178152
    179153%\subsection
    180154More recently exceptions seem to be vanishing from newer programming
    181 languages, replaced by ``panic".
    182 In Rust a panic is just a program level abort that may be implemented by
    183 unwinding the stack like in termination exception handling.
     155languages.
     156Rust and Go reduce this feature to panics.
     157Panicing is somewhere between a termination exception and a program abort.
     158Notably in Rust a panic can trigger either, a panic may unwind the stack or
     159simply kill the process.
    184160% https://doc.rust-lang.org/std/panic/fn.catch_unwind.html
    185 Go's panic through is very similar to a termination except it only supports
    186 a catch-all by calling \code{Go}{recover()}, simplifying the interface at
    187 the cost of flexability.
     161Go's panic is much more similar to a termination exception but there is
     162only a catch-all function with \code{Go}{recover()}.
     163So exceptions still are appearing, just in reduced forms.
    188164
    189165%\subsection
  • doc/theses/andrew_beach_MMath/performance.tex

    rd83b266 rc86ee4c  
    11\chapter{Performance}
    22\label{c:performance}
     3
     4\textbf{Just because of the stage of testing there are design notes for
     5the tests as well as commentary on them.}
    36
    47Performance has been of secondary importance for most of this project.
     
    811
    912\section{Test Set-Up}
    10 Tests will be run in \CFA, C++, Java and Python.
    11 In addition there are two sets of tests for \CFA,
    12 one for termination exceptions and once with resumption exceptions.
     13Tests will be run on \CFA, C++ and Java.
    1314
    1415C++ is the most comparable language because both it and \CFA use the same
     
    1718comparison. \CFA's EHM has had significantly less time to be optimized and
    1819does not generate its own assembly. It does have a slight advantage in that
    19 there are some features it does not handle, through utility functions,
    20 but otherwise \Cpp has a significant advantage.
     20there are some features it does not handle.
    2121
    2222Java is another very popular language with similar termination semantics.
     
    2525It also implements the finally clause on try blocks allowing for a direct
    2626feature-to-feature comparison.
    27 As with \Cpp, Java's implementation is more mature, has more optimizations
    28 and more extra features.
    29 
    30 Python was used as a point of comparison because of the \CFA EHM's
    31 current performance goals, which is not be prohibitively slow while the
    32 features are designed and examined. Python has similar performance goals for
    33 creating quick scripts and its wide use suggests it has achieved those goals.
    34 
    35 Unfortunately there are no notable modern programming languages with
    36 resumption exceptions. Even the older programming languages with resumptions
    37 seem to be notable only for having resumptions.
    38 So instead resumptions are compared to a less similar but much more familiar
    39 feature, termination exceptions.
    4027
    4128All tests are run inside a main loop which will perform the test
    4229repeatedly. This is to avoids start-up or tear-down time from
    4330affecting the timing results.
    44 Most test were run 1 000 000 (a million) times.
    45 The Java versions of the test also run this loop an extra 1000 times before
    46 beginning to time the results to ``warm-up" the JVM.
    47 
    48 Timing is done internally, with time measured immediately before and
    49 immediately after the test loop. The difference is calculated and printed.
    50 
    51 The loop structure and internal timing means it is impossible to test
    52 unhandled exceptions in \Cpp and Java as that would cause the process to
    53 terminate.
    54 Luckily, performance on the ``give-up and kill the process" path is not
    55 critical.
     31A consequence of this is that tests cannot terminate the program,
     32which does limit how tests can be implemented.
     33There are catch-alls to keep unhandled
     34exceptions from terminating tests.
    5635
    5736The exceptions used in these tests will always be a exception based off of
    5837the base exception. This requirement minimizes performance differences based
    59 on the object model used to repersent the exception.
     38on the object model.
     39Catch-alls are done by catching the root exception type (not using \Cpp's
     40\code{C++}{catch(...)}).
    6041
    61 All tests were designed to be as minimal as possible while still preventing
    62 exessive optimizations.
    63 For example, empty inline assembly blocks are used in \CFA and \Cpp to
    64 prevent excessive optimizations while adding no actual work.
    65 
    66 % We don't use catch-alls but if we did:
    67 % Catch-alls are done by catching the root exception type (not using \Cpp's
    68 % \code{C++}{catch(...)}).
     42Tests run in Java were not warmed because exception code paths should not be
     43hot.
    6944
    7045\section{Tests}
     
    7247components of the exception system.
    7348The should provide a guide as to where the EHM's costs can be found.
     49
     50Tests are run in \CFA, \Cpp and Java.
     51Not every test is run in every language, if the feature under test is missing
     52the test is skipped. These cases will be noted.
     53In addition to the termination tests for every language,
     54\CFA has a second set of tests that test resumption. These are the same
     55except that the raise statements and handler clauses are replaced with the
     56resumption variants.
    7457
    7558\paragraph{Raise and Handle}
     
    7962start-up and shutdown on the results.
    8063Each iteration of the main loop
    81 \begin{itemize}[nosep]
     64\begin{itemize}
    8265\item Empty Function:
    8366The repeating function is empty except for the necessary control code.
     
    8568The repeating function creates an object with a destructor before calling
    8669itself.
     70(Java is skipped as it does not destructors.)
    8771\item Finally:
    8872The repeating function calls itself inside a try block with a finally clause
    8973attached.
     74(\Cpp is skipped as it does not have finally clauses.)
    9075\item Other Handler:
    9176The repeating function calls itself inside a try block with a handler that
     
    9984In each iteration, a try statement is executed. Entering and leaving a loop
    10085is all the test wants to do.
    101 \begin{itemize}[nosep]
     86\begin{itemize}
    10287\item Handler:
    10388The try statement has a handler (of the matching kind).
     
    11095Only \CFA implements the language level conditional match,
    11196the other languages must mimic with an ``unconditional" match (it still
    112 checks the exception's type) and conditional re-raise if it was not supposed
    113 to handle that exception.
    114 \begin{itemize}[nosep]
    115 \item Match All:
     97checks the exception's type) and conditional re-raise.
     98\begin{itemize}
     99\item Catch All:
    116100The condition is always true. (Always matches or never re-raises.)
    117 \item Match None:
     101\item Catch None:
    118102The condition is always false. (Never matches or always re-raises.)
    119103\end{itemize}
     
    129113%related to -fexceptions.)
    130114
    131 \section{Results}
    132 Each test is was run five times, the best and worst result were discarded and
    133 the remaining values were averaged.
     115% Some languages I left out:
     116% Python: Its a scripting language, different
     117% uC++: Not well known and should the same results as C++, except for
     118%   resumption which should be the same.
    134119
    135 In cases where a feature is not supported by a language the test is skipped
    136 for that language. Similarly, if a test is does not change between resumption
    137 and termination in \CFA, then only one test is written and the result
    138 was put into the termination column.
    139 
    140 \begin{tabular}{|l|c c c c c|}
    141 \hline
    142               & \CFA (Terminate) & \CFA (Resume) & \Cpp & Java & Python \\
    143 \hline
    144 Raise Empty   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
    145 Raise D'tor   & 0.0 & 0.0 & 0.0 & N/A & N/A \\
    146 Raise Finally & 0.0 & 0.0 & N/A & 0.0 & 0.0 \\
    147 Raise Other   & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
    148 Cross Handler & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
    149 Cross Finally & 0.0 & N/A & N/A & 0.0 & 0.0 \\
    150 Match All     & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
    151 Match None    & 0.0 & 0.0 & 0.0 & 0.0 & 0.0 \\
    152 \hline
    153 \end{tabular}
     120%\section{Resumption Comparison}
     121\todo{Can we find a good language to compare resumptions in.}
  • doc/theses/mubeen_zulfiqar_MMath/allocator.tex

    rd83b266 rc86ee4c  
    4444
    4545\subsection{Design philosophy}
    46 The objective of uHeapLmmm's new design was to fulfill following requirements:
    47 \begin{itemize}
    48 \item It should be concurrent to be used in multi-threaded programs.
    49 \item It should avoid global locks, on resources shared across all threads, as much as possible.
    50 \item It's performance (FIX ME: cite performance benchmarks) should be comparable to the commonly used allocators (FIX ME: cite common allocators).
    51 \item It should be a lightweight memory allocator.
    52 \end{itemize}
     46
    5347
    5448%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    5549
    5650\section{Background and previous design of uHeapLmmm}
    57 uHeapLmmm was originally designed by X in X (FIX ME: add original author after confirming with Peter).
    58 (FIX ME: make and add figure of previous design with description)
     51
    5952
    6053%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    6154
    6255\section{Distributed design of uHeapLmmm}
    63 uHeapLmmm's design was reviewed and changed to fulfill new requirements (FIX ME: cite allocator philosophy). For this purpose, following two designs of uHeapLmm were proposed:
    6456
     57
     58\subsection{Advantages of distributed design}
     59
     60
     61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     62
     63\section{Added Features}
     64
     65
     66\subsection{Methods}
     67Why did we need it?
     68The added benefits.
     69
     70
     71\subsection{Alloc Interface}
     72Why did we need it?
     73The added benefits.
     74
     75
     76%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     77% Following is added by Peter
     78
     79\noindent
     80====================
     81
     82\newpage
    6583\paragraph{Design 1: Decentralized}
    6684Fixed number of heaps: shard the heap into N heaps each with a bump-area allocated from the @sbrk@ area.
     
    7492\input{AllocDS1}
    7593\end{cquote}
    76 Problems: need to know when a KT is created and destroyed to know when to assign/un-assign a heap to the KT.
     94Problems: need to know when a KT is created and destroyed to know when to create/delete the KT's heap.
     95On KT deletion, its heap freed-storage needs to be distributed somewhere.
    7796
    7897\paragraph{Design 2: Centralized}
     98
    7999One heap, but lower bucket sizes are N-shared across KTs.
    80100This design leverages the fact that 95\% of allocation requests are less than 512 bytes and there are only 3--5 different request sizes.
     
    87107\end{cquote}
    88108Problems: need to know when a kernel thread (KT) is created and destroyed to know when to assign a shared bucket-number.
    89 When no thread is assigned a bucket number, its free storage is unavailable. All KTs will be contended for one lock on sbrk for their initial allocations (before free-lists gets populated).
    90 
    91 Out of the two designs, Design 1 was chosen because it's concurrency is better across all bucket-sizes as design-2 shards a few buckets of selected sizes while design-1 shards all the buckets. Design-2 shards the whole heap which has all the buckets with the addition of sharding sbrk area.
    92 
    93 \subsection{Advantages of distributed design}
    94 The distributed design of uHeapLmmm is concurrent to work in multi-threaded applications.
    95 
    96 Some key benefits of the distributed design of uHeapLmmm are as follows:
    97 
    98 \begin{itemize}
    99 \item
    100 The bump allocation is concurrent as memory taken from sbrk is sharded across all heaps as bump allocation reserve. The lock on bump allocation (on memory taken from sbrk) will only be contended if KTs > N. The contention on sbrk area is less likely as it will only happen in the case if heaps assigned to two KTs get short of bump allocation reserve simultanously.
    101 \item
    102 N heaps are created at the start of the program and destroyed at the end of program. When a KT is created, we only assign it to one of the heaps. When a KT is destroyed, we only dissociate it from the assigned heap but we do not destroy that heap. That heap will go back to our pool-of-heaps, ready to be used by some new KT. And if that heap was shared among multiple KTs (like the case of KTs > N) then, on deletion of one KT, that heap will be still in-use of the other KTs. This will prevent creation and deletion of heaps during run-time as heaps are re-usable which helps in keeping low-memory footprint.
    103 \item
     109When no thread is assigned a bucket number, its free storage is unavailable.
    104110It is possible to use sharing and stealing techniques to share/find unused storage, when a free list is unused or empty.
    105 \item
    106 Distributed design avoids unnecassry locks on resources shared across all KTs.
    107 \end{itemize}
    108 
    109 FIX ME: Cite performance comparison of the two heap designs if required
    110 
    111 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    112 
    113 \section{Added Features and Methods}
    114 To improve the UHeapLmmm allocator (FIX ME: cite uHeapLmmm) interface and make it more user friendly, we added a few more routines to the C allocator. Also, we built a CFA (FIX ME: cite cforall) interface on top of C interface to increase the usability of the allocator.
    115 
    116 \subsection{C Interface}
    117 We added a few more features and routines to the allocator's C interface that can make the allocator more usable to the programmers. THese features will programmer more control on the dynamic memory allocation.
    118 
    119 \subsubsection void * aalloc( size_t dim, size_t elemSize )
    120 aalloc is an extension of malloc. It allows programmer to allocate a dynamic array of objects without calculating the total size of array explicitly. The only alternate of this routine in the other allocators is calloc but calloc also fills the dynamic memory with 0 which makes it slower for a programmer who only wants to dynamically allocate an array of objects without filling it with 0.
    121 \paragraph{Usage}
    122 aalloc takes two parameters.
    123 \begin{itemize}
    124 \item
    125 dim: number of objects in the array
    126 \item
    127 elemSize: size of the object in the array.
    128 \end{itemize}
    129 It returns address of dynamic object allocatoed on heap that can contain dim number of objects of the size elemSize. On failure, it returns NULL pointer.
    130 
    131 \subsubsection void * resize( void * oaddr, size_t size )
    132 resize is an extension of relloc. It allows programmer to reuse a cuurently allocated dynamic object with a new size requirement. Its alternate in the other allocators is realloc but relloc also copy the data in old object to the new object which makes it slower for the programmer who only wants to reuse an old dynamic object for a new size requirement but does not want to preserve the data in the old object to the new object.
    133 \paragraph{Usage}
    134 resize takes two parameters.
    135 \begin{itemize}
    136 \item
    137 oaddr: the address of the old object that needs to be resized.
    138 \item
    139 size: the new size requirement of the to which the old object needs to be resized.
    140 \end{itemize}
    141 It returns an object that is of the size given but it does not preserve the data in the old object. On failure, it returns NULL pointer.
    142 
    143 \subsubsection void * resize( void * oaddr, size_t nalign, size_t size )
    144 This resize is an extension of the above resize (FIX ME: cite above resize). In addition to resizing the size of of an old object, it can also realign the old object to a new alignment requirement.
    145 \paragraph{Usage}
    146 This resize takes three parameters. It takes an additional parameter of nalign as compared to the above resize (FIX ME: cite above resize).
    147 \begin{itemize}
    148 \item
    149 oaddr: the address of the old object that needs to be resized.
    150 \item
    151 nalign: the new alignment to which the old object needs to be realigned.
    152 \item
    153 size: the new size requirement of the to which the old object needs to be resized.
    154 \end{itemize}
    155 It returns an object with the size and alignment given in the parameters. On failure, it returns a NULL pointer.
    156 
    157 \subsubsection void * amemalign( size_t alignment, size_t dim, size_t elemSize )
    158 amemalign is a hybrid of memalign and aalloc. It allows programmer to allocate an aligned dynamic array of objects without calculating the total size of the array explicitly. It frees the programmer from calculating the total size of the array.
    159 \paragraph{Usage}
    160 amemalign takes three parameters.
    161 \begin{itemize}
    162 \item
    163 alignment: the alignment to which the dynamic array needs to be aligned.
    164 \item
    165 dim: number of objects in the array
    166 \item
    167 elemSize: size of the object in the array.
    168 \end{itemize}
    169 It returns a dynamic array of objects that has the capacity to contain dim number of objects of the size of elemSize. The returned dynamic array is aligned to the given alignment. On failure, it returns NULL pointer.
    170 
    171 \subsubsection void * cmemalign( size_t alignment, size_t dim, size_t elemSize )
    172 cmemalign is a hybrid of amemalign and calloc. It allows programmer to allocate an aligned dynamic array of objects that is 0 filled. The current way to do this in other allocators is to allocate an aligned object with memalign and then fill it with 0 explicitly. This routine provides both features of aligning and 0 filling, implicitly.
    173 \paragraph{Usage}
    174 cmemalign takes three parameters.
    175 \begin{itemize}
    176 \item
    177 alignment: the alignment to which the dynamic array needs to be aligned.
    178 \item
    179 dim: number of objects in the array
    180 \item
    181 elemSize: size of the object in the array.
    182 \end{itemize}
    183 It returns a dynamic array of objects that has the capacity to contain dim number of objects of the size of elemSize. The returned dynamic array is aligned to the given alignment and is 0 filled. On failure, it returns NULL pointer.
    184 
    185 \subsubsection size_t malloc_alignment( void * addr )
    186 malloc_alignment returns the alignment of a currently allocated dynamic object. It allows the programmer in memory management and personal bookkeeping. It helps the programmer in verofying the alignment of a dynamic object especially in a scenerio similar to prudcer-consumer where a producer allocates a dynamic object and the consumer needs to assure that the dynamic object was allocated with the required alignment.
    187 \paragraph{Usage}
    188 malloc_alignment takes one parameters.
    189 \begin{itemize}
    190 \item
    191 addr: the address of the currently allocated dynamic object.
    192 \end{itemize}
    193 malloc_alignment returns the alignment of the given dynamic object. On failure, it return the value of default alignment of the uHeapLmmm allocator.
    194 
    195 \subsubsection bool malloc_zero_fill( void * addr )
    196 malloc_zero_fill returns whether a currently allocated dynamic object was initially zero filled at the time of allocation. It allows the programmer in memory management and personal bookkeeping. It helps the programmer in verifying the zero filled property of a dynamic object especially in a scenerio similar to prudcer-consumer where a producer allocates a dynamic object and the consumer needs to assure that the dynamic object was zero filled at the time of allocation.
    197 \paragraph{Usage}
    198 malloc_zero_fill takes one parameters.
    199 \begin{itemize}
    200 \item
    201 addr: the address of the currently allocated dynamic object.
    202 \end{itemize}
    203 malloc_zero_fill returns true if the dynamic object was initially zero filled and return false otherwise. On failure, it returns false.
    204 
    205 \subsubsection size_t malloc_size( void * addr )
    206 malloc_size returns the allocation size of a currently allocated dynamic object. It allows the programmer in memory management and personal bookkeeping. It helps the programmer in verofying the alignment of a dynamic object especially in a scenerio similar to prudcer-consumer where a producer allocates a dynamic object and the consumer needs to assure that the dynamic object was allocated with the required size. Its current alternate in the other allocators is malloc_usable_size. But, malloc_size is different from malloc_usable_size as malloc_usabe_size returns the total data capacity of dynamic object including the extra space at the end of the dynamic object. On the other hand, malloc_size returns the size that was given to the allocator at the allocation of the dynamic object. This size is updated when an object is realloced, resized, or passed through a similar allocator routine.
    207 \paragraph{Usage}
    208 malloc_size takes one parameters.
    209 \begin{itemize}
    210 \item
    211 addr: the address of the currently allocated dynamic object.
    212 \end{itemize}
    213 malloc_size returns the allocation size of the given dynamic object. On failure, it return zero.
    214 
    215 \subsubsection void * realloc( void * oaddr, size_t nalign, size_t size )
    216 This realloc is an extension of the default realloc (FIX ME: cite default realloc). In addition to reallocating an old object and preserving the data in old object, it can also realign the old object to a new alignment requirement.
    217 \paragraph{Usage}
    218 This realloc takes three parameters. It takes an additional parameter of nalign as compared to the default realloc.
    219 \begin{itemize}
    220 \item
    221 oaddr: the address of the old object that needs to be reallocated.
    222 \item
    223 nalign: the new alignment to which the old object needs to be realigned.
    224 \item
    225 size: the new size requirement of the to which the old object needs to be resized.
    226 \end{itemize}
    227 It returns an object with the size and alignment given in the parameters that preserves the data in the old object. On failure, it returns a NULL pointer.
    228 
    229 \subsection{CFA Malloc Interface}
    230 We added some routines to the malloc interface of CFA. These routines can only be used in CFA and not in our standalone uHeapLmmm allocator as these routines use some features that are only provided by CFA and not by C. It makes the allocator even more usable to the programmers.
    231 CFA provides the liberty to know the returned type of a call to the allocator. So, mainly in these added routines, we removed the object size parameter from the routine as allocator can calculate the size of the object from the returned type.
    232 
    233 \subsubsection T * malloc( void )
    234 This malloc is a simplified polymorphic form of defualt malloc (FIX ME: cite malloc). It does not take any parameter as compared to default malloc that takes one parameter.
    235 \paragraph{Usage}
    236 This malloc takes no parameters.
    237 It returns a dynamic object of the size of type T. On failure, it return NULL pointer.
    238 
    239 \subsubsection T * aalloc( size_t dim )
    240 This aalloc is a simplified polymorphic form of above aalloc (FIX ME: cite aalloc). It takes one parameter as compared to the above aalloc that takes two parameters.
    241 \paragraph{Usage}
    242 aalloc takes one parameters.
    243 \begin{itemize}
    244 \item
    245 dim: required number of objects in the array.
    246 \end{itemize}
    247 It returns a dynamic object that has the capacity to contain dim number of objects, each of the size of type T. On failure, it return NULL pointer.
    248 
    249 \subsubsection T * calloc( size_t dim )
    250 This calloc is a simplified polymorphic form of defualt calloc (FIX ME: cite calloc). It takes one parameter as compared to the default calloc that takes two parameters.
    251 \paragraph{Usage}
    252 This calloc takes one parameter.
    253 \begin{itemize}
    254 \item
    255 dim: required number of objects in the array.
    256 \end{itemize}
    257 It returns a dynamic object that has the capacity to contain dim number of objects, each of the size of type T. On failure, it return NULL pointer.
    258 
    259 \subsubsection T * resize( T * ptr, size_t size )
    260 This resize is a simplified polymorphic form of above resize (FIX ME: cite resize with alignment). It takes two parameters as compared to the above resize that takes three parameters. It frees the programmer from explicitly mentioning the alignment of the allocation as CFA provides gives allocator the liberty to get the alignment of the returned type.
    261 \paragraph{Usage}
    262 This resize takes two parameters.
    263 \begin{itemize}
    264 \item
    265 ptr: address of the old object.
    266 \item
    267 size: the required size of the new object.
    268 \end{itemize}
    269 It returns a dynamic object of the size given in paramters. The returned object is aligned to the alignemtn of type T. On failure, it return NULL pointer.
    270 
    271 \subsubsection T * realloc( T * ptr, size_t size )
    272 This realloc is a simplified polymorphic form of defualt realloc (FIX ME: cite realloc with align). It takes two parameters as compared to the above realloc that takes three parameters. It frees the programmer from explicitly mentioning the alignment of the allocation as CFA provides gives allocator the liberty to get the alignment of the returned type.
    273 \paragraph{Usage}
    274 This realloc takes two parameters.
    275 \begin{itemize}
    276 \item
    277 ptr: address of the old object.
    278 \item
    279 size: the required size of the new object.
    280 \end{itemize}
    281 It returns a dynamic object of the size given in paramters that preserves the data in the given object. The returned object is aligned to the alignemtn of type T. On failure, it return NULL pointer.
    282 
    283 \subsubsection T * memalign( size_t align )
    284 This memalign is a simplified polymorphic form of defualt memalign (FIX ME: cite memalign). It takes one parameters as compared to the default memalign that takes two parameters.
    285 \paragraph{Usage}
    286 memalign takes one parameters.
    287 \begin{itemize}
    288 \item
    289 align: the required alignment of the dynamic object.
    290 \end{itemize}
    291 It returns a dynamic object of the size of type T that is aligned to given parameter align. On failure, it return NULL pointer.
    292 
    293 \subsubsection T * amemalign( size_t align, size_t dim )
    294 This amemalign is a simplified polymorphic form of above amemalign (FIX ME: cite amemalign). It takes two parameter as compared to the above amemalign that takes three parameters.
    295 \paragraph{Usage}
    296 amemalign takes two parameters.
    297 \begin{itemize}
    298 \item
    299 align: required alignment of the dynamic array.
    300 \item
    301 dim: required number of objects in the array.
    302 \end{itemize}
    303 It returns a dynamic object that has the capacity to contain dim number of objects, each of the size of type T. The returned object is aligned to the given parameter align. On failure, it return NULL pointer.
    304 
    305 \subsubsection T * cmemalign( size_t align, size_t dim  )
    306 This cmemalign is a simplified polymorphic form of above cmemalign (FIX ME: cite cmemalign). It takes two parameter as compared to the above cmemalign that takes three parameters.
    307 \paragraph{Usage}
    308 cmemalign takes two parameters.
    309 \begin{itemize}
    310 \item
    311 align: required alignment of the dynamic array.
    312 \item
    313 dim: required number of objects in the array.
    314 \end{itemize}
    315 It returns a dynamic object that has the capacity to contain dim number of objects, each of the size of type T. The returned object is aligned to the given parameter align and is zero filled. On failure, it return NULL pointer.
    316 
    317 \subsubsection T * aligned_alloc( size_t align )
    318 This aligned_alloc is a simplified polymorphic form of defualt aligned_alloc (FIX ME: cite aligned_alloc). It takes one parameter as compared to the default aligned_alloc that takes two parameters.
    319 \paragraph{Usage}
    320 This aligned_alloc takes one parameter.
    321 \begin{itemize}
    322 \item
    323 align: required alignment of the dynamic object.
    324 \end{itemize}
    325 It returns a dynamic object of the size of type T that is aligned to the given parameter. On failure, it return NULL pointer.
    326 
    327 \subsubsection int posix_memalign( T ** ptr, size_t align )
    328 This posix_memalign is a simplified polymorphic form of defualt posix_memalign (FIX ME: cite posix_memalign). It takes two parameters as compared to the default posix_memalign that takes three parameters.
    329 \paragraph{Usage}
    330 This posix_memalign takes two parameter.
    331 \begin{itemize}
    332 \item
    333 ptr: variable address to store the address of the allocated object.
    334 \item
    335 align: required alignment of the dynamic object.
    336 \end{itemize}
    337 It stores address of the dynamic object of the size of type T in given parameter ptr. This object is aligned to the given parameter. On failure, it return NULL pointer.
    338 
    339 \subsubsection T * valloc( void )
    340 This valloc is a simplified polymorphic form of defualt valloc (FIX ME: cite valloc). It takes no parameters as compared to the default valloc that takes one parameter.
    341 \paragraph{Usage}
    342 valloc takes no parameters.
    343 It returns a dynamic object of the size of type T that is aligned to the page size. On failure, it return NULL pointer.
    344 
    345 \subsubsection T * pvalloc( void )
    346 This pcvalloc is a simplified polymorphic form of defualt pcvalloc (FIX ME: cite pcvalloc). It takes no parameters as compared to the default pcvalloc that takes one parameter.
    347 \paragraph{Usage}
    348 pvalloc takes no parameters.
    349 It returns a dynamic object of the size that is calcutaed by rouding the size of type T. The returned object is also aligned to the page size. On failure, it return NULL pointer.
    350 
    351 \subsection{Alloc Interface}
    352 In addition to improve allocator interface both for CFA and our standalone allocator uHeapLmmm in C. We also added a new alloc interface in CFA that increases usability of dynamic memory allocation.
    353 This interface helps programmers in three major ways.
    354 \begin{itemize}
    355 \item
    356 Routine Name: alloc interfce frees programmers from remmebring different routine names for different kind of dynamic allocations.
    357 \item
    358 Parametre Positions: alloc interface frees programmers from remembering parameter postions in call to routines.
    359 \item
    360 Object Size: alloc interface does not require programmer to mention the object size as CFA allows allocator to determince the object size from returned type of alloc call.
    361 \end{itemize}
    362 
    363 Alloc interface uses polymorphism, backtick routines (FIX ME: cite backtick) and ttype parameters of CFA (FIX ME: cite ttype) to provide a very simple dynamic memory allocation interface to the programmers. The new interfece has just one routine name alloc that can be used to perform a wide range of dynamic allocations. The parameters use backtick functions to provide a similar-to named parameters feature for our alloc interface so that programmers do not have to remember parameter positions in alloc call except the position of dimension (dim) parameter.
    364 
    365 \subsubsection{Routine: T * alloc( ... )}
    366 Call to alloc wihout any parameter returns one object of size of type T allocated dynamically.
    367 Only the dimension (dim) parameter for array allocation has the fixed position in the alloc routine. If programmer wants to allocate an array of objects that the required number of members in the array has to be given as the first parameter to the alloc routine.
    368 alocc routine accepts six kinds of arguments. Using different combinations of tha parameters, different kind of allocations can be performed. Any combincation of parameters can be used together except `realloc and `resize that should not be used simultanously in one call to routine as it creates ambiguity about whether to reallocate or resize a currently allocated dynamic object. If both `resize and `realloc are used in a call to alloc then the latter one will take effect or unexpected resulted might be produced.
    369 
    370 \paragraph{Dim}
    371 This is the only parameter in the alloc routine that has a fixed-position and it is also the only parameter that does not use a backtick function. It has to be passed at the first position to alloc call in-case of an array allocation of objects of type T.
    372 It represents the required number of members in the array allocation as in CFA's aalloc (FIX ME: cite aalloc).
    373 This parameter should be of type size_t.
    374 
    375 Example: int a = alloc( 5 )
    376 This call will return a dynamic array of five integers.
    377 
    378 \paragraph{Align}
    379 This parameter is position-free and uses a backtick routine align (`align). The parameter passed with `align should be of type size_t. If the alignment parameter is not a power of two or is less than the default alignment of the allocator (that can be found out using routine libAlign in CFA) then the passed alignment parameter will be rejected and the default alignment will be used.
    380 
    381 Example: int b = alloc( 5 , 64`align )
    382 This call will return a dynamic array of five integers. It will align the allocated object to 64.
    383 
    384 \paragraph{Fill}
    385 This parameter is position-free and uses a backtick routine fill (`fill). In case of realloc, only the extra space after copying the data in the old object will be filled with given parameter.
    386 Three types of parameters can be passed using `fill.
    387 \begin{itemize}
    388 \item
    389 char: A char can be passed with `fill to fill the whole dynamic allocation with the given char recursively till the end of required allocation.
    390 \item
    391 Object of returned type: An object of type of returned type can be passed with `fill to fill the whole dynamic allocation with the given object recursively till the end of required allocation.
    392 \item
    393 Dynamic object of returned type: A dynamic object of type of returned type can be passed with `fill to fill the dynamic allocation with the given dynamic object. In this case, the allocated memory is not filled recursively till the end of allocation. The filling happen untill the end object passed to `fill or the end of requested allocation reaches.
    394 \end{itemize}
    395 
    396 Example: int b = alloc( 5 , 'a'`fill )
    397 This call will return a dynamic array of five integers. It will fill the allocated object with character 'a' recursively till the end of requested allocation size.
    398 
    399 Example: int b = alloc( 5 , 4`fill )
    400 This call will return a dynamic array of five integers. It will fill the allocated object with integer 4 recursively till the end of requested allocation size.
    401 
    402 Example: int b = alloc( 5 , a`fill ) where a is a pointer of int type
    403 This call will return a dynamic array of five integers. It will copy data in a to the returned object non-recursively untill end of a or the newly allocated object is reached.
    404 
    405 \paragraph{Resize}
    406 This parameter is position-free and uses a backtick routine resize (`resize). It represents the old dynamic object (oaddr) that the programmer wants to
    407 \begin{itemize}
    408 \item
    409 resize to a new size.
    410 \item
    411 realign to a new alignment
    412 \item
    413 fill with something.
    414 \end{itemize}
    415 The data in old dynamic object will not be preserved in the new object. The type of object passed to `resize and the returned type of alloc call can be different.
    416 
    417 Example: int b = alloc( 5 , a`resize )
    418 This call will resize object a to a dynamic array that can contain 5 integers.
    419 
    420 Example: int b = alloc( 5 , a`resize , 32`align )
    421 This call will resize object a to a dynamic array that can contain 5 integers. The returned object will also be aligned to 32.
    422 
    423 Example: int b = alloc( 5 , a`resize , 32`align , 2`fill)
    424 This call will resize object a to a dynamic array that can contain 5 integers. The returned object will also be aligned to 32 and will be filled with 2.
    425 
    426 \paragraph{Realloc}
    427 This parameter is position-free and uses a backtick routine realloc (`realloc). It represents the old dynamic object (oaddr) that the programmer wants to
    428 \begin{itemize}
    429 \item
    430 realloc to a new size.
    431 \item
    432 realign to a new alignment
    433 \item
    434 fill with something.
    435 \end{itemize}
    436 The data in old dynamic object will be preserved in the new object. The type of object passed to `realloc and the returned type of alloc call cannot be different.
    437 
    438 Example: int b = alloc( 5 , a`realloc )
    439 This call will realloc object a to a dynamic array that can contain 5 integers.
    440 
    441 Example: int b = alloc( 5 , a`realloc , 32`align )
    442 This call will realloc object a to a dynamic array that can contain 5 integers. The returned object will also be aligned to 32.
    443 
    444 Example: int b = alloc( 5 , a`realloc , 32`align , 2`fill)
    445 This call will resize object a to a dynamic array that can contain 5 integers. The returned object will also be aligned to 32. The extra space after copying data of a to the returned object will be filled with 2.
  • doc/theses/mubeen_zulfiqar_MMath/benchmarks.tex

    rd83b266 rc86ee4c  
    149149*** FIX ME: Insert a figure of above benchmark with description
    150150
    151 \paragrpah{Relevant Knobs}
     151\subsubsection{Relevant Knobs}
    152152*** FIX ME: Insert Relevant Knobs
    153153
     
    202202\paragraph{Relevant Knobs}
    203203*** FIX ME: Insert Relevant Knobs
     204
     205\section{Results}
     206*** FIX ME: add configuration details of memory allocators
     207
     208\subsection{Memory Benchmark}
     209
     210\subsubsection{Relevant Knobs}
     211
     212\subsection{Speed Benchmark}
     213
     214\subsubsection{Speed Time}
     215
     216\paragraph{Relevant Knobs}
     217
     218\subsubsection{Speed Workload}
     219
     220\paragraph{Relevant Knobs}
     221
     222\subsection{Cache Scratch}
     223
     224\subsubsection{Cache Scratch Time}
     225
     226\paragraph{Relevant Knobs}
     227
     228\subsubsection{Cache Scratch Layout}
     229
     230\paragraph{Relevant Knobs}
     231
     232\subsection{Cache Thrash}
     233
     234\subsubsection{Cache Thrash Time}
     235
     236\paragraph{Relevant Knobs}
     237
     238\subsubsection{Cache Thrash Layout}
     239
     240\paragraph{Relevant Knobs}
  • doc/theses/mubeen_zulfiqar_MMath/performance.tex

    rd83b266 rc86ee4c  
    11\chapter{Performance}
    2 
    3 \noindent
    4 ====================
    5 
    6 Writing Points:
    7 \begin{itemize}
    8 \item
    9 Machine Specification
    10 \item
    11 Allocators and their details
    12 \item
    13 Benchmarks and their details
    14 \item
    15 Results
    16 \end{itemize}
    17 
    18 \noindent
    19 ====================
    20 
    21 \section{Memory Allocators}
    22 For these experiments, we used 7 memory allocators excluding our standalone memory allocator uHeapLmmm.
    23 
    24 \begin{tabularx}{0.8\textwidth} {
    25         | >{\raggedright\arraybackslash}X
    26         | >{\centering\arraybackslash}X
    27         | >{\raggedleft\arraybackslash}X |
    28 }
    29 \hline
    30 Memory Allocator & Version     & Configurations \\
    31 \hline
    32 dl               &             &  \\
    33 \hline
    34 hoard            &             &  \\
    35 \hline
    36 je               &             &  \\
    37 \hline
    38 pt3              &             &  \\
    39 \hline
    40 rp               &             &  \\
    41 \hline
    42 tbb              &             &  \\
    43 \hline
    44 tc               &             &  \\
    45 \end{tabularx}
    46 (FIX ME: complete table)
    47 
    48 \section{Experiment Environment}
    49 We conducted these experiments ... (FIX ME: what machine and which specifications to add).
    50 
    51 We used our micro becnhmark suite (FIX ME: cite mbench) to evaluate other memory allocators (FIX ME: cite above memory allocators) and our uHeapLmmm.
    52 
    53 \section{Results}
    54 
    55 \subsection{Memory Benchmark}
    56 FIX ME: add experiment, knobs, graphs, and description
    57 
    58 \subsection{Speed Benchmark}
    59 FIX ME: add experiment, knobs, graphs, and description
    60 
    61 \subsubsection{Speed Time}
    62 FIX ME: add experiment, knobs, graphs, and description
    63 
    64 \subsubsection{Speed Workload}
    65 FIX ME: add experiment, knobs, graphs, and description
    66 
    67 \subsection{Cache Scratch}
    68 FIX ME: add experiment, knobs, graphs, and description
    69 
    70 \subsubsection{Cache Scratch Time}
    71 FIX ME: add experiment, knobs, graphs, and description
    72 
    73 \subsubsection{Cache Scratch Layout}
    74 FIX ME: add experiment, knobs, graphs, and description
    75 
    76 \subsection{Cache Thrash}
    77 FIX ME: add experiment, knobs, graphs, and description
    78 
    79 \subsubsection{Cache Thrash Time}
    80 FIX ME: add experiment, knobs, graphs, and description
    81 
    82 \subsubsection{Cache Thrash Layout}
    83 FIX ME: add experiment, knobs, graphs, and description
  • driver/cc1.cc

    rd83b266 rc86ee4c  
    1010// Created On       : Fri Aug 26 14:23:51 2005
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 21 09:46:24 2021
    13 // Update Count     : 419
     12// Last Modified On : Tue Jun  1 23:07:21 2021
     13// Update Count     : 415
    1414//
    1515
     
    372372                        if ( prefix( arg, "-fdiagnostics-color=" ) ) {
    373373                                string choice = arg.substr(20);
    374                                 if ( choice == "always" ) color_arg = Color_Always;
    375                                 else if ( choice == "never" ) color_arg = Color_Never;
    376                                 else if ( choice == "auto" ) color_arg = Color_Auto;
     374                                     if(choice == "always") color_arg = Color_Always;
     375                                else if(choice == "never" ) color_arg = Color_Never;
     376                                else if(choice == "auto" ) color_arg = Color_Auto;
    377377                        } else if ( arg == "-fno-diagnostics-color" ) {
    378378                                color_arg = Color_Auto;
     
    587587                Stage2( argc, argv );
    588588        } else {
    589                 cerr << "Usage: " << argv[0] << " [-E input-file [output-file] ] | [-fpreprocessed input-file output-file] [options]" << endl;
     589                cerr << "Usage: " << argv[0] << " input-file [output-file] [options]" << endl;
    590590                exit( EXIT_FAILURE );
    591591        } // if
  • driver/cfa.cc

    rd83b266 rc86ee4c  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 21:55:12 2021
    13 // Update Count     : 467
     12// Last Modified On : Sat Jan 16 07:30:19 2021
     13// Update Count     : 442
    1414//
    1515
     
    9494        // get executable path from /proc/self/exe
    9595        ssize_t size = readlink("/proc/self/exe", const_cast<char*>(abspath.c_str()), abspath.size());
    96         if ( size <= 0 ) {
     96        if(size <= 0) {
    9797                std::cerr << "Error could not evaluate absolute path from /proc/self/exe" << std::endl;
    9898                std::cerr << "Failed with " << std::strerror(errno) << std::endl;
    9999                std::exit(1);
    100         } // if
     100        }
    101101
    102102        // Trim extra characters
     
    104104
    105105        // Are we installed
    106         if ( abspath.rfind(CFA_BINDIR, 0) == 0 ) { return Installed; }
     106        if(abspath.rfind(CFA_BINDIR  , 0) == 0) { return Installed; }
    107107
    108108        // Is this the build tree
    109         if ( abspath.rfind(TOP_BUILDDIR, 0 ) == 0 ) { return BuildTree; }
     109        if(abspath.rfind(TOP_BUILDDIR, 0) == 0) { return BuildTree; }
    110110
    111111        // Does this look like distcc
    112         if ( abspath.find( "/.cfadistcc/" ) != std::string::npos ) { return Distributed; }
     112        if(abspath.find("/.cfadistcc/") != std::string::npos) { return Distributed; }
    113113
    114114        // None of the above? Give up since we don't know where the prelude or include directories are
     
    188188                                        i += 1;
    189189                                        if ( i == argc ) continue;                      // next argument available ?
    190                                         Putenv( argv, argv[i] );                        // make available for cc1
     190                                        Putenv( argv, argv[i] );
    191191                                } else if ( arg[5] == ',' ) {                   // CFA specific arguments
    192                                         string xcfargs = arg.substr( 6 ) + ","; // add sentinel
    193                                         for ( ;; ) {
    194                                                 size_t posn = xcfargs.find_first_of( "," ); // find separator
    195                                           if ( posn == string::npos ) break; // any characters left ?
    196                                                 string xcfarg = xcfargs.substr( 0, posn ); // remove XCFA argument
    197                                                 Putenv( argv, xcfarg );                 // make available for cc1
    198                                                 xcfargs.erase( 0, posn + 1 );   // remove first argument and comma
    199                                         } // for
     192                                        Putenv( argv, argv[i] + 6 );
    200193                                } else {                                                                // CFA specific arguments
    201                                         assert( false );                                        // this does not make sense
    202194                                        args[nargs++] = argv[i];
    203195                                } // if
     
    372364        args[nargs++] = "stdbool.h";
    373365
    374         if ( compiling_libs ) {
     366        if( compiling_libs ) {
    375367                Putenv( argv, "-t" );
    376368        } // if
  • libcfa/prelude/builtins.c

    rd83b266 rc86ee4c  
    1010// Created On       : Fri Jul 21 16:21:03 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 21 13:31:34 2021
    13 // Update Count     : 129
     12// Last Modified On : Tue Apr 13 17:26:32 2021
     13// Update Count     : 117
    1414//
    1515
     
    7777// implicit increment, decrement if += defined, and implicit not if != defined
    7878
    79 // C11 reference manual Section 6.5.16 (page101): "An assignment expression has the value of the left operand after the
    80 // assignment, but is not an lvalue." Hence, return a value not a reference.
    8179static inline {
    82         forall( T | { T ?+=?( T &, one_t ); } )
    83         T ++?( T & x ) { return x += 1; }
     80        forall( DT & | { DT & ?+=?( DT &, one_t ); } )
     81        DT & ++?( DT & x ) { return x += 1; }
    8482
    85         forall( T | { T ?+=?( T &, one_t ); } )
    86         T ?++( T & x ) { T tmp = x; x += 1; return tmp; }
     83        forall( DT & | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?+=?( DT &, one_t ); } )
     84        DT & ?++( DT & x ) { DT tmp = x; x += 1; return tmp; }
    8785
    88         forall( T | { T ?-=?( T &, one_t ); } )
    89         T --?( T & x ) { return x -= 1; }
     86        forall( DT & | { DT & ?-=?( DT &, one_t ); } )
     87        DT & --?( DT & x ) { return x -= 1; }
    9088
    91         forall( T | { T ?-=?( T &, one_t ); } )
    92         T ?--( T & x ) { T tmp = x; x -= 1; return tmp; }
     89        forall( DT & | sized(DT) | { void ?{}( DT &, DT ); void ^?{}( DT & ); DT & ?-=?( DT &, one_t ); } )
     90        DT & ?--( DT & x ) { DT tmp = x; x -= 1; return tmp; }
    9391
    94         forall( T | { int ?!=?( T, zero_t ); } )
    95         int !?( T & x ) { return !( x != 0 ); }
     92        forall( DT & | { int ?!=?( const DT &, zero_t ); } )
     93        int !?( const DT & x ) { return !( x != 0 ); }
    9694} // distribution
    9795
  • libcfa/src/Makefile.am

    rd83b266 rc86ee4c  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Fri Jul 16 16:00:40 2021
    14 ## Update Count     : 255
     13## Last Modified On : Sat Apr 24 09:09:56 2021
     14## Update Count     : 254
    1515###############################################################################
    1616
     
    4545        exception.h \
    4646        gmp.hfa \
    47         math.trait.hfa \
    4847        math.hfa \
    4948        time_t.hfa \
  • libcfa/src/concurrency/locks.cfa

    rd83b266 rc86ee4c  
    120120        owner = t;
    121121        recursion_count = ( t ? 1 : 0 );
    122         if ( t ) wait_count--;
     122        wait_count--;
    123123        unpark( t );
    124124}
  • libcfa/src/concurrency/locks.hfa

    rd83b266 rc86ee4c  
    276276static inline void  ?{}( linear_backoff_then_block_lock & this ) { this{4, 1024, 16, 0}; }
    277277static inline void ^?{}( linear_backoff_then_block_lock & this ) {}
    278 static inline void ?{}( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
    279 static inline void ?=?( linear_backoff_then_block_lock & this, linear_backoff_then_block_lock this2 ) = void;
    280278
    281279static inline bool internal_try_lock(linear_backoff_then_block_lock & this, size_t & compare_val) with(this) {
  • libcfa/src/fstream.cfa

    rd83b266 rc86ee4c  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 22 11:34:41 2021
    13 // Update Count     : 448
     12// Last Modified On : Wed Apr 28 20:37:53 2021
     13// Update Count     : 445
    1414//
    1515
     
    338338
    339339
    340 //EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table);
    341 static vtable(Open_Failure) Open_Failure_main_table;
    342 
    343 // exception I/O constructors
     340EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table);
    344341void ?{}( Open_Failure & this, ofstream & ostream ) {
    345342        this.virtual_table = &Open_Failure_main_table;
    346343        this.ostream = &ostream;
    347344        this.tag = 1;
    348 } // ?{}
    349 
     345}
    350346void ?{}( Open_Failure & this, ifstream & istream ) {
    351347        this.virtual_table = &Open_Failure_main_table;
    352348        this.istream = &istream;
    353349        this.tag = 0;
    354 } // ?{}
    355 
     350}
    356351void throwOpen_Failure( ofstream & ostream ) {
    357352        Open_Failure exc = { ostream };
    358353}
    359 
    360354void throwOpen_Failure( ifstream & istream ) {
    361355        Open_Failure exc = { istream };
  • libcfa/src/fstream.hfa

    rd83b266 rc86ee4c  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 21:18:03 2021
    13 // Update Count     : 232
     12// Last Modified On : Wed Apr 28 20:37:57 2021
     13// Update Count     : 230
    1414//
    1515
     
    148148
    149149
    150 exception Open_Failure {
     150EHM_EXCEPTION(Open_Failure)(
    151151        union {
    152152                ofstream * ostream;
     
    155155        // TEMPORARY: need polymorphic exceptions
    156156        int tag;                                                                                        // 1 => ostream; 0 => istream
    157 };
     157);
    158158
    159159void ?{}( Open_Failure & this, ofstream & );
  • libcfa/src/rational.cfa

    rd83b266 rc86ee4c  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 16:30:06 2021
    13 // Update Count     : 193
     12// Last Modified On : Sat Feb  8 17:56:36 2020
     13// Update Count     : 187
    1414//
    1515
     
    1818#include "stdlib.hfa"
    1919
    20 forall( T | Arithmetic( T ) ) {
     20forall( RationalImpl | arithmetic( RationalImpl ) ) {
    2121        // helper routines
    2222
    2323        // Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce
    2424        // rationals.  alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    25         static T gcd( T a, T b ) {
     25        static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
    2626                for ( ;; ) {                                                                    // Euclid's algorithm
    27                         T r = a % b;
    28                   if ( r == (T){0} ) break;
     27                        RationalImpl r = a % b;
     28                  if ( r == (RationalImpl){0} ) break;
    2929                        a = b;
    3030                        b = r;
     
    3333        } // gcd
    3434
    35         static T simplify( T & n, T & d ) {
    36                 if ( d == (T){0} ) {
     35        static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
     36                if ( d == (RationalImpl){0} ) {
    3737                        abort | "Invalid rational number construction: denominator cannot be equal to 0.";
    3838                } // exit
    39                 if ( d < (T){0} ) { d = -d; n = -n; } // move sign to numerator
     39                if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
    4040                return gcd( abs( n ), d );                                              // simplify
    4141        } // Rationalnumber::simplify
     
    4343        // constructors
    4444
    45         void ?{}( Rational(T) & r, zero_t ) {
    46                 r{ (T){0}, (T){1} };
    47         } // rational
    48 
    49         void ?{}( Rational(T) & r, one_t ) {
    50                 r{ (T){1}, (T){1} };
    51         } // rational
    52 
    53         void ?{}( Rational(T) & r ) {
    54                 r{ (T){0}, (T){1} };
    55         } // rational
    56 
    57         void ?{}( Rational(T) & r, T n ) {
    58                 r{ n, (T){1} };
    59         } // rational
    60 
    61         void ?{}( Rational(T) & r, T n, T d ) {
    62                 T t = simplify( n, d );                         // simplify
     45        void ?{}( Rational(RationalImpl) & r ) {
     46                r{ (RationalImpl){0}, (RationalImpl){1} };
     47        } // rational
     48
     49        void ?{}( Rational(RationalImpl) & r, RationalImpl n ) {
     50                r{ n, (RationalImpl){1} };
     51        } // rational
     52
     53        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
     54                RationalImpl t = simplify( n, d );                              // simplify
    6355                r.[numerator, denominator] = [n / t, d / t];
    6456        } // rational
    6557
     58        void ?{}( Rational(RationalImpl) & r, zero_t ) {
     59                r{ (RationalImpl){0}, (RationalImpl){1} };
     60        } // rational
     61
     62        void ?{}( Rational(RationalImpl) & r, one_t ) {
     63                r{ (RationalImpl){1}, (RationalImpl){1} };
     64        } // rational
     65
    6666        // getter for numerator/denominator
    6767
    68         T numerator( Rational(T) r ) {
     68        RationalImpl numerator( Rational(RationalImpl) r ) {
    6969                return r.numerator;
    7070        } // numerator
    7171
    72         T denominator( Rational(T) r ) {
     72        RationalImpl denominator( Rational(RationalImpl) r ) {
    7373                return r.denominator;
    7474        } // denominator
    7575
    76         [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {
     76        [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src ) {
    7777                return dest = src.[ numerator, denominator ];
    7878        } // ?=?
     
    8080        // setter for numerator/denominator
    8181
    82         T numerator( Rational(T) r, T n ) {
    83                 T prev = r.numerator;
    84                 T t = gcd( abs( n ), r.denominator ); // simplify
     82        RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n ) {
     83                RationalImpl prev = r.numerator;
     84                RationalImpl t = gcd( abs( n ), r.denominator ); // simplify
    8585                r.[numerator, denominator] = [n / t, r.denominator / t];
    8686                return prev;
    8787        } // numerator
    8888
    89         T denominator( Rational(T) r, T d ) {
    90                 T prev = r.denominator;
    91                 T t = simplify( r.numerator, d );       // simplify
     89        RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d ) {
     90                RationalImpl prev = r.denominator;
     91                RationalImpl t = simplify( r.numerator, d );    // simplify
    9292                r.[numerator, denominator] = [r.numerator / t, d / t];
    9393                return prev;
     
    9696        // comparison
    9797
    98         int ?==?( Rational(T) l, Rational(T) r ) {
     98        int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    9999                return l.numerator * r.denominator == l.denominator * r.numerator;
    100100        } // ?==?
    101101
    102         int ?!=?( Rational(T) l, Rational(T) r ) {
     102        int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    103103                return ! ( l == r );
    104104        } // ?!=?
    105105
    106         int ?!=?( Rational(T) l, zero_t ) {
    107                 return ! ( l == (Rational(T)){ 0 } );
    108         } // ?!=?
    109 
    110         int ?<?( Rational(T) l, Rational(T) r ) {
     106        int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    111107                return l.numerator * r.denominator < l.denominator * r.numerator;
    112108        } // ?<?
    113109
    114         int ?<=?( Rational(T) l, Rational(T) r ) {
     110        int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    115111                return l.numerator * r.denominator <= l.denominator * r.numerator;
    116112        } // ?<=?
    117113
    118         int ?>?( Rational(T) l, Rational(T) r ) {
     114        int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    119115                return ! ( l <= r );
    120116        } // ?>?
    121117
    122         int ?>=?( Rational(T) l, Rational(T) r ) {
     118        int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    123119                return ! ( l < r );
    124120        } // ?>=?
     
    126122        // arithmetic
    127123
    128         Rational(T) +?( Rational(T) r ) {
    129                 return (Rational(T)){ r.numerator, r.denominator };
     124        Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
     125                return (Rational(RationalImpl)){ r.numerator, r.denominator };
    130126        } // +?
    131127
    132         Rational(T) -?( Rational(T) r ) {
    133                 return (Rational(T)){ -r.numerator, r.denominator };
     128        Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
     129                return (Rational(RationalImpl)){ -r.numerator, r.denominator };
    134130        } // -?
    135131
    136         Rational(T) ?+?( Rational(T) l, Rational(T) r ) {
     132        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    137133                if ( l.denominator == r.denominator ) {                 // special case
    138                         return (Rational(T)){ l.numerator + r.numerator, l.denominator };
     134                        return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator };
    139135                } else {
    140                         return (Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     136                        return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
    141137                } // if
    142138        } // ?+?
    143139
    144         Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {
    145                 l = l + r;
    146                 return l;
    147         } // ?+?
    148 
    149         Rational(T) ?+=?( Rational(T) & l, one_t ) {
    150                 l = l + (Rational(T)){ 1 };
    151                 return l;
    152         } // ?+?
    153 
    154         Rational(T) ?-?( Rational(T) l, Rational(T) r ) {
     140        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    155141                if ( l.denominator == r.denominator ) {                 // special case
    156                         return (Rational(T)){ l.numerator - r.numerator, l.denominator };
     142                        return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator };
    157143                } else {
    158                         return (Rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     144                        return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
    159145                } // if
    160146        } // ?-?
    161147
    162         Rational(T) ?-=?( Rational(T) & l, Rational(T) r ) {
    163                 l = l - r;
    164                 return l;
    165         } // ?-?
    166 
    167         Rational(T) ?-=?( Rational(T) & l, one_t ) {
    168                 l = l - (Rational(T)){ 1 };
    169                 return l;
    170         } // ?-?
    171 
    172         Rational(T) ?*?( Rational(T) l, Rational(T) r ) {
    173                 return (Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };
     148        Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     149                return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator };
    174150        } // ?*?
    175151
    176         Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {
    177                 return l = l * r;
    178         } // ?*?
    179 
    180         Rational(T) ?/?( Rational(T) l, Rational(T) r ) {
    181                 if ( r.numerator < (T){0} ) {
     152        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
     153                if ( r.numerator < (RationalImpl){0} ) {
    182154                        r.[numerator, denominator] = [-r.numerator, -r.denominator];
    183155                } // if
    184                 return (Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };
     156                return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator };
    185157        } // ?/?
    186158
    187         Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {
    188                 return l = l / r;
    189         } // ?/?
    190 
    191159        // I/O
    192160
    193         forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } )
    194         istype & ?|?( istype & is, Rational(T) & r ) {
     161        forall( istype & | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
     162        istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
    195163                is | r.numerator | r.denominator;
    196                 T t = simplify( r.numerator, r.denominator );
     164                RationalImpl t = simplify( r.numerator, r.denominator );
    197165                r.numerator /= t;
    198166                r.denominator /= t;
     
    200168        } // ?|?
    201169
    202         forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) {
    203                 ostype & ?|?( ostype & os, Rational(T) r ) {
     170        forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) {
     171                ostype & ?|?( ostype & os, Rational(RationalImpl) r ) {
    204172                        return os | r.numerator | '/' | r.denominator;
    205173                } // ?|?
    206174
    207                 void ?|?( ostype & os, Rational(T) r ) {
     175                void ?|?( ostype & os, Rational(RationalImpl) r ) {
    208176                        (ostype &)(os | r); ends( os );
    209177                } // ?|?
     
    211179} // distribution
    212180
    213 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
    214         Rational(T) ?\?( Rational(T) x, long int y ) {
    215                 if ( y < 0 ) {
    216                         return (Rational(T)){ x.denominator \ -y, x.numerator \ -y };
    217                 } else {
    218                         return (Rational(T)){ x.numerator \ y, x.denominator \ y };
    219                 } // if
    220         } // ?\?
    221 
    222         Rational(T) ?\=?( Rational(T) & x, long int y ) {
    223                 return x = x \ y;
    224         } // ?\?
    225 } // distribution
     181forall( RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )
     182Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) {
     183        if ( y < 0 ) {
     184                return (Rational(RationalImpl)){ x.denominator \ -y, x.numerator \ -y };
     185        } else {
     186                return (Rational(RationalImpl)){ x.numerator \ y, x.denominator \ y };
     187        } // if
     188}
    226189
    227190// conversion
    228191
    229 forall( T | Arithmetic( T ) | { double convert( T ); } )
    230 double widen( Rational(T) r ) {
     192forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     193double widen( Rational(RationalImpl) r ) {
    231194        return convert( r.numerator ) / convert( r.denominator );
    232195} // widen
    233196
    234 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double ); } )
    235 Rational(T) narrow( double f, T md ) {
     197forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
     198Rational(RationalImpl) narrow( double f, RationalImpl md ) {
    236199        // http://www.ics.uci.edu/~eppstein/numth/frap.c
    237         if ( md <= (T){1} ) {                                   // maximum fractional digits too small?
    238                 return (Rational(T)){ convert( f ), (T){1}}; // truncate fraction
     200        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
     201                return (Rational(RationalImpl)){ convert( f ), (RationalImpl){1}}; // truncate fraction
    239202        } // if
    240203
    241204        // continued fraction coefficients
    242         T m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
    243         T ai, t;
     205        RationalImpl m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
     206        RationalImpl ai, t;
    244207
    245208        // find terms until denom gets too big
     
    258221          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
    259222        } // for
    260         return (Rational(T)){ m00, m10 };
     223        return (Rational(RationalImpl)){ m00, m10 };
    261224} // narrow
    262225
  • libcfa/src/rational.hfa

    rd83b266 rc86ee4c  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Tue Jul 20 17:45:29 2021
    15 // Update Count     : 118
     14// Last Modified On : Tue Mar 26 23:16:10 2019
     15// Update Count     : 109
    1616//
    1717
     
    1919
    2020#include "iostream.hfa"
    21 #include "math.trait.hfa"                                                               // Arithmetic
     21
     22trait scalar( T ) {
     23};
     24
     25trait arithmetic( T | scalar( T ) ) {
     26        int !?( T );
     27        int ?==?( T, T );
     28        int ?!=?( T, T );
     29        int ?<?( T, T );
     30        int ?<=?( T, T );
     31        int ?>?( T, T );
     32        int ?>=?( T, T );
     33        void ?{}( T &, zero_t );
     34        void ?{}( T &, one_t );
     35        T +?( T );
     36        T -?( T );
     37        T ?+?( T, T );
     38        T ?-?( T, T );
     39        T ?*?( T, T );
     40        T ?/?( T, T );
     41        T ?%?( T, T );
     42        T ?/=?( T &, T );
     43        T abs( T );
     44};
    2245
    2346// implementation
    2447
    25 forall( T | Arithmetic( T ) ) {
     48forall( RationalImpl | arithmetic( RationalImpl ) ) {
    2649        struct Rational {
    27                 T numerator, denominator;                                               // invariant: denominator > 0
     50                RationalImpl numerator, denominator;                    // invariant: denominator > 0
    2851        }; // Rational
    2952
    3053        // constructors
    3154
    32         void ?{}( Rational(T) & r );
    33         void ?{}( Rational(T) & r, zero_t );
    34         void ?{}( Rational(T) & r, one_t );
    35         void ?{}( Rational(T) & r, T n );
    36         void ?{}( Rational(T) & r, T n, T d );
     55        void ?{}( Rational(RationalImpl) & r );
     56        void ?{}( Rational(RationalImpl) & r, RationalImpl n );
     57        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d );
     58        void ?{}( Rational(RationalImpl) & r, zero_t );
     59        void ?{}( Rational(RationalImpl) & r, one_t );
    3760
    3861        // numerator/denominator getter
    3962
    40         T numerator( Rational(T) r );
    41         T denominator( Rational(T) r );
    42         [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src );
     63        RationalImpl numerator( Rational(RationalImpl) r );
     64        RationalImpl denominator( Rational(RationalImpl) r );
     65        [ RationalImpl, RationalImpl ] ?=?( & [ RationalImpl, RationalImpl ] dest, Rational(RationalImpl) src );
    4366
    4467        // numerator/denominator setter
    4568
    46         T numerator( Rational(T) r, T n );
    47         T denominator( Rational(T) r, T d );
     69        RationalImpl numerator( Rational(RationalImpl) r, RationalImpl n );
     70        RationalImpl denominator( Rational(RationalImpl) r, RationalImpl d );
    4871
    4972        // comparison
    5073
    51         int ?==?( Rational(T) l, Rational(T) r );
    52         int ?!=?( Rational(T) l, Rational(T) r );
    53         int ?!=?( Rational(T) l, zero_t );                                      // => !
    54         int ?<?( Rational(T) l, Rational(T) r );
    55         int ?<=?( Rational(T) l, Rational(T) r );
    56         int ?>?( Rational(T) l, Rational(T) r );
    57         int ?>=?( Rational(T) l, Rational(T) r );
     74        int ?==?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     75        int ?!=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     76        int ?<?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     77        int ?<=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     78        int ?>?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     79        int ?>=?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    5880
    5981        // arithmetic
    6082
    61         Rational(T) +?( Rational(T) r );
    62         Rational(T) -?( Rational(T) r );
    63         Rational(T) ?+?( Rational(T) l, Rational(T) r );
    64         Rational(T) ?+=?( Rational(T) & l, Rational(T) r );
    65         Rational(T) ?+=?( Rational(T) & l, one_t );                     // => ++?, ?++
    66         Rational(T) ?-?( Rational(T) l, Rational(T) r );
    67         Rational(T) ?-=?( Rational(T) & l, Rational(T) r );
    68         Rational(T) ?-=?( Rational(T) & l, one_t );                     // => --?, ?--
    69         Rational(T) ?*?( Rational(T) l, Rational(T) r );
    70         Rational(T) ?*=?( Rational(T) & l, Rational(T) r );
    71         Rational(T) ?/?( Rational(T) l, Rational(T) r );
    72         Rational(T) ?/=?( Rational(T) & l, Rational(T) r );
     83        Rational(RationalImpl) +?( Rational(RationalImpl) r );
     84        Rational(RationalImpl) -?( Rational(RationalImpl) r );
     85        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     86        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     87        Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r );
     88        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r );
    7389
    7490        // I/O
    75         forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } )
    76         istype & ?|?( istype &, Rational(T) & );
     91        forall( istype & | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
     92        istype & ?|?( istype &, Rational(RationalImpl) & );
    7793
    78         forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) {
    79                 ostype & ?|?( ostype &, Rational(T) );
    80                 void ?|?( ostype &, Rational(T) );
     94        forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) {
     95                ostype & ?|?( ostype &, Rational(RationalImpl) );
     96                void ?|?( ostype &, Rational(RationalImpl) );
    8197        } // distribution
    8298} // distribution
    8399
    84 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
    85         Rational(T) ?\?( Rational(T) x, long int y );
    86         Rational(T) ?\=?( Rational(T) & x, long int y );
    87 } // distribution
     100forall( RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} )
     101Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y );
    88102
    89103// conversion
    90 forall( T | Arithmetic( T ) | { double convert( T ); } )
    91 double widen( Rational(T) r );
    92 forall( T | Arithmetic( T ) | { double convert( T );  T convert( double );} )
    93 Rational(T) narrow( double f, T md );
     104forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     105double widen( Rational(RationalImpl) r );
     106forall( RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
     107Rational(RationalImpl) narrow( double f, RationalImpl md );
    94108
    95109// Local Variables: //
  • src/AST/Convert.cpp

    rd83b266 rc86ee4c  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu May 09 15::37::05 2019
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 16:15:00 2021
    13 // Update Count     : 37
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:43:51 2021
     13// Update Count     : 36
    1414//
    1515
     
    13561356        }
    13571357
    1358         const ast::Type * visit( const ast::VTableType * node ) override final {
    1359                 return visitType( node, new VTableType{
    1360                         cv( node ),
    1361                         get<Type>().accept1( node->base )
    1362                 } );
    1363         }
    1364 
    13651358        const ast::Type * visit( const ast::VarArgsType * node ) override final {
    13661359                return visitType( node, new VarArgsType{ cv( node ) } );
     
    28062799        }
    28072800
    2808         virtual void visit( const VTableType * old ) override final {
    2809                 visitType( old, new ast::VTableType{
    2810                         GET_ACCEPT_1( base, Type ),
    2811                         cv( old )
    2812                 } );
    2813         }
    2814 
    28152801        virtual void visit( const AttrType * ) override final {
    28162802                assertf( false, "AttrType deprecated in new AST." );
  • src/AST/Fwd.hpp

    rd83b266 rc86ee4c  
    117117class TupleType;
    118118class TypeofType;
    119 class VTableType;
    120119class VarArgsType;
    121120class ZeroType;
  • src/AST/Pass.hpp

    rd83b266 rc86ee4c  
    213213        const ast::Type *             visit( const ast::TupleType            * ) override final;
    214214        const ast::Type *             visit( const ast::TypeofType           * ) override final;
    215         const ast::Type *             visit( const ast::VTableType           * ) override final;
    216215        const ast::Type *             visit( const ast::VarArgsType          * ) override final;
    217216        const ast::Type *             visit( const ast::ZeroType             * ) override final;
  • src/AST/Pass.impl.hpp

    rd83b266 rc86ee4c  
    18731873
    18741874//--------------------------------------------------------------------------
    1875 // VTableType
    1876 template< typename core_t >
    1877 const ast::Type * ast::Pass< core_t >::visit( const ast::VTableType * node ) {
    1878         VISIT_START( node );
    1879 
    1880         VISIT(
    1881                 maybe_accept( node, &VTableType::base );
    1882         )
    1883 
    1884         VISIT_END( Type, node );
    1885 }
    1886 
    1887 //--------------------------------------------------------------------------
    18881875// VarArgsType
    18891876template< typename core_t >
  • src/AST/Print.cpp

    rd83b266 rc86ee4c  
    14161416        }
    14171417
    1418         virtual const ast::Type * visit( const ast::VTableType * node ) override final {
    1419                 preprint( node );
    1420                 os << "vtable for ";
    1421                 safe_print( node->base );
    1422 
    1423                 return node;
    1424         }
    1425 
    14261418        virtual const ast::Type * visit( const ast::VarArgsType * node ) override final {
    14271419                preprint( node );
  • src/AST/Type.hpp

    rd83b266 rc86ee4c  
    1010// Created On       : Thu May 9 10:00:00 2019
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 15:54:00 2021
    13 // Update Count     : 7
     12// Last Modified On : Thu Jul 23 14:15:00 2020
     13// Update Count     : 6
    1414//
    1515
     
    491491};
    492492
    493 /// Virtual Table Type `vtable(T)`
    494 class VTableType final : public Type {
    495 public:
    496         ptr<Type> base;
    497 
    498         VTableType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b) {}
    499 
    500         const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    501 private:
    502         VTableType * clone() const override { return new VTableType{ *this }; }
    503         MUTATE_FRIEND
    504 };
    505 
    506493/// GCC built-in varargs type
    507494class VarArgsType final : public Type {
  • src/AST/Visitor.hpp

    rd83b266 rc86ee4c  
    105105    virtual const ast::Type *             visit( const ast::TupleType            * ) = 0;
    106106    virtual const ast::Type *             visit( const ast::TypeofType           * ) = 0;
    107     virtual const ast::Type *             visit( const ast::VTableType           * ) = 0;
    108107    virtual const ast::Type *             visit( const ast::VarArgsType          * ) = 0;
    109108    virtual const ast::Type *             visit( const ast::ZeroType             * ) = 0;
  • src/Common/CodeLocationTools.cpp

    rd83b266 rc86ee4c  
    176176    macro(TupleType, Type) \
    177177    macro(TypeofType, Type) \
    178     macro(VTableType, Type) \
    179178    macro(VarArgsType, Type) \
    180179    macro(ZeroType, Type) \
  • src/Common/PassVisitor.h

    rd83b266 rc86ee4c  
    230230        virtual void visit( TypeofType * typeofType ) override final;
    231231        virtual void visit( const TypeofType * typeofType ) override final;
    232         virtual void visit( VTableType * vtableType ) override final;
    233         virtual void visit( const VTableType * vtableType ) override final;
    234232        virtual void visit( AttrType * attrType ) override final;
    235233        virtual void visit( const AttrType * attrType ) override final;
     
    345343        virtual Type * mutate( TupleType * tupleType ) override final;
    346344        virtual Type * mutate( TypeofType * typeofType ) override final;
    347         virtual Type * mutate( VTableType * vtableType ) override final;
    348345        virtual Type * mutate( AttrType * attrType ) override final;
    349346        virtual Type * mutate( VarArgsType * varArgsType ) override final;
  • src/Common/PassVisitor.impl.h

    rd83b266 rc86ee4c  
    36103610
    36113611//--------------------------------------------------------------------------
    3612 // VTableType
    3613 template< typename pass_type >
    3614 void PassVisitor< pass_type >::visit( VTableType * node ) {
    3615         VISIT_START( node );
    3616 
    3617         // Forall qualifiers should be on base type, not here
    3618         // maybeAccept_impl( node->forall, *this );
    3619         maybeAccept_impl( node->base, *this );
    3620 
    3621         VISIT_END( node );
    3622 }
    3623 
    3624 template< typename pass_type >
    3625 void PassVisitor< pass_type >::visit( const VTableType * node ) {
    3626         VISIT_START( node );
    3627 
    3628         // Forall qualifiers should be on base type, not here
    3629         // maybeAccept_impl( node->forall, *this );
    3630         maybeAccept_impl( node->base, *this );
    3631 
    3632         VISIT_END( node );
    3633 }
    3634 
    3635 template< typename pass_type >
    3636 Type * PassVisitor< pass_type >::mutate( VTableType * node ) {
    3637         MUTATE_START( node );
    3638 
    3639         // Forall qualifiers should be on base type, not here
    3640         // maybeMutate_impl( node->forall, *this );
    3641         maybeMutate_impl( node->base, *this );
    3642 
    3643         MUTATE_END( Type, node );
    3644 }
    3645 
    3646 //--------------------------------------------------------------------------
    36473612// AttrType
    36483613template< typename pass_type >
  • src/CompilationState.cc

    rd83b266 rc86ee4c  
    99// Author           : Rob Schluntz
    1010// Created On       : Mon Ju1 30 10:47:01 2018
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:27:35 2021
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri May  3 13:45:23 2019
     13// Update Count     : 4
    1414//
    1515
     
    2323        ctorinitp = false,
    2424        declstatsp = false,
    25         exdeclp = false,
    2625        exprp = false,
    2726        expraltp = false,
  • src/CompilationState.h

    rd83b266 rc86ee4c  
    99// Author           : Rob Schluntz
    1010// Created On       : Mon Ju1 30 10:47:01 2018
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:27:35 2021
    13 // Update Count     : 5
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri May  3 13:43:21 2019
     13// Update Count     : 4
    1414//
    1515
     
    2222        ctorinitp,
    2323        declstatsp,
    24         exdeclp,
    2524        exprp,
    2625        expraltp,
  • src/ControlStruct/module.mk

    rd83b266 rc86ee4c  
    1010## Author           : Richard C. Bilson
    1111## Created On       : Mon Jun  1 17:49:17 2015
    12 ## Last Modified By : Henry Xue
    13 ## Last Modified On : Tue Jul 20 04:10:50 2021
    14 ## Update Count     : 5
     12## Last Modified By : Andrew Beach
     13## Last Modified On : Wed Jun 28 16:15:00 2017
     14## Update Count     : 4
    1515###############################################################################
    1616
    1717SRC_CONTROLSTRUCT = \
    18         ControlStruct/ExceptDecl.cc \
    19         ControlStruct/ExceptDecl.h \
    2018        ControlStruct/ForExprMutator.cc \
    2119        ControlStruct/ForExprMutator.h \
  • src/GenPoly/Box.cc

    rd83b266 rc86ee4c  
    15461546                        long i = 0;
    15471547                        for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
    1548                                 if ( memberDecl->get_name() != (*decl)->get_name() )
    1549                                         continue;
    1550 
    1551                                 if ( memberDecl->get_name().empty() ) {
    1552                                         // plan-9 field: match on unique_id
    1553                                         if ( memberDecl->get_uniqueId() == (*decl)->get_uniqueId() )
    1554                                                 return i;
    1555                                         else
    1556                                                 continue;
    1557                                 }
    1558 
    1559                                 DeclarationWithType *declWithType = strict_dynamic_cast< DeclarationWithType* >( *decl );
    1560 
    1561                                 if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty() ) {
    1562                                         // tuple-element field: expect neither had mangled name; accept match on simple name (like field_2) only
    1563                                         assert( memberDecl->get_mangleName().empty() && declWithType->get_mangleName().empty() );
    1564                                         return i;
    1565                                 }
    1566 
    1567                                 // ordinary field: use full name to accommodate overloading
    1568                                 if ( memberDecl->get_mangleName() == declWithType->get_mangleName() )
    1569                                         return i;
    1570                                 else
    1571                                         continue;
     1548                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1549
     1550                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1551                                        if ( memberDecl->get_mangleName().empty() || declWithType->get_mangleName().empty()
     1552                                             || memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1553                                        else continue;
     1554                                } else return i;
    15721555                        }
    15731556                        return -1;
  • src/Parser/DeclarationNode.cc

    rd83b266 rc86ee4c  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 17:36:57 2021
    13 // Update Count     : 1154
     12// Last Modified On : Tue Mar 23 08:44:08 2021
     13// Update Count     : 1149
    1414//
    1515
     
    385385        newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
    386386        newnode->type->typeexpr = expr;
    387         return newnode;
    388 }
    389 
    390 DeclarationNode * DeclarationNode::newVtableType( DeclarationNode * decl ) {
    391         DeclarationNode * newnode = new DeclarationNode;
    392         newnode->type = new TypeData( TypeData::Vtable );
    393         newnode->setBase( decl->type );
    394387        return newnode;
    395388}
  • src/Parser/ParseNode.h

    rd83b266 rc86ee4c  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 17:28:53 2021
    13 // Update Count     : 900
     12// Last Modified On : Fri Mar 12 15:19:04 2021
     13// Update Count     : 897
    1414//
    1515
     
    249249        static DeclarationNode * newTuple( DeclarationNode * members );
    250250        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    251         static DeclarationNode * newVtableType( DeclarationNode * expr );
    252251        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    253252        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
  • src/Parser/TypeData.cc

    rd83b266 rc86ee4c  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:10:50 2021
    13 // Update Count     : 673
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Dec 16 07:56:46 2019
     13// Update Count     : 662
    1414//
    1515
     
    100100                typeexpr = nullptr;
    101101                break;
    102           case Vtable:
    103                 break;
    104102          case Builtin:
    105103                // builtin = new Builtin_t;
     
    172170                // delete typeexpr->expr;
    173171                delete typeexpr;
    174                 break;
    175           case Vtable:
    176172                break;
    177173          case Builtin:
     
    253249          case Basetypeof:
    254250                newtype->typeexpr = maybeClone( typeexpr );
    255                 break;
    256           case Vtable:
    257251                break;
    258252          case Builtin:
     
    473467          case Basetypeof:
    474468          case Builtin:
    475           case Vtable:
    476469                assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
    477470                break;
     
    553546          case TypeData::Basetypeof:
    554547                return buildTypeof( td );
    555           case TypeData::Vtable:
    556                 return buildVtable( td );
    557548          case TypeData::Builtin:
    558549                switch ( td->builtintype ) {
     
    778769          case AggregateDecl::Struct:
    779770          case AggregateDecl::Coroutine:
    780           case AggregateDecl::Exception:
    781771          case AggregateDecl::Generator:
    782772          case AggregateDecl::Monitor:
     
    955945        assert( td->typeexpr );
    956946        // assert( td->typeexpr->expr );
    957         return new TypeofType{ buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
     947        return new TypeofType{
     948                buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
    958949} // buildTypeof
    959 
    960 
    961 VTableType * buildVtable( const TypeData * td ) {
    962         assert( td->base );
    963         return new VTableType{ buildQualifiers( td ), typebuild( td->base ) };
    964 } // buildVtable
    965950
    966951
  • src/Parser/TypeData.h

    rd83b266 rc86ee4c  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jul 14 17:44:05 2021
    13 // Update Count     : 202
     12// Last Modified On : Sat Mar 27 09:05:35 2021
     13// Update Count     : 200
    1414//
    1515
     
    2727struct TypeData {
    2828        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
    29                                 SymbolicInst, Tuple, Typeof, Basetypeof, Vtable, Builtin, GlobalScope, Qualified, Unknown };
     29                                SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown };
    3030
    3131        struct Aggregate_t {
     
    128128TupleType * buildTuple( const TypeData * );
    129129TypeofType * buildTypeof( const TypeData * );
    130 VTableType * buildVtable( const TypeData * );
    131130Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName,
    132131                                                 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
  • src/Parser/parser.yy

    rd83b266 rc86ee4c  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 22:03:04 2021
    13 // Update Count     : 5031
     12// Last Modified On : Tue Jun 29 09:12:47 2021
     13// Update Count     : 5027
    1414//
    1515
     
    19231923
    19241924vtable:
    1925         VTABLE '(' type_name ')' default_opt
    1926                 { $$ = DeclarationNode::newVtableType( $3 ); }
    1927                 // { SemanticError( yylloc, "vtable is currently unimplemented." ); $$ = nullptr; }
     1925        VTABLE '(' type_list ')' default_opt
     1926                { SemanticError( yylloc, "vtable is currently unimplemented." ); $$ = nullptr; }
    19281927        ;
    19291928
  • src/SynTree/Declaration.h

    rd83b266 rc86ee4c  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:10:50 2021
    13 // Update Count     : 160
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 12 18:35:36 2021
     13// Update Count     : 159
    1414//
    1515
     
    300300
    301301        bool is_coroutine() { return kind == Coroutine; }
    302         bool is_exception() { return kind == Exception; }
    303302        bool is_generator() { return kind == Generator; }
    304303        bool is_monitor  () { return kind == Monitor  ; }
  • src/SynTree/Mutator.h

    rd83b266 rc86ee4c  
    112112        virtual Type * mutate( TupleType * tupleType ) = 0;
    113113        virtual Type * mutate( TypeofType * typeofType ) = 0;
    114         virtual Type * mutate( VTableType * vtableType ) = 0;
    115114        virtual Type * mutate( AttrType * attrType ) = 0;
    116115        virtual Type * mutate( VarArgsType * varArgsType ) = 0;
  • src/SynTree/SynTree.h

    rd83b266 rc86ee4c  
    119119class TupleType;
    120120class TypeofType;
    121 class VTableType;
    122121class AttrType;
    123122class VarArgsType;
  • src/SynTree/Type.cc

    rd83b266 rc86ee4c  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 15:47:00 2021
    13 // Update Count     : 50
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Dec 15 16:52:37 2019
     13// Update Count     : 49
    1414//
    1515#include "Type.h"
     
    178178}
    179179
    180 VTableType::VTableType( const Type::Qualifiers &tq, Type *base, const std::list< Attribute * > & attributes )
    181                 : Type( tq, attributes ), base( base ) {
    182         assertf( base, "VTableType with a null base created." );
    183 }
    184 
    185 VTableType::VTableType( const VTableType &other )
    186                 : Type( other ), base( other.base->clone() ) {
    187 }
    188 
    189 VTableType::~VTableType() {
    190         delete base;
    191 }
    192 
    193 void VTableType::print( std::ostream &os, Indenter indent ) const {
    194         Type::print( os, indent );
    195         os << "get virtual-table type of ";
    196         if ( base ) {
    197                 base->print( os, indent );
    198         } // if
    199 }
    200 
    201180// Local Variables: //
    202181// tab-width: 4 //
  • src/SynTree/Type.h

    rd83b266 rc86ee4c  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 14 15:40:00 2021
    13 // Update Count     : 171
     12// Last Modified On : Wed Sep  4 09:58:00 2019
     13// Update Count     : 170
    1414//
    1515
     
    651651};
    652652
    653 class VTableType : public Type {
    654 public:
    655         Type *base;
    656 
    657         VTableType( const Type::Qualifiers & tq, Type *base,
    658                 const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    659         VTableType( const VTableType & );
    660         virtual ~VTableType();
    661 
    662         Type *get_base() { return base; }
    663         void set_base( Type *newValue ) { base = newValue; }
    664 
    665         virtual VTableType *clone() const override { return new VTableType( *this ); }
    666         virtual void accept( Visitor & v ) override { v.visit( this ); }
    667         virtual void accept( Visitor & v ) const override { v.visit( this ); }
    668         virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    669         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    670 };
    671 
    672653class AttrType : public Type {
    673654  public:
  • src/SynTree/Visitor.h

    rd83b266 rc86ee4c  
    198198        virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); }
    199199        virtual void visit( const TypeofType * typeofType ) = 0;
    200         virtual void visit( VTableType * node ) { visit( const_cast<const VTableType *>(node) ); }
    201         virtual void visit( const VTableType * vtableType ) = 0;
    202200        virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); }
    203201        virtual void visit( const AttrType * attrType ) = 0;
  • src/main.cc

    rd83b266 rc86ee4c  
    99// Author           : Peter Buhr and Rob Schluntz
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Jul 20 04:27:35 2021
    13 // Update Count     : 658
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sat Mar  6 15:49:00 2021
     13// Update Count     : 656
    1414//
    1515
     
    4949#include "Common/utility.h"                 // for deleteAll, filter, printAll
    5050#include "Concurrency/Waitfor.h"            // for generateWaitfor
    51 #include "ControlStruct/ExceptDecl.h"       // for translateExcept
    5251#include "ControlStruct/ExceptTranslate.h"  // for translateEHM
    5352#include "ControlStruct/Mutate.h"           // for mutate
     
    306305                CodeTools::fillLocations( translationUnit );
    307306                Stats::Time::StopBlock();
    308 
    309                 PASS( "Translate Exception Declarations", ControlStruct::translateExcept( translationUnit ) );
    310                 if ( exdeclp ) {
    311                         dump( translationUnit );
    312                         return EXIT_SUCCESS;
    313                 } // if
    314307
    315308                // add the assignment statement after the initialization of a type parameter
     
    556549        // code dumps
    557550        { "ast", astp, true, "print AST after parsing" },
    558         { "exdecl", exdeclp, true, "print AST after translating exception decls" },
    559551        { "symevt", symtabp, true, "print AST after symbol table events" },
    560552        { "altexpr", expraltp, true, "print alternatives for expressions" },
  • tests/.expect/counter.txt

    rd83b266 rc86ee4c  
    1 inc 45
    2 dec 42
     145
     242
  • tests/.expect/polymorphism.txt

    rd83b266 rc86ee4c  
    11123 456 456
    225 5
    3 === checkPlan9offsets
    4 static:
    5   offset of inner double: 8
    6   offset of inner float:  16
    7 dynamic:
    8   offset of inner double: 8
    9   offset of inner float:  16
  • tests/.expect/rational.txt

    rd83b266 rc86ee4c  
    11constructor
    2 a : 3/1 b : 4/1 c : 0/1 d : 0/1 e : 1/1
    3 a : 1/2 b : 5/7
    4 a : 2/3 b : -3/2
    5 a : -2/3 b : 3/2
    6 
    7 comparison
    8 a : -2/1 b : -3/2
    9 a == 0 : 0
    10 a == 1 : 0
    11 a != 0 : 1
    12 ! a : 0
    13 a != b : 1
    14 a <  b : 1
    15 a <=  b : 1
    16 a >  b : 0
    17 a >=  b : 0
    18 
     23/1 4/1 0/1 0/1 1/1
     31/2 5/7
     42/3 -3/2
     5-2/3 3/2
     6logical
     7-2/1 -3/2
     81
     91
     101
     110
     120
    1913arithmetic
    20 a : -2/1 b : -3/2
    21 a + b : -7/2
    22 a += b : -7/2
    23 ++a : -5/2
    24 a++ : -5/2
    25 a : -3/2
    26 a - b : 0/1
    27 a -= b : 0/1
    28 --a : -1/1
    29 a-- : -1/1
    30 a : -2/1
    31 a * b : 3/1
    32 a / b : 4/3
    33 a \ 2 : 4/1 b \ 2 : 9/4
    34 a \ -2 : 1/4 b \ -2 : 4/9
    35 
     14-2/1 -3/2
     15-7/2
     16-1/2
     173/1
     184/3
    3619conversion
    37200.75
     
    41241/7
    4225355/113
    43 
     26decompose
    4427more tests
    4528-3/2
  • tests/Makefile.am

    rd83b266 rc86ee4c  
    8282        concurrent/clib_tls.c \
    8383        exceptions/with-threads.hfa \
    84         exceptions/except-io.hfa \
    85         unified_locking/mutex_test.hfa
     84        exceptions/except-io.hfa
    8685
    8786dist-hook:
  • tests/counter.cfa

    rd83b266 rc86ee4c  
    1010// Created On       : Thu Feb 22 15:27:00 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 21:25:30 2021
    13 // Update Count     : 4
     12// Last Modified On : Tue Nov  6 17:50:23 2018
     13// Update Count     : 2
    1414//
    15 
    16 #include <fstream.hfa>
    1715
    1816// Tests unified increment/decrement builtin functions.
     
    2119struct counter { int x; };
    2220
    23 counter ?+=?( counter & c, one_t ) { ++c.x; return c; }
    24 counter ?-=?( counter & c, one_t ) { --c.x; return c; }
     21counter& ?+=?( counter& c, one_t ) { ++c.x; return c; }
     22
     23counter& ?-=?( counter& c, one_t ) { --c.x; return c; }
    2524
    2625int main() {
     
    2928    ++c;
    3029    c++;
    31     sout | "inc" | c.x;
     30    printf("%d\n", c.x);
    3231    c -= 1;
    3332    --c;
    3433    c--;
    35     sout | "dec" | c.x;
     34    printf("%d\n", c.x);
    3635}
    3736
  • tests/polymorphism.cfa

    rd83b266 rc86ee4c  
    5454        b.i = s.i;
    5555        return b.j;
    56 }
    57 
    58 void checkPlan9offsets() {
    59 
    60         forall( T )
    61         struct thing {
    62                 T q;                // variable-sized padding
    63                 inline double;
    64                 inline float;
    65         };
    66 
    67         #define SHOW_OFFSETS \
    68                 double & x_inner_double = x; \
    69                 float  & x_inner_float  = x; \
    70                 printf("  offset of inner double: %ld\n", ((char *) & x_inner_double) - ((char *) & x) ); \
    71                 printf("  offset of inner float:  %ld\n", ((char *) & x_inner_float ) - ((char *) & x) );
    72 
    73         void showStatic( thing(long long int) & x ) {
    74                 printf("static:\n");
    75                 SHOW_OFFSETS
    76         }
    77 
    78         forall( T )
    79         void showDynamic( thing(T) & x ) {
    80                 printf("dynamic:\n");
    81                 SHOW_OFFSETS
    82         }
    83 
    84         #undef SHOW_OFFSETS
    85 
    86         printf("=== checkPlan9offsets\n");
    87         thing(long long int) x;
    88         showStatic(x);
    89         showDynamic(x);
    9056}
    9157
     
    148114                assertf(ret == u.f2, "union operation fails in polymorphic context.");
    149115        }
    150 
    151         checkPlan9offsets();
    152116}
    153117
  • tests/rational.cfa

    rd83b266 rc86ee4c  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 20 18:13:40 2021
    13 // Update Count     : 107
     12// Last Modified On : Sat Feb  8 18:46:23 2020
     13// Update Count     : 86
    1414//
    1515
     
    2626        sout | "constructor";
    2727        RatInt a = { 3 }, b = { 4 }, c, d = 0, e = 1;
    28         sout | "a : " | a | "b : " | b | "c : " | c | "d : " | d | "e : " | e;
     28        sout | a | b | c | d | e;
    2929
    3030        a = (RatInt){ 4, 8 };
    3131        b = (RatInt){ 5, 7 };
    32         sout | "a : " | a | "b : " | b;
     32        sout | a | b;
    3333        a = (RatInt){ -2, -3 };
    3434        b = (RatInt){ 3, -2 };
    35         sout | "a : " | a | "b : " | b;
     35        sout | a | b;
    3636        a = (RatInt){ -2, 3 };
    3737        b = (RatInt){ 3, 2 };
    38         sout | "a : " | a | "b : " | b;
    39         sout | nl;
     38        sout | a | b;
    4039
    41         sout | "comparison";
     40        sout | "logical";
    4241        a = (RatInt){ -2 };
    4342        b = (RatInt){ -3, 2 };
    44         sout | "a : " | a | "b : " | b;
    45         sout | "a == 0 : " | a == (Rational(int)){0}; // FIX ME
    46         sout | "a == 1 : " | a == (Rational(int)){1}; // FIX ME
    47         sout | "a != 0 : " | a != 0;
    48         sout | "! a : " | ! a;
    49         sout | "a != b : " | a != b;
    50         sout | "a <  b : " | a <  b;
    51         sout | "a <=  b : " | a <= b;
    52         sout | "a >  b : " | a >  b;
    53         sout | "a >=  b : " | a >= b;
    54         sout | nl;
     43        sout | a | b;
     44//      sout | a == 1; // FIX ME
     45        sout | a != b;
     46        sout | a <  b;
     47        sout | a <= b;
     48        sout | a >  b;
     49        sout | a >= b;
    5550
    5651        sout | "arithmetic";
    57         sout | "a : " | a | "b : " | b;
    58         sout | "a + b : " | a + b;
    59         sout | "a += b : " | (a += b);
    60         sout | "++a : " | ++a;
    61         sout | "a++ : " | a++;
    62         sout | "a : " | a;
    63         sout | "a - b : " | a - b;
    64         sout | "a -= b : " | (a -= b);
    65         sout | "--a : " | --a;
    66         sout | "a-- : " | a--;
    67         sout | "a : " | a;
    68         sout | "a * b : " | a * b;
    69         sout | "a / b : " | a / b;
    70         sout | "a \\ 2 : " | a \ 2u | "b \\ 2 : " | b \ 2u;
    71         sout | "a \\ -2 : " | a \ -2 | "b \\ -2 : " | b \ -2;
    72         sout | nl;
     52        sout | a | b;
     53        sout | a + b;
     54        sout | a - b;
     55        sout | a * b;
     56        sout | a / b;
     57//      sout | a \ 2 | b \ 2; // FIX ME
     58//      sout | a \ -2 | b \ -2;
    7359
    7460        sout | "conversion";
     
    8268        sout | narrow( 0.14285714285714, 16 );
    8369        sout | narrow( 3.14159265358979, 256 );
    84         sout | nl;
    8570
    86         // sout | "decompose";
    87         // int n, d;
    88         // [n, d] = a;
    89         // sout | a | n | d;
     71        sout | "decompose";
     72        int n, d;
     73//      [n, d] = a;
     74//      sout | a | n | d;
    9075
    9176        sout | "more tests";
  • tests/unified_locking/fast.cfa

    rd83b266 rc86ee4c  
     1#include <fstream.hfa>
    12#include <locks.hfa>
     3#include <thread.hfa>
    24
    3 #define LOCK fast_lock
    4 #include "mutex_test.hfa"
     5const unsigned int num_times = 50;
     6
     7struct MutexObj {
     8        fast_lock l;
     9        thread$ * id;
     10        uint32_t sum;
     11};
     12
     13MutexObj mo;
     14
     15void trash() {
     16        unsigned t[100];
     17        for(i; 100) {
     18                t[i] = 0xDEADBEEF;
     19        }
     20}
     21
     22uint32_t cs() {
     23        thread$ * me = active_thread();
     24        uint32_t value;
     25        lock(mo.l);
     26        {
     27                uint32_t tsum = mo.sum;
     28                mo.id = me;
     29                yield(random(5));
     30                value = ((uint32_t)random()) ^ ((uint32_t)me);
     31                if(mo.id != me) sout | "Intruder!";
     32                mo.sum = tsum + value;
     33        }
     34        unlock(mo.l);
     35        return value;
     36}
     37
     38thread LockCheck {
     39        uint32_t sum;
     40};
     41
     42void main(LockCheck & this) {
     43        this.sum = 0;
     44        for(num_times) {
     45                trash();
     46                this.sum += cs();
     47                trash();
     48                yield(random(10));
     49        }
     50}
    551
    652int main() {
    7     test();
     53        uint32_t sum = -32;
     54        mo.sum = -32;
     55        processor p[2];
     56        sout | "Starting";
     57        {
     58                LockCheck checkers[13];
     59                for(i;13) {
     60                        sum += join(checkers[i]).sum;
     61                }
     62        }
     63        sout | "Done!";
     64        if(sum == mo.sum) sout | "Match!";
     65        else sout | "No Match!" | sum | "vs" | mo.sum;
    866}
  • tests/unified_locking/thread_test.cfa

    rd83b266 rc86ee4c  
    88static unsigned int threadCount = 2;
    99static unsigned int lockCount = 1;
    10 static unsigned int total_times = 320000;
    11 static unsigned int num_times;
     10static unsigned int num_times = 10000;
    1211static const int workBufferSize = 16;
    1312static unsigned int work_unlocked = 10000;
     
    2625thread worker {
    2726    linear_backoff_then_block_lock * locks;
    28     bool improved;
    2927};
    3028
    31 void ?{}( worker & w, linear_backoff_then_block_lock * locks, bool improved ) {
     29void ?{}( worker & w, linear_backoff_then_block_lock * locks ) {
    3230        w.locks = locks;
    33     w.improved = improved;
    3431}
    3532
     33linear_backoff_then_block_lock norm_lock;
    3634
    3735void main( worker & this ) with(this) {
     
    3937    for (int i = 0; i < workBufferSize; i += 1) buffer[i] = rand() % 1024;
    4038    unsigned int lck = rand() % lockCount;
    41     linear_backoff_then_block_lock * curr_lock = &locks[lck];
     39    linear_backoff_then_block_lock * curr_lock = locks;//[lck];
    4240    for (unsigned int i = 0; i < num_times; i++) {
    4341        dowork(buffer, work_unlocked);
    44         if (improved) lock_improved(*curr_lock);
    45         else lock(*curr_lock);
     42        lock(*curr_lock);
     43        //printf("lock: %d %p ENTER\n", i, &curr_lock);
     44        //lock(norm_lock);
    4645        dowork(buffer, work_locked);
     46        //printf("lock: %d %p LEAVE\n", i, &curr_lock);
    4747        unlock(*curr_lock);
     48        //unlock(norm_lock);
    4849        lck = rand() % lockCount;
    49         curr_lock = &locks[lck];
     50        //curr_lock = locks[lck];
    5051    }
    5152}
    5253
    53 
    5454int main(int argc, char* argv[]) {
    5555    switch (argc) {
    56         case 7:
    57             work_unlocked = atoi(argv[5]);
    58         case 6:
    59             work_locked = atoi(argv[5]);
    6056        case 5:
    6157            num_times = atoi(argv[4]);
     
    7268    }
    7369        processor p[threadCount];
    74     linear_backoff_then_block_lock locks[lockCount];
     70    linear_backoff_then_block_lock locks;//[lockCount];
     71    printf("lock allocation address: %p \n", &locks);
    7572    worker * worker_arr[taskCount];
    76     num_times = total_times  / taskCount;
    7773
    78         //printf("Start Test: martin lock simple\n");
     74        printf("Start Test: martin lock simple\n");
    7975        clock_t begin = clock();
    8076        for (unsigned int i = 0; i < taskCount; i++) {
    81         worker_arr[i] = new( locks, false );
     77        worker_arr[i] = new( &locks );
    8278    }
    8379    for (unsigned int i = 0; i < taskCount; i++) {
    84         delete( worker_arr[i] );
     80        free( worker_arr[i] );
    8581    }
    8682        clock_t end = clock();
    8783        double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    88         printf("norm: %f\n", time_spent);
    89 
    90     //printf("Start Test: martin lock improved\n");
    91         begin = clock();
    92         for (unsigned int i = 0; i < taskCount; i++) {
    93         worker_arr[i] = new( locks, true );
    94     }
    95     for (unsigned int i = 0; i < taskCount; i++) {
    96         delete( worker_arr[i] );
    97     }
    98         end = clock();
    99         time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
    100         printf("improved: %f\n", time_spent);
     84        printf("Done Test, time: %f\n", time_spent);
    10185}
Note: See TracChangeset for help on using the changeset viewer.