Changeset 4bd3069


Ignore:
Timestamp:
Aug 19, 2018, 10:21:35 AM (3 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer
Children:
90ed538
Parents:
90cac45 (diff), 72a5a75 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into demangler

Files:
1 added
19 edited
2 moved

Legend:

Unmodified
Added
Removed
  • Jenkins/FullBuild

    r90cac45 r4bd3069  
    6161                parameters: [                                           \
    6262                        [$class: 'StringParameterValue',                \
    63                           name: 'pCompiler',                            \
     63                          name: 'Compiler',                             \
    6464                          value: cc],                                   \
    6565                        [$class: 'StringParameterValue',                \
    66                           name: 'pArchitecture',                        \
     66                          name: 'Architecture',                         \
    6767                          value: arch],                                 \
    6868                        [$class: 'BooleanParameterValue',               \
    69                           name: 'pRunAllTests',                         \
     69                          name: 'RunAllTests',                          \
    7070                          value: true],                                         \
    7171                        [$class: 'BooleanParameterValue',               \
    72                           name: 'pRunBenchmark',                        \
     72                          name: 'RunBenchmark',                         \
    7373                          value: true],                                         \
    7474                        [$class: 'BooleanParameterValue',               \
    75                           name: 'pBuildDocumentation',          \
     75                          name: 'BuildDocumentation',           \
    7676                          value: true],                                         \
    7777                        [$class: 'BooleanParameterValue',               \
    78                           name: 'pPublish',                             \
    79                           value: publish],                                      \
     78                          name: 'Publish',                              \
     79                          value: publish],                              \
    8080                        [$class: 'BooleanParameterValue',               \
    81                           name: 'pSilent',                              \
     81                          name: 'Silent',                               \
    8282                          value: true],                                         \
    8383                ],                                                              \
  • Jenkinsfile

    r90cac45 r4bd3069  
    66node ('master'){
    77
    8         boolean bIsSandbox = env.BRANCH_NAME == "jenkins-sandbox"
     8        // Globals
     9        BuildDir  = pwd tmp: true
     10        SrcDir    = pwd tmp: false
     11        Settings  = null
     12        StageName = ''
     13
     14        // Local variables
    915        def err = null
    1016        def log_needed = false
    11 
    12         stage_name              = ''
    13 
    14         compiler                = null
    15         arch_name               = ''
    16         architecture    = ''
    17 
    18         do_alltests             = false
    19         do_benchmark    = false
    20         do_doc          = false
    21         do_publish              = false
    22         do_sendemail    = true
    23 
    24         builddir = pwd tmp: true
    25         srcdir   = pwd tmp: false
    2617
    2718        currentBuild.result = "SUCCESS"
     
    3324                        notify_server(0)
    3425
    35                         prepare_build()
     26                        Settings = prepare_build()
    3627
    3728                        clean()
     
    6152                err = caughtError
    6253
     54                echo err.toString()
     55
    6356                //An error has occured, the build log is relevent
    6457                log_needed = true
    6558
    6659                //Store the result of the build log
    67                 currentBuild.result = "${stage_name} FAILURE".trim()
     60                currentBuild.result = "${StageName} FAILURE".trim()
    6861        }
    6962
    7063        finally {
    7164                //Send email with final results if this is not a full build
    72                 if( do_sendemail ) {
    73                         echo 'Notifying users of result'
    74                         email(currentBuild.result, log_needed, bIsSandbox)
     65                if( Settings && !Settings.Silent ) {
     66                        email(log_needed, Settings.IsSandbox)
    7567                }
    7668
     
    8577
    8678//===========================================================================================================
    87 // Helper classes/variables/routines
    88 //===========================================================================================================
    89 //Helper routine to collect information about the git history
    90 def collect_git_info() {
    91 
    92         checkout scm
    93 
    94         //create the temporary output directory in case it doesn't already exist
    95         def out_dir = pwd tmp: true
    96         sh "mkdir -p ${out_dir}"
    97 
    98         //parse git logs to find what changed
    99         gitRefName = env.BRANCH_NAME
    100         sh "git reflog > ${out_dir}/GIT_COMMIT"
    101         git_reflog = readFile("${out_dir}/GIT_COMMIT")
    102         gitRefOldValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][1]
    103         gitRefNewValue = (git_reflog =~ /moving from (.+) to (.+)/)[0][2]
    104 }
    105 
    106 def prepare_build() {
    107         properties ([                                                                                                   \
    108                 [$class: 'ParametersDefinitionProperty',                                                                \
    109                         parameterDefinitions: [                                                                         \
    110                                 [$class: 'ChoiceParameterDefinition',                                           \
    111                                         description: 'Which compiler to use',                                   \
    112                                         name: 'pCompiler',                                                              \
    113                                         choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
    114                                         defaultValue: 'gcc-6',                                                          \
    115                                 ],                                                                                              \
    116                                 [$class: 'ChoiceParameterDefinition',                                           \
    117                                         description: 'The target architecture',                                 \
    118                                         name: 'pArchitecture',                                                          \
    119                                         choices: 'x64\nx86',                                                            \
    120                                         defaultValue: 'x64',                                                            \
    121                                 ],                                                                                              \
    122                                 [$class: 'BooleanParameterDefinition',                                                  \
    123                                         description: 'If false, only the quick test suite is ran',              \
    124                                         name: 'pRunAllTests',                                                           \
    125                                         defaultValue: false,                                                            \
    126                                 ],                                                                                              \
    127                                 [$class: 'BooleanParameterDefinition',                                                  \
    128                                         description: 'If true, jenkins also runs benchmarks',           \
    129                                         name: 'pRunBenchmark',                                                          \
    130                                         defaultValue: false,                                                            \
    131                                 ],                                                                                              \
    132                                 [$class: 'BooleanParameterDefinition',                                                  \
    133                                         description: 'If true, jenkins also builds documentation',              \
    134                                         name: 'pBuildDocumentation',                                                    \
    135                                         defaultValue: true,                                                             \
    136                                 ],                                                                                              \
    137                                 [$class: 'BooleanParameterDefinition',                                                  \
    138                                         description: 'If true, jenkins also publishes results',                 \
    139                                         name: 'pPublish',                                                               \
    140                                         defaultValue: false,                                                            \
    141                                 ],                                                                                              \
    142                                 [$class: 'BooleanParameterDefinition',                                                  \
    143                                         description: 'If true, jenkins will not send emails',           \
    144                                         name: 'pSilent',                                                                        \
    145                                         defaultValue: false,                                                            \
    146                                 ],                                                                                              \
    147                         ],
    148                 ]])
    149 
    150         compiler                = compiler_from_params( pCompiler )
    151         arch_name               = pArchitecture
    152         architecture    = architecture_from_params( arch_name )
    153 
    154         do_alltests             = (pRunAllTests == 'true')
    155         do_benchmark    = (pRunBenchmark == 'true')
    156         do_doc          = (pBuildDocumentation == 'true')
    157         do_publish              = (pPublish == 'true')
    158         do_sendemail    = ! (pSilent == 'true')
    159 
    160         collect_git_info()
    161 
    162         def full = do_alltests ? " (Full)" : ""
    163         currentBuild.description = "${compiler.cc_name}:${arch_name}${full}"
    164 
    165         echo """Compiler              : ${compiler.cc_name} (${compiler.cpp_cc}/${compiler.cfa_cc})
    166 Architecture            : ${arch_name}
    167 Arc Flags               : ${architecture}
    168 Run All Tests           : ${ pRunAllTests.toString() }
    169 Run Benchmark           : ${ pRunBenchmark.toString() }
    170 Build Documentation     : ${ pBuildDocumentation.toString() }
    171 Publish                 : ${ pPublish.toString() }
    172 Silent                  : ${ pSilent.toString() }
    173 """
    174 }
    175 
    176 def build_stage(String name, Closure block ) {
    177         stage_name = name
    178         stage(name, block)
    179 }
    180 
    181 def notify_server(int wait) {
    182         sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
    183         return
    184 }
    185 
    186 def make_doc() {
    187         def err = null
    188         try {
    189                 sh 'make clean > /dev/null'
    190                 sh 'make > /dev/null 2>&1'
    191         }
    192         catch (Exception caughtError) {
    193                 err = caughtError //rethrow error later
    194                 sh 'cat *.log'
    195         }
    196         finally {
    197                 if (err) throw err // Must re-throw exception to propagate error
    198         }
    199 }
    200 
    201 //Description of a compiler (Must be serializable since pipelines are persistent)
    202 class CC_Desc implements Serializable {
    203         public String cc_name
    204         public String cpp_cc
    205         public String cfa_cc
    206 
    207         CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
    208                 this.cc_name = cc_name
    209                 this.cpp_cc = cpp_cc
    210                 this.cfa_cc = cfa_cc
    211         }
    212 }
    213 
    214 def compiler_from_params(cc) {
    215         switch( cc ) {
    216                 case 'gcc-6':
    217                         return new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
    218                 break
    219                 case 'gcc-5':
    220                         return new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
    221                 break
    222                 case 'gcc-4.9':
    223                         return new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
    224                 break
    225                 case 'clang':
    226                         return new CC_Desc('clang', 'clang++', 'gcc-6')
    227                 break
    228                 default :
    229                         error "Unhandled compiler : ${cc}"
    230         }
    231 }
    232 
    233 def architecture_from_params( arch ) {
    234         switch( arch ) {
    235                 case 'x64':
    236                         return '--host=x86_64'
    237                 break
    238                 case 'x86':
    239                         return '--host=i386'
    240                 break
    241                 default :
    242                         error "Unhandled architecture : ${arch}"
    243         }
    244 }
    245 
    246 //===========================================================================================================
    24779// Main compilation routines
    24880//===========================================================================================================
     
    25082        build_stage('Cleanup') {
    25183                // clean the build by wipping the build directory
    252                 dir(builddir) {
     84                dir(BuildDir) {
    25385                        deleteDir()
    25486                }
    255 
    256                 //Clean all temporary files to make sure no artifacts of the previous build remain
    257                 sh 'git clean -fdqx'
    258 
    259                 //Reset the git repo so no local changes persist
    260                 sh 'git reset --hard'
    26187        }
    26288}
     
    26692        build_stage('Checkout') {
    26793                //checkout the source code and clean the repo
    268                 checkout scm
     94                final scmVars = checkout scm
     95                Settings.GitNewRef = scmVars.GIT_COMMIT
     96                Settings.GitOldRef = scmVars.GIT_PREVIOUS_COMMIT
     97
     98                echo GitLogMessage()
    26999        }
    270100}
     
    273103        build_stage('Build') {
    274104                // Build outside of the src tree to ease cleaning
    275                 dir (builddir) {
     105                dir (BuildDir) {
    276106                        //Configure the conpilation (Output is not relevant)
    277107                        //Use the current directory as the installation target so nothing escapes the sandbox
    278108                        //Also specify the compiler by hand
    279109                        targets=""
    280                         if(do_alltests) {
     110                        if( Settings.RunAllTests ) {
    281111                                targets="--with-target-hosts='host:debug,host:nodebug'"
    282112                        } else {
     
    284114                        }
    285115
    286                         sh "${srcdir}/configure CXX=${compiler.cpp_cc} ${architecture} ${targets} --with-backend-compiler=${compiler.cfa_cc} --quiet"
     116                        sh "${SrcDir}/configure CXX=${Settings.Compiler.cpp_cc} ${Settings.Architecture.flags} ${targets} --with-backend-compiler=${Settings.Compiler.cfa_cc} --quiet"
    287117
    288118                        //Compile the project
     
    295125        build_stage('Test') {
    296126
    297                 dir (builddir) {
     127                dir (BuildDir) {
    298128                        //Run the tests from the tests directory
    299                         if ( do_alltests ) {
     129                        if ( Settings.RunAllTests ) {
    300130                                sh 'make --no-print-directory -C tests all-tests debug=yes'
    301131                                sh 'make --no-print-directory -C tests all-tests debug=no '
     
    311141        build_stage('Benchmark') {
    312142
    313                 if( !do_benchmark ) return
    314 
    315                 dir (builddir) {
     143                if( !Settings.RunBenchmark ) return
     144
     145                dir (BuildDir) {
    316146                        //Append bench results
    317                         sh "make --no-print-directory -C benchmark jenkins githash=${gitRefNewValue} arch=${arch_name} | tee ${srcdir}/bench.json"
     147                        sh "make --no-print-directory -C benchmark jenkins githash=${Settings.GitNewRef} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
    318148                }
    319149        }
     
    323153        build_stage('Documentation') {
    324154
    325                 if( !do_doc ) return
     155                if( !Settings.BuildDocumentation ) return
    326156
    327157                dir ('doc/user') {
     
    338168        build_stage('Publish') {
    339169
    340                 if( !do_publish ) return
     170                if( !Settings.Publish ) return
    341171
    342172                //Then publish the results
     
    348178//Routine responsible of sending the email notification once the build is completed
    349179//===========================================================================================================
    350 def gitBranchUpdate(String gitRefOldValue, String gitRefNewValue) {
    351         def update = ""
    352         sh "git rev-list ${gitRefOldValue}..${gitRefNewValue} > GIT_LOG";
    353         readFile('GIT_LOG').eachLine { rev ->
    354                 sh "git cat-file -t ${rev} > GIT_TYPE"
    355                 def type = readFile('GIT_TYPE')
    356 
    357                 update += "       via  ${rev} (${type})\n"
    358         }
    359         def rev = gitRefOldValue
    360         sh "git cat-file -t ${rev} > GIT_TYPE"
    361         def type = readFile('GIT_TYPE')
    362 
    363         update += "      from  ${rev} (${type})\n"
    364         return update
    365 
    366 def output=readFile('result').trim()
    367 echo "output=$output";
    368 }
    369 
    370 //Standard build email notification
    371 def email(String status, boolean log, boolean bIsSandbox) {
    372         //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
    373         //Configurations for email format
    374         def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
    375 
    376         def gitLog = 'Error retrieving git logs'
    377         def gitDiff = 'Error retrieving git diff'
    378         def gitUpdate = 'Error retrieving update'
    379 
    380         try {
    381                 gitUpdate = gitBranchUpdate(gitRefOldValue, gitRefNewValue)
    382 
    383                 sh "git rev-list --format=short ${gitRefOldValue}...${gitRefNewValue} > GIT_LOG"
    384                 gitLog = readFile('GIT_LOG')
    385 
    386                 sh "git diff --stat ${gitRefNewValue} ${gitRefOldValue} > GIT_DIFF"
    387                 gitDiff = readFile('GIT_DIFF')
    388         }
    389         catch (Exception error) {
    390                 echo error.toString()
    391                 echo error.getMessage()
    392         }
    393 
    394         def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${status}] - branch ${env.BRANCH_NAME}"
    395         def email_body = """This is an automated email from the Jenkins build machine. It was
    396 generated because of a git hooks/post-receive script following
    397 a ref change was pushed to the repository containing
    398 the project "UNNAMED PROJECT".
    399 
     180def GitLogMessage() {
     181        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
     182
     183        sh "${SrcDir}/tools/PrettyGitLogs.sh ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
     184
     185        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
     186        def gitLog    = readFile("${BuildDir}/GIT_LOG")
     187        def gitDiff   = readFile("${BuildDir}/GIT_DIFF")
     188
     189        return """
    400190The branch ${env.BRANCH_NAME} has been updated.
    401191${gitUpdate}
     
    405195- Status --------------------------------------------------------------
    406196
    407 BUILD# ${env.BUILD_NUMBER} - ${status}
     197BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}
    408198
    409199- Log -----------------------------------------------------------------
     
    413203${gitDiff}
    414204"""
     205}
     206
     207//Standard build email notification
     208def email(boolean log, boolean bIsSandbox) {
     209        //Since tokenizer doesn't work, figure stuff out from the environnement variables and command line
     210        //Configurations for email format
     211        echo 'Notifying users of result'
     212
     213        def project_name = (env.JOB_NAME =~ /(.+)\/.+/)[0][1].toLowerCase()
     214        def email_subject = "[${project_name} git][BUILD# ${env.BUILD_NUMBER} - ${currentBuild.result}] - branch ${env.BRANCH_NAME}"
     215        def email_body = """This is an automated email from the Jenkins build machine. It was
     216generated because of a git hooks/post-receive script following
     217a ref change which was pushed to the Cforall repository.
     218""" + GitLogMessage()
    415219
    416220        def email_to = "cforall@lists.uwaterloo.ca"
    417221
    418         if( !bIsSandbox ) {
     222        if( Settings && !Settings.IsSandbox ) {
    419223                //send email notification
    420224                emailext body: email_body, subject: email_subject, to: email_to, attachLog: log
     
    425229        }
    426230}
     231
     232//===========================================================================================================
     233// Helper classes/variables/routines
     234//===========================================================================================================
     235//Description of a compiler (Must be serializable since pipelines are persistent)
     236class CC_Desc implements Serializable {
     237        public String cc_name
     238        public String cpp_cc
     239        public String cfa_cc
     240
     241        CC_Desc(String cc_name, String cpp_cc, String cfa_cc) {
     242                this.cc_name = cc_name
     243                this.cpp_cc = cpp_cc
     244                this.cfa_cc = cfa_cc
     245        }
     246}
     247
     248//Description of an architecture (Must be serializable since pipelines are persistent)
     249class Arch_Desc implements Serializable {
     250        public String name
     251        public String flags
     252
     253        Arch_Desc(String name, String flags) {
     254                this.name  = name
     255                this.flags = flags
     256        }
     257}
     258
     259class BuildSettings implements Serializable {
     260        public final CC_Desc Compiler
     261        public final Arch_Desc Architecture
     262        public final Boolean RunAllTests
     263        public final Boolean RunBenchmark
     264        public final Boolean BuildDocumentation
     265        public final Boolean Publish
     266        public final Boolean Silent
     267        public final Boolean IsSandbox
     268        public final String DescLong
     269        public final String DescShort
     270
     271        public String GitNewRef
     272        public String GitOldRef
     273
     274        BuildSettings(java.util.Collections$UnmodifiableMap param, String branch) {
     275                switch( param.Compiler ) {
     276                        case 'gcc-6':
     277                                this.Compiler = new CC_Desc('gcc-6', 'g++-6', 'gcc-6')
     278                        break
     279                        case 'gcc-5':
     280                                this.Compiler = new CC_Desc('gcc-5', 'g++-5', 'gcc-5')
     281                        break
     282                        case 'gcc-4.9':
     283                                this.Compiler = new CC_Desc('gcc-4.9', 'g++-4.9', 'gcc-4.9')
     284                        break
     285                        case 'clang':
     286                                this.Compiler = new CC_Desc('clang', 'clang++', 'gcc-6')
     287                        break
     288                        default :
     289                                error "Unhandled compiler : ${cc}"
     290                }
     291
     292                switch( param.Architecture ) {
     293                        case 'x64':
     294                                this.Architecture = new Arch_Desc('x64', '--host=x86_64')
     295                        break
     296                        case 'x86':
     297                                this.Architecture = new Arch_Desc('x86', '--host=i386')
     298                        break
     299                        default :
     300                                error "Unhandled architecture : ${arch}"
     301                }
     302
     303                this.RunAllTests        = param.RunAllTests
     304                this.RunBenchmark       = param.RunBenchmark
     305                this.BuildDocumentation = param.BuildDocumentation
     306                this.Publish            = param.Publish
     307                this.Silent             = param.Silent
     308                this.IsSandbox          = (branch == "jenkins-sandbox")
     309
     310                def full = param.RunAllTests ? " (Full)" : ""
     311                this.DescShort = "${ this.Compiler.cc_name }:${ this.Architecture.name }${full}"
     312
     313                this.DescLong = """Compiler              : ${ this.Compiler.cc_name } (${ this.Compiler.cpp_cc }/${ this.Compiler.cfa_cc })
     314Architecture            : ${ this.Architecture.name }
     315Arc Flags               : ${ this.Architecture.flags }
     316Run All Tests           : ${ this.RunAllTests.toString() }
     317Run Benchmark           : ${ this.RunBenchmark.toString() }
     318Build Documentation     : ${ this.BuildDocumentation.toString() }
     319Publish                 : ${ this.Publish.toString() }
     320Silent                  : ${ this.Silent.toString() }
     321"""
     322
     323                this.GitNewRef = ''
     324                this.GitOldRef = ''
     325        }
     326}
     327
     328def prepare_build() {
     329        // prepare the properties
     330        properties ([                                                                                                   \
     331                [$class: 'ParametersDefinitionProperty',                                                                \
     332                        parameterDefinitions: [                                                                         \
     333                                [$class: 'ChoiceParameterDefinition',                                           \
     334                                        description: 'Which compiler to use',                                   \
     335                                        name: 'Compiler',                                                                       \
     336                                        choices: 'gcc-6\ngcc-5\ngcc-4.9\nclang',                                        \
     337                                        defaultValue: 'gcc-6',                                                          \
     338                                ],                                                                                              \
     339                                [$class: 'ChoiceParameterDefinition',                                           \
     340                                        description: 'The target architecture',                                 \
     341                                        name: 'Architecture',                                                           \
     342                                        choices: 'x64\nx86',                                                            \
     343                                        defaultValue: 'x64',                                                            \
     344                                ],                                                                                              \
     345                                [$class: 'BooleanParameterDefinition',                                                  \
     346                                        description: 'If false, only the quick test suite is ran',              \
     347                                        name: 'RunAllTests',                                                            \
     348                                        defaultValue: false,                                                            \
     349                                ],                                                                                              \
     350                                [$class: 'BooleanParameterDefinition',                                                  \
     351                                        description: 'If true, jenkins also runs benchmarks',           \
     352                                        name: 'RunBenchmark',                                                           \
     353                                        defaultValue: false,                                                            \
     354                                ],                                                                                              \
     355                                [$class: 'BooleanParameterDefinition',                                                  \
     356                                        description: 'If true, jenkins also builds documentation',              \
     357                                        name: 'BuildDocumentation',                                                     \
     358                                        defaultValue: true,                                                             \
     359                                ],                                                                                              \
     360                                [$class: 'BooleanParameterDefinition',                                                  \
     361                                        description: 'If true, jenkins also publishes results',                 \
     362                                        name: 'Publish',                                                                        \
     363                                        defaultValue: false,                                                            \
     364                                ],                                                                                              \
     365                                [$class: 'BooleanParameterDefinition',                                                  \
     366                                        description: 'If true, jenkins will not send emails',           \
     367                                        name: 'Silent',                                                                         \
     368                                        defaultValue: false,                                                            \
     369                                ],                                                                                              \
     370                        ],
     371                ]])
     372
     373        final settings = new BuildSettings(params, env.BRANCH_NAME)
     374
     375        currentBuild.description = settings.DescShort
     376        echo                       settings.DescLong
     377
     378        return settings
     379}
     380
     381def build_stage(String name, Closure block ) {
     382        StageName = name
     383        echo " -------- ${StageName} -------- "
     384        stage(name, block)
     385}
     386
     387def notify_server(int wait) {
     388        sh """curl --silent --show-error --data "wait=${wait}" -X POST https://cforall.uwaterloo.ca:8082/jenkins/notify > /dev/null || true"""
     389        return
     390}
     391
     392def make_doc() {
     393        def err = null
     394        try {
     395                sh 'make clean > /dev/null'
     396                sh 'make > /dev/null 2>&1'
     397        }
     398        catch (Exception caughtError) {
     399                err = caughtError //rethrow error later
     400                sh 'cat *.log'
     401        }
     402        finally {
     403                if (err) throw err // Must re-throw exception to propagate error
     404        }
     405}
  • examples/Tuple.c

    r90cac45 r4bd3069  
    11int f( int, int );
    22int g( int, int, int );
    3 static [ int, int *, * int, int ] h( int a, int b, * int c, [] char d );
     3static
     4[ int, int *, * int, int ] h( int a, int b, * int c, [] char d );
    45
    56struct inner {
     
    1415
    1516const volatile [ int, int ] t1;
    16 static const [ int, const int ] t2;
     17static const [ int, int ] t2;
    1718const static [ int, const int ] t3;
    1819
     
    2122
    2223[ short x, unsigned y ] f1( int w ) {
    23         [ y, x ] = [ x, y ] = [ w, 23 ];
     24//      return [ y, x ] = [ x, y ] = [ w, 23 ];
    2425}
    2526
    2627[ [ int, char, long, int ] r ] g1() {
    27         short x, p;
     28        short int x, p;
    2829        unsigned int y;
    2930        [ int, int ] z;
    3031
    31         [ x, y, z ] = [ p, f( 17 ), 3 ];
    32         [ x, y, z ] = ([short, unsigned int, [int, int]])([ p, f( 17 ), 3 ]);
     32        [ x, y, z ] = [ p, f( 17, 18 ), 4, 3 ];
     33//      [ x, y, z ] = ([short, unsigned int, [int, int]])([ p, f( 17, 18 ), 4, 3 ]);
    3334        r = [ x, y, z ];
    3435}
     
    3637[ int rc ] main( int argc, ** char argv ) {
    3738        int a, b, c, d;
    38         struct outer t = { .[ f1,f4 ] : [ 1,7.0 ] };
     39//      struct outer t = { .[ f1, f4 ] : [ 1, 7.0 ] };
    3940        f( [ 3,5 ] );
    4041        g( [ 3,5 ], 3 );
     
    4243        g( t1, 3 );
    4344
    44         [ , , , ];                                              /* empty tuple */
     45//      [ , , , ];                                              /* empty tuple */
    4546        [ 3, 5 ];
    4647        [ a, b ] = 3;
    47         [ a, b ] = [ 4.6 ];
     48//      [ a, b ] = [ 4.6 ];
     49        [ a, b ] = 4.6;
    4850        [ a, b ] = [ c, d ] = [ 3, 5 ];
    49         [ a, b, [ c ] ] = [ 2,[ a, b ] ];
     51//      [ a, b, [ c ] ] = [ 2, [ a, b ] ];
     52        [ a, b, c ] = [ 2, [ a, b ] ];
    5053        [ a, b ] = 3 > 4 ? [ b, 6 ] : [ 7, 8 ];
    5154
     
    5659        [ a, b ] = t1 = [ c, d ];
    5760        [ a, b ] = t1 = t2 = [ c, d ];
    58         t1 = [ 3, 4 ] = [ 3, 4 ] = t1 = [ 3, 4 ];
     61//      t1 = [ 3, 4 ] = [ 3, 4 ] = t1 = [ 3, 4 ];
    5962
    6063        s.[ f1, i.[ f2, f3 ], f4 ] = [ 11, 12, 13, 3.14159 ];
    61         s.[ f1, i.[ f2, f3 ], f4 ] = h( 3, 3, 0, "abc" );
    62         [ a, , b, ] = h( 3, 3, 0, "abc" );                      /* ignore some results */
    63         sp->[ f4,f1 ] = sp->[ f1, f4 ];
     64//      s.[ f1, i.[ f2, f3 ], f4 ] = h( 3, 3, (* int)0, "abc" );
     65//      [ a, , b, ] = h( 3, 3, 0, "abc" );                      /* ignore some results */
     66        sp->[ f4, f1 ] = sp->[ f1, f4 ];
    6467        printf( "expecting 3, 17, 23, 4; got %d, %d, %d, %d\n", s.[ f4, i.[ f3, f2 ], f1 ] );
    6568        rc = 0;
  • examples/includes.c

    r90cac45 r4bd3069  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 12 17:59:25 2016
    13 // Update Count     : 371
     12// Last Modified On : Wed Nov 15 23:06:24 2017
     13// Update Count     : 597
    1414//
    1515
     
    2222#endif // __CFA__
    2323
    24 #if 0
    2524#if 1
    2625#define _GNU_SOURCE
     26#include <a.out.h>
    2727#include <aio.h>
    28 #include <a.out.h>
    2928#include <aliases.h>
    3029#include <alloca.h>
     
    3433#include <argz.h>
    3534#include <assert.h>
    36 #include <bfd.h>
    37 #include <bfdlink.h>
     35//#include <bfd.h>
     36// #include <bfdlink.h>                         // keyword with
    3837#include <byteswap.h>
     38#include <bzlib.h>
    3939#include <cblas.h>
    4040#include <cblas_f77.h>
    4141#include <complex.h>
     42#include <com_err.h>
    4243#include <cpio.h>
    4344#include <crypt.h>
    4445#include <ctype.h>
    4546#include <curses.h>
    46 //#include <demangle.h>
    4747#include <dialog.h>
    4848#include <dirent.h>
    4949#include <dis-asm.h>
    50 #endif
    51 #if 0
    5250#include <dlfcn.h>
    5351#include <dlg_colors.h>
     
    6361#include <evdns.h>
    6462#include <event.h>
    65 #include <evhttp.h>
    66 #endif
    67 #if 0
    68 #include <evrpc.h>
    69 #include <evutil.h>
    70 #include <execinfo.h>
    71 #include <expat.h>
    72 #include <expat_config.h>
    73 #include <expat_external.h>
    74 #include <fcntl.h>
    75 #include <features.h>
    76 #include <fenv.h>
    77 #include <float.h>
    78 #include <fmtmsg.h>
    79 #include <fnmatch.h>
    80 #include <form.h>
    81 #include <fpu_control.h>
    82 #include <fstab.h>
    83 //#include <ft2build.h>
    84 #include <fts.h>
    85 #include <ftw.h>
    86 #include <gconv.h>
    87 //#include <gcrypt.h>
    88 //#include <gcrypt-module.h>
    89 #include <getopt.h>
    90 //#include <gettext-po.h>
    91 #include <glob.h>
    92 //#include <gmp.h>                      // infinite loop
    93 ////#include <gmpxx.h>
    94 //#include <gmp-x86_64.h>
    95 #include <gnu-versions.h>
    96 //#include <gpg-error.h>
    97 #include <grp.h>
    98 #include <gshadow.h>
    99 #include <iconv.h>
    100 #include <idna.h>
    101 #include <idn-free.h>
    102 #include <idn-int.h>
    103 #include <ieee754.h>
    104 #include <ifaddrs.h>
    105 #include <inttypes.h>
    106 #include <iso646.h>
    107 #include <jerror.h>
     63
     64// #include <evhttp.h>
     65// #include <sys/queue.h>
     66// #include <evrpc.h>                                   // evrpc.h depends on sys/queue.h
     67// #include <evutil.h>
     68// #include <execinfo.h>
     69// #include <expat.h>
     70// #include <expat_config.h>
     71// #include <expat_external.h>
     72// #include <fcntl.h>
     73// #include <features.h>
     74// #include <fenv.h>
     75// #include <fmtmsg.h>
     76// #include <fnmatch.h>
     77// #include <form.h>
     78// #include <fpu_control.h>
     79// #include <fstab.h>
     80// #include <fts.h>
     81// #include <ftw.h>
     82// #include <gconv.h>
     83// #include <getopt.h>
     84// #include <gettext-po.h>
     85// #include <glob.h>
     86// #include <gmp.h>
     87// #include <gnu-versions.h>
     88// #include <grp.h>
     89// #include <gshadow.h>
     90// #include <gssapi.h>
     91// #include <hwloc.h>                                   // keyword thread (setjmp)
     92// #include <iconv.h>
     93// #include <idna.h>
     94// #include <idn-free.h>
     95// #include <idn-int.h>
     96// #include <idn-int.h>
     97// #include <ifaddrs.h>
     98// #include <inttypes.h>
     99// #include <jerror.h>
     100
    108101//#include <jmorecfg.h>
    109102//#include <jpegint.h>
    110 //#include <jpeglib.h>
    111 #include <limits.h>
    112 #include <locale.h>
    113 #include <math.h>
    114 #include <ncurses.h>
     103// #include <jpeglib.h>
     104// #include <kdb.h>
     105// #include <krb5.h>                                    // keyword enable
     106// #include <langinfo.h>
     107// #include <lastlog.h>
     108// #include <lber.h>
     109// #include <lber_types.h>
     110// #include <ldap.h>
     111// #include <ldap_cdefs.h>
     112// #include <ldap_features.h>
     113// #include <ldap_schema.h>
     114// #include <ldap_utf8.h>
     115// #include <ldif.h>
     116// #include <libgen.h>
     117// #include <libintl.h>
     118// #include <libio.h>
     119// #include <libtasn1.h>
     120// #include <libudev.h>
     121// #include <limits.h>
     122// #include <link.h>
     123// #include <locale.h>
     124// #include <ltdl.h>
     125// #include <lzma.h>
     126// #include <malloc.h>
     127// #include <math.h>
     128// #include <mcheck.h>
     129// #include <memory.h>
     130// #include <menu.h>
     131// #include <mntent.h>
     132// #include <monetary.h>
     133// #include <mqueue.h>
     134// #include <ncurses.h>
     135// #include <ncurses_dll.h>
     136// #include <nc_tparm.h>
     137// #include <netdb.h>
     138// #include <nl_types.h>
     139// #include <nss.h>
     140// #include <numa.h>
     141// #include <numacompat1.h>
     142// #include <numaif.h>
     143// #include <obstack.h>
     144// #include <panel.h>
     145// #include <paths.h>
     146// #include <pciaccess.h>
     147// #include <pcre.h>
     148// //#include <pcreposix.h>                     // conflicts with regex.h
     149// #include <plugin-api.h>
     150// #include <png.h>                                                                             // setjmp
     151// #include <pngconf.h>                                                                 // setjmp
     152// #include <poll.h>
     153// #include <pr29.h>
     154// #include <printf.h>
     155// #include <profile.h>
     156// #include <pthread.h>                                                                 // setjmp
     157// #include <pty.h>
     158// #include <punycode.h>
     159// #include <pwd.h>
     160// #define INIT ;                                               // needed for regex.h
     161// #define GETC() 'a'
     162// #define PEEKC() 'a'
     163// #define UNGETC( c ) ;
     164// #define RETURN( ptr ) ;
     165// #define ERROR( val ) ;
     166// #include <regex.h>
     167// //#include <regexp.h>                                // GNU C Library no longer implements
     168// #include <resolv.h>
     169// #include <re_comp.h>
     170// #include <sched.h>
     171// #include <search.h>
     172// #include <semaphore.h>
     173// #include <setjmp.h>
     174// #include <sgtty.h>
     175// #include <shadow.h>
     176// #include <signal.h>
     177// #include <spawn.h>
     178// #include <stab.h>
     179// #include <stdatomic.h>
     180// #include <stdarg.h>
     181// #include <stdbool.h>
     182// #include <stdint.h>
     183// #include <stddef.h>
     184// #include <stdio.h>
     185// #include <stdio_ext.h>
     186// #include <stdlib.h>
     187// #include <string.h>
     188// #include <stringprep.h>
     189// #include <strings.h>
     190// #include <stropts.h>
     191// #include <sudo_plugin.h>
     192// #include <symcat.h>
     193// #include <syscall.h>
     194// #include <sysexits.h>
     195// #include <syslog.h>
     196// #include <tar.h>
     197// #include <term.h>
     198// #include <termcap.h>
     199// #include <termio.h>
     200// #include <termios.h>
     201// //#include <term_entry.h>
     202// #include <tgmath.h>
     203// #include <thread_db.h>                       // CFA bug
     204// #include <tic.h>
     205// #include <time.h>
     206// #include <tld.h>
     207// #include <ttyent.h>
     208// #include <turbojpeg.h>
     209// #include <ucontext.h>
     210// #include <ulimit.h>
     211// #include <unctrl.h>
     212// #include <unistd.h>
     213// #include <ustat.h>
     214// #include <utime.h>
     215// #include <utmp.h>
     216// #include <utmpx.h>
     217// #include <wait.h>
     218// #include <wchar.h>
     219// #include <wctype.h>
     220// #include <wordexp.h>
     221// #include <xlocale.h>
     222// #include <values.h>
     223// #include <zconf.h>
     224// #include <zlib.h>
     225// #include <_G_config.h>
     226
     227// #include <jpeglib.h>                         // after stdlib.h/stdio.h
     228// #include <jpegint.h>
     229// #include <jmorecfg.h>
     230#if 0
     231#endif // 0
     232
     233#else
     234
     235#define _GNU_SOURCE
     236
    115237#include <setjmp.h>
    116 #include <signal.h>
    117 #include <stdarg.h>
    118 #include <stdbool.h>
    119 #include <stddef.h>
    120 #include <stdlib.h>
    121 #include <stdio.h>
    122 #include <string.h>
    123 #include <tgmath.h>
    124 #include <time.h>
    125 #include <unistd.h>
    126 #include <wchar.h>
    127 #include <wctype.h>
    128 #endif // 0
    129 
    130 #else
    131 
    132 #define _GNU_SOURCE
    133 //#include <bfd.h>
    134 //#include <error.h>
    135 
    136 #include <demangle.h>
    137238
    138239#endif // 0
  • examples/twice.c

    r90cac45 r4bd3069  
    77// twice.c --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar  8 22:04:58 2016
    13 // Update Count     : 16
     12// Last Modified On : Thu Oct 19 21:52:57 2017
     13// Update Count     : 46
    1414//
    1515
    1616#include <fstream.hfa>
    1717
    18 forall( otype T | { T ?+?( T, T ); T ?++( T * ); [T] ?+=?( T *, T ); } )
     18forall( otype T | { T ?+?( T, T ); } )
    1919T twice( const T t ) {
    2020        return t + t;
    2121}
    2222
     23// char does not have addition
     24char ?+?( char op1, char op2 ) { return (int)op1 + op2; } // cast forces integer addition or recursion
     25
     26// signed char does not have addition
     27signed char ?+?( signed char op1, signed char op2 ) { return (int)op1 + op2; } // cast forces integer addition or recursion
     28
    2329int main( void ) {
    24         // char does not have addition
    25         char ?+?( char op1, char op2 ) { return (int)op1 + op2; } // cast forces integer addition or recursion
    26         char ++?( char *op ) { *op += 1; return *op; }
    27         char ?++( char *op ) { char temp = *op; *op += 1; return temp; }
    28 
    29         sout | twice( 'a' ) | ' ' | twice( 1 ) | twice( 3.2 ) | endl;
     30        sout | twice( ' ' ) | ' ' | twice( (signed char)0 ) | twice( (int)1 ) | twice( 3.2 ) | endl;
    3031}
    3132
  • libcfa/src/heap.cfa

    r90cac45 r4bd3069  
     1// #comment TD : this file uses both spaces and tabs for indentation
     2
    13//
    24// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
     
    2224} // extern "C"
    2325
     26// #comment TD : Many of these should be merged into math I believe
    2427#include "bits/align.hfa"                                                                       // libPow2
    2528#include "bits/defs.hfa"                                                                        // likely, unlikely
     
    3639
    3740size_t default_mmap_start() __attribute__(( weak )) {
    38     return __CFA_DEFAULT_MMAP_START__;
     41        return __CFA_DEFAULT_MMAP_START__;
    3942} // default_mmap_start
    4043
    4144size_t default_heap_expansion() __attribute__(( weak )) {
    42     return __CFA_DEFAULT_HEAP_EXPANSION__;
     45        return __CFA_DEFAULT_HEAP_EXPANSION__;
    4346} // default_heap_expansion
    4447
     
    6265#endif // LOCKFREE
    6366
     67// #comment TD : This defined is significantly different from the __ALIGN__ define from locks.hfa
    6468#define ALIGN 16
    6569
     
    136140
    137141static void checkUnfreed() {
    138     if ( allocFree != 0 ) {
     142        if ( allocFree != 0 ) {
    139143                // DO NOT USE STREAMS AS THEY MAY BE UNAVAILABLE AT THIS POINT.
    140144                // char helpText[512];
     
    143147                //                                      (long int)getpid(), allocFree, allocFree ); // always print the UNIX pid
    144148                // __cfaabi_dbg_bits_write( helpText, len );
    145     } // if
     149        } // if
    146150} // checkUnfreed
    147151
     
    167171                                struct RealHeader {
    168172                                        union {
     173                                                // #comment TD : this code use byte size but the comment uses bit size
     174
    169175                                                struct {                                                // 32-bit word => 64-bit header, 64-bit word => 128-bit header
    170176                                                        #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && __SIZEOF_POINTER__ == 4
     
    186192
    187193                                                };
     194
     195                                                // #comment TD : C++ code
    188196                                                #if BUCKLOCK == LOCKFREE
    189197                                                Stack<Storage>::Link next;              // freed block points next freed block of same size (double-wide)
     
    215223            Storage * freeList;
    216224                #elif BUCKLOCK == LOCKFREE
     225                // #comment TD : C++ code
    217226            StackLF<Storage> freeList;
    218227                #else
     
    240249static unsigned int maxBucketsUsed;                                             // maximum number of buckets in use
    241250
     251// #comment TD : This array is not const but it feels like it should be
    242252// Powers of 2 are common allocation sizes, so make powers of 2 generate the minimum required size.
    243253static unsigned int bucketSizes[NoBucketSizes] @= {             // different bucket sizes
    244     16, 32, 48, 64,
    245     64 + sizeof(HeapManager.Storage), 96, 112, 128, 128 + sizeof(HeapManager.Storage), 160, 192, 224,
    246     256 + sizeof(HeapManager.Storage), 320, 384, 448, 512 + sizeof(HeapManager.Storage), 640, 768, 896,
    247     1_024 + sizeof(HeapManager.Storage), 1_536, 2_048 + sizeof(HeapManager.Storage), 2_560, 3_072, 3_584, 4_096 + sizeof(HeapManager.Storage), 6_144,
    248     8_192 + sizeof(HeapManager.Storage), 9_216, 10_240, 11_264, 12_288, 13_312, 14_336, 15_360,
    249     16_384 + sizeof(HeapManager.Storage), 18_432, 20_480, 22_528, 24_576, 26_624, 28_672, 30_720,
    250     32_768 + sizeof(HeapManager.Storage), 36_864, 40_960, 45_056, 49_152, 53_248, 57_344, 61_440,
    251     65_536 + sizeof(HeapManager.Storage), 73_728, 81_920, 90_112, 98_304, 106_496, 114_688, 122_880,
    252     131_072 + sizeof(HeapManager.Storage), 147_456, 163_840, 180_224, 196_608, 212_992, 229_376, 245_760,
    253     262_144 + sizeof(HeapManager.Storage), 294_912, 327_680, 360_448, 393_216, 425_984, 458_752, 491_520,
    254     524_288 + sizeof(HeapManager.Storage), 655_360, 786_432, 917_504, 1_048_576 + sizeof(HeapManager.Storage), 1_179_648, 1_310_720, 1_441_792,
    255     1_572_864, 1_703_936, 1_835_008, 1_966_080, 2_097_152 + sizeof(HeapManager.Storage), 2_621_440, 3_145_728, 3_670_016,
    256     4_194_304 + sizeof(HeapManager.Storage)
     254        16, 32, 48, 64,
     255        64 + sizeof(HeapManager.Storage), 96, 112, 128, 128 + sizeof(HeapManager.Storage), 160, 192, 224,
     256        256 + sizeof(HeapManager.Storage), 320, 384, 448, 512 + sizeof(HeapManager.Storage), 640, 768, 896,
     257        1_024 + sizeof(HeapManager.Storage), 1_536, 2_048 + sizeof(HeapManager.Storage), 2_560, 3_072, 3_584, 4_096 + sizeof(HeapManager.Storage), 6_144,
     258        8_192 + sizeof(HeapManager.Storage), 9_216, 10_240, 11_264, 12_288, 13_312, 14_336, 15_360,
     259        16_384 + sizeof(HeapManager.Storage), 18_432, 20_480, 22_528, 24_576, 26_624, 28_672, 30_720,
     260        32_768 + sizeof(HeapManager.Storage), 36_864, 40_960, 45_056, 49_152, 53_248, 57_344, 61_440,
     261        65_536 + sizeof(HeapManager.Storage), 73_728, 81_920, 90_112, 98_304, 106_496, 114_688, 122_880,
     262        131_072 + sizeof(HeapManager.Storage), 147_456, 163_840, 180_224, 196_608, 212_992, 229_376, 245_760,
     263        262_144 + sizeof(HeapManager.Storage), 294_912, 327_680, 360_448, 393_216, 425_984, 458_752, 491_520,
     264        524_288 + sizeof(HeapManager.Storage), 655_360, 786_432, 917_504, 1_048_576 + sizeof(HeapManager.Storage), 1_179_648, 1_310_720, 1_441_792,
     265        1_572_864, 1_703_936, 1_835_008, 1_966_080, 2_097_152 + sizeof(HeapManager.Storage), 2_621_440, 3_145_728, 3_670_016,
     266        4_194_304 + sizeof(HeapManager.Storage)
    257267};
    258268#ifdef FASTLOOKUP
     
    267277static HeapManager heapManager __attribute__(( aligned (128) )) @= {}; // size of cache line to prevent false sharing
    268278
    269 
     279// #comment TD : The return type of this function should be commented
    270280static inline bool setMmapStart( size_t value ) {
    271     if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return true;
    272     mmapStart = value;                                                                  // set global
    273 
    274     // find the closest bucket size less than or equal to the mmapStart size
    275     maxBucketsUsed = bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search
    276     assert( maxBucketsUsed < NoBucketSizes );                   // subscript failure ?
    277     assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ?
    278     return false;
     281        if ( value < pageSize || bucketSizes[NoBucketSizes - 1] < value ) return true;
     282        mmapStart = value;                                                                      // set global
     283
     284        // find the closest bucket size less than or equal to the mmapStart size
     285        maxBucketsUsed = bsearchl( (unsigned int)mmapStart, bucketSizes, NoBucketSizes ); // binary search
     286        assert( maxBucketsUsed < NoBucketSizes );                       // subscript failure ?
     287        assert( mmapStart <= bucketSizes[maxBucketsUsed] ); // search failure ?
     288        return false;
    279289} // setMmapStart
    280290
    281291
    282292static void ?{}( HeapManager & manager ) with ( manager ) {
    283     pageSize = sysconf( _SC_PAGESIZE );
    284 
    285     for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists
     293        pageSize = sysconf( _SC_PAGESIZE );
     294
     295        for ( unsigned int i = 0; i < NoBucketSizes; i += 1 ) { // initialize the free lists
    286296                freeLists[i].blockSize = bucketSizes[i];
    287     } // for
     297        } // for
    288298
    289299        #ifdef FASTLOOKUP
    290     unsigned int idx = 0;
    291     for ( unsigned int i = 0; i < LookupSizes; i += 1 ) {
     300        unsigned int idx = 0;
     301        for ( unsigned int i = 0; i < LookupSizes; i += 1 ) {
    292302                if ( i > bucketSizes[idx] ) idx += 1;
    293303                lookup[i] = idx;
    294     } // for
     304        } // for
    295305        #endif // FASTLOOKUP
    296306
    297     if ( setMmapStart( default_mmap_start() ) ) {
     307        if ( setMmapStart( default_mmap_start() ) ) {
    298308                abort( "HeapManager : internal error, mmap start initialization failure." );
    299     } // if
    300     heapExpand = default_heap_expansion();
    301 
    302     char * End = (char *)sbrk( 0 );
    303     sbrk( (char *)libCeiling( (long unsigned int)End, libAlign() ) - End ); // move start of heap to multiple of alignment
    304     heapBegin = heapEnd = sbrk( 0 );                                    // get new start point
     309        } // if
     310        heapExpand = default_heap_expansion();
     311
     312        char * End = (char *)sbrk( 0 );
     313        sbrk( (char *)libCeiling( (long unsigned int)End, libAlign() ) - End ); // move start of heap to multiple of alignment
     314        heapBegin = heapEnd = sbrk( 0 );                                        // get new start point
    305315} // HeapManager
    306316
     
    326336        #endif // __CFA_DEBUG__
    327337
     338        // #comment TD : This assertion seems redundent with the above code
    328339        assert( heapManager.heapBegin == 0 );
    329340        heapManager{};
     
    361372// Use "write" because streams may be shutdown when calls are made.
    362373static void printStats() {
    363     char helpText[512];
     374        char helpText[512];
    364375        __cfaabi_dbg_bits_print_buffer( helpText, sizeof(helpText),
    365376                        "\nHeap statistics:\n"
     
    385396} // printStats
    386397
    387 
     398// #comment TD : Why do we have this?
    388399static int printStatsXML( FILE * stream ) {
    389     char helpText[512];
    390     int len = snprintf( helpText, sizeof(helpText),
     400        char helpText[512];
     401        int len = snprintf( helpText, sizeof(helpText),
    391402                                                "<malloc version=\"1\">\n"
    392403                                                "<heap nr=\"0\">\n"
     
    413424                                                sbrk_calls, sbrk_storage
    414425                );
    415     return write( fileno( stream ), helpText, len );    // -1 => error
     426        return write( fileno( stream ), helpText, len );        // -1 => error
    416427} // printStatsXML
    417428#endif // __STATISTICS__
    418429
    419 
     430// #comment TD : Is this the samething as Out-of-Memory?
    420431static inline void noMemory() {
    421     abort( "Heap memory exhausted at %zu bytes.\n"
     432        abort( "Heap memory exhausted at %zu bytes.\n"
    422433                        "Possible cause is very large memory allocation and/or large amount of unfreed storage allocated by the program or system/library routines.",
    423434                        ((char *)(sbrk( 0 )) - (char *)(heapManager.heapBegin)) );
     
    426437
    427438static inline void checkAlign( size_t alignment ) {
    428     if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) {
     439        if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) {
    429440                abort( "Alignment %zu for memory allocation is less than sizeof(void *) and/or not a power of 2.", alignment );
    430     } // if
     441        } // if
    431442} // checkAlign
    432443
    433444
    434445static inline bool setHeapExpand( size_t value ) {
    435     if ( heapExpand < pageSize ) return true;
    436     heapExpand = value;
    437     return false;
     446        if ( heapExpand < pageSize ) return true;
     447        heapExpand = value;
     448        return false;
    438449} // setHeapExpand
    439450
    440451
    441452static inline void checkHeader( bool check, const char * name, void * addr ) {
    442     if ( unlikely( check ) ) {                                                  // bad address ?
     453        if ( unlikely( check ) ) {                                                      // bad address ?
    443454                abort( "Attempt to %s storage %p with address outside the heap.\n"
    444455                                "Possible cause is duplicate free on same block or overwriting of memory.",
    445456                                name, addr );
    446     } // if
     457        } // if
    447458} // checkHeader
    448459
    449 
     460// #comment TD : function should be commented and/or have a more evocative name
     461//               this isn't either a check or a constructor which is what I would expect this function to be
    450462static inline void fakeHeader( HeapManager.Storage.Header *& header, size_t & size, size_t & alignment ) {
    451     if ( unlikely( (header->kind.fake.alignment & 1) == 1 ) ) { // fake header ?
     463        if ( unlikely( (header->kind.fake.alignment & 1) == 1 ) ) { // fake header ?
    452464                size_t offset = header->kind.fake.offset;
    453465                alignment = header->kind.fake.alignment & -2;   // remove flag from value
     
    456468                #endif // __CFA_DEBUG__
    457469                header = (HeapManager.Storage.Header *)((char *)header - offset);
    458     } // if
     470        } // if
    459471} // fakeHeader
    460472
    461 
     473// #comment TD : Why is this a define
    462474#define headerAddr( addr ) ((HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) ))
    463475
    464476static inline bool headers( const char * name, void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
    465     header = headerAddr( addr );
    466 
    467     if ( unlikely( heapEnd < addr ) ) {                                 // mmapped ?
     477        header = headerAddr( addr );
     478
     479        if ( unlikely( heapEnd < addr ) ) {                                     // mmapped ?
    468480                fakeHeader( header, size, alignment );
    469481                size = header->kind.real.blockSize & -3;                // mmap size
    470482                return true;
    471     } // if
     483        } // if
    472484
    473485        #ifdef __CFA_DEBUG__
    474     checkHeader( addr < heapBegin || header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ?
     486                        checkHeader( addr < heapBegin || header < (HeapManager.Storage.Header *)heapBegin, name, addr ); // bad low address ?
    475487        #endif // __CFA_DEBUG__
    476     // header may be safe to dereference
    477     fakeHeader( header, size, alignment );
     488
     489        // #comment TD : This code looks weird...
     490        //               It's called as the first statement of both branches of the last if, with the same parameters in all cases
     491
     492                // header may be safe to dereference
     493                fakeHeader( header, size, alignment );
    478494        #ifdef __CFA_DEBUG__
    479     checkHeader( header < (HeapManager.Storage.Header *)heapBegin || (HeapManager.Storage.Header *)heapEnd < header, name, addr ); // bad address ? (offset could be + or -)
     495                        checkHeader( header < (HeapManager.Storage.Header *)heapBegin || (HeapManager.Storage.Header *)heapEnd < header, name, addr ); // bad address ? (offset could be + or -)
    480496        #endif // __CFA_DEBUG__
    481497
    482     freeElem = (HeapManager.FreeHeader *)((size_t)header->kind.real.home & -3);
     498                freeElem = (HeapManager.FreeHeader *)((size_t)header->kind.real.home & -3);
    483499        #ifdef __CFA_DEBUG__
    484     if ( freeElem < &freeLists[0] || &freeLists[NoBucketSizes] <= freeElem ) {
    485                 abort( "Attempt to %s storage %p with corrupted header.\n"
    486                           "Possible cause is duplicate free on same block or overwriting of header information.",
    487                            name, addr );
    488     } // if
     500                        if ( freeElem < &freeLists[0] || &freeLists[NoBucketSizes] <= freeElem ) {
     501                        abort( "Attempt to %s storage %p with corrupted header.\n"
     502                                "Possible cause is duplicate free on same block or overwriting of header information.",
     503                                        name, addr );
     504                        } // if
    489505        #endif // __CFA_DEBUG__
    490     size = freeElem->blockSize;
    491     return false;
     506                size = freeElem->blockSize;
     507                return false;
    492508} // headers
    493509
    494510
    495511static inline void * extend( size_t size ) with ( heapManager ) {
    496     lock( extlock __cfaabi_dbg_ctx2 );
    497     ptrdiff_t rem = heapRemaining - size;
    498     if ( rem < 0 ) {
     512        lock( extlock __cfaabi_dbg_ctx2 );
     513        ptrdiff_t rem = heapRemaining - size;
     514        if ( rem < 0 ) {
    499515                // If the size requested is bigger than the current remaining storage, increase the size of the heap.
    500516
     
    514530#endif // __CFA_DEBUG__
    515531                rem = heapRemaining + increase - size;
    516     } // if
    517 
    518     HeapManager.Storage * block = (HeapManager.Storage *)heapEnd;
    519     heapRemaining = rem;
    520     heapEnd = (char *)heapEnd + size;
    521     unlock( extlock );
    522     return block;
     532        } // if
     533
     534        HeapManager.Storage * block = (HeapManager.Storage *)heapEnd;
     535        heapRemaining = rem;
     536        heapEnd = (char *)heapEnd + size;
     537        unlock( extlock );
     538        return block;
    523539} // extend
    524540
    525541
    526542static inline void * doMalloc( size_t size ) with ( heapManager ) {
    527     HeapManager.Storage * block;
    528 
    529     // Look up size in the size list.  Make sure the user request includes space for the header that must be allocated
    530     // along with the block and is a multiple of the alignment size.
    531 
    532     size_t tsize = size + sizeof(HeapManager.Storage);
    533     if ( likely( tsize < mmapStart ) ) {                                // small size => sbrk
     543        HeapManager.Storage * block;
     544
     545        // Look up size in the size list.  Make sure the user request includes space for the header that must be allocated
     546        // along with the block and is a multiple of the alignment size.
     547
     548        size_t tsize = size + sizeof(HeapManager.Storage);
     549        if ( likely( tsize < mmapStart ) ) {                            // small size => sbrk
    534550                HeapManager.FreeHeader * freeElem =
    535551                        #ifdef FASTLOOKUP
     
    544560
    545561                #if defined( SPINLOCK )
    546                 lock( freeElem->lock __cfaabi_dbg_ctx2 );
    547                 block = freeElem->freeList;                                             // remove node from stack
     562                        lock( freeElem->lock __cfaabi_dbg_ctx2 );
     563                        block = freeElem->freeList;                                             // remove node from stack
    548564                #else
    549                 block = freeElem->freeList.pop();
     565                        block = freeElem->freeList.pop();
    550566                #endif // SPINLOCK
    551567                if ( unlikely( block == 0 ) ) {                                 // no free block ?
     
    566582
    567583                block->header.kind.real.home = freeElem;                // pointer back to free list of apropriate size
    568     } else {                                                                                    // large size => mmap
     584                } else {                                                                                        // large size => mmap
    569585                tsize = libCeiling( tsize, pageSize );                  // must be multiple of page size
    570586                #ifdef __STATISTICS__
    571                 __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST );
    572                 __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
     587                        __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST );
     588                        __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
    573589                #endif // __STATISTICS__
    574590                block = (HeapManager.Storage *)mmap( 0, tsize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, mmapFd, 0 );
     
    582598#endif // __CFA_DEBUG__
    583599                block->header.kind.real.blockSize = tsize;              // storage size for munmap
    584     } // if
    585 
    586     void * area = &(block->data);                                               // adjust off header to user bytes
     600                } // if
     601
     602                void * area = &(block->data);                                           // adjust off header to user bytes
    587603
    588604        #ifdef __CFA_DEBUG__
    589     assert( ((uintptr_t)area & (libAlign() - 1)) == 0 ); // minimum alignment ?
    590     __atomic_add_fetch( &allocFree, tsize, __ATOMIC_SEQ_CST );
    591         if ( traceHeap() ) {
    592                 enum { BufferSize = 64 };
    593                 char helpText[BufferSize];
    594                 int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", area, size, tsize );
    595                 // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", area, size );
    596                 __cfaabi_dbg_bits_write( helpText, len );
    597         } // if
     605                        assert( ((uintptr_t)area & (libAlign() - 1)) == 0 ); // minimum alignment ?
     606                        __atomic_add_fetch( &allocFree, tsize, __ATOMIC_SEQ_CST );
     607                if ( traceHeap() ) {
     608                        enum { BufferSize = 64 };
     609                        char helpText[BufferSize];
     610                        int len = snprintf( helpText, BufferSize, "%p = Malloc( %zu ) (allocated %zu)\n", area, size, tsize );
     611                        // int len = snprintf( helpText, BufferSize, "Malloc %p %zu\n", area, size );
     612                        __cfaabi_dbg_bits_write( helpText, len );
     613                } // if
    598614        #endif // __CFA_DEBUG__
    599615
    600     return area;
     616        return area;
    601617} // doMalloc
    602618
     
    604620static inline void doFree( void * addr ) with ( heapManager ) {
    605621        #ifdef __CFA_DEBUG__
    606     if ( unlikely( heapManager.heapBegin == 0 ) ) {
    607                 abort( "doFree( %p ) : internal error, called before heap is initialized.", addr );
    608     } // if
     622                if ( unlikely( heapManager.heapBegin == 0 ) ) {
     623                        abort( "doFree( %p ) : internal error, called before heap is initialized.", addr );
     624                } // if
    609625        #endif // __CFA_DEBUG__
    610626
    611     HeapManager.Storage.Header * header;
    612     HeapManager.FreeHeader * freeElem;
    613     size_t size, alignment;                                                             // not used (see realloc)
    614 
    615     if ( headers( "free", addr, header, freeElem, size, alignment ) ) { // mmapped ?
    616                 #ifdef __STATISTICS__
    617                 __atomic_add_fetch( &munmap_calls, 1, __ATOMIC_SEQ_CST );
    618                 __atomic_add_fetch( &munmap_storage, size, __ATOMIC_SEQ_CST );
     627        HeapManager.Storage.Header * header;
     628        HeapManager.FreeHeader * freeElem;
     629        size_t size, alignment;                                                         // not used (see realloc)
     630
     631        if ( headers( "free", addr, header, freeElem, size, alignment ) ) { // mmapped ?
     632                #ifdef __STATISTICS__
     633                        __atomic_add_fetch( &munmap_calls, 1, __ATOMIC_SEQ_CST );
     634                        __atomic_add_fetch( &munmap_storage, size, __ATOMIC_SEQ_CST );
    619635                #endif // __STATISTICS__
    620636                if ( munmap( header, size ) == -1 ) {
     
    625641                        #endif // __CFA_DEBUG__
    626642                } // if
    627     } else {
     643                } else {
    628644                #ifdef __CFA_DEBUG__
    629                 // Set free memory to garbage so subsequent usages might fail.
    630                 memset( ((HeapManager.Storage *)header)->data, '\377', freeElem->blockSize - sizeof( HeapManager.Storage ) );
     645                        // Set free memory to garbage so subsequent usages might fail.
     646                        memset( ((HeapManager.Storage *)header)->data, '\377', freeElem->blockSize - sizeof( HeapManager.Storage ) );
    631647                #endif // __CFA_DEBUG__
    632648
    633649                #ifdef __STATISTICS__
    634                 free_storage += size;
     650                        free_storage += size;
    635651                #endif // __STATISTICS__
    636652                #if defined( SPINLOCK )
    637                 lock( freeElem->lock __cfaabi_dbg_ctx2 );               // acquire spin lock
    638                 header->kind.real.next = freeElem->freeList;    // push on stack
    639                 freeElem->freeList = (HeapManager.Storage *)header;
    640                 unlock( freeElem->lock );                                               // release spin lock
     653                        lock( freeElem->lock __cfaabi_dbg_ctx2 );               // acquire spin lock
     654                        header->kind.real.next = freeElem->freeList;    // push on stack
     655                        freeElem->freeList = (HeapManager.Storage *)header;
     656                        unlock( freeElem->lock );                                               // release spin lock
    641657                #else
    642                 freeElem->freeList.push( *(HeapManager.Storage *)header );
     658                        freeElem->freeList.push( *(HeapManager.Storage *)header );
    643659                #endif // SPINLOCK
    644     } // if
     660                } // if
    645661
    646662        #ifdef __CFA_DEBUG__
    647     __atomic_add_fetch( &allocFree, -size, __ATOMIC_SEQ_CST );
    648     if ( traceHeap() ) {
    649                 char helpText[64];
    650                 int len = snprintf( helpText, sizeof(helpText), "Free( %p ) size:%zu\n", addr, size );
    651                 __cfaabi_dbg_bits_write( helpText, len );
    652     } // if
     663                 __atomic_add_fetch( &allocFree, -size, __ATOMIC_SEQ_CST );
     664                if ( traceHeap() ) {
     665                        char helpText[64];
     666                        int len = snprintf( helpText, sizeof(helpText), "Free( %p ) size:%zu\n", addr, size );
     667                        __cfaabi_dbg_bits_write( helpText, len );
     668                } // if
    653669        #endif // __CFA_DEBUG__
    654670} // doFree
     
    656672
    657673size_t checkFree( HeapManager & manager ) with ( manager ) {
    658     size_t total = 0;
     674        size_t total = 0;
    659675        #ifdef __STATISTICS__
    660     __cfaabi_dbg_bits_acquire();
    661     __cfaabi_dbg_bits_print_nolock( "\nBin lists (bin size : free blocks on list)\n" );
     676                __cfaabi_dbg_bits_acquire();
     677                __cfaabi_dbg_bits_print_nolock( "\nBin lists (bin size : free blocks on list)\n" );
    662678        #endif // __STATISTICS__
    663     for ( unsigned int i = 0; i < maxBucketsUsed; i += 1 ) {
     679        for ( unsigned int i = 0; i < maxBucketsUsed; i += 1 ) {
    664680                size_t size = freeLists[i].blockSize;
    665681                #ifdef __STATISTICS__
    666682                unsigned int N = 0;
    667683                #endif // __STATISTICS__
     684
    668685                #if defined( SPINLOCK )
    669686                for ( HeapManager.Storage * p = freeLists[i].freeList; p != 0; p = p->header.kind.real.next ) {
     
    675692                        N += 1;
    676693                        #endif // __STATISTICS__
    677             } // for
    678                 #ifdef __STATISTICS__
    679             __cfaabi_dbg_bits_print_nolock( "%7zu, %-7u  ", size, N );
    680             if ( (i + 1) % 8 == 0 ) __cfaabi_dbg_bits_print_nolock( "\n" );
     694                } // for
     695
     696                #ifdef __STATISTICS__
     697                        __cfaabi_dbg_bits_print_nolock( "%7zu, %-7u  ", size, N );
     698                        if ( (i + 1) % 8 == 0 ) __cfaabi_dbg_bits_print_nolock( "\n" );
    681699                #endif // __STATISTICS__
    682700        } // for
    683701        #ifdef __STATISTICS__
    684         __cfaabi_dbg_bits_print_nolock( "\ntotal free blocks:%zu\n", total );
    685         __cfaabi_dbg_bits_release();
     702                __cfaabi_dbg_bits_print_nolock( "\ntotal free blocks:%zu\n", total );
     703                __cfaabi_dbg_bits_release();
    686704        #endif // __STATISTICS__
    687705        return (char *)heapEnd - (char *)heapBegin - total;
    688706} // checkFree
    689707
    690 
     708// #comment TD : This is not a good name, plus this feels like it could easily be folded into doMalloc
    691709static inline void * malloc2( size_t size ) {                   // necessary for malloc statistics
    692710        assert( heapManager.heapBegin != 0 );
    693     void * area = doMalloc( size );
    694     if ( unlikely( area == 0 ) ) errno = ENOMEM;                // POSIX
    695     return area;
     711        void * area = doMalloc( size );
     712        if ( unlikely( area == 0 ) ) errno = ENOMEM;            // POSIX
     713        return area;
    696714} // malloc2
    697715
     
    699717static inline void * memalign2( size_t alignment, size_t size ) { // necessary for malloc statistics
    700718#ifdef __CFA_DEBUG__
    701     checkAlign( alignment );                                                    // check alignment
     719        checkAlign( alignment );                                                        // check alignment
    702720#endif // __CFA_DEBUG__
    703721
    704     // if alignment <= default alignment, do normal malloc as two headers are unnecessary
    705     if ( unlikely( alignment <= libAlign() ) ) return malloc2( size );
    706 
    707     // Allocate enough storage to guarantee an address on the alignment boundary, and sufficient space before it for
    708     // administrative storage. NOTE, WHILE THERE ARE 2 HEADERS, THE FIRST ONE IS IMPLICITLY CREATED BY DOMALLOC.
    709     //      .-------------v-----------------v----------------v----------,
    710     //      | Real Header | ... padding ... |   Fake Header  | data ... |
    711     //      `-------------^-----------------^-+--------------^----------'
    712     //      |<--------------------------------' offset/align |<-- alignment boundary
    713 
    714     // subtract libAlign() because it is already the minimum alignment
    715     // add sizeof(Storage) for fake header
    716     char * area = (char *)doMalloc( size + alignment - libAlign() + sizeof(HeapManager.Storage) );
    717     if ( unlikely( area == 0 ) ) return area;
    718 
    719     // address in the block of the "next" alignment address
    720     char * user = (char *)libCeiling( (uintptr_t)(area + sizeof(HeapManager.Storage)), alignment );
    721 
    722     // address of header from malloc
    723     HeapManager.Storage.Header * realHeader = headerAddr( area );
    724     // address of fake header * before* the alignment location
    725     HeapManager.Storage.Header * fakeHeader = headerAddr( user );
    726     // SKULLDUGGERY: insert the offset to the start of the actual storage block and remember alignment
    727     fakeHeader->kind.fake.offset = (char *)fakeHeader - (char *)realHeader;
    728     // SKULLDUGGERY: odd alignment imples fake header
    729     fakeHeader->kind.fake.alignment = alignment | 1;
    730 
    731     return user;
     722        // if alignment <= default alignment, do normal malloc as two headers are unnecessary
     723        if ( unlikely( alignment <= libAlign() ) ) return malloc2( size );
     724
     725        // Allocate enough storage to guarantee an address on the alignment boundary, and sufficient space before it for
     726        // administrative storage. NOTE, WHILE THERE ARE 2 HEADERS, THE FIRST ONE IS IMPLICITLY CREATED BY DOMALLOC.
     727        //      .-------------v-----------------v----------------v----------,
     728        //      | Real Header | ... padding ... |   Fake Header  | data ... |
     729        //      `-------------^-----------------^-+--------------^----------'
     730        //      |<--------------------------------' offset/align |<-- alignment boundary
     731
     732        // subtract libAlign() because it is already the minimum alignment
     733        // add sizeof(Storage) for fake header
     734        // #comment TD : this is the only place that calls doMalloc without calling malloc2, why ?
     735        char * area = (char *)doMalloc( size + alignment - libAlign() + sizeof(HeapManager.Storage) );
     736        if ( unlikely( area == 0 ) ) return area;
     737
     738        // address in the block of the "next" alignment address
     739        char * user = (char *)libCeiling( (uintptr_t)(area + sizeof(HeapManager.Storage)), alignment );
     740
     741        // address of header from malloc
     742        HeapManager.Storage.Header * realHeader = headerAddr( area );
     743        // address of fake header * before* the alignment location
     744        HeapManager.Storage.Header * fakeHeader = headerAddr( user );
     745        // SKULLDUGGERY: insert the offset to the start of the actual storage block and remember alignment
     746        fakeHeader->kind.fake.offset = (char *)fakeHeader - (char *)realHeader;
     747        // SKULLDUGGERY: odd alignment imples fake header
     748        fakeHeader->kind.fake.alignment = alignment | 1;
     749
     750        return user;
    732751} // memalign2
    733752
    734753
    735754extern "C" {
    736     void * malloc( size_t size ) {
    737                 #ifdef __STATISTICS__
    738                 __atomic_add_fetch( &malloc_calls, 1, __ATOMIC_SEQ_CST );
    739                 __atomic_add_fetch( &malloc_storage, size, __ATOMIC_SEQ_CST );
     755        // The malloc() function allocates size bytes and returns a pointer to the
     756        // allocated memory. The memory is not initialized. If size is 0, then malloc()
     757        // returns either NULL, or a unique pointer value that can later be successfully
     758        // passed to free().
     759        void * malloc( size_t size ) {
     760                #ifdef __STATISTICS__
     761                        __atomic_add_fetch( &malloc_calls, 1, __ATOMIC_SEQ_CST );
     762                        __atomic_add_fetch( &malloc_storage, size, __ATOMIC_SEQ_CST );
    740763                #endif // __STATISTICS__
    741764
    742765                return malloc2( size );
    743     } // malloc
    744 
    745 
    746     void * calloc( size_t noOfElems, size_t elemSize ) {
     766                } // malloc
     767
     768        // The calloc() function allocates memory for an array of nmemb elements of
     769        // size bytes each and returns a pointer to the allocated memory. The memory
     770        // is set to zero. If nmemb or size is 0, then calloc() returns either NULL,
     771        // or a unique pointer value that can later be successfully passed to free().
     772                void * calloc( size_t noOfElems, size_t elemSize ) {
    747773                size_t size = noOfElems * elemSize;
    748774                #ifdef __STATISTICS__
    749                 __atomic_add_fetch( &calloc_calls, 1, __ATOMIC_SEQ_CST );
    750                 __atomic_add_fetch( &calloc_storage, size, __ATOMIC_SEQ_CST );
     775                        __atomic_add_fetch( &calloc_calls, 1, __ATOMIC_SEQ_CST );
     776                        __atomic_add_fetch( &calloc_storage, size, __ATOMIC_SEQ_CST );
    751777                #endif // __STATISTICS__
    752778
    753779                char * area = (char *)malloc2( size );
    754780                if ( unlikely( area == 0 ) ) return 0;
     781
    755782                HeapManager.Storage.Header * header;
    756783                HeapManager.FreeHeader * freeElem;
     
    762789                #endif // __CFA_DEBUG__
    763790                        memset( area, '\0', asize - sizeof(HeapManager.Storage) ); // set to zeros
     791
    764792                header->kind.real.blockSize |= 2;               // mark as zero filled
    765793                return area;
    766     } // calloc
    767 
    768 
    769     void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
     794                } // calloc
     795
     796        // #comment TD : Document this function
     797        void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ) {
    770798                size_t size = noOfElems * elemSize;
    771799                #ifdef __STATISTICS__
    772                 __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    773                 __atomic_add_fetch( &cmemalign_storage, size, __ATOMIC_SEQ_CST );
     800                        __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
     801                        __atomic_add_fetch( &cmemalign_storage, size, __ATOMIC_SEQ_CST );
    774802                #endif // __STATISTICS__
    775803
     
    788816
    789817                return area;
    790     } // cmemalign
    791 
    792 
    793     void * realloc( void * addr, size_t size ) {
    794                 #ifdef __STATISTICS__
    795                 __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
     818                } // cmemalign
     819
     820        // The realloc() function changes the size of the memory block pointed to by
     821        // ptr to size bytes. The contents will be unchanged in the range from the
     822        // start of the region up to the minimum of the old and new sizes. If the new
     823        // size is larger than the old size, the added memory will not be initialized.
     824        // If ptr is NULL, then the call is equivalent to malloc(size), for all values
     825        // of size; if size is equal to zero, and ptr is not NULL, then the call is
     826        // equivalent to free(ptr). Unless ptr is NULL, it must have been returned by
     827        // an earlier call to malloc(), calloc() or realloc(). If the area pointed to
     828        // was moved, a free(ptr) is done.
     829                void * realloc( void * addr, size_t size ) {
     830                #ifdef __STATISTICS__
     831                        __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
    796832                #endif // __STATISTICS__
    797833
     
    812848
    813849                #ifdef __STATISTICS__
    814                 __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
     850                        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    815851                #endif // __STATISTICS__
    816852
     
    835871                free( addr );
    836872                return area;
    837     } // realloc
    838 
    839 
    840     void * memalign( size_t alignment, size_t size ) {
     873        } // realloc
     874
     875
     876        // The obsolete function memalign() allocates size bytes and returns
     877        // a pointer to the allocated memory. The memory address will be a
     878        // multiple of alignment, which must be a power of two.
     879        void * memalign( size_t alignment, size_t size ) __attribute__ ((deprecated));
     880                void * memalign( size_t alignment, size_t size ) {
    841881                #ifdef __STATISTICS__
    842882                __atomic_add_fetch( &memalign_calls, 1, __ATOMIC_SEQ_CST );
     
    847887
    848888                return area;
    849     } // memalign
    850 
    851 
    852     void * aligned_alloc( size_t alignment, size_t size ) {
     889                } // memalign
     890
     891        // The function aligned_alloc() is the same as memalign(), except for
     892        // the added restriction that size should be a multiple of alignment.
     893        void * aligned_alloc( size_t alignment, size_t size ) {
    853894                return memalign( alignment, size );
    854     } // aligned_alloc
    855 
    856 
    857     int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
     895        } // aligned_alloc
     896
     897
     898        // The function posix_memalign() allocates size bytes and places the address
     899        // of the allocated memory in *memptr. The address of the allocated memory
     900        // will be a multiple of alignment, which must be a power of two and a multiple
     901        // of sizeof(void *). If size is 0, then posix_memalign() returns either NULL,
     902        // or a unique pointer value that can later be successfully passed to free(3).
     903        int posix_memalign( void ** memptr, size_t alignment, size_t size ) {
    858904                if ( alignment < sizeof(void *) || ! libPow2( alignment ) ) return EINVAL; // check alignment
    859905                * memptr = memalign( alignment, size );
    860906                if ( unlikely( * memptr == 0 ) ) return ENOMEM;
    861907                return 0;
    862     } // posix_memalign
    863 
    864 
    865     void * valloc( size_t size ) {
     908        } // posix_memalign
     909
     910        // The obsolete function valloc() allocates size bytes and returns a pointer
     911        // to the allocated memory. The memory address will be a multiple of the page size.
     912        // It is equivalent to memalign(sysconf(_SC_PAGESIZE),size).
     913        void * valloc( size_t size ) __attribute__ ((deprecated));
     914        void * valloc( size_t size ) {
    866915                return memalign( pageSize, size );
    867     } // valloc
    868 
    869 
    870     void free( void * addr ) {
    871                 #ifdef __STATISTICS__
    872                 __atomic_add_fetch( &free_calls, 1, __ATOMIC_SEQ_CST );
    873                 #endif // __STATISTICS__
    874 
     916        } // valloc
     917
     918
     919        // The free() function frees the memory space pointed to by ptr, which must
     920        // have been returned by a previous call to malloc(), calloc() or realloc().
     921        // Otherwise, or if free(ptr) has already been called before, undefined
     922        // behavior occurs. If ptr is NULL, no operation is performed.
     923        void free( void * addr ) {
     924                #ifdef __STATISTICS__
     925                        __atomic_add_fetch( &free_calls, 1, __ATOMIC_SEQ_CST );
     926                #endif // __STATISTICS__
     927
     928                // #comment TD : To decrease nesting I would but the special case in the
     929                //               else instead, plus it reads more naturally to have the
     930                //               short / normal case instead
    875931                if ( unlikely( addr == 0 ) ) {                                  // special case
    876932                        #ifdef __CFA_DEBUG__
    877                         if ( traceHeap() ) {
    878                                 #define nullmsg "Free( 0x0 ) size:0\n"
    879                                 // Do not debug print free( 0 ), as it can cause recursive entry from sprintf.
    880                                 __cfaabi_dbg_bits_write( nullmsg, sizeof(nullmsg) - 1 );
    881                         } // if
     933                                if ( traceHeap() ) {
     934                                        #define nullmsg "Free( 0x0 ) size:0\n"
     935                                        // Do not debug print free( 0 ), as it can cause recursive entry from sprintf.
     936                                        __cfaabi_dbg_bits_write( nullmsg, sizeof(nullmsg) - 1 );
     937                                } // if
    882938                        #endif // __CFA_DEBUG__
    883939                        return;
     
    885941
    886942                doFree( addr );
    887     } // free
    888 
    889 
    890     int mallopt( int option, int value ) {
     943        } // free
     944
     945        // The mallopt() function adjusts parameters that control the behavior of the
     946        // memory-allocation functions (see malloc(3)). The param argument specifies
     947        // the parameter to be modified, and value specifies the new value for that
     948        // parameter.
     949                int mallopt( int option, int value ) {
    891950                choose( option ) {
    892                   case M_TOP_PAD:
    893                         if ( setHeapExpand( value ) ) fallthru default;
    894                   case M_MMAP_THRESHOLD:
    895                         if ( setMmapStart( value ) ) fallthru default;
    896                   default:
    897                         return 1;                                                                       // success, or unsupported
     951                        case M_TOP_PAD:
     952                                if ( setHeapExpand( value ) ) fallthru default;
     953                        case M_MMAP_THRESHOLD:
     954                                if ( setMmapStart( value ) ) fallthru default;
     955                        default:
     956                                // #comment TD : 1 for unsopported feels wrong
     957                                return 1;                                                                       // success, or unsupported
    898958                } // switch
    899959                return 0;                                                                               // error
    900     } // mallopt
    901 
    902 
     960        } // mallopt
     961
     962        // The malloc_trim() function attempts to release free memory at the top
     963        // of the heap (by calling sbrk(2) with a suitable argument).
    903964        int malloc_trim( size_t ) {
    904965                return 0;                                                                               // => impossible to release memory
    905966        } // malloc_trim
    906967
    907     size_t malloc_usable_size( void * addr ) {
     968        // The malloc_usable_size() function returns the number of usable bytes in the
     969        // block pointed to by ptr, a pointer to a block of memory allocated by
     970        // malloc(3) or a related function.
     971                size_t malloc_usable_size( void * addr ) {
    908972                if ( unlikely( addr == 0 ) ) return 0;                  // null allocation has 0 size
     973
    909974                HeapManager.Storage.Header * header;
    910975                HeapManager.FreeHeader * freeElem;
     
    914979                size_t usize = size - ( (char *)addr - (char *)header ); // compute the amount of user storage in the block
    915980                return usize;
    916     } // malloc_usable_size
    917 
    918 
    919     size_t malloc_alignment( void * addr ) {
     981        } // malloc_usable_size
     982
     983
     984                // #comment TD : Document this function
     985        size_t malloc_alignment( void * addr ) {
    920986                if ( unlikely( addr == 0 ) ) return libAlign(); // minimum alignment
    921987                HeapManager.Storage.Header * header = (HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) );
     
    925991                        return libAlign ();                                                     // minimum alignment
    926992                } // if
    927     } // malloc_alignment
    928 
    929 
    930     bool malloc_zero_fill( void * addr ) {
     993                } // malloc_alignment
     994
     995
     996                // #comment TD : Document this function
     997        bool malloc_zero_fill( void * addr ) {
    931998                if ( unlikely( addr == 0 ) ) return false;              // null allocation is not zero fill
     999
    9321000                HeapManager.Storage.Header * header = (HeapManager.Storage.Header *)( (char *)addr - sizeof(HeapManager.Storage) );
    9331001                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     
    9351003                } // if
    9361004                return (header->kind.real.blockSize & 2) != 0;  // zero filled (calloc/cmemalign) ?
    937     } // malloc_zero_fill
    938 
    939 
    940     void malloc_stats( void ) {
    941                 #ifdef __STATISTICS__
    942                 printStats();
    943                 if ( checkFree() ) checkFree( heapManager );
    944                 #endif // __STATISTICS__
    945     } // malloc_stats
    946 
    947 
    948     int malloc_stats_fd( int fd ) {
    949                 #ifdef __STATISTICS__
    950                 int temp = statfd;
    951                 statfd = fd;
    952                 return temp;
     1005                } // malloc_zero_fill
     1006
     1007
     1008        // #comment TD : Document this function
     1009        void malloc_stats( void ) {
     1010                #ifdef __STATISTICS__
     1011                        printStats();
     1012                        if ( checkFree() ) checkFree( heapManager );
     1013                #endif // __STATISTICS__
     1014                } // malloc_stats
     1015
     1016        // #comment TD : Document this function
     1017                int malloc_stats_fd( int fd ) {
     1018                #ifdef __STATISTICS__
     1019                        int temp = statfd;
     1020                        statfd = fd;
     1021                        return temp;
    9531022                #else
    954                 return -1;
    955                 #endif // __STATISTICS__
    956     } // malloc_stats_fd
    957 
    958 
     1023                        return -1;
     1024                #endif // __STATISTICS__
     1025                } // malloc_stats_fd
     1026
     1027
     1028        // #comment TD : Document this function
    9591029        int malloc_info( int options, FILE * stream ) {
    9601030                return printStatsXML( stream );
     
    9621032
    9631033
     1034        // #comment TD : What are these two functions for?
    9641035        void * malloc_get_state( void ) {
    9651036                return 0;
    9661037        } // malloc_get_state
    967 
    9681038
    9691039        int malloc_set_state( void * ptr ) {
  • tests/Makefile.am

    r90cac45 r4bd3069  
    2424concurrent=
    2525
    26 TEST_PY = python ${srcdir}/test.py
     26TEST_PY = python ${builddir}/test.py
    2727
    2828# applies to both programs
  • tests/Makefile.in

    r90cac45 r4bd3069  
    301301quick_test = avl_test operators numericConstants expression enum array typeof cast raii/dtor-early-exit raii/init_once attributes
    302302concurrent =
    303 TEST_PY = python ${srcdir}/test.py
     303TEST_PY = python ${builddir}/test.py
    304304
    305305# applies to both programs
  • tests/concurrent/examples/boundedBufferEXT.c

    r90cac45 r4bd3069  
    88// Created On       : Wed Apr 18 22:52:12 2018
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Wed May  2 16:12:58 2018
    11 // Update Count     : 7
     10// Last Modified On : Thu Aug 16 08:17:03 2018
     11// Update Count     : 8
    1212//
    1313
     
    7373void main( Consumer & cons ) with( cons ) {
    7474        sum = 0;
    75         for ( ;; ) {
     75        for () {
    7676                yield( random( 5 ) );
    7777                int item = remove( buffer );
  • tests/concurrent/examples/boundedBufferINT.c

    r90cac45 r4bd3069  
    88// Created On       : Mon Oct 30 12:45:13 2017
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Thu Apr 26 23:08:17 2018
    11 // Update Count     : 82
     10// Last Modified On : Thu Aug 16 08:17:58 2018
     11// Update Count     : 83
    1212//
    1313
     
    7474void main( Consumer & cons ) with( cons ) {
    7575        sum = 0;
    76         for ( ;; ) {
     76        for () {
    7777                yield( random( 5 ) );
    7878                int item = remove( buffer );
  • tests/concurrent/examples/quickSort.c

    r90cac45 r4bd3069  
    99// Created On       : Wed Dec  6 12:15:52 2017
    1010// Last Modified By : Peter A. Buhr
    11 // Last Modified On : Tue Jan 30 15:58:58 2018
    12 // Update Count     : 162
     11// Last Modified On : Thu Aug 16 08:17:41 2018
     12// Update Count     : 163
    1313//
    1414
     
    131131
    132132        if ( &unsortedfile ) {                                                          // generate output ?
    133                 for ( ;; ) {
     133                for () {
    134134                        unsortedfile | size;                                            // read number of elements in the list
    135135                  if ( eof( unsortedfile ) ) break;
  • tests/config.py.in

    r90cac45 r4bd3069  
    55"""
    66
    7 SRCDIR   = "@srcdir@"
    8 BUILDDIR = "@builddir@"
     7SRCDIR   = "@abs_srcdir@"
     8BUILDDIR = "@abs_builddir@"
    99HOSTARCH = "@host_cpu@"
  • tests/coroutine/fibonacci.c

    r90cac45 r4bd3069  
    1111// Created On       : Thu Jun  8 07:29:37 2017
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Fri Apr 27 08:55:31 2018
    14 // Update Count     : 19
     13// Last Modified On : Thu Aug 16 08:18:16 2018
     14// Update Count     : 20
    1515//
    1616
     
    2626        fn = 1;  fn2 = fn1;  fn1 = fn;                                          // 2nd case
    2727        suspend();                                                                                      // restart last resume
    28         for ( ;; ) {
     28        for () {
    2929                fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn;                  // general case
    3030                suspend();                                                                              // restart last resume
  • tests/coroutine/fmtLines.c

    r90cac45 r4bd3069  
    1010// Created On       : Sun Sep 17 21:56:15 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 15 12:25:33 2018
    13 // Update Count     : 42
     12// Last Modified On : Thu Aug 16 08:20:54 2018
     13// Update Count     : 45
    1414//
    1515
     
    2323
    2424void main( Format & fmt ) with( fmt ) {
    25         for ( ;; ) {                                                                            // for as many characters
    26                 for ( g = 0; g < 5; g += 1 ) {                                  // groups of 5 blocks
    27                         for ( b = 0; b < 4; b += 1 ) {                          // blocks of 4 characters
    28                                 for ( ;; ) {                                                    // for newline characters
     25        for () {                                                                                        // for as many characters
     26                for ( g; 5 ) {                                                                  // groups of 5 blocks
     27                        for ( b; 4 ) {                                                          // blocks of 4 characters
     28                                for () {                                                                // for newline characters
    2929                                        suspend();
    3030                                        if ( ch != '\n' ) break;                        // ignore newline
     
    5353        Format fmt;
    5454
    55         eof: for ( ;; ) {                                                                       // read until end of file
     55  eof: for () {                                                                                 // read until end of file
    5656                sin | fmt.ch;                                                                   // read one character
    5757          if ( eof( sin ) ) break eof;                                          // eof ?
  • tests/coroutine/runningTotal.c

    r90cac45 r4bd3069  
    1010// Created On       : Wed Dec  6 08:05:27 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec  6 08:09:24 2017
    13 // Update Count     : 2
     12// Last Modified On : Thu Aug 16 08:22:29 2018
     13// Update Count     : 3
    1414//
    1515
     
    2929
    3030void main( RunTotal & rntl ) with( rntl ) {
    31         for ( ;; ) {
     31        for () {
    3232                update( rntl, input );
    3333        } // for
     
    4141int main() {
    4242        RunTotal rntl;
    43         for ( int i = 0; i < 10; i += 1 ) {
     43        for ( i; 10 ) {
    4444                sout | i | add( rntl, i ) | endl;
    4545        } // for
  • tests/fallthrough.c

    r90cac45 r4bd3069  
    1010// Created On       : Wed Mar 14 10:06:25 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 14 22:45:13 2018
    13 // Update Count     : 13
     12// Last Modified On : Thu Aug 16 08:21:46 2018
     13// Update Count     : 14
    1414//
    1515
     
    9292        choose ( 3 ) {
    9393                case 2:
    94                         for ( ;; ) {
     94                        for () {
    9595                                choose ( 2 ) {
    9696                                        case 1:
  • tests/forctrl.c

    r90cac45 r4bd3069  
    1010// Created On       : Wed Aug  8 18:32:59 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug  9 07:50:48 2018
    13 // Update Count     : 5
     12// Last Modified On : Thu Aug 16 09:25:47 2018
     13// Update Count     : 6
    1414//
    1515
    16 #include <fstream>
     16#include <fstream.hfa>
    1717
    1818struct S { int i, j; };
  • tests/labelledExit.c

    r90cac45 r4bd3069  
    1010// Created On       : Wed Aug 10 07:29:39 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 07:30:15 2016
    13 // Update Count     : 1
     12// Last Modified On : Thu Aug 16 08:55:39 2018
     13// Update Count     : 3
    1414//
    1515
     
    6060        }
    6161
    62   D: for ( ;; ) {
     62  D: for () {
    6363                break D;
    6464                continue D;
     
    6767  Z : i += 1;
    6868        goto Z;
    69   X: Y: for ( ;; ) {
     69  X: Y: for () {
    7070                i += 1;
    7171                if ( i > 5 ) continue X;
     
    7474                break;
    7575        }
    76   XX: for ( ;; ) {
    77           YY: for ( ;; ) {
    78                   ZZ: for ( ;; ) {
     76  XX: for () {
     77          YY: for () {
     78                  ZZ: for () {
    7979                                i += 1;
    8080                                if ( i > 5 ) continue XX;
     
    8989        }
    9090
    91         for ( ;; ) ;
     91        for () ;
    9292        for ( int i = 0 ;; ) ;
    9393        for (  ; i < 0; ) ;
     
    9797  L20: L21: L22: L23: L24: L25: L26: L27: L28: L29:
    9898  L31: L32: L33: L34:
    99         for ( ;; ) {
     99        for () {
    100100                break L0;
    101101        }
  • tests/pybin/settings.py

    r90cac45 r4bd3069  
    66
    77try :
    8         sys.path.append(os.getcwd())
     8        testpath = os.path.dirname(os.path.abspath(os.path.join(os.getcwd(), sys.argv[0])))
     9        sys.path.append(testpath)
    910        import config
    1011
    1112        SRCDIR = os.path.abspath(config.SRCDIR)
    1213        BUILDDIR = os.path.abspath(config.BUILDDIR)
     14        os.chdir(testpath)
     15
    1316except:
    1417        print('ERROR: missing config.py, re-run configure script.', file=sys.stderr)
     
    8891                self.flags  = """INSTALL_FLAGS="%s" """ % ("" if value else "-in-tree")
    8992
     93class Timeouts:
     94        def __init__(self, ts, tg):
     95                self.single = Timeouts.check(ts)
     96                self.total  = Timeouts.check(tg)
     97
     98        @classmethod
     99        def check(_, value):
     100                if value < 1:
     101                        print("Timeouts must be at least 1 second", file=sys.stderr)
     102                        sys.exit(1)
     103
     104                return value
     105
    90106def init( options ):
    91107        global arch
     
    95111        global debug
    96112        global install
     113        global timeout
    97114
    98115        dry_run    = options.dry_run
     
    102119        install    = Install(options.install)
    103120        arch       = Architecture(options.arch)
     121        timeout    = Timeouts(options.timeout, options.global_timeout)
    104122
    105123
     
    110128
    111129def validate():
    112         make_ret, _ = tools.make( ".validate", error_file = ".validate.err", redirects  = "2> /dev/null 1> /dev/null", )
     130        errf = os.path.join(BUILDDIR, ".validate.err")
     131        make_ret, _ = tools.make( ".validate", error_file = errf, redirects  = "2> /dev/null 1> /dev/null", )
    113132        if make_ret != 0:
    114                 with open (".validate.err", "r") as myfile:
     133                with open (errf, "r") as myfile:
    115134                        error=myfile.read()
    116135                print("ERROR: Invalid configuration %s:%s" % (arch.string, debug.string), file=sys.stderr)
    117136                print("       verify returned : \n%s" % error, file=sys.stderr)
    118                 tools.rm("%s/.validate.err" % BUILDDIR)
     137                tools.rm(errf)
    119138                sys.exit(1)
    120139
    121         tools.rm("%s/.validate.err" % BUILDDIR)
     140        tools.rm(errf)
  • tests/test.py

    r90cac45 r4bd3069  
    8888        parser.add_argument('--install', help='Run all tests based on installed binaries or tree binaries', type=yes_no, default='no')
    8989        parser.add_argument('--arch', help='Test for specific architecture', type=str, default='')
     90        parser.add_argument('--timeout', help='Maximum duration in seconds after a single test is considered to have timed out', type=int, default=60)
     91        parser.add_argument('--global-timeout', help='Maximum cumulative duration in seconds after the ALL tests are considered to have timed out', type=int, default=7200)
    9092        parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true')
    9193        parser.add_argument('--list', help='List all test available', action='store_true')
     
    160162                if settings.dry_run or fileIsExecutable(exe_file) :
    161163                        # run test
    162                         retcode, _ = sh("timeout 60 %s > %s 2>&1" % (exe_file, out_file), input = in_file)
     164                        retcode, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe_file, out_file), input = in_file)
    163165                else :
    164166                        # simply cat the result into the output
     
    234236                        tests,
    235237                        chunksize = 1
    236                 ).get(7200)
     238                ).get(settings.timeout.total)
    237239        except KeyboardInterrupt:
    238240                pool.terminate()
     
    283285        # users may want to simply list the tests
    284286        if options.list_comp :
    285                 print("-h --help --debug --dry-run --list --arch --all --regenerate-expected -j --jobs ", end='')
     287                print("-h --help --debug --dry-run --list --arch --all --regenerate-expected --install --timeout --global-timeout -j --jobs ", end='')
    286288                print(" ".join(map(lambda t: "%s" % (t.target()), tests)))
    287289
Note: See TracChangeset for help on using the changeset viewer.