Changes in / [2055098:12d3187]


Ignore:
Files:
2 added
10 deleted
38 edited

Legend:

Unmodified
Added
Removed
  • .gitignore

    r2055098 r12d3187  
    11# build files
    22*.[ao]
    3 *.pyc
    43
    54# generated by configure
  • doc/generic_types/evaluation/Makefile

    r2055098 r12d3187  
    1 CC = gcc
    21CFA = cfa
    32DEPFLAGS = -MMD -MP
     
    76endif
    87CXXFLAGS = $(CFLAGS) --std=c++14
    9 MAKEFILE_NAME = ${firstword ${MAKEFILE_LIST}}
    108
    11 .PHONY : all clean run-c run-cpp run-cfa run
     9.PHONY: all clean distclean run-c run-cpp run-cfa run
    1210
    13 all : c-bench cpp-bench cpp-vbench cfa-bench
     11all: c-bench cpp-bench cfa-bench cpp-vbench
    1412
    1513# rewrite object generation to auto-determine deps
     
    1917
    2018c-%.o : c-%.c
     19c-%.o : c-%.c c-%.d
    2120        $(COMPILE.c) $(OUTPUT_OPTION) -c $<
    2221
    2322cpp-%.o : cpp-%.cpp
     23cpp-%.o : cpp-%.cpp cpp-%.d
    2424        $(COMPILE.cpp) $(OUTPUT_OPTION) -c $<
    2525
    2626cfa-%.o : cfa-%.c
     27cfa-%.o : cfa-%.c cfa-%.d
    2728        $(COMPILE.cfa) $(OUTPUT_OPTION) -c $<
    2829
    29 COBJS = c-stack.o c-pair.o c-print.o c-bench.o
    30 CPPOBJS = cpp-bench.o
    31 CPPVOBJS = cpp-vstack.o cpp-vbench.o
    32 CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o cfa-bench.o
     30COBJS = c-stack.o c-pair.o c-print.o
     31CPPOBJS =
     32CPPVOBJS = cpp-vstack.o
     33CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o
    3334
    34 ${COBJS} ${CPPOBJS} ${CPPVOBJS} ${CFAOBJS} : ${MAKEFILE_NAME}
     35CFILES = c-bench.c bench.h $(COBJS:.o=.h) $(COBJS:.o=.c)
     36CPPFILES = cpp-bench.cpp bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp
     37CPPVFILES = cpp-vbench.cpp bench.hpp object.hpp $(CPPVOBJS:.o=.hpp) $(CPPVOBJS:.o=.cpp) cpp-vprint.hpp
     38CFAFILES = cfa-bench.c bench.h $(CFAOBJS:.o=.h) $(CFAOBJS:.o=.c)
    3539
    36 CFILES = bench.h $(patsubst c-bench.h,,$(COBJS:.o=.h)) $(COBJS:.o=.c)
    37 CPPFILES = bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp $(CPPOBJS:.o=.cpp)
    38 CPPVFILES = bench.hpp object.hpp cpp-vprint.hpp $(patsubst cpp-vbench.hpp,,$(CPPVOBJS:.o=.hpp)) $(CPPVOBJS:.o=.cpp)
    39 CFAFILES = bench.h $(patsubst cfa-bench.h,,$(CFAOBJS:.o=.h)) $(CFAOBJS:.o=.c)
     40c-bench: c-bench.c c-bench.d $(COBJS)
     41        $(COMPILE.c) -o $@ $< $(COBJS) $(LDFLAGS)
    4042
    41 c-bench : $(COBJS) c-bench.o
    42         $(COMPILE.c) $(LDFLAGS) $^ -o $@
     43cpp-bench: cpp-bench.cpp cpp-bench.d $(CPPOBJS)
     44        $(COMPILE.cpp) -o $@ $< $(CPPOBJS) $(LDFLAGS)
    4345
    44 cpp-bench : $(CPPOBJS) cpp-bench.o
    45         $(COMPILE.cpp) $(LDFLAGS) $^ -o $@
     46cpp-vbench: cpp-vbench.cpp cpp-vbench.d $(CPPVOBJS)
     47        $(COMPILE.cpp) -o $@ $< $(CPPVOBJS) $(LDFLAGS)
    4648
    47 cpp-vbench : $(CPPVOBJS) cpp-vbench.o
    48         $(COMPILE.cpp) $(LDFLAGS) $^ -o $@
     49cfa-bench: cfa-bench.c cfa-bench.d $(CFAOBJS)
     50        $(COMPILE.cfa) -o $@ $< $(CFAOBJS) $(LDFLAGS)
    4951
    50 cfa-bench : $(CFAOBJS) cfa-bench.o
    51         $(COMPILE.cfa) $(LDFLAGS) $^ -o $@
     52clean:
     53        -rm $(COBJS) c-bench
     54        -rm $(CPPOBJS) cpp-bench
     55        -rm $(CPPVOBJS) cpp-vbench
     56        -rm $(CFAOBJS) cfa-bench
     57
     58distclean: clean
     59        -rm $(COBJS:.o=.d) c-bench.d
     60        -rm $(CPPOBJS:.o=.d) cpp-bench.d
     61        -rm $(CPPVOBJS:.o=.d) cpp-vbench.d
     62        -rm $(CFAOBJS:.o=.d) cfa-bench.d
     63
     64run-c: c-bench
     65        @echo
     66        @echo '## C ##'
     67        @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./c-bench
     68        @printf 'source_size:\t%8d lines\n' `cat $(CFILES) | wc -l`
     69        @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFILES) | fgrep '/***/' -c`
     70        @printf 'binary_size:\t%8d bytes\n' `stat -c %s c-bench`
     71
     72run-cfa: cfa-bench
     73        @echo
     74        @echo '## Cforall ##'
     75        @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./cfa-bench
     76        @printf 'source_size:\t%8d lines\n' `cat $(CFAFILES) | wc -l`
     77        @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFAFILES) | fgrep '/***/' -c`
     78        @printf 'binary_size:\t%8d bytes\n' `stat -c %s cfa-bench`
     79
     80run-cpp: cpp-bench
     81        @echo
     82        @echo '## C++ ##'
     83        @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./cpp-bench
     84        @printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l`
     85        @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPFILES) | fgrep '/***/' -c`
     86        @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-bench`
     87
     88run-cppv: cpp-vbench
     89        @echo
     90        @echo '## C++obj ##'
     91        @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./cpp-vbench
     92        @printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l`
     93        @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPVFILES) | fgrep '/***/' -c`
     94        @printf 'binary_size:\t%8d bytes\n' `stat -c %s cpp-vbench`
     95
     96run: run-c run-cfa run-cpp run-cppv
     97
     98# so make doesn't fail without dependency files
     99%.d: ;
     100
     101# so make won't delete dependency files
     102.PRECIOUS: %.d
    52103
    53104# include dependency files
    54 -include $(COBJS:.o=.d)
    55 -include $(CPPOBJS:.o=.d)
    56 -include $(CPPVOBJS:.o=.d)
    57 -include $(CFAOBJS:.o=.d)
    58 
    59 clean :
    60         rm -f $(COBJS) $(COBJS:.o=.d) c-bench
    61         rm -f $(CPPOBJS) $(CPPOBJS:.o=.d) cpp-bench
    62         rm -f $(CPPVOBJS) $(CPPVOBJS:.o=.d) cpp-vbench
    63         rm -f $(CFAOBJS) $(CFAOBJS:.o=.d) cfa-bench
    64 
    65 run-c : c-bench
    66         @echo
    67         @echo '## C ##'
    68         @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$<
    69         @printf 'source_size:\t%8d lines\n' `cat $(CFILES) | wc -l`
    70         @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFILES) | fgrep '/***/' -c`
    71         @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
    72 
    73 run-cpp : cpp-bench
    74         @echo
    75         @echo '## C++ ##'
    76         @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$<
    77         @printf 'source_size:\t%8d lines\n' `cat $(CPPFILES) | wc -l`
    78         @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPFILES) | fgrep '/***/' -c`
    79         @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
    80 
    81 run-cppv : cpp-vbench
    82         @echo
    83         @echo '## C++obj ##'
    84         @/usr/bin/time -f 'max_memory:\t%M kilobytes' ./$<
    85         @printf 'source_size:\t%8d lines\n' `cat $(CPPVFILES) | wc -l`
    86         @printf 'redundant_type_annotations:%8d lines\n' `cat $(CPPVFILES) | fgrep '/***/' -c`
    87         @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
    88 
    89 run-cfa : cfa-bench
    90         @echo
    91         @echo '## Cforall ##'
    92         @/usr/bin/time -f 'max_memory:\t %M kilobytes' ./$<
    93         @printf 'source_size:\t%8d lines\n' `cat $(CFAFILES) | wc -l`
    94         @printf 'redundant_type_annotations:%8d lines\n' `cat $(CFAFILES) | fgrep '/***/' -c`
    95         @printf 'binary_size:\t%8d bytes\n' `stat -c %s $<`
    96 
    97 run : run-c run-cfa run-cpp run-cppv
     105-include: $(COBJS:.o=.d)
     106-include: $(CPPOBJS:.o=.d)
     107-include: $(CFAOBJS:.o=.d)
     108-include: c-bench.d
     109-include: cpp-bench.d
     110-include: cfa-bench.d
  • doc/generic_types/evaluation/c-bench.c

    r2055098 r12d3187  
    3939
    4040int main(int argc, char** argv) {
    41         FILE * out = fopen("/dev/null", "w");
     41        FILE * out = fopen("c-out.txt", "w");
    4242        int maxi = 0, vali = 42;
    4343        struct stack si = new_stack(), ti;
  • doc/generic_types/evaluation/c-stack.c

    r2055098 r12d3187  
    1111void copy_stack(struct stack* s, const struct stack* t, void* (*copy)(const void*)) {
    1212        struct stack_node** crnt = &s->head;
    13         for ( struct stack_node* next = t->head; next; next = next->next ) {
     13        struct stack_node* next = t->head;
     14        while ( next ) {
    1415                *crnt = malloc(sizeof(struct stack_node)); /***/
    1516                **crnt = (struct stack_node){ copy(next->value) }; /***/
    1617                crnt = &(*crnt)->next;
     18                next = next->next;
    1719        }
    1820        *crnt = 0;
     
    2022
    2123void clear_stack(struct stack* s, void (*free_el)(void*)) {
    22     for ( struct stack_node* next = s->head; next; ) {
     24        struct stack_node* next = s->head;
     25        while ( next ) {
    2326                struct stack_node* crnt = next;
    2427                next = crnt->next;
  • doc/generic_types/evaluation/cfa-bench.c

    r2055098 r12d3187  
    66
    77int main( int argc, char *argv[] ) {
    8         FILE * out = fopen( "/dev/null", "w" );
     8        FILE * out = fopen( "cfa-out.txt", "w" );
    99        int maxi = 0, vali = 42;
    1010        stack(int) si, ti;
  • doc/generic_types/evaluation/cfa-stack.c

    r2055098 r12d3187  
    1111forall(otype T) void ?{}(stack(T)* s, stack(T) t) {
    1212        stack_node(T)** crnt = &s->head;
    13         for ( stack_node(T)* next = t.head; next; next = next->next ) {
     13        stack_node(T)* next = t.head;
     14        while ( next ) {
    1415                *crnt = ((stack_node(T)*)malloc()){ next->value }; /***/
    1516                stack_node(T)* acrnt = *crnt;
    1617                crnt = &acrnt->next;
     18                next = next->next;
    1719        }
    1820        *crnt = 0;
     
    4446
    4547forall(otype T) void clear(stack(T)* s) {
    46     for ( stack_node(T)* next = s->head; next; ) {
     48        stack_node(T)* next = s->head;
     49        while ( next ) {
    4750                stack_node(T)* crnt = next;
    4851                next = crnt->next;
  • doc/generic_types/evaluation/cpp-bench.cpp

    r2055098 r12d3187  
    77
    88int main(int argc, char** argv) {
    9         std::ofstream out{"/dev/null"};
     9        std::ofstream out{"cpp-out.txt"};
    1010        int maxi = 0, vali = 42;
    1111        stack<int> si, ti;
  • doc/generic_types/evaluation/cpp-stack.hpp

    r2055098 r12d3187  
    1313        void copy(const stack<T>& o) {
    1414                node** crnt = &head;
    15                 for ( node* next = o.head; next; next = next->next ) {
     15                node* next = o.head;
     16                while ( next ) {
    1617                        *crnt = new node{ next->value }; /***/
    1718                        crnt = &(*crnt)->next;
     19                        next = next->next;
    1820                }
    1921                *crnt = nullptr;
     
    2123public:
    2224        void clear() {
    23             for ( node* next = head; next; ) {
     25                node* next = head;
     26                while ( next ) {
    2427                        node* crnt = next;
    2528                        next = crnt->next;
  • doc/generic_types/evaluation/cpp-vbench.cpp

    r2055098 r12d3187  
    77
    88int main(int argc, char** argv) {
    9         std::ofstream out{"/dev/null"};
     9        std::ofstream out{"cpp-vout.txt"};
    1010        integer maxi{ 0 }, vali{ 42 };
    1111        stack si, ti;
  • doc/generic_types/evaluation/cpp-vstack.cpp

    r2055098 r12d3187  
    66void stack::copy(const stack& o) {
    77        node** crnt = &head;
    8         for ( node* next = o.head; next; next = next->next ) {
     8        node* next = o.head;
     9        while ( next ) {
    910                *crnt = new node{ *next->value };
    1011                crnt = &(*crnt)->next;
     12                next = next->next;
    1113        }
    1214        *crnt = nullptr;
     
    3335
    3436void stack::clear() {
    35     for ( node* next = head; next; ) {
     37        node* next = head;
     38        while ( next ) {
    3639                node* crnt = next;
    3740                next = crnt->next;
  • doc/generic_types/generic_types.tex

    r2055098 r12d3187  
    232232int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
    233233                                *(double *)t2 < *(double *)t1 ? 1 : 0; }
    234 double key = 5.0, vals[10] = { /* 10 sorted floating-point values */ };
     234double key = 5.0, vals[10] = { /* 10 floating-point values */ };
    235235double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      $\C{// search sorted array}$
    236236\end{lstlisting}
     
    354354One of the known shortcomings of standard C is that it does not provide reusable type-safe abstractions for generic data structures and algorithms.
    355355Broadly speaking, there are three approaches to implement abstract data-structures in C.
    356 One approach is to write bespoke data-structures for each context in which they are needed.
     356One approach is to write bespoke data structures for each context in which they are needed.
    357357While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures.
    358358A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@; an approach which does allow reuse of code for common functionality.
     
    542542\end{lstlisting}
    543543where the tuple variable-name serves the same purpose as the parameter name(s).
    544 Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown in C.
     544Tuple variables can be composed of any types, except for array types, since array sizes are generally unknown.
    545545
    546546One way to access the tuple-variable components is with assignment or composition:
     
    552552\begin{lstlisting}
    553553[int, int] * p = &qr;                                           $\C{// tuple pointer}$
    554 int rem = qr`.1`;                                                       $\C{// access remainder}$
    555 int quo = div( 13, 5 )`.0`;                                     $\C{// access quotient}$
    556 p`->0` = 5;                                                                     $\C{// change quotient}$
    557 bar( qr`.1`, qr );                                                      $\C{// pass remainder and quotient/remainder}$
    558 rem = [42, div( 13, 5 )]`.0.1`;                         $\C{// access 2nd component of 1st component of tuple expression}$
     554int rem = qr.1;                                                         $\C{// access remainder}$
     555int quo = div( 13, 5 ).0;                                       $\C{// access quotient}$
     556p->0 = 5;                                                                       $\C{// change quotient}$
     557bar( qr.1, qr );                                                        $\C{// pass remainder and quotient/remainder}$
     558rem = [42, div( 13, 5 )].0.1;                           $\C{// access 2nd component of 1st component of tuple expression}$
    559559\end{lstlisting}
    560560
     
    616616This semantics means mass assignment differs from C cascading assignment (\eg @a = b = c@) in that conversions are applied in each individual assignment, which prevents data loss from the chain of conversions that can happen during a cascading assignment.
    617617For example, @[y, x] = 3.14@ performs the assignments @y = 3.14@ and @x = 3.14@, yielding @y == 3.14@ and @x == 3@;
    618 whereas, C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@.
     618whereas C cascading assignment @y = x = 3.14@ performs the assignments @x = 3.14@ and @y = x@, yielding @3@ in @y@ and @x@.
    619619Finally, tuple assignment is an expression where the result type is the type of the left-hand side of the assignment, just like all other assignment expressions in C.
    620620This example shows mass, multiple, and cascading assignment used in one expression:
     
    742742\end{lstlisting}
    743743Hence, function parameter and return lists are flattened for the purposes of type unification allowing the example to pass expression resolution.
    744 This relaxation is possible by extending the thunk scheme described by~\citet{Bilson03}.
     744This relaxation is possible by extending the thunk scheme described by \citet{Bilson03}.
    745745Whenever a candidate's parameter structure does not exactly match the formal parameter's structure, a thunk is generated to specialize calls to the actual function:
    746746\begin{lstlisting}
     
    748748\end{lstlisting}
    749749so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism.
    750 These thunks take advantage of GCC C nested-functions to produce closures that have the usual function-pointer signature.
     750These thunks take advantage of GCC C nested-functions to produce closures that have the usual function pointer signature.
    751751
    752752
     
    829829\subsection{Implementation}
    830830
    831 Tuples are implemented in the \CFA translator via a transformation into \emph{generic types}.
     831Tuples are implemented in the \CFA translator via a transformation into generic types.
    832832For each $N$, the first time an $N$-tuple is seen in a scope a generic type with $N$ type parameters is generated, \eg:
    833833\begin{lstlisting}
     
    10861086Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable.
    10871087
    1088 There is ongoing work on a wide range of \CFA feature extensions, including reference types, arrays with size, exceptions, concurrent primitives and modules.
     1088There is ongoing work on a wide range of \CFA feature extensions, including reference types, exceptions, concurrent primitives and modules.
    10891089(While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these additional extensions.)
    10901090In addition, there are interesting future directions for the polymorphism design.
     
    10921092\CFA polymorphic functions use dynamic virtual-dispatch;
    10931093the runtime overhead of this approach is low, but not as low as inlining, and it may be beneficial to provide a mechanism for performance-sensitive code.
    1094 Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types (\CC template specialization).
     1094Two promising approaches are an @inline@ annotation at polymorphic function call sites to create a template-specialization of the function (provided the code is visible) or placing an @inline@ annotation on polymorphic function-definitions to instantiate a specialized version for some set of types.
    10951095These approaches are not mutually exclusive and allow performance optimizations to be applied only when necessary, without suffering global code-bloat.
    10961096In general, we believe separate compilation, producing smaller code, works well with loaded hardware-caches, which may offset the benefit of larger inlined-code.
     
    11171117Throughout, @/***/@ designates a counted redundant type annotation.
    11181118
    1119 \smallskip\noindent
     1119\medskip\noindent
    11201120\CFA
    11211121\begin{lstlisting}[xleftmargin=2\parindentlnth,aboveskip=0pt,belowskip=0pt]
  • src/libcfa/concurrency/invoke.h

    r2055098 r12d3187  
    3838      };
    3939
    40       struct __condition_stack_t {
    41             struct __condition_criterion_t * top;
     40      struct __thread_stack_t {
     41            struct thread_desc * top;
    4242      };
    4343
     
    4848            struct thread_desc * pop_head( struct __thread_queue_t * );
    4949
    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 * );
     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 * );
    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 __condition_stack_t signal_stack;  // stack of conditions to run next once we exit the monitor
     84            struct __thread_stack_t signal_stack;     // stack of threads 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

    r2055098 r12d3187  
    5555//-----------------------------------------------------------------------------
    5656// Processor
    57 enum 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)
     57enum FinishOpCode { No_Action, Release, Schedule, Release_Schedule };
    6058struct FinishAction {
    6159        FinishOpCode action_code;
    6260        thread_desc * thrd;
    6361        spinlock * lock;
    64         spinlock ** locks;
    65         unsigned short lock_count;
    66         thread_desc ** thrds;
    67         unsigned short thrd_count;
    6862};
    6963static inline void ?{}(FinishAction * this) {
  • src/libcfa/concurrency/kernel.c

    r2055098 r12d3187  
    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         }
    250237        else {
    251238                assert(this->finish.action_code == No_Action);
     
    348335        this_processor->finish.lock = lock;
    349336        this_processor->finish.thrd = thrd;
    350         suspend();
    351 }
    352 
    353 void 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 
    360 void 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;
    366337        suspend();
    367338}
     
    558529}
    559530
    560 void ?{}( __condition_stack_t * this ) {
     531void ?{}( __thread_stack_t * this ) {
    561532        this->top = NULL;
    562533}
    563534
    564 void push( __condition_stack_t * this, __condition_criterion_t * t ) {
    565         assert( !t->next );
     535void push( __thread_stack_t * this, thread_desc * t ) {
     536        assert(t->next != NULL);
    566537        t->next = this->top;
    567538        this->top = t;
    568539}
    569540
    570 __condition_criterion_t * pop( __condition_stack_t * this ) {
    571         __condition_criterion_t * top = this->top;
     541thread_desc * pop( __thread_stack_t * this ) {
     542        thread_desc * top = this->top;
    572543        if( top ) {
    573544                this->top = top->next;
  • src/libcfa/concurrency/kernel_private.h

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

    r2055098 r12d3187  
    4646//-----------------------------------------------------------------------------
    4747// Internal scheduling
    48 
    49 struct __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 
    56 struct __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 
    63 struct __condition_blocked_queue_t {
    64         __condition_node_t * head;
    65         __condition_node_t ** tail;
    66 };
    67 
    68 void ?{}( __condition_blocked_queue_t * );
    69 void append( __condition_blocked_queue_t *, __condition_node_t * );
    70 __condition_node_t * pop_head( __condition_blocked_queue_t * );
    71 
    7248struct condition {
    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
     49        __thread_queue_t blocked;
     50        monitor_desc ** monitors;
     51        unsigned short monitor_count;
    7652};
    7753
  • src/libcfa/concurrency/monitor.c

    r2055098 r12d3187  
    2020#include "libhdr.h"
    2121
    22 //-----------------------------------------------------------------------------
    23 // Forward declarations
    24 static inline void set_owner( monitor_desc * this, thread_desc * owner );
    25 static inline thread_desc * next_thread( monitor_desc * this );
    26 
    27 static inline void lock_all( spinlock ** locks, unsigned short count );
    28 static inline void lock_all( monitor_desc ** source, spinlock ** /*out*/ locks, unsigned short count );
    29 static inline void unlock_all( spinlock ** locks, unsigned short count );
    30 static inline void unlock_all( monitor_desc ** locks, unsigned short count );
    31 
    32 static inline void save_recursion   ( monitor_desc ** ctx, unsigned int * /*out*/ recursions, unsigned short count );
    33 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count );
    34 
    35 static inline thread_desc * check_condition( __condition_criterion_t * );
    36 static inline void brand_condition( condition * );
    37 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val );
    38 
    39 //-----------------------------------------------------------------------------
    40 // Enter/Leave routines
    41 
     22void 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}
    4229
    4330extern "C" {
    44         void __enter_monitor_desc(monitor_desc * this) {
     31        void __enter_monitor_desc(monitor_desc * this, monitor_desc * leader) {
    4532                lock( &this->lock );
    4633                thread_desc * thrd = this_thread();
    4734
    48                 LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion);
     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);
    4939
    5040                if( !this->owner ) {
     
    7161
    7262        // leave pseudo code :
    73         //      TODO
    74         void __leave_monitor_desc(monitor_desc * this) {
     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) {
    7578                lock( &this->lock );
    7679
     80                LIB_DEBUG_PRINT_SAFE("Leaving %p (o: %p, r: %i)\n", this, this->owner, this->recursion);
     81
    7782                thread_desc * thrd = this_thread();
    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 );
     83                assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", this->owner, thrd, this->recursion );
    8184
    8285                //Leaving a recursion level, decrement the counter
     
    8689                //it means we don't need to do anything
    8790                if( this->recursion != 0) {
     91                        // this->stack_owner = leader;
    8892                        unlock( &this->lock );
    8993                        return;
    9094                }
    91 
    92                 thread_desc * new_owner = next_thread( this );
     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;
    93125
    94126                //We can now let other threads in safely
     
    101133
    102134static inline void enter(monitor_desc ** monitors, int count) {
    103         for(int i = 0; i < count; i++) {
    104                 __enter_monitor_desc( monitors[i] );
     135        __enter_monitor_desc( monitors[0], NULL );
     136        for(int i = 1; i < count; i++) {
     137                __enter_monitor_desc( monitors[i], monitors[0] );
    105138        }
    106139}
    107140
    108141static inline void leave(monitor_desc ** monitors, int count) {
    109         for(int i = count - 1; i >= 0; i--) {
    110                 __leave_monitor_desc( monitors[i] );
     142        __leave_monitor_desc( monitors[0], NULL );
     143        for(int i = count - 1; i >= 1; i--) {
     144                __leave_monitor_desc( monitors[i], monitors[0] );
    111145        }
    112146}
     
    135169// Internal scheduling
    136170void wait( condition * this ) {
    137         LIB_DEBUG_PRINT_SAFE("Waiting\n");
    138 
    139         brand_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        }
     179
     180        unsigned short count = this->monitor_count;
    140181
    141182        //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 );
    144 
    145         unsigned short count = this->monitor_count;
     183        assert( this->monitors != NULL );
     184        assert( this->monitor_count != 0 );
     185
    146186        unsigned int recursions[ count ];               //Save the current recursion levels to restore them later
    147187        spinlock *   locks     [ count ];               //We need to pass-in an array of locks to ScheduleInternal
    148188
    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 );
     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 );
    189220
    190221
     
    193224
    194225        //We are back, restore the owners and recursions
    195         lock_all( locks, count );
    196         restore_recursion( this->monitors, recursions, count );
    197         unlock_all( locks, count );
    198 }
    199 
    200 void signal( condition * this ) {
    201         if( !this->blocked.head ) {
    202                 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n");
    203                 return;
    204         }
     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
     241static void __signal_internal( condition * this ) {
     242        assertf(false, "NO SUPPORTED");
     243        if( !this->blocked.head ) return;
    205244
    206245        //Check that everything is as expected
    207246        assert( this->monitors );
    208247        assert( this->monitor_count != 0 );
    209 
    210         unsigned short count = this->monitor_count;
    211248       
    212249        LIB_DEBUG_DO(
    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 );
     250                if ( this->monitors != this_thread()->current_monitors ) {
     251                        abortf( "Signal on condition %p made outside of the correct monitor(s)", this );
    216252                } // 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                 }
    223253        );
    224254
    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 
    244 static 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 
    252 static 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 
    272 static inline void lock_all( spinlock ** locks, unsigned short count ) {
    273         for( int i = 0; i < count; i++ ) {
    274                 lock( locks[i] );
    275         }
    276 }
    277 
    278 static 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 
    286 static inline void unlock_all( spinlock ** locks, unsigned short count ) {
    287         for( int i = 0; i < count; i++ ) {
    288                 unlock( locks[i] );
    289         }
    290 }
    291 
    292 static 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 
    299 static 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 
    305 static 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
    315 static 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 
    336 static 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 
    346 static 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 
    355 void ?{}( __condition_blocked_queue_t * this ) {
    356         this->head = NULL;
    357         this->tail = &this->head;
    358 }
    359 
    360 void 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 }
     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
     264void signal( condition * this ) {
     265        __signal_internal( this );
     266}
  • src/libcfa/interpose.c

    r2055098 r12d3187  
    2626
    2727#include "libhdr/libdebug.h"
    28 #include "libhdr/libtools.h"
    2928#include "startup.h"
     29
     30void abortf( const char *fmt, ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__));
    3031
    3132void interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
     
    114115static char abort_text[ abort_text_size ];
    115116
    116 extern "C" {
    117         void abortf( const char fmt[], ... ) __attribute__ ((__nothrow__, __leaf__, __noreturn__)) {
    118                 void * kernel_data = kernel_abort();
     117void 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 );
    119125
    120                 int len;
     126                len = vsnprintf( abort_text, abort_text_size, fmt, args );
    121127
    122                 if( fmt ) {
    123                         va_list args;
    124                         va_start( args, fmt );
     128                va_end( args );
    125129
    126                         len = vsnprintf( abort_text, abort_text_size, fmt, args );
     130                __lib_debug_write( STDERR_FILENO, abort_text, len );
     131                __lib_debug_write( STDERR_FILENO, "\n", 1 );
     132        }
    127133
    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)
    135                 __lib_debug_write( STDERR_FILENO, abort_text, len );
     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();
    141         }
     140        libc_abort();
    142141}
  • src/libcfa/libhdr/libtools.h

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

    r2055098 r12d3187  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Mon May  1 08:25:06 2017
    15 // Update Count     : 33
     14// Last Modified On : Wed May  4 14:11:45 2016
     15// Update Count     : 16
    1616//
    17 
    1817#ifndef RATIONAL_H
    1918#define RATIONAL_H
     
    2221
    2322// implementation
    24 typedef long int RationalImpl;
    2523struct Rational {
    26         RationalImpl numerator, denominator;                                    // invariant: denominator > 0
     24        long int numerator, denominator;                                        // invariant: denominator > 0
    2725}; // Rational
    2826
     
    3331// constructors
    3432void ?{}( Rational * r );
    35 void ?{}( Rational * r, RationalImpl n );
    36 void ?{}( Rational * r, RationalImpl n, RationalImpl d );
     33void ?{}( Rational * r, long int n );
     34void ?{}( Rational * r, long int n, long int d );
    3735
    38 // getter for numerator/denominator
    39 RationalImpl numerator( Rational r );
    40 RationalImpl denominator( Rational r );
    41 [ RationalImpl, RationalImpl ] ?=?( * [ RationalImpl, RationalImpl ] dest, Rational src );
    42 // setter for numerator/denominator
    43 RationalImpl numerator( Rational r, RationalImpl n );
    44 RationalImpl denominator( Rational r, RationalImpl d );
     36// getter/setter for numerator/denominator
     37long int numerator( Rational r );
     38long int numerator( Rational r, long int n );
     39long int denominator( Rational r );
     40long int denominator( Rational r, long int d );
    4541
    4642// comparison
     
    6157// conversion
    6258double widen( Rational r );
    63 Rational narrow( double f, RationalImpl md );
     59Rational narrow( double f, long int md );
    6460
    6561// I/O
  • src/libcfa/rational.c

    r2055098 r12d3187  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 27 17:05:06 2017
    13 // Update Count     : 51
     12// Last Modified On : Sat Jul  9 11:18:04 2016
     13// Update Count     : 40
    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 RationalImpl gcd( RationalImpl a, RationalImpl b ) {
     32static long int gcd( long int a, long int b ) {
    3333        for ( ;; ) {                                                                            // Euclid's algorithm
    34                 RationalImpl r = a % b;
     34                long int r = a % b;
    3535          if ( r == 0 ) break;
    3636                a = b;
     
    4040} // gcd
    4141
    42 static RationalImpl simplify( RationalImpl *n, RationalImpl *d ) {
     42static long int simplify( long int *n, long int *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, RationalImpl n ) {
     58void ?{}( Rational * r, long int n ) {
    5959        r{ n, 1 };
    6060} // rational
    6161
    62 void ?{}( Rational * r, RationalImpl n, RationalImpl d ) {
    63         RationalImpl t = simplify( &n, &d );                            // simplify
     62void ?{}( Rational * r, long int n, long int d ) {
     63        long int t = simplify( &n, &d );                                        // simplify
    6464        r->numerator = n / t;
    6565        r->denominator = d / t;
     
    6767
    6868
    69 // getter for numerator/denominator
    70 
    71 RationalImpl numerator( Rational r ) {
     69// getter/setter for numerator/denominator
     70
     71long int numerator( Rational r ) {
    7272        return r.numerator;
    7373} // numerator
    7474
    75 RationalImpl 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 
    85 RationalImpl numerator( Rational r, RationalImpl n ) {
    86         RationalImpl prev = r.numerator;
    87         RationalImpl t = gcd( abs( n ), r.denominator );                // simplify
     75long int numerator( Rational r, long int n ) {
     76        long int prev = r.numerator;
     77        long int t = gcd( abs( n ), r.denominator );            // simplify
    8878        r.numerator = n / t;
    8979        r.denominator = r.denominator / t;
     
    9181} // numerator
    9282
    93 RationalImpl denominator( Rational r, RationalImpl d ) {
    94         RationalImpl prev = r.denominator;
    95         RationalImpl t = simplify( &r.numerator, &d );                  // simplify
     83long int denominator( Rational r ) {
     84        return r.denominator;
     85} // denominator
     86
     87long int denominator( Rational r, long int d ) {
     88        long int prev = r.denominator;
     89        long int t = simplify( &r.numerator, &d );                      // simplify
    9690        r.numerator = r.numerator / t;
    9791        r.denominator = d / t;
     
    176170
    177171// http://www.ics.uci.edu/~eppstein/numth/frap.c
    178 Rational narrow( double f, RationalImpl md ) {
     172Rational narrow( double f, long int md ) {
    179173        if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
    180174                return (Rational){ f, 1};                                               // truncate fraction
     
    182176
    183177        // continued fraction coefficients
    184         RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
    185         RationalImpl ai, t;
     178        long int m00 = 1, m11 = 1, m01 = 0, m10 = 0;
     179        long int ai, t;
    186180
    187181        // find terms until denom gets too big
    188182        for ( ;; ) {
    189                 ai = (RationalImpl)f;
     183                ai = (long int)f;
    190184          if ( ! (m10 * ai + m11 <= md) ) break;
    191185                t = m00 * ai + m01;
     
    208202forall( dtype istype | istream( istype ) )
    209203istype * ?|?( istype *is, Rational *r ) {
    210         RationalImpl t;
     204        long int t;
    211205        is | &(r->numerator) | &(r->denominator);
    212206        t = simplify( &(r->numerator), &(r->denominator) );
  • src/tests/.expect/32/attributes.txt

    r2055098 r12d3187  
    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);
    6 extern int printf(const char *__restrict __format, ...);
    7 int __la__Fi___1(){
    8     int ___retval_la__i_1;
    9     L: __attribute__ ((unused)) ((void)1);
    10 }
    11 __attribute__ ((unused)) struct __anonymous0 {
    12 };
    13 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
    14 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    15 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1);
    16 static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
    17 static inline void ___constructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
    18 }
    19 static inline void ___constructor__F_P13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
    20 }
    21 static inline void ___destructor__F_P13s__anonymous0_autogen___1(struct __anonymous0 *___dst__P13s__anonymous0_1){
    22 }
    23 static 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 };
    29 static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
    30 static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
    31 static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
    32 static inline struct Agn2 ___operator_assign__F5sAgn2_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
    33 static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){
    34 }
    35 static inline void ___constructor__F_P5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
    36 }
    37 static inline void ___destructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1){
    38 }
    39 static 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 }
    42 enum __attribute__ ((unused)) __anonymous1 {
    43     __E1__C13e__anonymous1_1,
    44 };
    45 enum __attribute__ ((unused)) Agn3;
    46 enum __attribute__ ((packed)) Agn3 {
    47     __E2__C5eAgn3_1,
    48 };
    49 __attribute__ ((unused)) struct __anonymous2;
    50 __attribute__ ((unused)) struct __anonymous3;
    51 struct 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 };
    63 static inline void ___constructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1);
    64 static inline void ___constructor__F_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1);
    65 static inline void ___destructor__F_P4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1);
    66 static inline struct Fdl ___operator_assign__F4sFdl_P4sFdl4sFdl_autogen___1(struct Fdl *___dst__P4sFdl_1, struct Fdl ___src__4sFdl_1);
    67 static 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 }
    78 static 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 }
    89 static 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 }
    100 static 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 }
    112 static 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 }
    123 static 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 }
    134 static 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 }
    145 static 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 }
    156 static 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 }
    167 static 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 }
    178 static 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 }
    189 static 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 }
    200 static 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 }
    236 int __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 }
    245 int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) int __p__i_1, __attribute__ ((unused,unused,unused)) int __q__i_1);
    246 int __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 }
    249 int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    250 int __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 }
    253 int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__p__Pi_1, __attribute__ ((unused,unused,unused)) int *__q__Pi_1);
    254 int __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 }
    257 int __ipd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__p__PFi___1)(), __attribute__ ((unused,unused,unused)) int (*__q__PFi___1)());
    258 int __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 }
    261 int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) int __Foo__i_1);
    262 int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1);
    263 int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1);
    264 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((unsigned int )5)]));
    265 int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    266 int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    267 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
    268 int __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 }
    316 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11);
    317 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13);
    318 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15);
    319 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)());
    320 int __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));
    321 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)());
    322 int __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));
    323 struct 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 };
    329 static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
    330 static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1);
    331 static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
    332 static inline struct Vad ___operator_assign__F4sVad_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1);
    333 static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){
    334 }
    335 static inline void ___constructor__F_P4sVad4sVad_autogen___1(struct Vad *___dst__P4sVad_1, struct Vad ___src__4sVad_1){
    336 }
    337 static inline void ___destructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1){
    338 }
    339 static 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 }
     1attributes.c:74 error: cannot redefine typedef: ptrdiff_t
     2attributes.c:75 error: cannot redefine typedef: size_t
     3make: *** [attributes] Error 1
  • src/tests/.expect/64/attributes.txt

    r2055098 r12d3187  
    99    L: __attribute__ ((unused)) ((void)1);
    1010}
    11 __attribute__ ((unused)) struct __anonymous0 {
     11struct __attribute__ ((unused)) __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 __attribute__ ((unused)) struct Agn1;
    27 __attribute__ ((unused)) struct Agn2 {
     26struct __attribute__ ((unused)) Agn1;
     27struct __attribute__ ((unused)) Agn2 {
    2828};
    2929static inline void ___constructor__F_P5sAgn2_autogen___1(struct Agn2 *___dst__P5sAgn2_1);
     
    4747    __E2__C5eAgn3_1,
    4848};
    49 __attribute__ ((unused)) struct __anonymous2;
    50 __attribute__ ((unused)) struct __anonymous3;
     49struct __attribute__ ((unused)) __anonymous2;
     50struct __attribute__ ((unused)) __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, ...);
    236242int __vtr__Fi___1(){
    237243    int ___retval_vtr__i_1;
     
    262268int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) int **__Foo__PPi_1);
    263269int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) int *__Foo__Pi_1);
    264 int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object5)(__attribute__ ((unused,unused)) int __anonymous_object6[((long unsigned int )5)]));
     270int __tpr4__Fi_PFi_Pi___1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused,unused)) int __anonymous_object8[((long unsigned int )5)]));
    265271int __tpr5__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    266272int __tpr6__Fi_PFi____1(__attribute__ ((unused,unused,unused)) int (*__Foo__PFi___1)());
    267 int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object7)(__attribute__ ((unused)) int (*__anonymous_object8)(__attribute__ ((unused,unused)) int __anonymous_object9)));
     273int __tpr7__Fi_PFi_PFi_i____1(__attribute__ ((unused,unused)) int (*__anonymous_object9)(__attribute__ ((unused)) int (*__anonymous_object10)(__attribute__ ((unused,unused)) int __anonymous_object11)));
    268274int __ad__Fi___1(){
    269275    int ___retval_ad__i_1;
     
    279285    ((void)sizeof(__attribute__ ((unused,unused,unused)) int (*)[10]));
    280286    ((void)sizeof(__attribute__ ((unused,unused,unused)) int ()));
    281     __attribute__ ((unused)) struct __anonymous4 {
     287    struct __attribute__ ((unused)) __anonymous4 {
    282288        int __i__i_2;
    283289    };
     
    314320    ((void)sizeof(enum __anonymous5 ));
    315321}
    316 int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object10, __attribute__ ((unused,unused,unused)) int *__anonymous_object11);
    317 int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object12, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object13);
    318 int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object14, __attribute__ ((unused,unused,unused)) int *__anonymous_object15);
    319 int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object16)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object17)());
    320 int __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));
    321 int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object22)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object23)());
    322 int __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));
     322int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object12, __attribute__ ((unused,unused,unused)) int *__anonymous_object13);
     323int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) int **__anonymous_object14, __attribute__ ((unused,unused,unused,unused)) int **__anonymous_object15);
     324int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) int *__anonymous_object16, __attribute__ ((unused,unused,unused)) int *__anonymous_object17);
     325int __apd4__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object18)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object19)());
     326int __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));
     327int __apd6__Fi_PFi__PFi____1(__attribute__ ((unused,unused,unused)) int (*__anonymous_object24)(), __attribute__ ((unused,unused,unused)) int (*__anonymous_object25)());
     328int __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));
    323329struct Vad {
    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)();
     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)();
    328334};
    329335static inline void ___constructor__F_P4sVad_autogen___1(struct Vad *___dst__P4sVad_1);
  • src/tests/.expect/castError.txt

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

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

    r2055098 r12d3187  
    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
     33make: *** [constant0-1DP] Error 1
  • src/tests/.expect/constant0-1NDDP.txt

    r2055098 r12d3187  
    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
     17make: *** [constant0-1NDDP] Error 1
  • src/tests/.expect/declarationErrors.txt

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

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

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

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

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

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

    r2055098 r12d3187  
    2222concurrent=yes
    2323quick_test+= coroutine thread monitor
    24 concurrent_test=coroutine thread monitor multi-monitor sched-int sched-int-multi sched-int-multi2 sched-ext sched-ext-multi preempt
    2524else
    2625concurrent=no
    27 concurrent_test=
    2826endif
     27
    2928
    3029# applies to both programs
    3130EXTRA_FLAGS =
    32 BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
    33 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    34 CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
     31CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
    3532CC = @CFA_BINDIR@/@CFA_NAME@
    3633
     
    5451        @+python test.py --list --concurrent=${concurrent}
    5552
    56 concurrency :
    57         @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
    58 
    5953.dummy : .dummy.c
    60         ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
     54        ${CC} ${CFLAGS} -XCFA -n ${<} -o ${@}
    6155
    6256constant0-1DP : constant0-1.c
  • src/tests/Makefile.in

    r2055098 r12d3187  
    125125CFA_NAME = @CFA_NAME@
    126126CFA_PREFIX = @CFA_PREFIX@
    127 CFLAGS = ${TEST_FLAGS} ${BUILD_FLAGS}
     127CFLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_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
    233231
    234232# applies to both programs
    235233EXTRA_FLAGS =
    236 BUILD_FLAGS = -g -Wall -Wno-unused-function @CFA_FLAGS@ ${EXTRA_FLAGS}
    237 TEST_FLAGS = $(if $(test), 2> .err/${@}.log, )
    238234fstream_test_SOURCES = fstream_test.c
    239235vector_test_SOURCES = vector/vector_int.c vector/array.c vector/vector_test.c
     
    673669        @+python test.py --list --concurrent=${concurrent}
    674670
    675 concurrency :
    676         @+python test.py --debug=${debug} --concurrent=${concurrent} ${concurrent_test}
    677 
    678671.dummy : .dummy.c
    679         ${CC} ${BUILD_FLAGS} -XCFA -n ${<} -o ${@}                              #don't use CFLAGS, this rule is not a real test
     672        ${CC} ${CFLAGS} -XCFA -n ${<} -o ${@}
    680673
    681674constant0-1DP : constant0-1.c
  • src/tests/attributes.c

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

    r2055098 r12d3187  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 27 17:05:19 2017
    13 // Update Count     : 40
     12// Last Modified On : Tue Jul  5 18:29:37 2016
     13// Update Count     : 25
    1414//
    1515
     
    3636        b = (Rational){ -3, 2 };
    3737        sout | a | b | endl;
    38 //      sout | a == 1 | endl; // FIX ME
     38        sout | a == 1 | endl;
    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;
    6963        Rational x = { 1, 2 }, y = { 2 };
    7064        sout | x - y | endl;
  • src/tests/test.py

    r2055098 r12d3187  
    66from os import listdir, environ
    77from os.path import isfile, join, splitext
    8 from pybin.tools import *
     8from subprocess import Popen, PIPE, STDOUT
    99
    1010import argparse
    11 import multiprocessing
    1211import os
    1312import re
    14 import signal
     13import stat
    1514import sys
    1615
     
    2726def getMachineType():
    2827        sh('echo "void ?{}(int*a,int b){}int main(){return 0;}" > .dummy.c')
    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 
     28        sh("make .dummy", print2stdout=False)
    3829        _, out = sh("file .dummy", print2stdout=False)
    39         rm( (".dummy.c",".dummy") )
    40 
     30        sh("rm -f .dummy.c > /dev/null 2>&1")
     31        sh("rm -f .dummy > /dev/null 2>&1")
    4132        return re.search("ELF\s([0-9]+)-bit", out).group(1)
    4233
     
    6758        return generic_list + typed_list + concurrent_list;
    6859
    69 # from the found tests, filter all the valid tests/desired tests
    70 def 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
    101 def 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 
    129 def 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
     60# helper functions to run terminal commands
     61def 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
     71def 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
     87def 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
     92def 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
     100def 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
    146109
    147110################################################################################
    148111#               running test functions
    149112################################################################################
    150 # logic to run a single test and return the result (No handling of printing or other test framework logic)
    151113def run_single_test(test, generate, dry_run, debug):
    152114
    153115        # find the output file based on the test name and options flag
    154116        out_file = (".out/%s.log" % test.name) if not generate else (".expect/%s.txt" % test.path)
    155         err_file = ".err/%s.log" % test.name
    156117
    157118        # remove any outputs from the previous tests to prevent side effects
    158         rm( (out_file, test.name), dry_run )
    159 
    160         options = "-debug" if debug else "-nodebug"
     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";
    161123
    162124        # build, skipping to next test on error
    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)
     125        make_ret, _ = sh("""%s EXTRA_FLAGS="-quiet %s" %s 2> %s 1> /dev/null""" % (make_cmd, options, test.name, out_file), dry_run)
    164126
    165127        # if the make command succeds continue otherwise skip to diff
     
    175137                        sh("cat %s > %s" % (test.name, out_file), dry_run)
    176138
    177         else :
    178                 # command failed save the log to less temporary file
    179                 sh("mv %s %s" % (err_file, out_file), dry_run)
    180 
    181139        retcode = 0
    182140        error = None
     141
     142        # fix output to prevent make depth to cause issues
     143        fix_MakeLevel(out_file)
    183144
    184145        if generate :
     
    190151
    191152        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
    192168                # fetch return code and error from the diff command
    193                 retcode, error = diff(".expect/%s.txt" % test.path, ".out/%s.log" % test.name, dry_run)
    194        
     169                retcode, error = sh(diff_cmd % (test.path, test.name), dry_run, False)
     170
    195171        # clean the executable
    196172        sh("rm -f %s > /dev/null 2>&1" % test.name, dry_run)
     
    198174        return retcode, error
    199175
    200 # run a single test and handle the errors, outputs, printing, exception handling, etc.
    201 def 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
     176def 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
    231207
    232208# run the given list of tests with the given parameters
     
    235211        sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
    236212
    237         # make sure the required folder are present
    238         sh('mkdir -p .out .expect .err', dry_run)
     213        #make sure the required folder are present
     214        sh('mkdir -p .out .expect', dry_run)
    239215
    240216        if generate :
    241217                print( "Regenerate tests for: " )
    242218
    243         # create the executor for our jobs and handle the signal properly
    244         original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
     219        # for each test to run
    245220        pool = Pool(jobs)
    246         signal.signal(signal.SIGINT, original_sigint_handler)
    247 
    248         # for each test to run
    249221        try :
    250                 results = pool.map_async(partial(run_test_worker, generate=generate, dry_run=dry_run, debug=debug), tests ).get(3600)
     222                results = pool.map_async(partial(run_test_instance, generate=generate, dry_run=dry_run, debug=debug), tests ).get(9999)
    251223        except KeyboardInterrupt:
    252224                pool.terminate()
     
    254226                sys.exit(1)
    255227
    256         # clean the workspace
     228        #clean the workspace
    257229        sh("%s clean > /dev/null 2>&1" % make_cmd, dry_run)
    258230
     
    263235        return 0
    264236
     237def 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
    265245
    266246################################################################################
    267247#               main loop
    268248################################################################################
    269 if __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
     249# create a parser with the arguments for the tests script
     250parser = argparse.ArgumentParser(description='Script which runs cforall tests')
     251parser.add_argument('--debug', help='Run all tests in debug or release', type=yes_no, default='no')
     252parser.add_argument('--concurrent', help='Run concurrent tests', type=yes_no, default='yes')
     253parser.add_argument('--dry-run', help='Don\'t run the tests, only output the commands', action='store_true')
     254parser.add_argument('--list', help='List all test available', action='store_true')
     255parser.add_argument('--all', help='Run all test available', action='store_true')
     256parser.add_argument('--regenerate-expected', help='Regenerate the .expect by running the specified tets, can be used with --all option', action='store_true')
     257parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously', type=int, default='8')
     258parser.add_argument('tests', metavar='test', type=str, nargs='*', help='a list of tests to run')
     259
     260# parse the command line arguments
     261options = parser.parse_args()
     262
     263# script must have at least some tests to run
     264if (len(options.tests) > 0  and     options.all and not options.list) \
     265or (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
     271allTests = listTests( options.concurrent )
     272
     273# if user wants all tests than no other treatement of the test list is required
     274if options.all or options.list :
     275        tests = allTests
     276
     277else :
     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) )
    282290
    283291        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) )
     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
     307tests.sort(key=lambda t: t.name)
     308
     309# check if the user already passed in a number of jobs for multi-threading
     310make_flags = environ.get('MAKEFLAGS')
     311make_jobs_fds = re.search("--jobserver-fds=\s*([0-9]+),([0-9]+)", make_flags) if make_flags else None
     312if 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
     318if options.jobs <= 0 :
     319        print('ERROR: Invalid number of jobs', file=sys.stderr)
     320        sys.exit(1)
     321
     322print('Running (%s) on %i cores' % ("debug" if options.debug else "no debug", options.jobs))
     323make_cmd = "make" if make_flags else ("make -j%i" % options.jobs)
     324
     325# users may want to simply list the tests
     326if options.list :
     327        print("\n".join(map(lambda t: "%s (%s)" % (t.name, t.path), tests)))
     328
     329else :
     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) )
Note: See TracChangeset for help on using the changeset viewer.