Changeset 2055098 for src


Ignore:
Timestamp:
May 1, 2017, 1:40:13 PM (8 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
5544465, ed8a0d2
Parents:
12d3187 (diff), 13e2c54 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Location:
src
Files:
9 added
1 deleted
27 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/libcfa/concurrency/invoke.h

    r12d3187 r2055098  
    3838      };
    3939
    40       struct __thread_stack_t {
    41             struct thread_desc * top;
     40      struct __condition_stack_t {
     41            struct __condition_criterion_t * top;
    4242      };
    4343
     
    4848            struct thread_desc * pop_head( struct __thread_queue_t * );
    4949
    50             void ?{}( struct __thread_stack_t * );
    51             void push( struct __thread_stack_t *, struct thread_desc * );           
    52             struct thread_desc * pop( struct __thread_stack_t * );
     50            void ?{}( struct __condition_stack_t * );
     51            void push( struct __condition_stack_t *, struct __condition_criterion_t * );
     52            struct __condition_criterion_t * pop( struct __condition_stack_t * );
    5353
    5454            void ?{}(spinlock * this);
     
    8282            struct thread_desc * owner;               // current owner of the monitor
    8383            struct __thread_queue_t entry_queue;      // queue of threads that are blocked waiting for the monitor
    84             struct __thread_stack_t signal_stack;     // stack of threads to run next once we exit the monitor
     84            struct __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
    8585            struct monitor_desc * stack_owner;        // if bulk acquiring was used we need to synchronize signals with an other monitor
    8686            unsigned int recursion;                   // monitor routines can be called recursively, we need to keep track of that
  • src/libcfa/concurrency/kernel

    r12d3187 r2055098  
    5555//-----------------------------------------------------------------------------
    5656// Processor
    57 enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule };
     57enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule, Release_Multi, Release_Multi_Schedule };
     58
     59//TODO use union, many of these fields are mutually exclusive (i.e. MULTI vs NOMULTI)
    5860struct FinishAction {
    5961        FinishOpCode action_code;
    6062        thread_desc * thrd;
    6163        spinlock * lock;
     64        spinlock ** locks;
     65        unsigned short lock_count;
     66        thread_desc ** thrds;
     67        unsigned short thrd_count;
    6268};
    6369static inline void ?{}(FinishAction * this) {
  • src/libcfa/concurrency/kernel.c

    r12d3187 r2055098  
    235235                ScheduleThread( this->finish.thrd );
    236236        }
     237        else if( this->finish.action_code == Release_Multi ) {
     238                for(int i = 0; i < this->finish.lock_count; i++) {
     239                        unlock( this->finish.locks[i] );
     240                }
     241        }
     242        else if( this->finish.action_code == Release_Multi_Schedule ) {
     243                for(int i = 0; i < this->finish.lock_count; i++) {
     244                        unlock( this->finish.locks[i] );
     245                }
     246                for(int i = 0; i < this->finish.thrd_count; i++) {
     247                        ScheduleThread( this->finish.thrds[i] );
     248                }
     249        }
    237250        else {
    238251                assert(this->finish.action_code == No_Action);
     
    335348        this_processor->finish.lock = lock;
    336349        this_processor->finish.thrd = thrd;
     350        suspend();
     351}
     352
     353void ScheduleInternal(spinlock ** locks, unsigned short count) {
     354        this_processor->finish.action_code = Release_Multi;
     355        this_processor->finish.locks = locks;
     356        this_processor->finish.lock_count = count;
     357        suspend();
     358}
     359
     360void ScheduleInternal(spinlock ** locks, unsigned short lock_count, thread_desc ** thrds, unsigned short thrd_count) {
     361        this_processor->finish.action_code = Release_Multi_Schedule;
     362        this_processor->finish.locks = locks;
     363        this_processor->finish.lock_count = lock_count;
     364        this_processor->finish.thrds = thrds;
     365        this_processor->finish.thrd_count = thrd_count;
    337366        suspend();
    338367}
     
    529558}
    530559
    531 void ?{}( __thread_stack_t * this ) {
     560void ?{}( __condition_stack_t * this ) {
    532561        this->top = NULL;
    533562}
    534563
    535 void push( __thread_stack_t * this, thread_desc * t ) {
    536         assert(t->next != NULL);
     564void push( __condition_stack_t * this, __condition_criterion_t * t ) {
     565        assert( !t->next );
    537566        t->next = this->top;
    538567        this->top = t;
    539568}
    540569
    541 thread_desc * pop( __thread_stack_t * this ) {
    542         thread_desc * top = this->top;
     570__condition_criterion_t * pop( __condition_stack_t * this ) {
     571        __condition_criterion_t * top = this->top;
    543572        if( top ) {
    544573                this->top = top->next;
  • src/libcfa/concurrency/kernel_private.h

    r12d3187 r2055098  
    2626thread_desc * nextThread(cluster * this);
    2727
    28 void ScheduleInternal();
     28void ScheduleInternal(void);
    2929void ScheduleInternal(spinlock * lock);
    3030void ScheduleInternal(thread_desc * thrd);
    3131void ScheduleInternal(spinlock * lock, thread_desc * thrd);
     32void ScheduleInternal(spinlock ** locks, unsigned short count);
     33void ScheduleInternal(spinlock ** locks, unsigned short count, thread_desc ** thrds, unsigned short thrd_count);
    3234
    3335//-----------------------------------------------------------------------------
  • src/libcfa/concurrency/monitor

    r12d3187 r2055098  
    4646//-----------------------------------------------------------------------------
    4747// Internal scheduling
     48
     49struct __condition_criterion_t {
     50        bool ready;                                             //Whether or not the criterion is met (True if met)
     51        monitor_desc * target;                          //The monitor this criterion concerns
     52        struct __condition_node_t * owner;              //The parent node to which this criterion belongs
     53        __condition_criterion_t * next;         //Intrusive linked list Next field
     54};
     55
     56struct __condition_node_t {
     57        thread_desc * waiting_thread;                   //Thread that needs to be woken when all criteria are met
     58        __condition_criterion_t * criteria;     //Array of criteria (Criterions are contiguous in memory)
     59        unsigned short count;                           //Number of criterions in the criteria
     60        __condition_node_t * next;                      //Intrusive linked list Next field
     61};
     62
     63struct __condition_blocked_queue_t {
     64        __condition_node_t * head;
     65        __condition_node_t ** tail;
     66};
     67
     68void ?{}( __condition_blocked_queue_t * );
     69void append( __condition_blocked_queue_t *, __condition_node_t * );
     70__condition_node_t * pop_head( __condition_blocked_queue_t * );
     71
    4872struct condition {
    49         __thread_queue_t blocked;
    50         monitor_desc ** monitors;
    51         unsigned short monitor_count;
     73        __condition_blocked_queue_t blocked;    //Link list which contains the blocked threads as-well as the information needed to unblock them
     74        monitor_desc ** monitors;                       //Array of monitor pointers (Monitors are NOT contiguous in memory)
     75        unsigned short monitor_count;                   //Number of monitors in the array
    5276};
    5377
  • src/libcfa/concurrency/monitor.c

    r12d3187 r2055098  
    2020#include "libhdr.h"
    2121
    22 void set_owner( monitor_desc * this, thread_desc * owner ) {
    23         //Pass the monitor appropriately
    24         this->owner = owner;
    25 
    26         //We are passing the monitor to someone else, which means recursion level is not 0
    27         this->recursion = owner ? 1 : 0;
    28 }
     22//-----------------------------------------------------------------------------
     23// Forward declarations
     24static inline void set_owner( monitor_desc * this, thread_desc * owner );
     25static inline thread_desc * next_thread( monitor_desc * this );
     26
     27static inline void lock_all( spinlock ** locks, unsigned short count );
     28static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
     29static inline void unlock_all( spinlock ** locks, unsigned short count );
     30static inline void unlock_all( monitor_desc ** locks, unsigned short count );
     31
     32static inline void save_recursion   ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count );
     33static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
     34
     35static inline thread_desc * check_condition( __condition_criterion_t * );
     36static inline void brand_condition( condition * );
     37static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
     38
     39//-----------------------------------------------------------------------------
     40// Enter/Leave routines
     41
    2942
    3043extern "C" {
    31         void __enter_monitor_desc(monitor_desc * this, monitor_desc * leader) {
     44        void __enter_monitor_desc(monitor_desc * this) {
    3245                lock( &this->lock );
    3346                thread_desc * thrd = this_thread();
    3447
    35                 // //Update the stack owner
    36                 // this->stack_owner = leader;
    37 
    38                 LIB_DEBUG_PRINT_SAFE("Entering %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
     48                LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
    3949
    4050                if( !this->owner ) {
     
    6171
    6272        // leave pseudo code :
    63         //      decrement level
    64         //      leve == 0 ?
    65         //              no : done
    66         //              yes :
    67         //                      signal stack empty ?
    68         //                              has leader :
    69         //                                      bulk acquiring means we don't own the signal stack
    70         //                                      ignore it but don't release the monitor
    71         //                              yes :
    72         //                                      next in entry queue is new owner
    73         //                              no :
    74         //                                      top of the signal stack is the owner
    75         //                                      context switch to him right away
    76         //
    77         void __leave_monitor_desc(monitor_desc * this, monitor_desc * leader) {
     73        //      TODO
     74        void __leave_monitor_desc(monitor_desc * this) {
    7875                lock( &this->lock );
    7976
    80                 LIB_DEBUG_PRINT_SAFE("Leaving %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
    81 
    8277                thread_desc * thrd = this_thread();
    83                 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", this->owner, thrd, this->recursion );
     78
     79                LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     80                assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion );
    8481
    8582                //Leaving a recursion level, decrement the counter
     
    8986                //it means we don't need to do anything
    9087                if( this->recursion != 0) {
    91                         // this->stack_owner = leader;
    9288                        unlock( &this->lock );
    9389                        return;
    9490                }
    95                        
    96                 // //If we don't own the signal stack then just leave it to the owner
    97                 // if( this->stack_owner ) {
    98                 //      this->stack_owner = leader;
    99                 //      unlock( &this->lock );
    100                 //      return;
    101                 // }
    102 
    103                 //We are the stack owner and have left the last recursion level.
    104                 //We are in charge of passing the monitor
    105                 thread_desc * new_owner = 0;
    106 
    107                 //Check the signaller stack
    108                 new_owner = pop( &this->signal_stack );
    109                 if( new_owner ) {
    110                         //The signaller stack is not empty,
    111                         //transfer control immediately
    112                         set_owner( this, new_owner );
    113                         // this->stack_owner = leader;
    114                         ScheduleInternal( &this->lock, new_owner );
    115                         return;
    116                 }
    117                
    118                 // No signaller thread
    119                 // Get the next thread in the entry_queue
    120                 new_owner = pop_head( &this->entry_queue );
    121                 set_owner( this, new_owner );
    122 
    123                 // //Update the stack owner
    124                 // this->stack_owner = leader;
     91
     92                thread_desc * new_owner = next_thread( this );
    12593
    12694                //We can now let other threads in safely
     
    133101
    134102static inline void enter(monitor_desc ** monitors, int count) {
    135         __enter_monitor_desc( monitors[0], NULL );
    136         for(int i = 1; i < count; i++) {
    137                 __enter_monitor_desc( monitors[i], monitors[0] );
     103        for(int i = 0; i < count; i++) {
     104                __enter_monitor_desc( monitors[i] );
    138105        }
    139106}
    140107
    141108static inline void leave(monitor_desc ** monitors, int count) {
    142         __leave_monitor_desc( monitors[0], NULL );
    143         for(int i = count - 1; i >= 1; i--) {
    144                 __leave_monitor_desc( monitors[i], monitors[0] );
     109        for(int i = count - 1; i >= 0; i--) {
     110                __leave_monitor_desc( monitors[i] );
    145111        }
    146112}
     
    169135// Internal scheduling
    170136void wait( condition * this ) {
    171         assertf(false, "NO SUPPORTED");
    172         // LIB_DEBUG_FPRINTF("Waiting\n");
    173         thread_desc * this_thrd = this_thread();
    174 
    175         if( !this->monitors ) {
    176                 this->monitors = this_thrd->current_monitors;
    177                 this->monitor_count = this_thrd->current_monitor_count;
    178         }
     137        LIB_DEBUG_PRINT_SAFE("Waiting\n");
     138
     139        brand_condition( this );
     140
     141        //Check that everything is as expected
     142        assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );
     143        assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );
    179144
    180145        unsigned short count = this->monitor_count;
    181 
    182         //Check that everything is as expected
    183         assert( this->monitors != NULL );
    184         assert( this->monitor_count != 0 );
    185 
    186146        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    187147        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    188148
    189         // LIB_DEBUG_FPRINTF("Getting ready to wait\n");
    190 
    191         //Loop on all the monitors and release the owner
    192         for( unsigned int i = 0; i < count; i++ ) {
    193                 monitor_desc * cur = this->monitors[i];
    194 
    195                 assert( cur );
    196 
    197                 // LIB_DEBUG_FPRINTF("cur %p lock %p\n", cur, &cur->lock);
    198 
    199                 //Store the locks for later
    200                 locks[i] = &cur->lock;
    201 
    202                 //Protect the monitors
    203                 lock( locks[i] );
    204                 {               
    205                         //Save the recursion levels
    206                         recursions[i] = cur->recursion;
    207 
    208                         //Release the owner
    209                         cur->recursion = 0;
    210                         cur->owner = NULL;
    211                 }
    212                 //Release the monitor
    213                 unlock( locks[i] );
    214         }
    215 
    216         // LIB_DEBUG_FPRINTF("Waiting now\n");
    217 
    218         //Everything is ready to go to sleep
    219         ScheduleInternal( locks, count );
     149        LIB_DEBUG_PRINT_SAFE("count %i\n", count);
     150
     151        __condition_node_t waiter;
     152        waiter.waiting_thread = this_thread();
     153        waiter.count = count;
     154        waiter.next = NULL;
     155
     156        __condition_criterion_t criteria[count];
     157        for(int i = 0; i < count; i++) {
     158                criteria[i].ready  = false;
     159                criteria[i].target = this->monitors[i];
     160                criteria[i].owner  = &waiter;
     161                criteria[i].next   = NULL;
     162                LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] );
     163        }
     164
     165        waiter.criteria = criteria;
     166        append( &this->blocked, &waiter );
     167
     168        lock_all( this->monitors, locks, count );
     169        save_recursion( this->monitors, recursions, count );
     170        //DON'T unlock, ask the kernel to do it
     171
     172        //Find the next thread(s) to run
     173        unsigned short thread_count = count;
     174        thread_desc * threads[ count ];
     175
     176        for( int i = 0; i < count; i++) {
     177                thread_desc * new_owner = next_thread( this->monitors[i] );
     178                thread_count = insert_unique( threads, i, new_owner );
     179        }
     180
     181        LIB_DEBUG_PRINT_SAFE("Will unblock: ");
     182        for(int i = 0; i < thread_count; i++) {
     183                LIB_DEBUG_PRINT_SAFE("%p ", threads[i]);
     184        }
     185        LIB_DEBUG_PRINT_SAFE("\n");
     186
     187        // Everything is ready to go to sleep
     188        ScheduleInternal( locks, count, threads, thread_count );
    220189
    221190
     
    224193
    225194        //We are back, restore the owners and recursions
    226         for( unsigned int i = 0; i < count; i++ ) {
    227                 monitor_desc * cur = this->monitors[i];
    228 
    229                 //Protect the monitors
    230                 lock( locks[i] );
    231                 {
    232                         //Release the owner
    233                         cur->owner = this_thrd;
    234                         cur->recursion = recursions[i];
    235                 }
    236                 //Release the monitor
    237                 unlock( locks[i] );
    238         }
    239 }
    240 
    241 static void __signal_internal( condition * this ) {
    242         assertf(false, "NO SUPPORTED");
    243         if( !this->blocked.head ) return;
     195        lock_all( locks, count );
     196        restore_recursion( this->monitors, recursions, count );
     197        unlock_all( locks, count );
     198}
     199
     200void signal( condition * this ) {
     201        if( !this->blocked.head ) {
     202                LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
     203                return;
     204        }
    244205
    245206        //Check that everything is as expected
    246207        assert( this->monitors );
    247208        assert( this->monitor_count != 0 );
     209
     210        unsigned short count = this->monitor_count;
    248211       
    249212        LIB_DEBUG_DO(
    250                 if ( this->monitors != this_thread()->current_monitors ) {
    251                         abortf( "Signal on condition %p made outside of the correct monitor(s)", this );
     213                thread_desc * this_thrd = this_thread();
     214                if ( this->monitor_count != this_thrd->current_monitor_count ) {
     215                        abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count );
    252216                } // if
     217
     218                for(int i = 0; i < this->monitor_count; i++) {
     219                        if ( this->monitors[i] != this_thrd->current_monitors[i] ) {
     220                                abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] );
     221                        } // if
     222                }
    253223        );
    254224
    255         monitor_desc * owner = this->monitors[0];
    256         lock( &owner->lock );
    257         {
    258                 thread_desc * unblock = pop_head( &this->blocked );
    259                 push( &owner->signal_stack, unblock );
    260         }
    261         unlock( &owner->lock );
    262 }
    263 
    264 void signal( condition * this ) {
    265         __signal_internal( this );
    266 }
     225        lock_all( this->monitors, NULL, count );
     226        LIB_DEBUG_PRINT_SAFE("Signalling");
     227
     228        __condition_node_t * node = pop_head( &this->blocked );
     229        for(int i = 0; i < count; i++) {
     230                __condition_criterion_t * crit = &node->criteria[i];
     231                LIB_DEBUG_PRINT_SAFE(" %p", crit->target);
     232                assert( !crit->ready );
     233                push( &crit->target->signal_stack, crit );
     234        }
     235
     236        LIB_DEBUG_PRINT_SAFE("\n");
     237
     238        unlock_all( this->monitors, count );
     239}
     240
     241//-----------------------------------------------------------------------------
     242// Utilities
     243
     244static inline void set_owner( monitor_desc * this, thread_desc * owner ) {
     245        //Pass the monitor appropriately
     246        this->owner = owner;
     247
     248        //We are passing the monitor to someone else, which means recursion level is not 0
     249        this->recursion = owner ? 1 : 0;
     250}
     251
     252static inline thread_desc * next_thread( monitor_desc * this ) {
     253        //Check the signaller stack
     254        __condition_criterion_t * urgent = pop( &this->signal_stack );
     255        if( urgent ) {
     256                //The signaller stack is not empty,
     257                //regardless of if we are ready to baton pass,
     258                //we need to set the monitor as in use
     259                set_owner( this,  urgent->owner->waiting_thread );
     260
     261                return check_condition( urgent );
     262        }
     263
     264        // No signaller thread
     265        // Get the next thread in the entry_queue
     266        thread_desc * new_owner = pop_head( &this->entry_queue );
     267        set_owner( this, new_owner );
     268
     269        return new_owner;
     270}
     271
     272static inline void lock_all( spinlock ** locks, unsigned short count ) {
     273        for( int i = 0; i < count; i++ ) {
     274                lock( locks[i] );
     275        }
     276}
     277
     278static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count ) {
     279        for( int i = 0; i < count; i++ ) {
     280                spinlock * l = &source[i]->lock;
     281                lock( l );
     282                if(locks) locks[i] = l;
     283        }
     284}
     285
     286static inline void unlock_all( spinlock ** locks, unsigned short count ) {
     287        for( int i = 0; i < count; i++ ) {
     288                unlock( locks[i] );
     289        }
     290}
     291
     292static inline void unlock_all( monitor_desc ** locks, unsigned short count ) {
     293        for( int i = 0; i < count; i++ ) {
     294                unlock( &locks[i]->lock );
     295        }
     296}
     297
     298
     299static inline void save_recursion   ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count ) {
     300        for( int i = 0; i < count; i++ ) {
     301                recursions[i] = ctx[i]->recursion;
     302        }
     303}
     304
     305static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ) {
     306        for( int i = 0; i < count; i++ ) {
     307                ctx[i]->recursion = recursions[i];
     308        }
     309}
     310
     311// Function has 2 different behavior
     312// 1 - Marks a monitors as being ready to run
     313// 2 - Checks if all the monitors are ready to run
     314//     if so return the thread to run
     315static inline thread_desc * check_condition( __condition_criterion_t * target ) {
     316        __condition_node_t * node = target->owner;
     317        unsigned short count = node->count;
     318        __condition_criterion_t * criteria = node->criteria;
     319
     320        bool ready2run = true;
     321
     322        for(    int i = 0; i < count; i++ ) {
     323                LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target );
     324                if( &criteria[i] == target ) {
     325                        criteria[i].ready = true;
     326                        LIB_DEBUG_PRINT_SAFE( "True\n" );
     327                }
     328
     329                ready2run = criteria[i].ready && ready2run;
     330        }
     331
     332        LIB_DEBUG_PRINT_SAFE( "Runing %i\n", ready2run );
     333        return ready2run ? node->waiting_thread : NULL;
     334}
     335
     336static inline void brand_condition( condition * this ) {
     337        thread_desc * thrd = this_thread();
     338        if( !this->monitors ) {
     339                LIB_DEBUG_PRINT_SAFE("Branding\n");
     340                assertf( thrd->current_monitors != NULL, "No current monitor to brand condition", thrd->current_monitors );
     341                this->monitors = thrd->current_monitors;
     342                this->monitor_count = thrd->current_monitor_count;
     343        }
     344}
     345
     346static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ) {
     347        for(int i = 0; i < end; i++) {
     348                if( thrds[i] == val ) return end;
     349        }
     350
     351        thrds[end] = val;
     352        return end + 1;
     353}
     354
     355void ?{}( __condition_blocked_queue_t * this ) {
     356        this->head = NULL;
     357        this->tail = &this->head;
     358}
     359
     360void append( __condition_blocked_queue_t * this, __condition_node_t * c ) {
     361        assert(this->tail != NULL);
     362        *this->tail = c;
     363        this->tail = &c->next;
     364}
     365
     366__condition_node_t * pop_head( __condition_blocked_queue_t * this ) {
     367        __condition_node_t * head = this->head;
     368        if( head ) {
     369                this->head = head->next;
     370                if( !head->next ) {
     371                        this->tail = &this->head;
     372                }
     373                head->next = NULL;
     374        }
     375        return head;
     376}
  • src/libcfa/interpose.c

    r12d3187 r2055098  
    2626
    2727#include "libhdr/libdebug.h"
     28#include "libhdr/libtools.h"
    2829#include "startup.h"
    29 
    30 void abortf( const char *fmt, ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));
    3130
    3231void interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
     
    115114static char abort_text[ abort_text_size ];
    116115
    117 void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
    118         void * kernel_data = kernel_abort();
    119        
    120         int len;
    121        
    122         if( fmt ) {
    123                 va_list args;
    124                 va_start( args, fmt );
     116extern "C" {
     117        void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
     118                void * kernel_data = kernel_abort();
    125119
    126                 len = vsnprintf( abort_text, abort_text_size, fmt, args );
     120                int len;
    127121
    128                 va_end( args );
     122                if( fmt ) {
     123                        va_list args;
     124                        va_start( args, fmt );
    129125
     126                        len = vsnprintf( abort_text, abort_text_size, fmt, args );
     127
     128                        va_end( args );
     129
     130                        __lib_debug_write( STDERR_FILENO, abort_text, len );
     131                        __lib_debug_write( STDERR_FILENO, "\n", 1 );
     132                }
     133
     134                len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid)
    130135                __lib_debug_write( STDERR_FILENO, abort_text, len );
    131                 __lib_debug_write( STDERR_FILENO, "\n", 1 );
    132         }
    133 
    134         len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld)\n", (long int)getpid() ); // use UNIX pid (versus getPid)
    135         __lib_debug_write( STDERR_FILENO, abort_text, len );
    136136
    137137
    138         kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     138                kernel_abort_msg( kernel_data, abort_text, abort_text_size );
    139139
    140         libc_abort();
     140                libc_abort();
     141        }
    141142}
  • src/libcfa/libhdr/libtools.h

    r12d3187 r2055098  
    2222// } // libAbort
    2323
    24 #define abortf(...) abort();
    25 
     24#ifdef __cforall
     25extern "C" {
     26#endif
     27void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));
     28#ifdef __cforall
     29}
     30#endif
    2631
    2732#endif //__LIB_TOOLS_H__
  • src/libcfa/rational

    r12d3187 r2055098  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Wed May  4 14:11:45 2016
    15 // Update Count     : 16
     14// Last Modified On : Mon May  1 08:25:06 2017
     15// Update Count     : 33
    1616//
     17
    1718#ifndef RATIONAL_H
    1819#define RATIONAL_H
     
    2122
    2223// implementation
     24typedef long int RationalImpl;
    2325struct Rational {
    24         long int numerator, denominator;                                        // invariant: denominator > 0
     26        RationalImpl numerator, denominator;                                    // invariant: denominator > 0
    2527}; // Rational
    2628
     
    3133// constructors
    3234void ?{}( Rational * r );
    33 void ?{}( Rational * r, long int n );
    34 void ?{}( Rational * r, long int n, long int d );
     35void ?{}( Rational * r, RationalImpl n );
     36void ?{}( Rational * r, RationalImpl n, RationalImpl d );
    3537
    36 // getter/setter for numerator/denominator
    37 long int numerator( Rational r );
    38 long int numerator( Rational r, long int n );
    39 long int denominator( Rational r );
    40 long int denominator( Rational r, long int d );
     38// getter for numerator/denominator
     39RationalImpl numerator( Rational r );
     40RationalImpl denominator( Rational r );
     41[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src );
     42// setter for numerator/denominator
     43RationalImpl numerator( Rational r, RationalImpl n );
     44RationalImpl denominator( Rational r, RationalImpl d );
    4145
    4246// comparison
     
    5761// conversion
    5862double widen( Rational r );
    59 Rational narrow( double f, long int md );
     63Rational narrow( double f, RationalImpl md );
    6064
    6165// I/O
  • src/libcfa/rational.c

    r12d3187 r2055098  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul  9 11:18:04 2016
    13 // Update Count     : 40
     12// Last Modified On : Thu Apr 27 17:05:06 2017
     13// Update Count     : 51
    1414//
    1515
     
    3030// Calculate greatest common denominator of two numbers, the first of which may be negative. Used to reduce rationals.
    3131// alternative: https://en.wikipedia.org/wiki/Binary_GCD_algorithm
    32 static long int gcd( long int a, long int b ) {
     32static RationalImpl gcd( RationalImpl a, RationalImpl b ) {
    3333        for ( ;; ) {                                                                            // Euclid's algorithm
    34                 long int r = a % b;
     34                RationalImpl r = a % b;
    3535          if ( r == 0 ) break;
    3636                a = b;
     
    4040} // gcd
    4141
    42 static long int simplify( long int *n, long int *d ) {
     42static RationalImpl simplify( RationalImpl *n, RationalImpl *d ) {
    4343        if ( *d == 0 ) {
    4444                serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl;
     
    5656} // rational
    5757
    58 void ?{}( Rational * r, long int n ) {
     58void ?{}( Rational * r, RationalImpl n ) {
    5959        r{ n, 1 };
    6060} // rational
    6161
    62 void ?{}( Rational * r, long int n, long int d ) {
    63         long int t = simplify( &n, &d );                                        // simplify
     62void ?{}( Rational * r, RationalImpl n, RationalImpl d ) {
     63        RationalImpl t = simplify( &n, &d );                            // simplify
    6464        r->numerator = n / t;
    6565        r->denominator = d / t;
     
    6767
    6868
    69 // getter/setter for numerator/denominator
    70 
    71 long int numerator( Rational r ) {
     69// getter for numerator/denominator
     70
     71RationalImpl numerator( Rational r ) {
    7272        return r.numerator;
    7373} // numerator
    7474
    75 long int numerator( Rational r, long int n ) {
    76         long int prev = r.numerator;
    77         long int t = gcd( abs( n ), r.denominator );            // simplify
     75RationalImpl denominator( Rational r ) {
     76        return r.denominator;
     77} // denominator
     78
     79[ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src ) {
     80        return *dest = src.[ numerator, denominator ];
     81}
     82
     83// setter for numerator/denominator
     84
     85RationalImpl numerator( Rational r, RationalImpl n ) {
     86        RationalImpl prev = r.numerator;
     87        RationalImpl t = gcd( abs( n ), r.denominator );                // simplify
    7888        r.numerator = n / t;
    7989        r.denominator = r.denominator / t;
     
    8191} // numerator
    8292
    83 long int denominator( Rational r ) {
    84         return r.denominator;
    85 } // denominator
    86 
    87 long int denominator( Rational r, long int d ) {
    88         long int prev = r.denominator;
    89         long int t = simplify( &r.numerator, &d );                      // simplify
     93RationalImpl denominator( Rational r, RationalImpl d ) {
     94        RationalImpl prev = r.denominator;
     95        RationalImpl t = simplify( &r.numerator, &d );                  // simplify
    9096        r.numerator = r.numerator / t;
    9197        r.denominator = d / t;
     
    170176
    171177// http://www.ics.uci.edu/~eppstein/numth/frap.c
    172 Rational narrow( double f, long int md ) {
     178Rational narrow( double f, RationalImpl md ) {
    173179        if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
    174180                return (Rational){ f, 1};                                               // truncate fraction
     
    176182
    177183        // continued fraction coefficients
    178         long int m00 = 1, m11 = 1, m01 = 0, m10 = 0;
    179         long int ai, t;
     184        RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
     185        RationalImpl ai, t;
    180186
    181187        // find terms until denom gets too big
    182188        for ( ;; ) {
    183                 ai = (long int)f;
     189                ai = (RationalImpl)f;
    184190          if ( ! (m10 * ai + m11 <= md) ) break;
    185191                t = m00 * ai + m01;
     
    202208forall( dtype istype | istream( istype ) )
    203209istype * ?|?( istype *is, Rational *r ) {
    204         long int t;
     210        RationalImpl t;
    205211        is | &(r->numerator) | &(r->denominator);
    206212        t = simplify( &(r->numerator), &(r->denominator) );
  • src/tests/.expect/32/attributes.txt

    r12d3187 r2055098  
    1 attributes.c:74 error: cannot redefine typedef: ptrdiff_t
    2 attributes.c:75 error: cannot redefine typedef: size_t
    3 make: *** [attributes] Error 1
     1__attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size);
     2__attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
     3__attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);
     4__attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void));
     5__attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status);
     6extern int printf(const char *__restrict __format, ...);
     7int __la__Fi___1(){
     8    int ___retval_la__i_1;
     9    L: __attribute__ ((unused)) ((void)1);
     10}
     11__attribute__ ((unused)) struct __anonymous0 {
     12};
     13static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
     14static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
     15static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
     16static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
     17static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
     18}
     19static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
     20}
     21static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
     22}
     23static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
     24    return ((struct __anonymous0 )___src__13s__anonymous0_1);
     25}
     26__attribute__ ((unused)) struct Agn1;
     27__attribute__ ((unused)) struct Agn2 {
     28};
     29static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
     30static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
     31static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
     32static inline struct Agn2 ___operator_assign__F5sAgn2_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
     33static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){
     34}
     35static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
     36}
     37static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){
     38}
     39static inline struct Agn2 ___operator_assign__F5sAgn2_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
     40    return ((struct Agn2 )___src__5sAgn2_1);
     41}
     42enum __attribute__ ((unused)) __anonymous1 {
     43    __E1__C13e__anonymous1_1,
     44};
     45enum __attribute__ ((unused)) Agn3;
     46enum __attribute__ ((packed)) Agn3 {
     47    __E2__C5eAgn3_1,
     48};
     49__attribute__ ((unused)) struct __anonymous2;
     50__attribute__ ((unused)) struct __anonymous3;
     51struct Fdl {
     52    __attribute__ ((unused)) int __f1__i_1;
     53    __attribute__ ((unused)) int __f2__i_1;
     54    __attribute__ ((unused,unused)) int __f3__i_1;
     55    __attribute__ ((unused)) int __f4__i_1;
     56    __attribute__ ((unused,unused)) int __f5__i_1;
     57    __attribute__ ((used,packed)) int __f6__i_1;
     58    __attribute__ ((used,unused,unused)) int __f7__i_1;
     59    __attribute__ ((used,used,unused)) int __f8__i_1;
     60    __attribute__ ((unused)) int __anonymous_object0;
     61    __attribute__ ((unused,unused)) int *__f9__Pi_1;
     62};
     63static inline void ___constructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1);
     64static inline void ___constructor__F_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1);
     65static inline void ___destructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1);
     66static inline struct Fdl ___operator_assign__F4sFdl_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1);
     67static inline void ___constructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1){
     68    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))) /* ?{} */);
     69    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ?{} */);
     70    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */);
     71    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */);
     72    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */);
     73    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     74    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     75    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     76    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     77}
     78static inline void ___constructor__F_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1){
     79    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=___src__4sFdl_1.__f1__i_1) /* ?{} */);
     80    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=___src__4sFdl_1.__f2__i_1) /* ?{} */);
     81    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=___src__4sFdl_1.__f3__i_1) /* ?{} */);
     82    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=___src__4sFdl_1.__f4__i_1) /* ?{} */);
     83    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=___src__4sFdl_1.__f5__i_1) /* ?{} */);
     84    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=___src__4sFdl_1.__f6__i_1) /* ?{} */);
     85    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=___src__4sFdl_1.__f7__i_1) /* ?{} */);
     86    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=___src__4sFdl_1.__f8__i_1) /* ?{} */);
     87    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))=___src__4sFdl_1.__f9__Pi_1) /* ?{} */);
     88}
     89static inline void ___destructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1){
     90    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ^?{} */);
     91    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ^?{} */);
     92    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ^?{} */);
     93    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ^?{} */);
     94    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ^?{} */);
     95    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ^?{} */);
     96    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ^?{} */);
     97    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ^?{} */);
     98    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))) /* ^?{} */);
     99}
     100static inline struct Fdl ___operator_assign__F4sFdl_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1){
     101    ((void)((*___dst__P4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1));
     102    ((void)((*___dst__P4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1));
     103    ((void)((*___dst__P4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1));
     104    ((void)((*___dst__P4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1));
     105    ((void)((*___dst__P4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1));
     106    ((void)((*___dst__P4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1));
     107    ((void)((*___dst__P4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1));
     108    ((void)((*___dst__P4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1));
     109    ((void)((*___dst__P4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1));
     110    return ((struct Fdl )___src__4sFdl_1);
     111}
     112static inline void ___constructor__F_P4sFdli_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1){
     113    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     114    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))) /* ?{} */);
     115    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */);
     116    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */);
     117    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */);
     118    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     119    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     120    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     121    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     122}
     123static inline void ___constructor__F_P4sFdlii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1){
     124    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     125    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     126    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))) /* ?{} */);
     127    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */);
     128    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */);
     129    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     130    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     131    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     132    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     133}
     134static inline void ___constructor__F_P4sFdliii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1){
     135    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     136    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     137    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     138    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))) /* ?{} */);
     139    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */);
     140    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     141    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     142    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     143    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     144}
     145static inline void ___constructor__F_P4sFdliiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1){
     146    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     147    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     148    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     149    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     150    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))) /* ?{} */);
     151    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     152    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     153    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     154    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     155}
     156static inline void ___constructor__F_P4sFdliiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1){
     157    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     158    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     159    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     160    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     161    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */);
     162    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))) /* ?{} */);
     163    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     164    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     165    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     166}
     167static inline void ___constructor__F_P4sFdliiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1){
     168    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     169    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     170    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     171    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     172    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */);
     173    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */);
     174    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))) /* ?{} */);
     175    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     176    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     177}
     178static inline void ___constructor__F_P4sFdliiiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1){
     179    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     180    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     181    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     182    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     183    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */);
     184    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */);
     185    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */);
     186    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))) /* ?{} */);
     187    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     188}
     189static inline void ___constructor__F_P4sFdliiiiiiii_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1, int __f8__i_1){
     190    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     191    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     192    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     193    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     194    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */);
     195    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */);
     196    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */);
     197    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=__f8__i_1) /* ?{} */);
     198    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))) /* ?{} */);
     199}
     200static inline void ___constructor__F_P4sFdliiiiiiiiPi_autogen___1(struct Fdl *___dst__P4sFdl_1, int __f1__i_1, int __f2__i_1, int __f3__i_1, int __f4__i_1, int __f5__i_1, int __f6__i_1, int __f7__i_1, int __f8__i_1, int *__f9__Pi_1){
     201    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f1__i_1)))=__f1__i_1) /* ?{} */);
     202    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f2__i_1)))=__f2__i_1) /* ?{} */);
     203    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f3__i_1)))=__f3__i_1) /* ?{} */);
     204    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f4__i_1)))=__f4__i_1) /* ?{} */);
     205    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f5__i_1)))=__f5__i_1) /* ?{} */);
     206    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f6__i_1)))=__f6__i_1) /* ?{} */);
     207    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f7__i_1)))=__f7__i_1) /* ?{} */);
     208    ((void)((*((int *)(&(*___dst__P4sFdl_1).__f8__i_1)))=__f8__i_1) /* ?{} */);
     209    ((void)((*((int **)(&(*___dst__P4sFdl_1).__f9__Pi_1)))=__f9__Pi_1) /* ?{} */);
     210}
     211__attribute__ ((unused)) int __f__Fi___1() asm ( "xyz" );
     212__attribute__ ((used,used)) const int __vd1__Ci_1;
     213__attribute__ ((used,unused)) const int __vd2__Ci_1;
     214__attribute__ ((used,used,used,used)) const int *__vd3__PCi_1;
     215__attribute__ ((used,used,unused,used,unused)) const int *__vd4__PCi_1;
     216__attribute__ ((used,used,used)) const int __vd5__A0Ci_1[((unsigned int )5)];
     217__attribute__ ((used,used,unused,used)) const int __vd6__A0Ci_1[((unsigned int )5)];
     218__attribute__ ((used,used,used,used)) const int (*__vd7__PFCi___1)();
     219__attribute__ ((used,used,unused,used,used)) const int (*__vd8__PFCi___1)();
     220__attribute__ ((unused,used)) int __f1__Fi___1();
     221__attribute__ ((unused)) int __f1__Fi___1(){
     222    int ___retval_f1__i_1;
     223}
     224__attribute__ ((unused,unused,unused,used)) int **const __f2__FCPPi___1();
     225__attribute__ ((unused,unused,unused)) int **const __f2__FCPPi___1(){
     226    int **const ___retval_f2__CPPi_1;
     227}
     228__attribute__ ((unused,used,unused)) int (*__f3__FPA0i_i__1(int __anonymous_object1))[];
     229__attribute__ ((unused,unused)) int (*__f3__FPA0i_i__1(int __p__i_1))[]{
     230    int (*___retval_f3__PA0i_1)[];
     231}
     232__attribute__ ((unused,used,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object2);
     233__attribute__ ((unused,unused)) int (*__f4__FPFi_i____1())(int __anonymous_object3){
     234    int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
     235}
     236int __vtr__Fi___1(){
     237    int ___retval_vtr__i_1;
     238    __attribute__ ((unused,unused,used)) int __t1__i_2;
     239    __attribute__ ((unused,unused,unused,unused,unused)) int **__t2__PPi_2;
     240    __attribute__ ((unused,unused,unused)) int __t3__A0i_2[((unsigned int )5)];
     241    __attribute__ ((unused,unused,unused,unused,unused)) int **__t4__A0PPi_2[((unsigned int )5)];
     242    __attribute__ ((unused,unused,unused)) int __t5__Fi___2();
     243    __attribute__ ((unused,unused,unused,unused)) int *__t6__FPi___2();
     244}
     245int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1);
     246int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1){
     247    int ___retval_ipd1__i_1;
     248}
     249int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
     250int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
     251    int ___retval_ipd2__i_1;
     252}
     253int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
     254int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1){
     255    int ___retval_ipd3__i_1;
     256}
     257int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)());
     258int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)()){
     259    int ___retval_ipd4__i_1;
     260}
     261int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) int __Foo__i_1);
     262int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1);
     263int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1);
     264int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((unsigned int )5)]));
     265int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
     266int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
     267int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
     268int __ad__Fi___1(){
     269    int ___retval_ad__i_1;
     270    __attribute__ ((used,unused)) int __ad1__i_2;
     271    __attribute__ ((unused,unused,unused)) int *__ad2__Pi_2;
     272    __attribute__ ((unused,unused,unused)) int __ad3__A0i_2[((unsigned int )5)];
     273    __attribute__ ((unused,unused,unused,unused,unused)) int (*__ad4__PA0i_2)[((unsigned int )10)];
     274    __attribute__ ((unused,unused,unused,unused,used)) int __ad5__i_2;
     275    __attribute__ ((unused,unused,unused,unused,unused)) int __ad6__Fi___2();
     276    ((void)sizeof(__attribute__ ((unused,unused)) int ));
     277    ((void)sizeof(__attribute__ ((unused,unused,unused,unused)) int **));
     278    ((void)sizeof(__attribute__ ((unused,unused,unused)) int [5]));
     279    ((void)sizeof(__attribute__ ((unused,unused,unused)) int (*)[10]));
     280    ((void)sizeof(__attribute__ ((unused,unused,unused)) int ()));
     281    __attribute__ ((unused)) struct __anonymous4 {
     282        int __i__i_2;
     283    };
     284    inline void ___constructor__F_P13s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2){
     285        ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))) /* ?{} */);
     286    }
     287    inline void ___constructor__F_P13s__anonymous413s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, struct __anonymous4 ___src__13s__anonymous4_2){
     288        ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))=___src__13s__anonymous4_2.__i__i_2) /* ?{} */);
     289    }
     290    inline void ___destructor__F_P13s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2){
     291        ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))) /* ^?{} */);
     292    }
     293    inline struct __anonymous4 ___operator_assign__F13s__anonymous4_P13s__anonymous413s__anonymous4_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, struct __anonymous4 ___src__13s__anonymous4_2){
     294        ((void)((*___dst__P13s__anonymous4_2).__i__i_2=___src__13s__anonymous4_2.__i__i_2));
     295        return ((struct __anonymous4 )___src__13s__anonymous4_2);
     296    }
     297    inline void ___constructor__F_P13s__anonymous4i_autogen___2(struct __anonymous4 *___dst__P13s__anonymous4_2, int __i__i_2){
     298        ((void)((*((int *)(&(*___dst__P13s__anonymous4_2).__i__i_2)))=__i__i_2) /* ?{} */);
     299    }
     300    ((void)sizeof(struct __anonymous4 ));
     301    enum __attribute__ ((unused)) __anonymous5 {
     302        __R__C13e__anonymous5_2,
     303    };
     304    inline void ___constructor__F_P13e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2){
     305    }
     306    inline void ___constructor__F_P13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
     307        ((void)((*___dst__P13e__anonymous5_2)=___src__13e__anonymous5_2));
     308    }
     309    inline void ___destructor__F_P13e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2){
     310    }
     311    inline enum __anonymous5 ___operator_assign__F13e__anonymous5_P13e__anonymous513e__anonymous5_intrinsic___2(enum __anonymous5 *___dst__P13e__anonymous5_2, enum __anonymous5 ___src__13e__anonymous5_2){
     312        return ((enum __anonymous5 )((*___dst__P13e__anonymous5_2)=___src__13e__anonymous5_2));
     313    }
     314    ((void)sizeof(enum __anonymous5 ));
     315}
     316int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11);
     317int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13);
     318int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15);
     319int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)());
     320int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(__attribute__ ((unused)) int __anonymous_object19), __attribute__ ((unused,unused,unused)) int (*__anonymous_object20)(__attribute__ ((unused)) int __anonymous_object21));
     321int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)());
     322int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(__attribute__ ((unused)) int __anonymous_object25), __attribute__ ((unused,unused,unused)) int (*__anonymous_object26)(__attribute__ ((unused)) int __anonymous_object27));
     323struct Vad {
     324    __attribute__ ((unused)) int __anonymous_object28;
     325    __attribute__ ((unused,unused)) int *__anonymous_object29;
     326    __attribute__ ((unused,unused)) int __anonymous_object30[((unsigned int )10)];
     327    __attribute__ ((unused,unused)) int (*__anonymous_object31)();
     328};
     329static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
     330static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1);
     331static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
     332static inline struct Vad ___operator_assign__F4sVad_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1);
     333static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){
     334}
     335static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1){
     336}
     337static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){
     338}
     339static inline struct Vad ___operator_assign__F4sVad_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1){
     340    return ((struct Vad )___src__4sVad_1);
     341}
  • src/tests/.expect/64/attributes.txt

    r12d3187 r2055098  
    99    L: __attribute__ ((unused)) ((void)1);
    1010}
    11 struct __attribute__ ((unused)) __anonymous0 {
     11__attribute__ ((unused)) struct __anonymous0 {
    1212};
    1313static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
     
    2424    return ((struct __anonymous0 )___src__13s__anonymous0_1);
    2525}
    26 struct __attribute__ ((unused)) Agn1;
    27 struct __attribute__ ((unused)) Agn2 {
     26__attribute__ ((unused)) struct Agn1;
     27__attribute__ ((unused)) struct Agn2 {
    2828};
    2929static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
     
    4747    __E2__C5eAgn3_1,
    4848};
    49 struct __attribute__ ((unused)) __anonymous2;
    50 struct __attribute__ ((unused)) __anonymous3;
     49__attribute__ ((unused)) struct __anonymous2;
     50__attribute__ ((unused)) struct __anonymous3;
    5151struct Fdl {
    5252    __attribute__ ((unused)) int __f1__i_1;
     
    234234    int (*___retval_f4__PFi_i__1)(int __anonymous_object4);
    235235}
    236 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(long unsigned int __size);
    237 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr);
    238 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void);
    239 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit0(void (*__func)(void), void *__anonymous_object5, void *__anonymous_object6);
    240 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status);
    241 __attribute__ ((format(printf, 1, 2))) extern int printf(const char *__restrict __format, ...);
    242236int __vtr__Fi___1(){
    243237    int ___retval_vtr__i_1;
     
    268262int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1);
    269263int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1);
    270 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused,unused)) int __anonymous_object8[((long unsigned int )5)]));
     264int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((long unsigned int )5)]));
    271265int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    272266int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    273 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object9)(__attribute__ ((unused)) int (*__anonymous_object10)(__attribute__ ((unused,unused)) int __anonymous_object11)));
     267int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
    274268int __ad__Fi___1(){
    275269    int ___retval_ad__i_1;
     
    285279    ((void)sizeof(__attribute__ ((unused,unused,unused)) int (*)[10]));
    286280    ((void)sizeof(__attribute__ ((unused,unused,unused)) int ()));
    287     struct __attribute__ ((unused)) __anonymous4 {
     281    __attribute__ ((unused)) struct __anonymous4 {
    288282        int __i__i_2;
    289283    };
     
    320314    ((void)sizeof(enum __anonymous5 ));
    321315}
    322 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object12, __attribute__ ((unused,unused,unused)) int *__anonymous_object13);
    323 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object14, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object15);
    324 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object16, __attribute__ ((unused,unused,unused)) int *__anonymous_object17);
    325 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object19)());
    326 int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object20)(__attribute__ ((unused)) int __anonymous_object21), __attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(__attribute__ ((unused)) int __anonymous_object23));
    327 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object25)());
    328 int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object26)(__attribute__ ((unused)) int __anonymous_object27), __attribute__ ((unused,unused,unused)) int (*__anonymous_object28)(__attribute__ ((unused)) int __anonymous_object29));
     316int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11);
     317int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13);
     318int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15);
     319int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)());
     320int __apd5__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(__attribute__ ((unused)) int __anonymous_object19), __attribute__ ((unused,unused,unused)) int (*__anonymous_object20)(__attribute__ ((unused)) int __anonymous_object21));
     321int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)());
     322int __apd7__Fi_PFi_i_PFi_i___1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(__attribute__ ((unused)) int __anonymous_object25), __attribute__ ((unused,unused,unused)) int (*__anonymous_object26)(__attribute__ ((unused)) int __anonymous_object27));
    329323struct Vad {
    330     __attribute__ ((unused)) int __anonymous_object30;
    331     __attribute__ ((unused,unused)) int *__anonymous_object31;
    332     __attribute__ ((unused,unused)) int __anonymous_object32[((long unsigned int )10)];
    333     __attribute__ ((unused,unused)) int (*__anonymous_object33)();
     324    __attribute__ ((unused)) int __anonymous_object28;
     325    __attribute__ ((unused,unused)) int *__anonymous_object29;
     326    __attribute__ ((unused,unused)) int __anonymous_object30[((long unsigned int )10)];
     327    __attribute__ ((unused,unused)) int (*__anonymous_object31)();
    334328};
    335329static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
  • src/tests/.expect/castError.txt

    r12d3187 r2055098  
    3939
    4040
    41 make: *** [castError] Error 1
  • src/tests/.expect/completeTypeError.txt

    r12d3187 r2055098  
    4141
    4242
    43 make: *** [completeTypeError] Error 1
  • src/tests/.expect/constant0-1DP.txt

    r12d3187 r2055098  
    3131constant0-1.c:50 error: duplicate object definition for x: const pointer to pointer to signed int
    3232constant0-1.c:50 error: duplicate object definition for 0: pointer to pointer to signed int
    33 make: *** [constant0-1DP] Error 1
  • src/tests/.expect/constant0-1NDDP.txt

    r12d3187 r2055098  
    1515constant0-1.c:67 error: duplicate object definition for x: const pointer to signed int
    1616constant0-1.c:67 error: duplicate object definition for 0: const pointer to signed int
    17 make: *** [constant0-1NDDP] Error 1
  • src/tests/.expect/declarationErrors.txt

    r12d3187 r2055098  
    6767
    6868
    69 make: *** [declarationErrors] Error 1
  • src/tests/.expect/dtor-early-exit-ERR1.txt

    r12d3187 r2055098  
    11dtor-early-exit.c:142 error: jump to label 'L1' crosses initialization of y Branch (Goto)
    2 
    3 make: *** [dtor-early-exit-ERR1] Error 1
  • src/tests/.expect/dtor-early-exit-ERR2.txt

    r12d3187 r2055098  
    11dtor-early-exit.c:142 error: jump to label 'L2' crosses initialization of y Branch (Goto)
    2 
    3 make: *** [dtor-early-exit-ERR2] Error 1
  • src/tests/.expect/memberCtors-ERR1.txt

    r12d3187 r2055098  
    11memberCtors.c:62 error: in void ?{}(B *b), field a2 used before being constructed
    2 make: *** [memberCtors-ERR1] Error 1
  • src/tests/.expect/scopeErrors.txt

    r12d3187 r2055098  
    77  with body
    88    CompoundStmt
    9 
    10 make: *** [scopeErrors] Error 1
  • src/tests/.gitignore

    r12d3187 r2055098  
    11.out/
     2.err/
  • src/tests/Makefile.am

    r12d3187 r2055098  
    2222concurrent=yes
    2323quick_test+= coroutine thread monitor
     24concurrent_test=coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt
    2425else
    2526concurrent=no
     27concurrent_test=
    2628endif
    27 
    2829
    2930# applies to both programs
    3031EXTRA_FLAGS =
    31 CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
     32BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
     33TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
     34CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
    3235CC = @CFA_BINDIR@/@CFA_NAME@
    3336
     
    5154        @+python test.py --list --concurrent=${concurrent}
    5255
     56concurrency :
     57        @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
     58
    5359.dummy : .dummy.c
    54         ${CC} ${CFLAGS} -XCFA -n ${<} -o ${@}
     60        ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
    5561
    5662constant0-1DP : constant0-1.c
  • src/tests/Makefile.in

    r12d3187 r2055098  
    125125CFA_NAME = @CFA_NAME@
    126126CFA_PREFIX = @CFA_PREFIX@
    127 CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
     127CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
    128128CPP = @CPP@
    129129CPPFLAGS = @CPPFLAGS@
     
    229229@BUILD_CONCURRENCY_FALSE@concurrent = no
    230230@BUILD_CONCURRENCY_TRUE@concurrent = yes
     231@BUILD_CONCURRENCY_FALSE@concurrent_test =
     232@BUILD_CONCURRENCY_TRUE@concurrent_test = coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt
    231233
    232234# applies to both programs
    233235EXTRA_FLAGS =
     236BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
     237TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    234238fstream_test_SOURCES = fstream_test.c
    235239vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c
     
    669673        @+python test.py --list --concurrent=${concurrent}
    670674
     675concurrency :
     676        @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
     677
    671678.dummy : .dummy.c
    672         ${CC} ${CFLAGS} -XCFA -n ${<} -o ${@}
     679        ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
    673680
    674681constant0-1DP : constant0-1.c
  • src/tests/attributes.c

    r12d3187 r2055098  
    6868__attribute__(( unused )) int (* __attribute__(( unused )) f4())(int) __attribute__(( used ));
    6969__attribute__(( unused )) int (* __attribute__(( unused )) f4())(int) {}
    70 
    71 #ifdef __CFA__
    72 extern "C" {
    73 #endif // __CFA__
    74 typedef long int ptrdiff_t;
    75 typedef long unsigned int size_t;
    76 extern void *malloc (size_t __size) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;
    77 extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__));
    78 extern void abort (void) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
    79 extern int atexit0 (void (*__func) (void), void *, void *) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__nonnull__ (1)));
    80 extern void exit (int __status) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__noreturn__));
    81 extern int printf (__const char *__restrict __format, ...) __attribute__ ((format (printf, 1, 2)));
    82 #ifdef __CFA__
    83 }
    84 #endif // __CFA__
    8570
    8671
  • src/tests/rational.c

    r12d3187 r2055098  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 18:29:37 2016
    13 // Update Count     : 25
     12// Last Modified On : Thu Apr 27 17:05:19 2017
     13// Update Count     : 40
    1414//
    1515
     
    3636        b = (Rational){ -3, 2 };
    3737        sout | a | b | endl;
    38         sout | a == 1 | endl;
     38//      sout | a == 1 | endl; // FIX ME
    3939        sout | a != b | endl;
    4040        sout | a <  b | endl;
     
    6161        sout | narrow( 3.14159265358979, 256 ) | endl;
    6262
     63        sout | "decompose" | endl;
     64        RationalImpl n, d;
     65        [n, d] = a;
     66        sout | a | n | d | endl;
     67
     68        sout | "more tests" | endl;
    6369        Rational x = { 1, 2 }, y = { 2 };
    6470        sout | x - y | endl;
  • src/tests/sched-int.c

    r12d3187 r2055098  
     1#include <fstream>
    12#include <kernel>
    23#include <monitor>
     
    1516
    1617void step1( global_t * mutex this ) {
     18        sout | "Step 1" | endl;
    1719        this->value = 1;
    1820        wait( &cond );
     
    2224        if( this->value != 1) abort();
    2325
     26        sout | "Step 2" | endl;
    2427        this->value = 2;
    2528        signal( &cond );
     
    2932        if( this->value != 2) abort();
    3033
    31         this->value = 2;
     34        sout | "Step 3" | endl;
     35        this->value = 3;
    3236        signal( &cond );
    3337}
  • src/tests/test.py

    r12d3187 r2055098  
    66from os import listdir, environ
    77from os.path import isfile, join, splitext
    8 from subprocess import Popen, PIPE, STDOUT
     8from pybin.tools import *
    99
    1010import argparse
     11import multiprocessing
    1112import os
    1213import re
    13 import stat
     14import signal
    1415import sys
    1516
     
    2627def getMachineType():
    2728        sh('echo "void ?{}(int*a,int b){}int main(){return 0;}" > .dummy.c')
    28         sh("make .dummy", print2stdout=False)
     29        ret, out = sh("make .dummy -s", print2stdout=True)
     30       
     31        if ret != 0:
     32                print("Failed to identify architecture:")
     33                print(out)
     34                print("Stopping")
     35                rm( (".dummy.c",".dummy") )
     36                sys.exit(1)
     37
    2938        _, out = sh("file .dummy", print2stdout=False)
    30         sh("rm -f .dummy.c > /dev/null 2>&1")
    31         sh("rm -f .dummy > /dev/null 2>&1")
     39        rm( (".dummy.c",".dummy") )
     40
    3241        return re.search("ELF\s([0-9]+)-bit", out).group(1)
    3342
     
    5867        return generic_list + typed_list + concurrent_list;
    5968
    60 # helper functions to run terminal commands
    61 def sh(cmd, dry_run = False, print2stdout = True):
    62         if dry_run :    # if this is a dry_run, only print the commands that would be ran
    63                 print("cmd: %s" % cmd)
    64                 return 0, None
    65         else :                  # otherwise create a pipe and run the desired command
    66                 proc = Popen(cmd, stdout=None if print2stdout else PIPE, stderr=STDOUT, shell=True)
    67                 out, err = proc.communicate()
    68                 return proc.returncode, out
    69 
    70 # helper function to replace patterns in a file
    71 def file_replace(fname, pat, s_after):
    72     # first, see if the pattern is even in the file.
    73     with open(fname) as f:
    74         if not any(re.search(pat, line) for line in f):
    75             return # pattern does not occur in file so we are done.
    76 
    77     # pattern is in the file, so perform replace operation.
    78     with open(fname) as f:
    79         out_fname = fname + ".tmp"
    80         out = open(out_fname, "w")
    81         for line in f:
    82             out.write(re.sub(pat, s_after, line))
    83         out.close()
    84         os.rename(out_fname, fname)
    85 
    86 # tests output may differ depending on the depth of the makefile
    87 def fix_MakeLevel(file) :
    88         if environ.get('MAKELEVEL') :
    89                 file_replace(file, "make\[%i\]" % int(environ.get('MAKELEVEL')), 'make' )
    90 
    91 # helper function to check if a files contains only a spacific string
    92 def fileContainsOnly(file, text) :
    93         with open(file) as f:
    94                 ff = f.read().strip()
    95                 result = ff == text.strip()
    96 
    97                 return result;
    98 
    99 # check whether or not a file is executable
    100 def fileIsExecutable(file) :
    101         try :
    102                 fileinfo = os.stat(file)
    103                 return bool(fileinfo.st_mode & stat.S_IXUSR)
    104         except Exception as inst:
    105                 print(type(inst))    # the exception instance
    106                 print(inst.args)     # arguments stored in .args
    107                 print(inst)
    108                 return False
     69# from the found tests, filter all the valid tests/desired tests
     70def validTests( options ):
     71        tests = []
     72
     73        # if we are regenerating the tests we need to find the information of the
     74        # already existing tests and create new info for the new tests
     75        if options.regenerate_expected :
     76                for testname in options.tests :
     77                        if testname.endswith( (".c", ".cc", ".cpp") ):
     78                                print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr)
     79                        else :
     80                                found = [test for test in allTests if test.name == testname]
     81                                tests.append( found[0] if len(found) == 1 else Test(testname, testname) )
     82
     83        else :
     84                # otherwise we only need to validate that all tests are present in the complete list
     85                for testname in options.tests:
     86                        test = [t for t in allTests if t.name == testname]
     87
     88                        if len(test) != 0 :
     89                                tests.append( test[0] )
     90                        else :
     91                                print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr)
     92
     93        # make sure we have at least some test to run
     94        if len(tests) == 0 :
     95                print('ERROR: No valid test to run', file=sys.stderr)
     96                sys.exit(1)
     97
     98        return tests
     99
     100# parses the option
     101def getOptions():
     102        # create a parser with the arguments for the tests script
     103        parser = argparse.ArgumentParser(description='Script which runs cforall tests')
     104        parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no')
     105        parser.add_argument('--concurrent', help='Run concurrent tests', type=yes_no, default='yes')
     106        parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true')
     107        parser.add_argument('--list', help='List all test available', action='store_true')
     108        parser.add_argument('--all', help='Run all test available', action='store_true')
     109        parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true')
     110        parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8')
     111        parser.add_argument('--list-comp', help='List all valide arguments', action='store_true')
     112        parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run')
     113
     114        options =  parser.parse_args()
     115
     116        # script must have at least some tests to run or be listing
     117        listing    = options.list or options.list_comp
     118        all_tests  = options.all
     119        some_tests = len(options.tests) > 0
     120
     121        # check that exactly one of the booleans is set to true
     122        if not sum( (listing, all_tests, some_tests) ) == 1 :
     123                print('ERROR: must have option \'--all\', \'--list\' or non-empty test list', file=sys.stderr)
     124                parser.print_help()
     125                sys.exit(1)
     126
     127        return options
     128
     129def jobCount( options ):
     130        # check if the user already passed in a number of jobs for multi-threading
     131        make_flags = environ.get('MAKEFLAGS')
     132        make_jobs_fds = re.search("--jobserver-(auth|fds)=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
     133        if make_jobs_fds :
     134                tokens = os.read(int(make_jobs_fds.group(2)), 1024)
     135                options.jobs = len(tokens)
     136                os.write(int(make_jobs_fds.group(3)), tokens)
     137        else :
     138                options.jobs = multiprocessing.cpu_count()
     139
     140        # make sure we have a valid number of jobs that corresponds to user input
     141        if options.jobs <= 0 :
     142                print('ERROR: Invalid number of jobs', file=sys.stderr)
     143                sys.exit(1)
     144
     145        return min( options.jobs, len(tests) ), True if make_flags else False
    109146
    110147################################################################################
    111148#               running test functions
    112149################################################################################
     150# logic to run a single test and return the result (No handling of printing or other test framework logic)
    113151def run_single_test(test, generate, dry_run, debug):
    114152
    115153        # find the output file based on the test name and options flag
    116154        out_file = (".out/%s.log" % test.name) if not generate else (".expect/%s.txt" % test.path)
     155        err_file = ".err/%s.log" % test.name
    117156
    118157        # remove any outputs from the previous tests to prevent side effects
    119         sh("rm -f %s" % out_file, dry_run)
    120         sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run)
    121 
    122         options = "-debug" if debug else "-nodebug";
     158        rm( (out_file, test.name), dry_run )
     159
     160        options = "-debug" if debug else "-nodebug"
    123161
    124162        # build, skipping to next test on error
    125         make_ret, _ = sh("""%s EXTRA_FLAGS="-quiet %s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)
     163        make_ret, _ = sh("""%s test=yes EXTRA_FLAGS="-quiet %s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)
    126164
    127165        # if the make command succeds continue otherwise skip to diff
     
    137175                        sh("cat %s > %s" % (test.name, out_file), dry_run)
    138176
     177        else :
     178                # command failed save the log to less temporary file
     179                sh("mv %s %s" % (err_file, out_file), dry_run)
     180
    139181        retcode = 0
    140182        error = None
    141 
    142         # fix output to prevent make depth to cause issues
    143         fix_MakeLevel(out_file)
    144183
    145184        if generate :
     
    151190
    152191        else :
    153                 # diff the output of the files
    154                 diff_cmd = ("diff --old-group-format='\t\tmissing lines :\n"
    155                                         "%%<' \\\n"
    156                                         "--new-group-format='\t\tnew lines :\n"
    157                                         "%%>' \\\n"
    158                                         "--unchanged-group-format='%%=' \\"
    159                                         "--changed-group-format='\t\texpected :\n"
    160                                         "%%<\n"
    161                                         "\t\tgot :\n"
    162                                         "%%>' \\\n"
    163                                         "--new-line-format='\t\t%%dn\t%%L' \\\n"
    164                                         "--old-line-format='\t\t%%dn\t%%L' \\\n"
    165                                         "--unchanged-line-format='' \\\n"
    166                                         ".expect/%s.txt .out/%s.log")
    167 
    168192                # fetch return code and error from the diff command
    169                 retcode, error = sh(diff_cmd % (test.path, test.name), dry_run, False)
    170 
     193                retcode, error = diff(".expect/%s.txt" % test.path, ".out/%s.log" % test.name, dry_run)
     194       
    171195        # clean the executable
    172196        sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run)
     
    174198        return retcode, error
    175199
    176 def run_test_instance(t, generate, dry_run, debug) :
    177         try :
    178                 # print formated name
    179                 name_txt = "%20s  " % t.name
    180 
    181                 #run the test instance and collect the result
    182                 test_failed, error = run_single_test(t, generate, dry_run, debug)
    183 
    184                 # update output based on current action
    185                 if generate :
    186                         failed_txt = "ERROR"
    187                         success_txt = "Done"
    188                 else :
    189                         failed_txt = "FAILED"
    190                         success_txt = "PASSED"
    191 
    192                 #print result with error if needed
    193                 text = name_txt + (failed_txt if test_failed else success_txt)
    194                 out = sys.stdout
    195                 if error :
    196                         text = text + "\n" + error
    197                         out = sys.stderr
    198 
    199                 print(text, file = out);
    200                 sys.stdout.flush()
    201                 sys.stderr.flush()
    202                 return test_failed
    203 
    204         except KeyboardInterrupt:
    205                 test_failed = True
    206 
     200# run a single test and handle the errors, outputs, printing, exception handling, etc.
     201def run_test_worker(t, generate, dry_run, debug) :
     202
     203        signal.signal(signal.SIGINT, signal.SIG_DFL)
     204        # print formated name
     205        name_txt = "%20s  " % t.name
     206
     207        #run the test instance and collect the result
     208        test_failed, error = run_single_test(t, generate, dry_run, debug)
     209
     210        # update output based on current action
     211        if generate :
     212                failed_txt = "ERROR"
     213                success_txt = "Done"
     214        else :
     215                failed_txt = "FAILED"
     216                success_txt = "PASSED"
     217
     218        #print result with error if needed
     219        text = name_txt + (failed_txt if test_failed else success_txt)
     220        out = sys.stdout
     221        if error :
     222                text = text + "\n" + error
     223                out = sys.stderr
     224
     225        print(text, file = out);
     226        sys.stdout.flush()
     227        sys.stderr.flush()
     228        signal.signal(signal.SIGINT, signal.SIG_IGN)
     229
     230        return test_failed
    207231
    208232# run the given list of tests with the given parameters
     
    211235        sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
    212236
    213         #make sure the required folder are present
    214         sh('mkdir -p .out .expect', dry_run)
     237        # make sure the required folder are present
     238        sh('mkdir -p .out .expect .err', dry_run)
    215239
    216240        if generate :
    217241                print( "Regenerate tests for: " )
    218242
     243        # create the executor for our jobs and handle the signal properly
     244        original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
     245        pool = Pool(jobs)
     246        signal.signal(signal.SIGINT, original_sigint_handler)
     247
    219248        # for each test to run
    220         pool = Pool(jobs)
    221249        try :
    222                 results = pool.map_async(partial(run_test_instance, generate=generate, dry_run=dry_run, debug=debug), tests ).get(9999)
     250                results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests ).get(3600)
    223251        except KeyboardInterrupt:
    224252                pool.terminate()
     
    226254                sys.exit(1)
    227255
    228         #clean the workspace
     256        # clean the workspace
    229257        sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
    230258
     
    235263        return 0
    236264
    237 def yes_no(string):
    238         if string == "yes" :
    239                 return True
    240         if string == "no" :
    241                 return False
    242         raise argparse.ArgumentTypeError(msg)
    243         return False
    244 
    245265
    246266################################################################################
    247267#               main loop
    248268################################################################################
    249 # create a parser with the arguments for the tests script
    250 parser = argparse.ArgumentParser(description='Script which runs cforall tests')
    251 parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no')
    252 parser.add_argument('--concurrent', help='Run concurrent tests', type=yes_no, default='yes')
    253 parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true')
    254 parser.add_argument('--list', help='List all test available', action='store_true')
    255 parser.add_argument('--all', help='Run all test available', action='store_true')
    256 parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true')
    257 parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8')
    258 parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run')
    259 
    260 # parse the command line arguments
    261 options = parser.parse_args()
    262 
    263 # script must have at least some tests to run
    264 if (len(options.tests) > 0  and     options.all and not options.list) \
    265 or (len(options.tests) == 0 and not options.all and not options.list) :
    266         print('ERROR: must have option \'--all\' or non-empty test list', file=sys.stderr)
    267         parser.print_help()
    268         sys.exit(1)
    269 
    270 # fetch the liest of all valid tests
    271 allTests = listTests( options.concurrent )
    272 
    273 # if user wants all tests than no other treatement of the test list is required
    274 if options.all or options.list :
    275         tests = allTests
    276 
    277 else :
    278         #otherwise we need to validate that the test list that was entered is valid
    279         tests = []
    280 
    281         # if we are regenerating the tests we need to find the information of the
    282         # already existing tests and create new info for the new tests
    283         if options.regenerate_expected :
    284                 for testname in options.tests :
    285                         if testname.endswith(".c") or testname.endswith(".cc") or testname.endswith(".cpp") :
    286                                 print('ERROR: "%s", tests are not allowed to end with a C/C++/CFA extension, ignoring it' % testname, file=sys.stderr)
    287                         else :
    288                                 found = [test for test in allTests if test.name == testname]
    289                                 tests.append( found[0] if len(found) == 1 else Test(testname, testname) )
    290 
    291         else :
    292                 # otherwise we only need to validate that all tests are present in the complete list
    293                 for testname in options.tests:
    294                         test = [t for t in allTests if t.name == testname]
    295 
    296                         if len(test) != 0 :
    297                                 tests.append( test[0] )
    298                         else :
    299                                 print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr)
    300 
    301         # make sure we have at least some test to run
    302         if len(tests) == 0 :
    303                 print('ERROR: No valid test to run', file=sys.stderr)
    304                 sys.exit(1)
    305 
    306 # sort the test alphabetically for convenience
    307 tests.sort(key=lambda t: t.name)
    308 
    309 # check if the user already passed in a number of jobs for multi-threading
    310 make_flags = environ.get('MAKEFLAGS')
    311 make_jobs_fds = re.search("--jobserver-fds=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
    312 if make_jobs_fds :
    313         tokens = os.read(int(make_jobs_fds.group(1)), 1024)
    314         options.jobs = len(tokens)
    315         os.write(int(make_jobs_fds.group(2)), tokens)
    316 
    317 # make sure we have a valid number of jobs that corresponds to user input
    318 if options.jobs <= 0 :
    319         print('ERROR: Invalid number of jobs', file=sys.stderr)
    320         sys.exit(1)
    321 
    322 print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs))
    323 make_cmd = "make" if make_flags else ("make -j%i" % options.jobs)
    324 
    325 # users may want to simply list the tests
    326 if options.list :
    327         print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests)))
    328 
    329 else :
    330         # otherwise run all tests and make sure to return the correct error code
    331         sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run, options.jobs, options.debug) )
     269if __name__ == "__main__":
     270        #always run from same folder
     271        chdir()
     272       
     273        # parse the command line arguments
     274        options = getOptions()
     275
     276        # fetch the liest of all valid tests
     277        allTests = listTests( options.concurrent )
     278
     279        # if user wants all tests than no other treatement of the test list is required
     280        if options.all or options.list or options.list_comp :
     281                tests = allTests
     282
     283        else :
     284                #otherwise we need to validate that the test list that was entered is valid
     285                tests = validTests( options )
     286
     287        # sort the test alphabetically for convenience
     288        tests.sort(key=lambda t: t.name)
     289
     290        # users may want to simply list the tests
     291        if options.list_comp :
     292                print("-h --help --debug --concurrent --dry-run --list --all --regenerate-expected -j --jobs ", end='')
     293                print(" ".join(map(lambda t: "%s" % (t.name), tests)))
     294
     295        elif options.list :
     296                print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests)))
     297
     298        else :
     299                options.jobs, forceJobs = jobCount( options )
     300
     301                print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs))
     302                make_cmd = "make" if forceJobs else ("make -j%i" % options.jobs)
     303
     304                # otherwise run all tests and make sure to return the correct error code
     305                sys.exit( run_tests(tests, options.regenerate_expected, options.dry_run, options.jobs, options.debug) )
Note: See TracChangeset for help on using the changeset viewer.