Changeset b7d6a36 for libcfa/src


Ignore:
Timestamp:
Feb 20, 2020, 4:15:51 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6a490b2
Parents:
dca5802 (diff), 2cbfe92 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into relaxed_ready

Location:
libcfa/src
Files:
43 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.in

    rdca5802 rb7d6a36  
    423423am__v_CFA_0 = @echo "  CFA     " $@;
    424424am__v_CFA_1 =
    425 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    426 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    427 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    428 am__v_JAVAC_1 =
    429 AM_V_GOC = $(am__v_GOC_@AM_V@)
    430 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    431 am__v_GOC_0 = @echo "  GOC     " $@;
    432 am__v_GOC_1 =
    433425UPPCC = u++
    434426UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    437429am__v_UPP_0 = @echo "  UPP     " $@;
    438430am__v_UPP_1 =
     431AM_V_GOC = $(am__v_GOC_@AM_V@)
     432am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     433am__v_GOC_0 = @echo "  GOC     " $@;
     434am__v_GOC_1 =
     435AM_V_RUST = $(am__v_RUST_@AM_V@)
     436am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     437am__v_RUST_0 = @echo "  RUST     " $@;
     438am__v_RUST_1 =
     439AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     440am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     441am__v_NODEJS_0 = @echo "  NODEJS     " $@;
     442am__v_NODEJS_1 =
     443AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     444am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     445am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     446am__v_JAVAC_1 =
    439447lib_LTLIBRARIES = libcfa.la libcfathread.la
    440448gdbwaittarget = ""
  • libcfa/src/assert.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 21 17:09:26 2019
    13 // Update Count     : 5
     12// Last Modified On : Tue Feb  4 13:00:18 2020
     13// Update Count     : 6
    1414//
    1515
     
    2626
    2727        // called by macro assert in assert.h
    28         void __assert_fail( const char *assertion, const char *file, unsigned int line, const char *function ) {
     28        void __assert_fail( const char assertion[], const char file[], unsigned int line, const char function[] ) {
    2929                __cfaabi_bits_print_safe( STDERR_FILENO, CFA_ASSERT_FMT ".\n", assertion, __progname, function, line, file );
    3030                abort();
     
    3232
    3333        // called by macro assertf
    34         void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) {
     34        void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) {
    3535                __cfaabi_bits_acquire();
    3636                __cfaabi_bits_print_nolock( STDERR_FILENO, CFA_ASSERT_FMT ": ", assertion, __progname, function, line, file );
  • libcfa/src/bits/containers.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Oct 31 16:38:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 26 08:52:20 2019
    13 // Update Count     : 4
     12// Last Modified On : Wed Jan 15 07:42:35 2020
     13// Update Count     : 28
    1414
    1515#pragma once
     
    4444
    4545        forall(dtype T | sized(T))
    46         static inline T& ?[?]( __small_array(T) & this, __lock_size_t idx) {
     46        static inline T & ?[?]( __small_array(T) & this, __lock_size_t idx ) {
    4747                return ((typeof(this.data))this.data)[idx];
    4848        }
    4949
    5050        forall(dtype T | sized(T))
    51         static inline T& ?[?]( const __small_array(T) & this, __lock_size_t idx) {
     51        static inline T & ?[?]( const __small_array(T) & this, __lock_size_t idx ) {
    5252                return ((typeof(this.data))this.data)[idx];
    5353        }
    5454
     55        forall(dtype T)
     56        static inline T * begin( const __small_array(T) & this ) {
     57                return ((typeof(this.data))this.data);
     58        }
     59
    5560        forall(dtype T | sized(T))
    56         static inline T* begin( const __small_array(T) & this ) {
    57                 return ((typeof(this.data))this.data);
    58         }
    59 
    60         forall(dtype T | sized(T))
    61         static inline T* end( const __small_array(T) & this ) {
     61        static inline T * end( const __small_array(T) & this ) {
    6262                return ((typeof(this.data))this.data) + this.size;
    6363        }
     
    7070#ifdef __cforall
    7171        trait is_node(dtype T) {
    72                 T*& get_next( T& );
     72                T *& get_next( T & );
    7373        };
    7474#endif
     
    9797        forall(dtype T)
    9898        static inline void ?{}( __stack(T) & this ) {
    99                 (this.top){ NULL };
    100         }
    101 
    102         forall(dtype T | is_node(T) | sized(T))
    103         static inline void push( __stack(T) & this, T * val ) {
    104                 verify( !get_next( *val ) );
    105                 get_next( *val ) = this.top;
    106                 this.top = val;
    107         }
    108 
    109         forall(dtype T | is_node(T) | sized(T))
    110         static inline T * pop( __stack(T) & this ) {
    111                 T * top = this.top;
    112                 if( top ) {
    113                         this.top = get_next( *top );
    114                         get_next( *top ) = NULL;
    115                 }
    116                 return top;
    117         }
    118 
    119         forall(dtype T | is_node(T))
    120         static inline int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
    121                 return this.top != 0;
     99                (this.top){ 0p };
     100        }
     101
     102        static inline forall( dtype T | is_node(T) ) {
     103                void push( __stack(T) & this, T * val ) {
     104                        verify( !get_next( *val ) );
     105                        get_next( *val ) = this.top;
     106                        this.top = val;
     107                }
     108
     109                T * pop( __stack(T) & this ) {
     110                        T * top = this.top;
     111                        if( top ) {
     112                                this.top = get_next( *top );
     113                                get_next( *top ) = 0p;
     114                        }
     115                        return top;
     116                }
     117
     118                int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) {
     119                        return this.top != 0;
     120                }
    122121        }
    123122#endif
     
    145144
    146145#ifdef __cforall
    147 
    148         forall(dtype T)
    149         static inline void ?{}( __queue(T) & this ) with( this ) {
    150                 head{ NULL };
    151                 tail{ &head };
    152         }
    153 
    154         forall(dtype T | is_node(T) | sized(T))
    155         static inline void append( __queue(T) & this, T * val ) with( this ) {
    156                 verify(tail != NULL);
    157                 *tail = val;
    158                 tail = &get_next( *val );
    159         }
    160 
    161         forall(dtype T | is_node(T) | sized(T))
    162         static inline T * pop_head( __queue(T) & this ) {
    163                 T * head = this.head;
    164                 if( head ) {
    165                         this.head = get_next( *head );
    166                         if( !get_next( *head ) ) {
    167                                 this.tail = &this.head;
    168                         }
    169                         get_next( *head ) = NULL;
    170                 }
    171                 return head;
    172         }
    173 
    174         forall(dtype T | is_node(T) | sized(T))
    175         static inline T * remove( __queue(T) & this, T ** it ) with( this ) {
    176                 T * val = *it;
    177                 verify( val );
    178 
    179                 (*it) = get_next( *val );
    180 
    181                 if( tail == &get_next( *val ) ) {
    182                         tail = it;
    183                 }
    184 
    185                 get_next( *val ) = NULL;
    186 
    187                 verify( (head == NULL) == (&head == tail) );
    188                 verify( *tail == NULL );
    189                 return val;
    190         }
    191 
    192         forall(dtype T | is_node(T))
    193         static inline int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
    194                 return this.head != 0;
     146        static inline forall( dtype T | is_node(T) ) {
     147                void ?{}( __queue(T) & this ) with( this ) {
     148                        head{ 0p };
     149                        tail{ &head };
     150                }
     151
     152                void append( __queue(T) & this, T * val ) with( this ) {
     153                        verify(tail != 0p);
     154                        *tail = val;
     155                        tail = &get_next( *val );
     156                }
     157
     158                T * pop_head( __queue(T) & this ) {
     159                        T * head = this.head;
     160                        if( head ) {
     161                                this.head = get_next( *head );
     162                                if( !get_next( *head ) ) {
     163                                        this.tail = &this.head;
     164                                }
     165                                get_next( *head ) = 0p;
     166                        }
     167                        return head;
     168                }
     169
     170                T * remove( __queue(T) & this, T ** it ) with( this ) {
     171                        T * val = *it;
     172                        verify( val );
     173
     174                        (*it) = get_next( *val );
     175
     176                        if( tail == &get_next( *val ) ) {
     177                                tail = it;
     178                        }
     179
     180                        get_next( *val ) = 0p;
     181
     182                        verify( (head == 0p) == (&head == tail) );
     183                        verify( *tail == 0p );
     184                        return val;
     185                }
     186
     187                int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) {
     188                        return this.head != 0;
     189                }
    195190        }
    196191#endif
     
    223218
    224219#ifdef __cforall
    225 
    226         forall(dtype T | sized(T))
     220        forall(dtype T )
    227221        static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) {
    228                 this.head{ NULL };
     222                this.head{ 0p };
    229223                this.__get = __get;
    230224        }
     
    232226        #define next 0
    233227        #define prev 1
    234         forall(dtype T | sized(T))
    235         static inline void push_front( __dllist(T) & this, T & node ) with( this ) {
    236                 verify(__get);
    237                 if ( head ) {
    238                         __get( node ).next = head;
    239                         __get( node ).prev = __get( *head ).prev;
    240                         // inserted node must be consistent before it is seen
     228        static inline forall(dtype T) {
     229                void push_front( __dllist(T) & this, T & node ) with( this ) {
     230                        verify(__get);
     231                        if ( head ) {
     232                                __get( node ).next = head;
     233                                __get( node ).prev = __get( *head ).prev;
     234                                // inserted node must be consistent before it is seen
     235                                // prevent code movement across barrier
     236                                asm( "" : : : "memory" );
     237                                __get( *head ).prev = &node;
     238                                T & _prev = *__get( node ).prev;
     239                                __get( _prev ).next = &node;
     240                        } else {
     241                                __get( node ).next = &node;
     242                                __get( node ).prev = &node;
     243                        }
     244
    241245                        // prevent code movement across barrier
    242246                        asm( "" : : : "memory" );
    243                         __get( *head ).prev = &node;
    244                         T & _prev = *__get( node ).prev;
    245                         __get( _prev ).next = &node;
    246                 }
    247                 else {
    248                         __get( node ).next = &node;
    249                         __get( node ).prev = &node;
    250                 }
    251 
    252                 // prevent code movement across barrier
    253                 asm( "" : : : "memory" );
    254                 head = &node;
    255         }
    256 
    257         forall(dtype T | sized(T))
    258         static inline void remove( __dllist(T) & this, T & node ) with( this ) {
    259                 verify(__get);
    260                 if ( &node == head ) {
    261                         if ( __get( *head ).next == head ) {
    262                                 head = NULL;
    263                         }
    264                         else {
    265                                 head = __get( *head ).next;
    266                         }
    267                 }
    268                 __get( *__get( node ).next ).prev = __get( node ).prev;
    269                 __get( *__get( node ).prev ).next = __get( node ).next;
    270                 __get( node ).next = NULL;
    271                 __get( node ).prev = NULL;
    272         }
    273 
    274         forall(dtype T | sized(T))
    275         static inline int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
    276                 return this.head != 0;
     247                        head = &node;
     248                }
     249
     250                void remove( __dllist(T) & this, T & node ) with( this ) {
     251                        verify(__get);
     252                        if ( &node == head ) {
     253                                if ( __get( *head ).next == head ) {
     254                                        head = 0p;
     255                                } else {
     256                                        head = __get( *head ).next;
     257                                }
     258                        }
     259                        __get( *__get( node ).next ).prev = __get( node ).prev;
     260                        __get( *__get( node ).prev ).next = __get( node ).next;
     261                        __get( node ).next = 0p;
     262                        __get( node ).prev = 0p;
     263                }
     264
     265                int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) {
     266                        return this.head != 0;
     267                }
    277268        }
    278269        #undef next
     
    286277
    287278#endif
     279
     280// Local Variables: //
     281// tab-width: 4 //
     282// End: //
  • libcfa/src/bits/debug.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Mar 30 12:30:01 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 21 17:16:30 2019
    13 // Update Count     : 10
     12// Last Modified On : Tue Feb  4 13:03:16 2020
     13// Update Count     : 11
    1414//
    1515
     
    2727
    2828extern "C" {
    29 
    30         void __cfaabi_bits_write( int fd, const char *in_buffer, int len ) {
     29        void __cfaabi_bits_write( int fd, const char in_buffer[], int len ) {
    3130                // ensure all data is written
    3231                for ( int count = 0, retcode; count < len; count += retcode ) {
  • libcfa/src/bits/debug.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov 21 17:06:58 2019
    13 // Update Count     : 8
     12// Last Modified On : Tue Feb  4 12:29:21 2020
     13// Update Count     : 9
    1414//
    1515
     
    2121        #define __cfaabi_dbg_ctx __PRETTY_FUNCTION__
    2222        #define __cfaabi_dbg_ctx2 , __PRETTY_FUNCTION__
    23         #define __cfaabi_dbg_ctx_param const char * caller
    24         #define __cfaabi_dbg_ctx_param2 , const char * caller
     23        #define __cfaabi_dbg_ctx_param const char caller[]
     24        #define __cfaabi_dbg_ctx_param2 , const char caller[]
    2525#else
    2626        #define __cfaabi_dbg_debug_do(...)
     
    3939        #include <unistd.h>
    4040
    41         extern void __cfaabi_bits_write( int fd, const char *buffer, int len );
     41        extern void __cfaabi_bits_write( int fd, const char buffer[], int len );
    4242        extern void __cfaabi_bits_acquire();
    4343        extern void __cfaabi_bits_release();
  • libcfa/src/bits/defs.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Nov  9 13:24:10 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 16:22:41 2018
    13 // Update Count     : 8
     12// Last Modified On : Tue Jan 28 22:38:27 2020
     13// Update Count     : 9
    1414//
    1515
     
    3434
    3535#ifdef __cforall
    36 void abort ( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     36void abort( const char fmt[], ... ) __attribute__ (( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     37void abort( bool signalAbort, const char fmt[], ... ) __attribute__ (( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    3738extern "C" {
    3839#endif
  • libcfa/src/bits/locks.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Aug 11 15:42:24 2018
    13 // Update Count     : 10
     12// Last Modified On : Tue Feb  4 13:03:19 2020
     13// Update Count     : 11
    1414//
    1515
     
    5454
    5555                #ifdef __CFA_DEBUG__
    56                         void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);
     56                        void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]);
    5757                #else
    5858                        #define __cfaabi_dbg_record(x, y)
  • libcfa/src/bits/signal.hfa

    rdca5802 rb7d6a36  
    3737
    3838        act.sa_sigaction = (void (*)(int, siginfo_t *, void *))handler;
     39        sigemptyset( &act.sa_mask );
     40        sigaddset( &act.sa_mask, SIGALRM );             // disabled during signal handler
     41        sigaddset( &act.sa_mask, SIGUSR1 );
     42        sigaddset( &act.sa_mask, SIGSEGV );
     43        sigaddset( &act.sa_mask, SIGBUS );
     44        sigaddset( &act.sa_mask, SIGILL );
     45        sigaddset( &act.sa_mask, SIGFPE );
     46        sigaddset( &act.sa_mask, SIGHUP );              // revert to default on second delivery
     47        sigaddset( &act.sa_mask, SIGTERM );
     48        sigaddset( &act.sa_mask, SIGINT );
    3949        act.sa_flags = flags;
    4050
    41         if ( sigaction( sig, &act, NULL ) == -1 ) {
     51        if ( sigaction( sig, &act, 0p ) == -1 ) {
    4252                __cfaabi_dbg_print_buffer_decl(
    4353                        " __cfaabi_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
     
    4555                );
    4656                _exit( EXIT_FAILURE );
    47         }
     57        } // if
    4858}
    49 
    50 // Sigaction wrapper : restore default handler
    51 static void __cfaabi_sigdefault( int sig ) {
    52         struct sigaction act;
    53 
    54         act.sa_handler = SIG_DFL;
    55         act.sa_flags = 0;
    56         sigemptyset( &act.sa_mask );
    57 
    58         if ( sigaction( sig, &act, NULL ) == -1 ) {
    59                 __cfaabi_dbg_print_buffer_decl(
    60                         " __cfaabi_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    61                         sig, errno, strerror( errno )
    62                 );
    63                 _exit( EXIT_FAILURE );
    64         }
    65 }
  • libcfa/src/clock.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Apr 12 14:36:06 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun 13 21:21:13 2019
    13 // Update Count     : 8
     12// Last Modified On : Mon Jan  6 12:49:58 2020
     13// Update Count     : 9
    1414//
    1515
    1616#include <time.hfa>
    17 
    1817
    1918//######################### C time #########################
     
    2625static inline tm * localtime_r( time_t tp, tm * result ) { return localtime_r( &tp, result ); }
    2726
    28 
    2927//######################### Clock #########################
    3028
    3129struct Clock {                                                                                  // private
    3230        Duration offset;                                                                        // for virtual clock: contains offset from real-time
    33         int clocktype;                                                                          // implementation only -1 (virtual), CLOCK_REALTIME
    3431};
    3532
    3633static inline {
    37         void resetClock( Clock & clk ) with( clk ) {
    38                 clocktype = CLOCK_REALTIME_COARSE;
    39         } // Clock::resetClock
    40 
    4134        void resetClock( Clock & clk, Duration adj ) with( clk ) {
    42                 clocktype = -1;
    4335                offset = adj + __timezone`s;                                    // timezone (global) is (UTC - local time) in seconds
    4436        } // resetClock
    4537
    46         void ?{}( Clock & clk ) { resetClock( clk ); }
    4738        void ?{}( Clock & clk, Duration adj ) { resetClock( clk, adj ); }
    4839
     
    8980                return ret;
    9081        } // getTime
     82
     83        Time getCPUTime() {
     84                timespec ts;
     85                clock_gettime( CLOCK_THREAD_CPUTIME_ID, &ts );
     86                return (Time){ ts };
     87    } // getCPUTime
    9188} // distribution
    9289
  • libcfa/src/concurrency/CtxSwitch-x86_64.S

    rdca5802 rb7d6a36  
    8787CtxInvokeStub:
    8888        movq %rbx, %rdi
    89         jmp *%r12
     89        movq %r12, %rsi
     90        jmp *%r13
    9091        .size  CtxInvokeStub, .-CtxInvokeStub
    9192
  • libcfa/src/concurrency/alarm.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  3 22:47:24 2019
    13 // Update Count     : 68
     12// Last Modified On : Sun Jan  5 08:41:36 2020
     13// Update Count     : 69
    1414//
    1515
     
    3939
    4040void __kernel_set_timer( Duration alarm ) {
    41         verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm.tv);
     41        verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm`ns);
    4242        setitimer( ITIMER_REAL, &(itimerval){ alarm }, 0p );
    4343}
  • libcfa/src/concurrency/coroutine.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec  5 14:37:29 2019
    13 // Update Count     : 15
     12// Last Modified On : Tue Feb  4 12:29:25 2020
     13// Update Count     : 16
    1414//
    1515
     
    8989}
    9090
    91 void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize ) with( this ) {
     91void ?{}( coroutine_desc & this, const char name[], void * storage, size_t storageSize ) with( this ) {
    9292        (this.context){0p, 0p};
    9393        (this.stack){storage, storageSize};
     
    187187// is not inline (We can't inline Cforall in C)
    188188extern "C" {
    189         void __suspend_internal(void) {
    190                 suspend();
    191         }
    192 
    193         void __leave_coroutine( coroutine_desc * src ) {
     189        void __leave_coroutine( struct coroutine_desc * src ) {
    194190                coroutine_desc * starter = src->cancellation != 0 ? src->last : src->starter;
    195191
     
    207203                CoroutineCtxSwitch( src, starter );
    208204        }
     205
     206        struct coroutine_desc * __finish_coroutine(void) {
     207                struct coroutine_desc * cor = kernelTLS.this_thread->curr_cor;
     208
     209                if(cor->state == Primed) {
     210                        suspend();
     211                }
     212
     213                cor->state = Active;
     214
     215                return cor;
     216        }
    209217}
    210218
  • libcfa/src/concurrency/coroutine.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  3 22:47:58 2019
    13 // Update Count     : 10
     12// Last Modified On : Tue Feb  4 12:29:26 2020
     13// Update Count     : 11
    1414//
    1515
     
    3535// void ^?{}( coStack_t & this );
    3636
    37 void ?{}( coroutine_desc & this, const char * name, void * storage, size_t storageSize );
     37void ?{}( coroutine_desc & this, const char name[], void * storage, size_t storageSize );
    3838void ^?{}( coroutine_desc & this );
    3939
     
    4141static inline void ?{}( coroutine_desc & this, size_t stackSize)                     { this{ "Anonymous Coroutine", 0p, stackSize }; }
    4242static inline void ?{}( coroutine_desc & this, void * storage, size_t storageSize )  { this{ "Anonymous Coroutine", storage, storageSize }; }
    43 static inline void ?{}( coroutine_desc & this, const char * name)                    { this{ name, 0p, 0 }; }
    44 static inline void ?{}( coroutine_desc & this, const char * name, size_t stackSize ) { this{ name, 0p, stackSize }; }
     43static inline void ?{}( coroutine_desc & this, const char name[])                    { this{ name, 0p, 0 }; }
     44static inline void ?{}( coroutine_desc & this, const char name[], size_t stackSize ) { this{ name, 0p, stackSize }; }
    4545
    4646//-----------------------------------------------------------------------------
     
    6161// Start coroutine routines
    6262extern "C" {
    63       forall(dtype T | is_coroutine(T))
    64       void CtxInvokeCoroutine(T * this);
     63        void CtxInvokeCoroutine(void (*main)(void *), void * this);
    6564
    66       forall(dtype T | is_coroutine(T))
    67       void CtxStart(T * this, void ( *invoke)(T *));
     65        forall(dtype T)
     66        void CtxStart(void (*main)(T &), struct coroutine_desc * cor, T & this, void (*invoke)(void (*main)(void *), void *));
    6867
    6968        extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__));
     
    129128
    130129        if( unlikely(dst->context.SP == 0p) ) {
     130                TL_GET( this_thread )->curr_cor = dst;
    131131                __stack_prepare(&dst->stack, 65000);
    132                 CtxStart(&cor, CtxInvokeCoroutine);
     132                CtxStart(main, dst, cor, CtxInvokeCoroutine);
     133                TL_GET( this_thread )->curr_cor = src;
    133134        }
    134135
  • libcfa/src/concurrency/invoke.c

    rdca5802 rb7d6a36  
    2929// Called from the kernel when starting a coroutine or task so must switch back to user mode.
    3030
    31 extern void __suspend_internal(void);
    32 extern void __leave_coroutine( struct coroutine_desc * );
    33 extern void __finish_creation( struct thread_desc * );
    34 extern void __leave_thread_monitor( struct thread_desc * this );
     31extern void __leave_coroutine ( struct coroutine_desc * );
     32extern struct coroutine_desc * __finish_coroutine(void);
     33extern void __leave_thread_monitor();
    3534extern void disable_interrupts() OPTIONAL_THREAD;
    3635extern void enable_interrupts( __cfaabi_dbg_ctx_param );
     
    3837void CtxInvokeCoroutine(
    3938        void (*main)(void *),
    40         struct coroutine_desc *(*get_coroutine)(void *),
    4139        void *this
    4240) {
    43         struct coroutine_desc* cor = get_coroutine( this );
     41        // Finish setting up the coroutine by setting its state
     42        struct coroutine_desc * cor = __finish_coroutine();
    4443
    45         if(cor->state == Primed) {
    46                 __suspend_internal();
    47         }
    48 
    49         cor->state = Active;
    50 
     44        // Call the main of the coroutine
    5145        main( this );
    5246
     
    8377
    8478void CtxInvokeThread(
    85         void (*dtor)(void *),
    8679        void (*main)(void *),
    87         struct thread_desc *(*get_thread)(void *),
    8880        void *this
    8981) {
    90         // Fetch the thread handle from the user defined thread structure
    91         struct thread_desc* thrd = get_thread( this );
    92 
    93         // First suspend, once the thread arrives here,
    94         // the function pointer to main can be invalidated without risk
    95         __finish_creation( thrd );
    96 
    9782        // Officially start the thread by enabling preemption
    9883        enable_interrupts( __cfaabi_dbg_ctx );
     
    10893        // The order of these 4 operations is very important
    10994        //Final suspend, should never return
    110         __leave_thread_monitor( thrd );
     95        __leave_thread_monitor();
    11196        __cabi_abort( "Resumed dead thread" );
    11297}
    11398
    114 
    11599void CtxStart(
    116100        void (*main)(void *),
    117         struct coroutine_desc *(*get_coroutine)(void *),
     101        struct coroutine_desc * cor,
    118102        void *this,
    119103        void (*invoke)(void *)
    120104) {
    121         struct coroutine_desc * cor = get_coroutine( this );
    122105        struct __stack_t * stack = cor->stack.storage;
    123106
     
    138121
    139122        fs->dummyReturn = NULL;
    140         fs->argument[0] = this;     // argument to invoke
     123        fs->argument[0] = main;     // argument to invoke
     124        fs->argument[1] = this;     // argument to invoke
    141125        fs->rturn = invoke;
    142126
     
    156140        fs->dummyReturn = NULL;
    157141        fs->rturn = CtxInvokeStub;
    158         fs->fixedRegisters[0] = this;
    159         fs->fixedRegisters[1] = invoke;
     142        fs->fixedRegisters[0] = main;
     143        fs->fixedRegisters[1] = this;
     144        fs->fixedRegisters[2] = invoke;
    160145
    161146#elif defined( __ARM_ARCH )
    162 
     147#error ARM needs to be upgrade to use to parameters like X86/X64 (A.K.A. : I broke this and do not know how to fix it)
    163148        struct FakeStack {
    164149                float fpRegs[16];                       // floating point registers
  • libcfa/src/concurrency/kernel.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec  5 16:25:52 2019
    13 // Update Count     : 52
     12// Last Modified On : Tue Feb  4 13:03:15 2020
     13// Update Count     : 58
    1414//
    1515
     
    210210
    211211static void start(processor * this);
    212 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
     212void ?{}(processor & this, const char name[], cluster & cltr) with( this ) {
    213213        this.name = name;
    214214        this.cltr = &cltr;
     
    240240}
    241241
    242 void ?{}(cluster & this, const char * name, Duration preemption_rate) with( this ) {
     242void ?{}(cluster & this, const char name[], Duration preemption_rate) with( this ) {
    243243        this.name = name;
    244244        this.preemption_rate = preemption_rate;
     
    454454}
    455455
    456 static void Abort( int ret, const char * func ) {
     456static void Abort( int ret, const char func[] ) {
    457457        if ( ret ) {                                                                            // pthread routines return errno values
    458458                abort( "%s : internal error, error(%d) %s.", func, ret, strerror( ret ) );
     
    503503        verify( ! kernelTLS.preemption_state.enabled );
    504504
     505        kernelTLS.this_thread->curr_cor = dst;
    505506        __stack_prepare( &dst->stack, 65000 );
    506         CtxStart(&this->runner, CtxInvokeCoroutine);
     507        CtxStart(main, dst, this->runner, CtxInvokeCoroutine);
    507508
    508509        verify( ! kernelTLS.preemption_state.enabled );
     
    518519        CtxSwitch( &src->context, &dst->context );
    519520        // when CtxSwitch returns we are back in the src coroutine
     521
     522        mainThread->curr_cor = &mainThread->self_cor;
    520523
    521524        // set state of new coroutine to active
     
    864867                sigemptyset( &mask );
    865868                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
    866                 sigsuspend( &mask );                    // block the processor to prevent further damage during abort
    867                 _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     869                sigaddset( &mask, SIGUSR1 );            // block SIGALRM signals
     870                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
     871                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    868872        }
    869873        else {
     
    986990__cfaabi_dbg_debug_do(
    987991        extern "C" {
    988                 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) {
     992                void __cfaabi_dbg_record(__spinlock_t & this, const char prev_name[]) {
    989993                        this.prev_name = prev_name;
    990994                        this.prev_thrd = kernelTLS.this_thread;
  • libcfa/src/concurrency/kernel.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Dec  4 07:54:51 2019
    13 // Update Count     : 18
     12// Last Modified On : Tue Feb  4 12:29:26 2020
     13// Update Count     : 22
    1414//
    1515
     
    151151};
    152152
    153 void  ?{}(processor & this, const char * name, struct cluster & cltr);
     153void  ?{}(processor & this, const char name[], struct cluster & cltr);
    154154void ^?{}(processor & this);
    155155
    156156static inline void  ?{}(processor & this)                    { this{ "Anonymous Processor", *mainCluster}; }
    157157static inline void  ?{}(processor & this, struct cluster & cltr)    { this{ "Anonymous Processor", cltr}; }
    158 static inline void  ?{}(processor & this, const char * name) { this{name, *mainCluster }; }
     158static inline void  ?{}(processor & this, const char name[]) { this{name, *mainCluster }; }
    159159
    160160static inline [processor *&, processor *& ] __get( processor & this ) {
     
    344344extern Duration default_preemption();
    345345
    346 void ?{} (cluster & this, const char * name, Duration preemption_rate);
     346void ?{} (cluster & this, const char name[], Duration preemption_rate);
    347347void ^?{}(cluster & this);
    348348
    349349static inline void ?{} (cluster & this)                           { this{"Anonymous Cluster", default_preemption()}; }
    350350static inline void ?{} (cluster & this, Duration preemption_rate) { this{"Anonymous Cluster", preemption_rate}; }
    351 static inline void ?{} (cluster & this, const char * name)        { this{name, default_preemption()}; }
     351static inline void ?{} (cluster & this, const char name[])        { this{name, default_preemption()}; }
    352352
    353353static inline [cluster *&, cluster *& ] __get( cluster & this ) {
  • libcfa/src/concurrency/kernel_private.hfa

    rdca5802 rb7d6a36  
    8888// Threads
    8989extern "C" {
    90       forall(dtype T | is_thread(T))
    91       void CtxInvokeThread(T * this);
     90      void CtxInvokeThread(void (*main)(void *), void * this);
    9291}
    9392
  • libcfa/src/concurrency/monitor.cfa

    rdca5802 rb7d6a36  
    243243        // last routine called by a thread.
    244244        // Should never return
    245         void __leave_thread_monitor( thread_desc * thrd ) {
     245        void __leave_thread_monitor() {
     246                thread_desc * thrd = TL_GET( this_thread );
    246247                monitor_desc * this = &thrd->self_mon;
    247248
  • libcfa/src/concurrency/thread.cfa

    rdca5802 rb7d6a36  
    5959void ?{}( scoped(T)& this ) with( this ) {
    6060        handle{};
    61         __thrd_start(handle);
     61        __thrd_start(handle, main);
    6262}
    6363
     
    6565void ?{}( scoped(T)& this, P params ) with( this ) {
    6666        handle{ params };
    67         __thrd_start(handle);
     67        __thrd_start(handle, main);
    6868}
    6969
     
    7676// Starting and stopping threads
    7777forall( dtype T | is_thread(T) )
    78 void __thrd_start( T& this ) {
     78void __thrd_start( T & this, void (*main_p)(T &) ) {
    7979        thread_desc * this_thrd = get_thread(this);
    80         thread_desc * curr_thrd = TL_GET( this_thread );
    8180
    8281        disable_interrupts();
    83         CtxStart(&this, CtxInvokeThread);
     82        CtxStart(main_p, get_coroutine(this), this, CtxInvokeThread);
     83
    8484        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
    8585        verify( this_thrd->context.SP );
    86         CtxSwitch( &curr_thrd->context, &this_thrd->context );
    8786
    8887        ScheduleThread(this_thrd);
    8988        enable_interrupts( __cfaabi_dbg_ctx );
    90 }
    91 
    92 extern "C" {
    93         // KERNEL ONLY
    94         void __finish_creation(thread_desc * this) {
    95                 // set new coroutine that the processor is executing
    96                 // and context switch to it
    97                 verify( kernelTLS.this_thread != this );
    98                 verify( kernelTLS.this_thread->context.SP );
    99                 CtxSwitch( &this->context, &kernelTLS.this_thread->context );
    100         }
    10189}
    10290
  • libcfa/src/concurrency/thread.hfa

    rdca5802 rb7d6a36  
    5454
    5555forall( dtype T | is_thread(T) )
    56 void __thrd_start( T & this );
     56void __thrd_start( T & this, void (*)(T &) );
    5757
    5858//-----------------------------------------------------------------------------
  • libcfa/src/exception.c

    rdca5802 rb7d6a36  
    6969
    7070
    71 // This macro should be the only thing that needs to change across machines.  Used in the personality function, way down
    72 // in termination.
     71// This macro should be the only thing that needs to change across machines.
     72// Used in the personality function, way down in termination.
    7373// struct _Unwind_Context * -> _Unwind_Reason_Code(*)(exception_t *)
    7474#define MATCHER_FROM_CONTEXT(ptr_to_context) \
     
    102102}
    103103
    104 // Do we control where exceptions get thrown even with concurency?  If not these are not quite thread safe, the cleanup
    105 // hook has to be added after the node is built but before it is made the top node.
     104// Do we control where exceptions get thrown even with concurency?
     105// If not these are not quite thread safe, the cleanup hook has to
     106// be added after the node is built but before it is made the top node.
    106107
    107108void __cfaabi_ehm__try_resume_setup(struct __cfaabi_ehm__try_resume_node * node,
     
    212213        _Unwind_Reason_Code ret = _Unwind_RaiseException( &this_exception_storage );
    213214
    214         // If we reach here it means something happened.  For resumption to work we need to find a way to return back to
    215         // here.  Most of them will probably boil down to setting a global flag and making the phase 1 either stop or
    216         // fail.  Causing an error on purpose may help avoiding unnecessary work but it might have some weird side
    217         // effects.  If we just pretend no handler was found that would work but may be expensive for no reason since we
    218         // will always search the whole stack.
     215        // If we reach here it means something happened. For resumption to work we need to find a way
     216        // to return back to here. Most of them will probably boil down to setting a global flag and
     217        // making the phase 1 either stop or fail. Causing an error on purpose may help avoiding
     218        // unnecessary work but it might have some weird side effects. If we just pretend no handler
     219        // was found that would work but may be expensive for no reason since we will always search
     220        // the whole stack.
    219221
    220222        if( ret == _URC_END_OF_STACK ) {
    221                 // No proper handler was found.  This can be handled in several way.  C++ calls std::terminate Here we
    222                 // force unwind the stack, basically raising a cancellation.
     223                // No proper handler was found. This can be handled in many ways, C++ calls std::terminate.
     224                // Here we force unwind the stack, basically raising a cancellation.
    223225                printf("Uncaught exception %p\n", &this_exception_storage);
    224226
     
    228230        }
    229231
    230         // We did not simply reach the end of the stack without finding a handler.  Something wen't wrong
     232        // We did not simply reach the end of the stack without finding a handler. This is an error.
    231233        printf("UNWIND ERROR %d after raise exception\n", ret);
    232234        abort();
     
    246248}
    247249
    248 #if defined(PIC)
    249 #warning Exceptions not yet supported when using Position-Independent Code
    250 __attribute__((noinline))
    251 void __cfaabi_ehm__try_terminate(void (*try_block)(),
    252                 void (*catch_block)(int index, exception_t * except),
    253                 __attribute__((unused)) int (*match_block)(exception_t * except)) {
    254         abort();
    255 }
    256 #else
    257 // This is our personality routine.  For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0".
    258 // This function will be called twice when unwinding.  Once in the search phased and once in the cleanup phase.
     250#pragma GCC push_options
     251#pragma GCC optimize("O0")
     252
     253// This is our personality routine. For every stack frame annotated with
     254// ".cfi_personality 0x3,__gcfa_personality_v0" this function will be called twice when unwinding.
     255//  Once in the search phase and once in the cleanup phase.
    259256_Unwind_Reason_Code __gcfa_personality_v0 (
    260257                int version, _Unwind_Action actions, unsigned long long exceptionClass,
     
    264261
    265262        //__cfaabi_dbg_print_safe("CFA: 0x%lx\n", _Unwind_GetCFA(context));
    266         __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):", version, actions, exceptionClass, unwind_exception, context);
     263        __cfaabi_dbg_print_safe("Personality function (%d, %x, %llu, %p, %p):",
     264                        version, actions, exceptionClass, unwind_exception, context);
    267265
    268266        // If we've reached the end of the stack then there is nothing much we can do...
     
    291289        // Get the instuction pointer and a reading pointer into the exception table
    292290        lsda_header_info lsd_info;
    293         const unsigned char * cur_ptr = parse_lsda_header( context, lsd, &lsd_info);
     291        const unsigned char * cur_ptr = parse_lsda_header(context, lsd, &lsd_info);
    294292        _Unwind_Ptr instruction_ptr = _Unwind_GetIP( context );
    295293
     
    302300
    303301                // Decode the common stuff we have in here
    304                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
    305                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
    306                 cur_ptr = read_encoded_value (0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
    307                 cur_ptr = read_uleb128 (cur_ptr, &callsite_action);
     302                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_start);
     303                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_len);
     304                cur_ptr = read_encoded_value(0, lsd_info.call_site_encoding, cur_ptr, &callsite_landing_pad);
     305                cur_ptr = read_uleb128(cur_ptr, &callsite_action);
    308306
    309307                // Have we reach the correct frame info yet?
     
    316314                        void * ep = (void*)lsd_info.Start + callsite_start + callsite_len;
    317315                        void * ip = (void*)instruction_ptr;
    318                         __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n", bp, ep, ls, cs, cl, ip);
     316                        __cfaabi_dbg_print_safe("\nfound %p - %p (%p, %p, %p), looking for %p\n",
     317                                        bp, ep, ls, cs, cl, ip);
    319318#endif // __CFA_DEBUG_PRINT__
    320319                        continue;
    321320                }
    322321
    323                 // Have we gone too far
     322                // Have we gone too far?
    324323                if( lsd_info.Start + callsite_start > instruction_ptr ) {
    325324                        printf(" gone too far");
     
    331330                        // Which phase are we in
    332331                        if (actions & _UA_SEARCH_PHASE) {
    333                                 // Search phase, this means we probably found a potential handler and must check if it is a match
    334 
    335                                 // If we have arbitrarily decided that 0 means nothing to do and 1 means there is a potential handler
    336                                 // This doesn't seem to conflict the gcc default behavior
     332                                // In search phase, these means we found a potential handler we must check.
     333
     334                                // We have arbitrarily decided that 0 means nothing to do and 1 means there is
     335                                // a potential handler. This doesn't seem to conflict the gcc default behavior.
    337336                                if (callsite_action != 0) {
    338337                                        // Now we want to run some code to see if the handler matches
     
    351350                                        // The current apprach uses one exception table entry per try block
    352351                                        _uleb128_t imatcher;
    353                                         // Get the relative offset to the
    354                                         cur_ptr = read_uleb128 (cur_ptr, &imatcher);
    355 
    356                                         // Get a function pointer from the relative offset and call it
    357                                         // _Unwind_Reason_Code (*matcher)() = (_Unwind_Reason_Code (*)())lsd_info.LPStart + imatcher;
     352                                        // Get the relative offset to the {...}?
     353                                        cur_ptr = read_uleb128(cur_ptr, &imatcher);
    358354
    359355                                        _Unwind_Reason_Code (*matcher)(exception_t *) =
     
    414410}
    415411
    416 // Try statements are hoisted out see comments for details.  With this could probably be unique and simply linked from
    417 // libcfa but there is one problem left, see the exception table for details
     412// Try statements are hoisted out see comments for details. While this could probably be unique
     413// and simply linked from libcfa but there is one problem left, see the exception table for details
    418414__attribute__((noinline))
    419415void __cfaabi_ehm__try_terminate(void (*try_block)(),
     
    428424        // assembly works.
    429425
    430         // Setup the personality routine
     426        // Setup the personality routine and exception table.
     427#ifdef __PIC__
     428        asm volatile (".cfi_personality 0x9b,CFA.ref.__gcfa_personality_v0");
     429        asm volatile (".cfi_lsda 0x1b, .LLSDACFA2");
     430#else
    431431        asm volatile (".cfi_personality 0x3,__gcfa_personality_v0");
    432         // Setup the exception table
    433432        asm volatile (".cfi_lsda 0x3, .LLSDACFA2");
     433#endif
    434434
    435435        // Label which defines the start of the area for which the handler is setup.
     
    442442        asm volatile goto ("" : : : : CATCH );
    443443
    444         // Normal return
     444        // Normal return for when there is no throw.
    445445        return;
    446446
     
    459459}
    460460
    461 // Exception table data we need to generate.  While this is almost generic, the custom data refers to foo_try_match try
    462 // match, which is no way generic.  Some more works need to be done if we want to have a single call to the try routine.
    463 
     461// Exception table data we need to generate. While this is almost generic, the custom data refers
     462// to {*}try_terminate, which is no way generic. Some more works need to be done if we want to
     463// have a single call to the try routine.
     464
     465#ifdef __PIC__
    464466#if defined( __i386 ) || defined( __x86_64 )
    465467asm (
    466         //HEADER
     468        // HEADER
    467469        ".LFECFA1:\n"
    468470        "       .globl  __gcfa_personality_v0\n"
    469471        "       .section        .gcc_except_table,\"a\",@progbits\n"
    470         ".LLSDACFA2:\n"                                                 //TABLE header
     472        // TABLE HEADER (important field is the BODY length at the end)
     473        ".LLSDACFA2:\n"
    471474        "       .byte   0xff\n"
    472475        "       .byte   0xff\n"
    473476        "       .byte   0x1\n"
    474         "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"         // BODY length
    475         // Body uses language specific data and therefore could be modified arbitrarily
    476         ".LLSDACSBCFA2:\n"                                              // BODY start
    477         "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"               // Handled area start  (relative to start of function)
    478         "       .uleb128 .TRYEND-.TRYSTART\n"                           // Handled area length
    479         "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"                          // Hanlder landing pad adress  (relative to start of function)
    480         "       .uleb128 1\n"                                           // Action code, gcc seems to use always 0
    481         ".LLSDACSECFA2:\n"                                              // BODY end
    482         "       .text\n"                                                        // TABLE footer
     477        "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
     478        // BODY (language specific data)
     479        // This uses language specific data and can be modified arbitrarily
     480        // We use handled area offset, handled area length,
     481        // handler landing pad offset and 1 (action code, gcc seems to use 0).
     482        ".LLSDACSBCFA2:\n"
     483        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     484        "       .uleb128 .TRYEND-.TRYSTART\n"
     485        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     486        "       .uleb128 1\n"
     487        ".LLSDACSECFA2:\n"
     488        // TABLE FOOTER
     489        "       .text\n"
     490        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
     491);
     492
     493// Somehow this piece of helps with the resolution of debug symbols.
     494__attribute__((unused)) static const int dummy = 0;
     495
     496asm (
     497        // Add a hidden symbol which points at the function.
     498        "       .hidden CFA.ref.__gcfa_personality_v0\n"
     499        "       .weak   CFA.ref.__gcfa_personality_v0\n"
     500        // No clue what this does specifically
     501        "       .section        .data.rel.local.CFA.ref.__gcfa_personality_v0,\"awG\",@progbits,CFA.ref.__gcfa_personality_v0,comdat\n"
     502        "       .align 8\n"
     503        "       .type CFA.ref.__gcfa_personality_v0, @object\n"
     504        "       .size CFA.ref.__gcfa_personality_v0, 8\n"
     505        "CFA.ref.__gcfa_personality_v0:\n"
     506#if defined( __x86_64 )
     507        "       .quad __gcfa_personality_v0\n"
     508#else // then __i386
     509        "   .long __gcfa_personality_v0\n"
     510#endif
     511);
     512#else
     513#error Exception Handling: unknown architecture for position independent code.
     514#endif // __i386 || __x86_64
     515#else // __PIC__
     516#if defined( __i386 ) || defined( __x86_64 )
     517asm (
     518        // HEADER
     519        ".LFECFA1:\n"
     520        "       .globl  __gcfa_personality_v0\n"
     521        "       .section        .gcc_except_table,\"a\",@progbits\n"
     522        // TABLE HEADER (important field is the BODY length at the end)
     523        ".LLSDACFA2:\n"
     524        "       .byte   0xff\n"
     525        "       .byte   0xff\n"
     526        "       .byte   0x1\n"
     527        "       .uleb128 .LLSDACSECFA2-.LLSDACSBCFA2\n"
     528        // BODY (language specific data)
     529        ".LLSDACSBCFA2:\n"
     530        //      Handled area start (relative to start of function)
     531        "       .uleb128 .TRYSTART-__cfaabi_ehm__try_terminate\n"
     532        //      Handled area length
     533        "       .uleb128 .TRYEND-.TRYSTART\n"
     534        //      Handler landing pad address (relative to start of function)
     535        "       .uleb128 .CATCH-__cfaabi_ehm__try_terminate\n"
     536        //      Action code, gcc seems to always use 0.
     537        "       .uleb128 1\n"
     538        // TABLE FOOTER
     539        ".LLSDACSECFA2:\n"
     540        "       .text\n"
    483541        "       .size   __cfaabi_ehm__try_terminate, .-__cfaabi_ehm__try_terminate\n"
    484542        "       .ident  \"GCC: (Ubuntu 6.2.0-3ubuntu11~16.04) 6.2.0 20160901\"\n"
    485 //      "       .section        .note.GNU-stack,\"x\",@progbits\n"
     543        "       .section        .note.GNU-stack,\"x\",@progbits\n"
    486544);
     545#else
     546#error Exception Handling: unknown architecture for position dependent code.
    487547#endif // __i386 || __x86_64
    488 #endif //PIC
     548#endif // __PIC__
     549
     550#pragma GCC pop_options
  • libcfa/src/executor.cfa

    rdca5802 rb7d6a36  
    88#include <stdio.h>
    99
    10 forall( otype T | is_node(T) | is_monitor(T) ) {
    11     monitor Buffer {                                    // unbounded buffer
    12         __queue_t( T ) queue;                           // unbounded list of work requests
    13         condition delay;
    14     }; // Buffer
    15 
     10forall( dtype T )
     11monitor Buffer {                                        // unbounded buffer
     12    __queue_t( T ) queue;                               // unbounded list of work requests
     13    condition delay;
     14}; // Buffer
     15forall( dtype T | is_node(T) ) {
    1616    void insert( Buffer( T ) & mutex buf, T * elem ) with(buf) {
    1717        append( queue, elem );                          // insert element into buffer
     
    2020
    2121    T * remove( Buffer( T ) & mutex buf ) with(buf) {
    22         if ( ! queue ) wait( delay );                   // no request to process ? => wait
    23         return pop_head( queue );
     22        if ( queue.head != 0 ) wait( delay );                   // no request to process ? => wait
     23//      return pop_head( queue );
    2424    } // remove
    2525} // distribution
  • libcfa/src/fstream.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 29 06:56:46 2019
    13 // Update Count     : 355
     12// Last Modified On : Fri Feb  7 19:01:01 2020
     13// Update Count     : 363
    1414//
    1515
     
    3232
    3333void ?{}( ofstream & os, void * file ) {
    34         os.file = file;
    35         os.sepDefault = true;
    36         os.sepOnOff = false;
    37         os.nlOnOff = true;
    38         os.prt = false;
    39         os.sawNL = false;
     34        os.$file = file;
     35        os.$sepDefault = true;
     36        os.$sepOnOff = false;
     37        os.$nlOnOff = true;
     38        os.$prt = false;
     39        os.$sawNL = false;
     40        $sepSetCur( os, sepGet( os ) );
    4041        sepSet( os, " " );
    41         sepSetCur( os, sepGet( os ) );
    4242        sepSetTuple( os, ", " );
    4343} // ?{}
    4444
    4545// private
    46 bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }
    47 void sepReset( ofstream & os ) { os.sepOnOff = os.sepDefault; }
    48 void sepReset( ofstream & os, bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }
    49 const char * sepGetCur( ofstream & os ) { return os.sepCur; }
    50 void sepSetCur( ofstream & os, const char * sepCur ) { os.sepCur = sepCur; }
    51 bool getNL( ofstream & os ) { return os.sawNL; }
    52 void setNL( ofstream & os, bool state ) { os.sawNL = state; }
    53 bool getANL( ofstream & os ) { return os.nlOnOff; }
    54 bool getPrt( ofstream & os ) { return os.prt; }
    55 void setPrt( ofstream & os, bool state ) { os.prt = state; }
     46bool $sepPrt( ofstream & os ) { $setNL( os, false ); return os.$sepOnOff; }
     47void $sepReset( ofstream & os ) { os.$sepOnOff = os.$sepDefault; }
     48void $sepReset( ofstream & os, bool reset ) { os.$sepDefault = reset; os.$sepOnOff = os.$sepDefault; }
     49const char * $sepGetCur( ofstream & os ) { return os.$sepCur; }
     50void $sepSetCur( ofstream & os, const char sepCur[] ) { os.$sepCur = sepCur; }
     51bool $getNL( ofstream & os ) { return os.$sawNL; }
     52void $setNL( ofstream & os, bool state ) { os.$sawNL = state; }
     53bool $getANL( ofstream & os ) { return os.$nlOnOff; }
     54bool $getPrt( ofstream & os ) { return os.$prt; }
     55void $setPrt( ofstream & os, bool state ) { os.$prt = state; }
    5656
    5757// public
    58 void ?{}( ofstream & os ) { os.file = 0; }
    59 
    60 void ?{}( ofstream & os, const char * name, const char * mode ) {
     58void ?{}( ofstream & os ) { os.$file = 0p; }
     59
     60void ?{}( ofstream & os, const char name[], const char mode[] ) {
    6161        open( os, name, mode );
    6262} // ?{}
    6363
    64 void ?{}( ofstream & os, const char * name ) {
     64void ?{}( ofstream & os, const char name[] ) {
    6565        open( os, name, "w" );
    6666} // ?{}
     
    7070} // ^?{}
    7171
    72 void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
    73 void sepOff( ofstream & os ) { os.sepOnOff = false; }
     72void sepOn( ofstream & os ) { os.$sepOnOff = ! $getNL( os ); }
     73void sepOff( ofstream & os ) { os.$sepOnOff = false; }
    7474
    7575bool sepDisable( ofstream & os ) {
    76         bool temp = os.sepDefault;
    77         os.sepDefault = false;
    78         sepReset( os );
     76        bool temp = os.$sepDefault;
     77        os.$sepDefault = false;
     78        $sepReset( os );
    7979        return temp;
    8080} // sepDisable
    8181
    8282bool sepEnable( ofstream & os ) {
    83         bool temp = os.sepDefault;
    84         os.sepDefault = true;
    85         if ( os.sepOnOff ) sepReset( os );                                      // start of line ?
     83        bool temp = os.$sepDefault;
     84        os.$sepDefault = true;
     85        if ( os.$sepOnOff ) $sepReset( os );                            // start of line ?
    8686        return temp;
    8787} // sepEnable
    8888
    89 void nlOn( ofstream & os ) { os.nlOnOff = true; }
    90 void nlOff( ofstream & os ) { os.nlOnOff = false; }
    91 
    92 const char * sepGet( ofstream & os ) { return os.separator; }
    93 void sepSet( ofstream & os, const char * s ) {
     89void nlOn( ofstream & os ) { os.$nlOnOff = true; }
     90void nlOff( ofstream & os ) { os.$nlOnOff = false; }
     91
     92const char * sepGet( ofstream & os ) { return os.$separator; }
     93void sepSet( ofstream & os, const char s[] ) {
    9494        assert( s );
    95         strncpy( os.separator, s, sepSize - 1 );
    96         os.separator[sepSize - 1] = '\0';
     95        strncpy( os.$separator, s, sepSize - 1 );
     96        os.$separator[sepSize - 1] = '\0';
    9797} // sepSet
    9898
    99 const char * sepGetTuple( ofstream & os ) { return os.tupleSeparator; }
    100 void sepSetTuple( ofstream & os, const char * s ) {
     99const char * sepGetTuple( ofstream & os ) { return os.$tupleSeparator; }
     100void sepSetTuple( ofstream & os, const char s[] ) {
    101101        assert( s );
    102         strncpy( os.tupleSeparator, s, sepSize - 1 );
    103         os.tupleSeparator[sepSize - 1] = '\0';
     102        strncpy( os.$tupleSeparator, s, sepSize - 1 );
     103        os.$tupleSeparator[sepSize - 1] = '\0';
    104104} // sepSet
    105105
    106106void ends( ofstream & os ) {
    107         if ( getANL( os ) ) nl( os );
    108         else setPrt( os, false );                                                       // turn off
     107        if ( $getANL( os ) ) nl( os );
     108        else $setPrt( os, false );                                                      // turn off
    109109        if ( &os == &exit ) exit( EXIT_FAILURE );
    110110        if ( &os == &abort ) abort();
     
    112112
    113113int fail( ofstream & os ) {
    114         return os.file == 0 || ferror( (FILE *)(os.file) );
     114        return os.$file == 0 || ferror( (FILE *)(os.$file) );
    115115} // fail
    116116
    117117int flush( ofstream & os ) {
    118         return fflush( (FILE *)(os.file) );
     118        return fflush( (FILE *)(os.$file) );
    119119} // flush
    120120
    121 void open( ofstream & os, const char * name, const char * mode ) {
     121void open( ofstream & os, const char name[], const char mode[] ) {
    122122        FILE * file = fopen( name, mode );
    123123        #ifdef __CFA_DEBUG__
    124         if ( file == 0 ) {
     124        if ( file == 0p ) {
    125125                abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    126126        } // if
     
    129129} // open
    130130
    131 void open( ofstream & os, const char * name ) {
     131void open( ofstream & os, const char name[] ) {
    132132        open( os, name, "w" );
    133133} // open
    134134
    135135void close( ofstream & os ) {
    136         if ( (FILE *)(os.file) == stdout || (FILE *)(os.file) == stderr ) return;
    137 
    138         if ( fclose( (FILE *)(os.file) ) == EOF ) {
     136        if ( (FILE *)(os.$file) == stdout || (FILE *)(os.$file) == stderr ) return;
     137
     138        if ( fclose( (FILE *)(os.$file) ) == EOF ) {
    139139                abort | IO_MSG "close output" | nl | strerror( errno );
    140140        } // if
    141141} // close
    142142
    143 ofstream & write( ofstream & os, const char * data, size_t size ) {
     143ofstream & write( ofstream & os, const char data[], size_t size ) {
    144144        if ( fail( os ) ) {
    145145                abort | IO_MSG "attempt write I/O on failed stream";
    146146        } // if
    147147
    148         if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) {
     148        if ( fwrite( data, 1, size, (FILE *)(os.$file) ) != size ) {
    149149                abort | IO_MSG "write" | nl | strerror( errno );
    150150        } // if
     
    155155        va_list args;
    156156        va_start( args, format );
    157         int len = vfprintf( (FILE *)(os.file), format, args );
     157        int len = vfprintf( (FILE *)(os.$file), format, args );
    158158        if ( len == EOF ) {
    159                 if ( ferror( (FILE *)(os.file) ) ) {
     159                if ( ferror( (FILE *)(os.$file) ) ) {
    160160                        abort | IO_MSG "invalid write";
    161161                } // if
     
    163163        va_end( args );
    164164
    165         setPrt( os, true );                                                                     // called in output cascade
    166         sepReset( os );                                                                         // reset separator
     165        $setPrt( os, true );                                                            // called in output cascade
     166        $sepReset( os );                                                                        // reset separator
    167167        return len;
    168168} // fmt
     
    184184// private
    185185void ?{}( ifstream & is, void * file ) {
    186         is.file = file;
    187         is.nlOnOff = false;
     186        is.$file = file;
     187        is.$nlOnOff = false;
    188188} // ?{}
    189189
    190190// public
    191 void ?{}( ifstream & is ) {     is.file = 0; }
    192 
    193 void ?{}( ifstream & is, const char * name, const char * mode ) {
     191void ?{}( ifstream & is ) { is.$file = 0p; }
     192
     193void ?{}( ifstream & is, const char name[], const char mode[] ) {
    194194        open( is, name, mode );
    195195} // ?{}
    196196
    197 void ?{}( ifstream & is, const char * name ) {
     197void ?{}( ifstream & is, const char name[] ) {
    198198        open( is, name, "r" );
    199199} // ?{}
     
    203203} // ^?{}
    204204
    205 void nlOn( ifstream & os ) { os.nlOnOff = true; }
    206 void nlOff( ifstream & os ) { os.nlOnOff = false; }
    207 bool getANL( ifstream & os ) { return os.nlOnOff; }
     205void nlOn( ifstream & os ) { os.$nlOnOff = true; }
     206void nlOff( ifstream & os ) { os.$nlOnOff = false; }
     207bool getANL( ifstream & os ) { return os.$nlOnOff; }
    208208
    209209int fail( ifstream & is ) {
    210         return is.file == 0 || ferror( (FILE *)(is.file) );
     210        return is.$file == 0p || ferror( (FILE *)(is.$file) );
    211211} // fail
    212212
    213213int eof( ifstream & is ) {
    214         return feof( (FILE *)(is.file) );
     214        return feof( (FILE *)(is.$file) );
    215215} // eof
    216216
    217 void open( ifstream & is, const char * name, const char * mode ) {
     217void open( ifstream & is, const char name[], const char mode[] ) {
    218218        FILE * file = fopen( name, mode );
    219219        #ifdef __CFA_DEBUG__
    220         if ( file == 0 ) {
     220        if ( file == 0p ) {
    221221                abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    222222        } // if
    223223        #endif // __CFA_DEBUG__
    224         is.file = file;
    225 } // open
    226 
    227 void open( ifstream & is, const char * name ) {
     224        is.$file = file;
     225} // open
     226
     227void open( ifstream & is, const char name[] ) {
    228228        open( is, name, "r" );
    229229} // open
    230230
    231231void close( ifstream & is ) {
    232         if ( (FILE *)(is.file) == stdin ) return;
    233 
    234         if ( fclose( (FILE *)(is.file) ) == EOF ) {
     232        if ( (FILE *)(is.$file) == stdin ) return;
     233
     234        if ( fclose( (FILE *)(is.$file) ) == EOF ) {
    235235                abort | IO_MSG "close input" | nl | strerror( errno );
    236236        } // if
     
    242242        } // if
    243243
    244         if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) {
     244        if ( fread( data, size, 1, (FILE *)(is.$file) ) == 0 ) {
    245245                abort | IO_MSG "read" | nl | strerror( errno );
    246246        } // if
     
    253253        } // if
    254254
    255         if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
     255        if ( ungetc( c, (FILE *)(is.$file) ) == EOF ) {
    256256                abort | IO_MSG "ungetc" | nl | strerror( errno );
    257257        } // if
     
    263263
    264264        va_start( args, format );
    265         int len = vfscanf( (FILE *)(is.file), format, args );
     265        int len = vfscanf( (FILE *)(is.$file), format, args );
    266266        if ( len == EOF ) {
    267                 if ( ferror( (FILE *)(is.file) ) ) {
     267                if ( ferror( (FILE *)(is.$file) ) ) {
    268268                        abort | IO_MSG "invalid read";
    269269                } // if
  • libcfa/src/fstream.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 29 06:56:02 2019
    13 // Update Count     : 168
     12// Last Modified On : Mon Feb 17 08:29:23 2020
     13// Update Count     : 175
    1414//
    1515
     
    2424enum { sepSize = 16 };
    2525struct ofstream {
    26         void * file;
    27         bool sepDefault;
    28         bool sepOnOff;
    29         bool nlOnOff;
    30         bool prt;                                                                                       // print text
    31         bool sawNL;
    32         const char * sepCur;
    33         char separator[sepSize];
    34         char tupleSeparator[sepSize];
     26        void * $file;
     27        bool $sepDefault;
     28        bool $sepOnOff;
     29        bool $nlOnOff;
     30        bool $prt;                                                                                      // print text
     31        bool $sawNL;
     32        const char * $sepCur;
     33        char $separator[sepSize];
     34        char $tupleSeparator[sepSize];
    3535}; // ofstream
    3636
    3737// private
    38 bool sepPrt( ofstream & );
    39 void sepReset( ofstream & );
    40 void sepReset( ofstream &, bool );
    41 const char * sepGetCur( ofstream & );
    42 void sepSetCur( ofstream &, const char * );
    43 bool getNL( ofstream & );
    44 void setNL( ofstream &, bool );
    45 bool getANL( ofstream & );
    46 bool getPrt( ofstream & );
    47 void setPrt( ofstream &, bool );
     38bool $sepPrt( ofstream & );
     39void $sepReset( ofstream & );
     40void $sepReset( ofstream &, bool );
     41const char * $sepGetCur( ofstream & );
     42void $sepSetCur( ofstream &, const char [] );
     43bool $getNL( ofstream & );
     44void $setNL( ofstream &, bool );
     45bool $getANL( ofstream & );
     46bool $getPrt( ofstream & );
     47void $setPrt( ofstream &, bool );
    4848
    4949// public
     
    5656
    5757const char * sepGet( ofstream & );
    58 void sepSet( ofstream &, const char * );
     58void sepSet( ofstream &, const char [] );
    5959const char * sepGetTuple( ofstream & );
    60 void sepSetTuple( ofstream &, const char * );
     60void sepSetTuple( ofstream &, const char [] );
    6161
    6262void ends( ofstream & os );
    6363int fail( ofstream & );
    6464int flush( ofstream & );
    65 void open( ofstream &, const char * name, const char * mode );
    66 void open( ofstream &, const char * name );
     65void open( ofstream &, const char name[], const char mode[] );
     66void open( ofstream &, const char name[] );
    6767void close( ofstream & );
    68 ofstream & write( ofstream &, const char * data, size_t size );
    69 int fmt( ofstream &, const char format[], ... );
     68ofstream & write( ofstream &, const char data[], size_t size );
     69int fmt( ofstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    7070
    7171void ?{}( ofstream & os );
    72 void ?{}( ofstream & os, const char * name, const char * mode );
    73 void ?{}( ofstream & os, const char * name );
     72void ?{}( ofstream & os, const char name[], const char mode[] );
     73void ?{}( ofstream & os, const char name[] );
    7474void ^?{}( ofstream & os );
    7575
     
    8282
    8383struct ifstream {
    84         void * file;
    85         bool nlOnOff;
     84        void * $file;
     85        bool $nlOnOff;
    8686}; // ifstream
    8787
     
    9292int fail( ifstream & is );
    9393int eof( ifstream & is );
    94 void open( ifstream & is, const char * name, const char * mode );
    95 void open( ifstream & is, const char * name );
     94void open( ifstream & is, const char name[], const char mode[] );
     95void open( ifstream & is, const char name[] );
    9696void close( ifstream & is );
    9797ifstream & read( ifstream & is, char * data, size_t size );
    9898ifstream & ungetc( ifstream & is, char c );
    99 int fmt( ifstream &, const char format[], ... );
     99int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
    100100
    101101void ?{}( ifstream & is );
    102 void ?{}( ifstream & is, const char * name, const char * mode );
    103 void ?{}( ifstream & is, const char * name );
     102void ?{}( ifstream & is, const char name[], const char mode[] );
     103void ?{}( ifstream & is, const char name[] );
    104104void ^?{}( ifstream & is );
    105105
  • libcfa/src/gmp.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 15:25:05 2019
    13 // Update Count     : 27
     12// Last Modified On : Sun Feb  9 09:56:54 2020
     13// Update Count     : 31
    1414//
    1515
     
    2424
    2525static inline {
    26         // constructor
     26        // constructor, zero_t/one_t are unnecessary because of relationship with signed/unsigned int
    2727        void ?{}( Int & this ) { mpz_init( this.mpz ); }
    2828        void ?{}( Int & this, Int init ) { mpz_init_set( this.mpz, init.mpz ); }
    29         void ?{}( Int & this, zero_t ) { mpz_init_set_si( this.mpz, 0 ); }
    30         void ?{}( Int & this, one_t ) { mpz_init_set_si( this.mpz, 1 ); }
    3129        void ?{}( Int & this, signed long int init ) { mpz_init_set_si( this.mpz, init ); }
    3230        void ?{}( Int & this, unsigned long int init ) { mpz_init_set_ui( this.mpz, init ); }
    33         void ?{}( Int & this, const char * val ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
     31        void ?{}( Int & this, const char val[] ) { if ( mpz_init_set_str( this.mpz, val, 0 ) ) abort(); }
    3432        void ^?{}( Int & this ) { mpz_clear( this.mpz ); }
    3533
     
    3735        Int ?`mp( signed long int init ) { return (Int){ init }; }
    3836        Int ?`mp( unsigned long int init ) { return (Int){ init }; }
    39         Int ?`mp( const char * init ) { return (Int){ init }; }
     37        Int ?`mp( const char init[] ) { return (Int){ init }; }
    4038
    4139        // assignment
     
    4341        Int ?=?( Int & lhs, long int rhs ) { mpz_set_si( lhs.mpz, rhs ); return lhs; }
    4442        Int ?=?( Int & lhs, unsigned long int rhs ) { mpz_set_ui( lhs.mpz, rhs ); return lhs; }
    45         Int ?=?( Int & lhs, const char * rhs ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
     43        Int ?=?( Int & lhs, const char rhs[] ) { if ( mpz_set_str( lhs.mpz, rhs, 0 ) ) { abort | "invalid string conversion"; } return lhs; }
    4644
    4745        char ?=?( char & lhs, Int rhs ) { char val = mpz_get_si( rhs.mpz ); lhs = val; return lhs; }
     
    265263        forall( dtype ostype | ostream( ostype ) ) {
    266264                ostype & ?|?( ostype & os, Int mp ) {
    267                         if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     265                        if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    268266                        gmp_printf( "%Zd", mp.mpz );
    269267                        sepOn( os );
  • libcfa/src/heap.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Dec  8 21:01:31 2019
    13 // Update Count     : 647
     12// Last Modified On : Tue Feb  4 10:04:51 2020
     13// Update Count     : 648
    1414//
    1515
     
    380380
    381381
    382 static inline void checkHeader( bool check, const char * name, void * addr ) {
     382static inline void checkHeader( bool check, const char name[], void * addr ) {
    383383        if ( unlikely( check ) ) {                                                      // bad address ?
    384384                abort( "Attempt to %s storage %p with address outside the heap.\n"
     
    418418
    419419
    420 static inline bool headers( const char * name __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
     420static inline bool headers( const char name[] __attribute__(( unused )), void * addr, HeapManager.Storage.Header *& header, HeapManager.FreeHeader *& freeElem, size_t & size, size_t & alignment ) with ( heapManager ) {
    421421        header = headerAddr( addr );
    422422
  • libcfa/src/interpose.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Nov 30 07:09:42 2019
    13 // Update Count     : 119
     12// Last Modified On : Mon Feb 17 10:18:53 2020
     13// Update Count     : 166
    1414//
    1515
     
    2929#include "bits/signal.hfa"                                                              // sigHandler_?
    3030#include "startup.hfa"                                                                  // STARTUP_PRIORITY_CORE
     31#include <assert.h>
    3132
    3233//=============================================================================================
     
    4041
    4142typedef void (* generic_fptr_t)(void);
    42 generic_fptr_t interpose_symbol( const char * symbol, const char * version ) {
     43generic_fptr_t interpose_symbol( const char symbol[], const char version[] ) {
    4344        const char * error;
    4445
     
    9596        void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    9697        void __cfaabi_interpose_startup( void ) {
    97                 const char *version = NULL;
     98                const char *version = 0p;
    9899
    99100                preload_libgcc();
     
    105106#pragma GCC diagnostic pop
    106107
     108                // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because
     109                // task stacks might be very small (4K) and the signal delivery corrupts memory to the point that a clean
     110                // shutdown is impossible. Also, when a stack overflow encounters the non-accessible sentinel page (debug only)
     111                // and generates a segment fault, the signal cannot be delivered on the sentinel page. Finally, calls to abort
     112                // print a stack trace that uses substantial stack space.
     113
     114                #define MINSTKSZ SIGSTKSZ * 8
     115                static char stack[MINSTKSZ] __attribute__(( aligned (16) ));
     116                static stack_t ss;
     117
     118                ss.ss_sp = stack;
     119                ss.ss_size = MINSTKSZ;
     120                ss.ss_flags = 0;
     121                if ( sigaltstack( &ss, 0p ) == -1 ) {
     122                        abort( "__cfaabi_interpose_startup : internal error, sigaltstack error(%d) %s.", errno, strerror( errno ) );
     123                } // if
     124
    107125                // Failure handler
    108                 __cfaabi_sigaction( SIGSEGV, sigHandler_segv , SA_SIGINFO );
    109                 __cfaabi_sigaction( SIGBUS , sigHandler_segv , SA_SIGINFO );
    110                 __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    111                 __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    112                 __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND);
    113                 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    114                 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     126                __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     127                __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     128                __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK );
     129                __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK );
     130                __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default
     131                __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     132                __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     133                __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup
    115134        }
    116135}
     
    123142void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    124143void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     144void abort( bool signalAbort, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    125145
    126146extern "C" {
    127147        void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    128                 abort( NULL );
     148                abort( false, "%s", "" );
    129149        }
    130150
     
    132152                va_list argp;
    133153                va_start( argp, fmt );
    134                 abort( fmt, argp );
     154                abort( false, fmt, argp );
    135155                va_end( argp );
    136156        }
     
    141161}
    142162
    143 void * kernel_abort    ( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return NULL; }
    144 void   kernel_abort_msg( void * data, char * buffer, int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     163void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
     164void kernel_abort_msg( void * data, char buffer[], int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     165// See concurrency/kernel.cfa for strong definition used in multi-processor mode.
    145166int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    146167
    147168enum { abort_text_size = 1024 };
    148169static char abort_text[ abort_text_size ];
    149 static int abort_lastframe;
    150 
    151 void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ )) {
    152     va_list args;
    153     va_start( args, fmt );
    154     vfprintf( stderr, fmt, args );
    155     va_end( args );
    156         __cabi_libc.exit( status );
    157 }
    158 
    159 void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ )) {
    160         void * kernel_data = kernel_abort();                    // must be done here to lock down kernel
    161         int len;
    162 
    163         abort_lastframe = kernel_abort_lastframe();
    164         len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
    165         __cfaabi_dbg_write( abort_text, len );
    166 
    167         if ( fmt ) {
    168                 va_list args;
    169                 va_start( args, fmt );
    170 
    171                 len = vsnprintf( abort_text, abort_text_size, fmt, args );
    172                 va_end( args );
    173                 __cfaabi_dbg_write( abort_text, len );
    174 
    175                 if ( fmt[strlen( fmt ) - 1] != '\n' ) {         // add optional newline if missing at the end of the format text
    176                         __cfaabi_dbg_write( "\n", 1 );
    177                 }
    178         }
    179 
    180         kernel_abort_msg( kernel_data, abort_text, abort_text_size );
    181         __cabi_libc.abort();
    182 }
    183 
    184 static void __cfaabi_backtrace() {
    185         enum {
    186                 Frames = 50,                                                                    // maximum number of stack frames
    187                 Start = 8,                                                                              // skip first N stack frames
    188         };
     170
     171static void __cfaabi_backtrace( int start ) {
     172        enum { Frames = 50, };                                                          // maximum number of stack frames
     173        int last = kernel_abort_lastframe();                            // skip last N stack frames
    189174
    190175        void * array[Frames];
    191176        size_t size = backtrace( array, Frames );
    192         char ** messages = backtrace_symbols( array, size );
    193 
    194         // find executable name
    195         *index( messages[0], '(' ) = '\0';
     177        char ** messages = backtrace_symbols( array, size ); // does not demangle names
     178
     179        *index( messages[0], '(' ) = '\0';                                      // find executable name
    196180        __cfaabi_bits_print_nolock( STDERR_FILENO, "Stack back trace for: %s\n", messages[0]);
    197181
    198         for ( int i = Start; i < size - abort_lastframe && messages != 0p; i += 1 ) {
     182        for ( unsigned int i = start; i < size - last && messages != 0p; i += 1 ) {
    199183                char * name = 0p, * offset_begin = 0p, * offset_end = 0p;
    200184
    201                 for ( char * p = messages[i]; *p; ++p ) {
     185                for ( char * p = messages[i]; *p; p += 1 ) {    // find parantheses and +offset
    202186                        //__cfaabi_bits_print_nolock( "X %s\n", p);
    203                         // find parantheses and +offset
    204187                        if ( *p == '(' ) {
    205188                                name = p;
     
    212195                }
    213196
    214                 // if line contains symbol print it
    215                 int frameNo = i - Start;
     197                // if line contains symbol, print it
     198                int frameNo = i - start;
    216199                if ( name && offset_begin && offset_end && name < offset_begin ) {
    217                         // delimit strings
    218                         *name++ = '\0';
     200                        *name++ = '\0';                                                         // delimit strings
    219201                        *offset_begin++ = '\0';
    220202                        *offset_end++ = '\0';
     
    228210}
    229211
     212void exit( int status, const char fmt[], ... ) {
     213        va_list args;
     214        va_start( args, fmt );
     215        vfprintf( stderr, fmt, args );
     216        va_end( args );
     217        __cabi_libc.exit( status );
     218}
     219
     220void abort( bool signalAbort, const char fmt[], ... ) {
     221        void * kernel_data = kernel_abort();                            // must be done here to lock down kernel
     222        int len;
     223
     224        signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
     225
     226        len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
     227        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     228
     229        assert( fmt );
     230        va_list args;
     231        va_start( args, fmt );
     232
     233        len = vsnprintf( abort_text, abort_text_size, fmt, args );
     234        va_end( args );
     235        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     236
     237        if ( fmt[strlen( fmt ) - 1] != '\n' ) {                         // add optional newline if missing at the end of the format text
     238                __cfaabi_dbg_write( "\n", 1 );
     239        } // if
     240        kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     241
     242        __cfaabi_backtrace( signalAbort ? 4 : 2 );
     243
     244        __cabi_libc.abort();                                                            // print stack trace in handler
     245}
     246
     247void abort( const char fmt[], ... ) {
     248        va_list args;
     249        va_start( args, fmt );
     250        abort( false, fmt, args );
     251        va_end( args );
     252}
     253
    230254void sigHandler_segv( __CFA_SIGPARMS__ ) {
    231         abort( "Addressing invalid memory at location %p\n"
    232                         "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript.\n",
    233                         sfp->si_addr );
     255                if ( sfp->si_addr == 0p ) {
     256                        abort( true, "Null pointer (0p) dereference.\n" );
     257                } else {
     258                        abort( true, "%s at memory location %p.\n"
     259                                   "Possible cause is reading outside the address space or writing to a protected area within the address space with an invalid pointer or subscript.\n",
     260                                   (sig == SIGSEGV ? "Segment fault" : "Bus error"), sfp->si_addr );
     261                }
    234262}
    235263
    236264void sigHandler_ill( __CFA_SIGPARMS__ ) {
    237         abort( "Executing illegal instruction at location %p.\n"
     265        abort( true, "Executing illegal instruction at location %p.\n"
    238266                        "Possible cause is stack corruption.\n",
    239267                        sfp->si_addr );
     
    251279          default: msg = "unknown";
    252280        } // choose
    253         abort( "Computation error %s at location %p.\n", msg, sfp->si_addr );
    254 }
    255 
    256 void sigHandler_abrt( __CFA_SIGPARMS__ ) {
    257         __cfaabi_backtrace();
    258 
    259         // reset default signal handler
    260         __cfaabi_sigdefault( SIGABRT );
    261 
    262         raise( SIGABRT );
     281        abort( true, "Computation error %s at location %p.\n", msg, sfp->si_addr );
    263282}
    264283
    265284void sigHandler_term( __CFA_SIGPARMS__ ) {
    266         abort( "Application stopped by %s signal.", sig == SIGINT ? "an interrupt (SIGINT)" : "a terminate (SIGTERM)" );
     285        abort( true, "Application interrupted by signal: %s.\n", strsignal( sig ) );
    267286}
    268287
  • libcfa/src/iostream.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:07:59 2019
    13 // Update Count     : 821
     12// Last Modified On : Thu Feb 20 15:53:23 2020
     13// Update Count     : 829
    1414//
    1515
     
    1919#include <stdio.h>
    2020#include <stdbool.h>                                                                    // true/false
     21#include <stdint.h>                                                                             // UINT64_MAX
    2122//#include <string.h>                                                                   // strlen, strcmp
    2223extern size_t strlen (const char *__s) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__pure__)) __attribute__ ((__nonnull__ (1)));
     
    3536forall( dtype ostype | ostream( ostype ) ) {
    3637        ostype & ?|?( ostype & os, zero_t ) {
    37                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     38                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    3839                fmt( os, "%d", 0n );
    3940                return os;
     
    4445
    4546        ostype & ?|?( ostype & os, one_t ) {
    46                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     47                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    4748                fmt( os, "%d", 1n );
    4849                return os;
     
    5354
    5455        ostype & ?|?( ostype & os, bool b ) {
    55                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     56                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    5657                fmt( os, "%s", b ? "true" : "false" );
    5758                return os;
     
    6364        ostype & ?|?( ostype & os, char c ) {
    6465                fmt( os, "%c", c );
    65                 if ( c == '\n' ) setNL( os, true );
     66                if ( c == '\n' ) $setNL( os, true );
    6667                return sepOff( os );
    6768        } // ?|?
     
    7172
    7273        ostype & ?|?( ostype & os, signed char sc ) {
    73                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     74                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    7475                fmt( os, "%hhd", sc );
    7576                return os;
     
    8081
    8182        ostype & ?|?( ostype & os, unsigned char usc ) {
    82                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     83                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    8384                fmt( os, "%hhu", usc );
    8485                return os;
     
    8990
    9091        ostype & ?|?( ostype & os, short int si ) {
    91                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     92                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    9293                fmt( os, "%hd", si );
    9394                return os;
     
    9899
    99100        ostype & ?|?( ostype & os, unsigned short int usi ) {
    100                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     101                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    101102                fmt( os, "%hu", usi );
    102103                return os;
     
    107108
    108109        ostype & ?|?( ostype & os, int i ) {
    109                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     110                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    110111                fmt( os, "%d", i );
    111112                return os;
     
    116117
    117118        ostype & ?|?( ostype & os, unsigned int ui ) {
    118                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     119                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    119120                fmt( os, "%u", ui );
    120121                return os;
     
    125126
    126127        ostype & ?|?( ostype & os, long int li ) {
    127                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     128                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    128129                fmt( os, "%ld", li );
    129130                return os;
     
    134135
    135136        ostype & ?|?( ostype & os, unsigned long int uli ) {
    136                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     137                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    137138                fmt( os, "%lu", uli );
    138139                return os;
     
    143144
    144145        ostype & ?|?( ostype & os, long long int lli ) {
    145                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     146                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    146147                fmt( os, "%lld", lli );
    147148                return os;
     
    152153
    153154        ostype & ?|?( ostype & os, unsigned long long int ulli ) {
    154                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     155                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    155156                fmt( os, "%llu", ulli );
    156157                return os;
     
    159160                (ostype &)(os | ulli); ends( os );
    160161        } // ?|?
     162
     163#if defined( __SIZEOF_INT128__ )
     164        //      UINT64_MAX 18_446_744_073_709_551_615_ULL
     165        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
     166
     167        static void base10_128( ostype & os, unsigned int128 val ) {
     168                if ( val > UINT64_MAX ) {
     169                        base10_128( os, val / P10_UINT64 );                     // recursive
     170                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     171                } else {
     172                        fmt( os, "%lu", (uint64_t)val );
     173                } // if
     174        } // base10_128
     175
     176        static void base10_128( ostype & os, int128 val ) {
     177                if ( val < 0 ) {
     178                        fmt( os, "-" );                                                         // leading negative sign
     179                        val = -val;
     180                } // if
     181                base10_128( os, (unsigned int128)val );                 // print zero/positive value
     182        } // base10_128
     183
     184        ostype & ?|?( ostype & os, int128 llli ) {
     185                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     186                base10_128( os, llli );
     187                return os;
     188        } // ?|?
     189        void & ?|?( ostype & os, int128 llli ) {
     190                (ostype &)(os | llli); ends( os );
     191        } // ?|?
     192
     193        ostype & ?|?( ostype & os, unsigned int128 ullli ) {
     194                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
     195                base10_128( os, ullli );
     196                return os;
     197        } // ?|?
     198        void & ?|?( ostype & os, unsigned int128 ullli ) {
     199                (ostype &)(os | ullli); ends( os );
     200        } // ?|?
     201#endif // __SIZEOF_INT128__
    161202
    162203        #define PrintWithDP( os, format, val, ... ) \
     
    175216
    176217        ostype & ?|?( ostype & os, float f ) {
    177                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     218                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    178219                PrintWithDP( os, "%g", f );
    179220                return os;
     
    184225
    185226        ostype & ?|?( ostype & os, double d ) {
    186                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     227                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    187228                PrintWithDP( os, "%.*lg", d, DBL_DIG );
    188229                return os;
     
    193234
    194235        ostype & ?|?( ostype & os, long double ld ) {
    195                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     236                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    196237                PrintWithDP( os, "%.*Lg", ld, LDBL_DIG );
    197238                return os;
     
    202243
    203244        ostype & ?|?( ostype & os, float _Complex fc ) {
    204                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     245                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    205246//              os | crealf( fc ) | nonl;
    206247                PrintWithDP( os, "%g", crealf( fc ) );
     
    214255
    215256        ostype & ?|?( ostype & os, double _Complex dc ) {
    216                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     257                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    217258//              os | creal( dc ) | nonl;
    218259                PrintWithDP( os, "%.*lg", creal( dc ), DBL_DIG );
     
    226267
    227268        ostype & ?|?( ostype & os, long double _Complex ldc ) {
    228                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     269                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    229270//              os | creall( ldc ) || nonl;
    230271                PrintWithDP( os, "%.*Lg", creall( ldc ), LDBL_DIG );
     
    237278        } // ?|?
    238279
    239         ostype & ?|?( ostype & os, const char * str ) {
     280        ostype & ?|?( ostype & os, const char str[] ) {
    240281                enum { Open = 1, Close, OpenClose };
    241282                static const unsigned char mask[256] @= {
     
    257298                // first character IS NOT spacing or closing punctuation => add left separator
    258299                unsigned char ch = str[0];                                              // must make unsigned
    259                 if ( sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
    260                         fmt( os, "%s", sepGetCur( os ) );
     300                if ( $sepPrt( os ) && mask[ ch ] != Close && mask[ ch ] != OpenClose ) {
     301                        fmt( os, "%s", $sepGetCur( os ) );
    261302                } // if
    262303
    263304                // if string starts line, must reset to determine open state because separator is off
    264                 sepReset( os );                                                                 // reset separator
     305                $sepReset( os );                                                                // reset separator
    265306
    266307                // last character IS spacing or opening punctuation => turn off separator for next item
    267308                size_t len = strlen( str );
    268309                ch = str[len - 1];                                                              // must make unsigned
    269                 if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     310                if ( $sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
    270311                        sepOn( os );
    271312                } else {
    272313                        sepOff( os );
    273314                } // if
    274                 if ( ch == '\n' ) setNL( os, true );                    // check *AFTER* sepPrt call above as it resets NL flag
     315                if ( ch == '\n' ) $setNL( os, true );                   // check *AFTER* $sepPrt call above as it resets NL flag
    275316                return write( os, str, len );
    276317        } // ?|?
    277         void ?|?( ostype & os, const char * str ) {
     318
     319        void ?|?( ostype & os, const char str[] ) {
    278320                (ostype &)(os | str); ends( os );
    279321        } // ?|?
    280322
    281323//      ostype & ?|?( ostype & os, const char16_t * str ) {
    282 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     324//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    283325//              fmt( os, "%ls", str );
    284326//              return os;
     
    287329// #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    288330//      ostype & ?|?( ostype & os, const char32_t * str ) {
    289 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     331//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    290332//              fmt( os, "%ls", str );
    291333//              return os;
     
    294336
    295337//      ostype & ?|?( ostype & os, const wchar_t * str ) {
    296 //              if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     338//              if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    297339//              fmt( os, "%ls", str );
    298340//              return os;
     
    300342
    301343        ostype & ?|?( ostype & os, const void * p ) {
    302                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     344                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    303345                fmt( os, "%p", p );
    304346                return os;
     
    315357        void ?|?( ostype & os, ostype & (* manip)( ostype & ) ) {
    316358                (ostype &)(manip( os ));
    317                 if ( getPrt( os ) ) ends( os );                                 // something printed ?
    318                 setPrt( os, false );                                                    // turn off
     359                if ( $getPrt( os ) ) ends( os );                                // something printed ?
     360                $setPrt( os, false );                                                   // turn off
    319361        } // ?|?
    320362
     
    329371        ostype & nl( ostype & os ) {
    330372                (ostype &)(os | '\n');
    331                 setPrt( os, false );                                                    // turn off
    332                 setNL( os, true );
     373                $setPrt( os, false );                                                   // turn off
     374                $setNL( os, true );
    333375                flush( os );
    334376                return sepOff( os );                                                    // prepare for next line
     
    336378
    337379        ostype & nonl( ostype & os ) {
    338                 setPrt( os, false );                                                    // turn off
     380                $setPrt( os, false );                                                   // turn off
    339381                return os;
    340382        } // nonl
     
    375417        ostype & ?|?( ostype & os, T arg, Params rest ) {
    376418                (ostype &)(os | arg);                                                   // print first argument
    377                 sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
     419                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    378420                (ostype &)(os | rest);                                                  // print remaining arguments
    379                 sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
     421                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    380422                return os;
    381423        } // ?|?
     
    383425                // (ostype &)(?|?( os, arg, rest )); ends( os );
    384426                (ostype &)(os | arg);                                                   // print first argument
    385                 sepSetCur( os, sepGetTuple( os ) );                             // switch to tuple separator
     427                $sepSetCur( os, sepGetTuple( os ) );                    // switch to tuple separator
    386428                (ostype &)(os | rest);                                                  // print remaining arguments
    387                 sepSetCur( os, sepGet( os ) );                                  // switch to regular separator
     429                $sepSetCur( os, sepGet( os ) );                                 // switch to regular separator
    388430                ends( os );
    389431        } // ?|?
     
    414456forall( dtype ostype | ostream( ostype ) ) { \
    415457        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    416                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     458                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    417459\
    418460                if ( f.base == 'b' || f.base == 'B' ) {                 /* bespoke binary format */ \
     
    463505\
    464506                if ( ! f.flags.pc ) {                                                   /* no precision */ \
    465                         /* printf( "%s\n", &fmtstr[star] ); */ \
    466507                        fmtstr[sizeof(IFMTNP)-2] = f.base;                      /* sizeof includes '\0' */ \
     508                        /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
    467509                        fmt( os, &fmtstr[star], f.wd, f.val ); \
    468510                } else {                                                                                /* precision */ \
    469511                        fmtstr[sizeof(IFMTP)-2] = f.base;                       /* sizeof includes '\0' */ \
    470                         /* printf( "%s\n", &fmtstr[star] ); */ \
     512                        /* printf( "%s %c %c\n", &fmtstr[star], f.base, CODE ); */ \
    471513                        fmt( os, &fmtstr[star], f.wd, f.pc, f.val ); \
    472514                } /* if */ \
     
    486528IntegralFMTImpl( signed long long int, 'd', "%    *ll ", "%    *.*ll " )
    487529IntegralFMTImpl( unsigned long long int, 'u', "%    *ll ", "%    *.*ll " )
     530
     531
     532#if defined( __SIZEOF_INT128__ )
     533// Default prefix for non-decimal prints is 0b, 0, 0x.
     534#define IntegralFMTImpl128( T, SIGNED, CODE, IFMTNP, IFMTP ) \
     535forall( dtype ostype | ostream( ostype ) ) \
     536static void base10_128( ostype & os, _Ostream_Manip(T) fmt ) { \
     537        if ( fmt.val > UINT64_MAX ) { \
     538                fmt.val /= P10_UINT64; \
     539                base10_128( os, fmt ); /* recursive */ \
     540                _Ostream_Manip(unsigned long long int) fmt2 @= { (uint64_t)(fmt.val % P10_UINT64), 0, 19, 'u', { .all : 0 } }; \
     541                fmt2.flags.nobsdp = true; \
     542                printf( "fmt2 %c %lld %d\n", fmt2.base, fmt2.val, fmt2.all );   \
     543                sepOff( os ); \
     544                (ostype &)(os | fmt2); \
     545        } else { \
     546                printf( "fmt %c %lld %d\n", fmt.base, fmt.val, fmt.all ); \
     547                (ostype &)(os | fmt); \
     548        } /* if */ \
     549} /* base10_128 */                                                 \
     550forall( dtype ostype | ostream( ostype ) ) { \
     551        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
     552                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
     553\
     554                if ( f.base == 'b' | f.base == 'o' | f.base == 'x' | f.base == 'X' ) { \
     555                        unsigned long long int msig = (unsigned long long int)(f.val >> 64); \
     556                        unsigned long long int lsig = (unsigned long long int)(f.val); \
     557                        _Ostream_Manip(SIGNED long long int) fmt @= { msig, f.wd, f.pc, f.base, { .all : f.all } }; \
     558                        _Ostream_Manip(unsigned long long int) fmt2 @= { lsig, 0, 0, f.base, { .all : 0 } }; \
     559                        if ( msig == 0 ) { \
     560                                fmt.val = lsig; \
     561                                (ostype &)(os | fmt); \
     562                        } else { \
     563                                fmt2.flags.pad0 = fmt2.flags.nobsdp = true;     \
     564                                if ( f.base == 'b' ) { \
     565                                        if ( f.wd > 64 ) fmt.wd = f.wd - 64; \
     566                                        fmt2.wd = 64; \
     567                                        (ostype &)(os | fmt | "" | fmt2); \
     568                                } else if ( f.base == 'o' ) { \
     569                                        fmt.val = (unsigned long long int)fmt.val >> 2; \
     570                                        if ( f.wd > 21 ) fmt.wd = f.wd - 21; \
     571                                        fmt2.wd = 1; \
     572                                        fmt2.val = ((msig & 0x3) << 1) + 1; \
     573                                        (ostype &)(os | fmt | "" | fmt2); \
     574                                        sepOff( os ); \
     575                                        fmt2.wd = 21; \
     576                                        fmt2.val = lsig & 0x7fffffffffffffff; \
     577                                        (ostype &)(os | fmt2); \
     578                                } else { \
     579                                        if ( f.flags.left ) { \
     580                                                if ( f.wd > 16 ) fmt2.wd = f.wd - 16;   \
     581                                                fmt.wd = 16;                                                    \
     582                                        } else { \
     583                                                if ( f.wd > 16 ) fmt.wd = f.wd - 16;    \
     584                                                fmt2.wd = 16;                                                   \
     585                                        } /* if */ \
     586                                        (ostype &)(os | fmt | "" | fmt2); \
     587                                } /* if */ \
     588                        } /* if */ \
     589                } else { \
     590                        base10_128( os, f ); \
     591                } /* if */ \
     592                return os; \
     593        } /* ?|? */ \
     594        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
     595} // distribution
     596
     597IntegralFMTImpl128( int128, signed, 'd', "%    *ll ", "%    *.*ll " )
     598IntegralFMTImpl128( unsigned int128, unsigned, 'u', "%    *ll ", "%    *.*ll " )
     599#endif // __SIZEOF_INT128__
    488600
    489601//*********************************** floating point ***********************************
     
    513625forall( dtype ostype | ostream( ostype ) ) { \
    514626        ostype & ?|?( ostype & os, _Ostream_Manip(T) f ) { \
    515                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) ); \
     627                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) ); \
    516628                char fmtstr[sizeof(DFMTP)];                                             /* sizeof includes '\0' */ \
    517629                if ( ! f.flags.pc ) memcpy( &fmtstr, DFMTNP, sizeof(DFMTNP) ); \
     
    536648                return os; \
    537649        } /* ?|? */ \
     650\
    538651        void ?|?( ostype & os, _Ostream_Manip(T) f ) { (ostype &)(os | f); ends( os ); } \
    539652} // distribution
     
    555668                } // if
    556669
    557                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     670                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    558671
    559672                #define CFMTNP "% * "
     
    571684                return os;
    572685        } // ?|?
     686
    573687        void ?|?( ostype & os, _Ostream_Manip(char) f ) { (ostype &)(os | f); ends( os ); }
    574688} // distribution
     
    592706                } // if
    593707
    594                 if ( sepPrt( os ) ) fmt( os, "%s", sepGetCur( os ) );
     708                if ( $sepPrt( os ) ) fmt( os, "%s", $sepGetCur( os ) );
    595709
    596710                #define SFMTNP "% * "
     
    616730                return os;
    617731        } // ?|?
     732
    618733        void ?|?( ostype & os, _Ostream_Manip(const char *) f ) { (ostype &)(os | f); ends( os ); }
    619734} // distribution
     
    735850        } // ?|?
    736851
    737         // istype & ?|?( istype & is, const char * fmt ) {
     852        // istype & ?|?( istype & is, const char fmt[] ) {
    738853        //      fmt( is, fmt, "" );
    739854        //      return is;
  • libcfa/src/iostream.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 12:08:38 2019
    13 // Update Count     : 334
     12// Last Modified On : Thu Feb 20 15:30:56 2020
     13// Update Count     : 337
    1414//
    1515
     
    2424trait ostream( dtype ostype ) {
    2525        // private
    26         bool sepPrt( ostype & );                                                        // get separator state (on/off)
    27         void sepReset( ostype & );                                                      // set separator state to default state
    28         void sepReset( ostype &, bool );                                        // set separator and default state
    29         const char * sepGetCur( ostype & );                                     // get current separator string
    30         void sepSetCur( ostype &, const char * );                       // set current separator string
    31         bool getNL( ostype & );                                                         // check newline
    32         void setNL( ostype &, bool );                                           // saw newline
    33         bool getANL( ostype & );                                                        // get auto newline (on/off)
    34         bool getPrt( ostype & );                                                        // get fmt called in output cascade
    35         void setPrt( ostype &, bool );                                          // set fmt called in output cascade
     26        bool $sepPrt( ostype & );                                                       // get separator state (on/off)
     27        void $sepReset( ostype & );                                                     // set separator state to default state
     28        void $sepReset( ostype &, bool );                                       // set separator and default state
     29        const char * $sepGetCur( ostype & );                            // get current separator string
     30        void $sepSetCur( ostype &, const char [] );                     // set current separator string
     31        bool $getNL( ostype & );                                                        // check newline
     32        void $setNL( ostype &, bool );                                          // saw newline
     33        bool $getANL( ostype & );                                                       // get auto newline (on/off)
     34        bool $getPrt( ostype & );                                                       // get fmt called in output cascade
     35        void $setPrt( ostype &, bool );                                         // set fmt called in output cascade
    3636        // public
    3737        void sepOn( ostype & );                                                         // turn separator state on
     
    4343
    4444        const char * sepGet( ostype & );                                        // get separator string
    45         void sepSet( ostype &, const char * );                          // set separator to string (15 character maximum)
     45        void sepSet( ostype &, const char [] );                         // set separator to string (15 character maximum)
    4646        const char * sepGetTuple( ostype & );                           // get tuple separator string
    47         void sepSetTuple( ostype &, const char * );                     // set tuple separator to string (15 character maximum)
     47        void sepSetTuple( ostype &, const char [] );            // set tuple separator to string (15 character maximum)
    4848
    4949        void ends( ostype & os );                                                       // end of output statement
    5050        int fail( ostype & );
    5151        int flush( ostype & );
    52         void open( ostype & os, const char * name, const char * mode );
     52        void open( ostype & os, const char name[], const char mode[] );
    5353        void close( ostype & os );
    54         ostype & write( ostype &, const char *, size_t );
     54        ostype & write( ostype &, const char [], size_t );
    5555        int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    5656}; // ostream
     
    9898        ostype & ?|?( ostype &, unsigned long long int );
    9999        void ?|?( ostype &, unsigned long long int );
     100#if defined( __SIZEOF_INT128__ )
     101        ostype & ?|?( ostype &, int128 );
     102        void ?|?( ostype &, int128 );
     103        ostype & ?|?( ostype &, unsigned int128 );
     104        void ?|?( ostype &, unsigned int128 );
     105#endif // __SIZEOF_INT128__
    100106
    101107        ostype & ?|?( ostype &, float );
     
    113119        void ?|?( ostype &, long double _Complex );
    114120
    115         ostype & ?|?( ostype &, const char * );
    116         void ?|?( ostype &, const char * );
     121        ostype & ?|?( ostype &, const char [] );
     122        void ?|?( ostype &, const char [] );
    117123        // ostype & ?|?( ostype &, const char16_t * );
    118124#if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
     
    206212IntegralFMTDecl( signed long long int, 'd' )
    207213IntegralFMTDecl( unsigned long long int, 'u' )
     214#if defined( __SIZEOF_INT128__ )
     215IntegralFMTDecl( int128, 'd' )
     216IntegralFMTDecl( unsigned int128, 'u' )
     217#endif
    208218
    209219//*********************************** floating point ***********************************
     
    256266
    257267static inline {
    258         _Ostream_Manip(const char *) bin( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
    259         _Ostream_Manip(const char *) oct( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
    260         _Ostream_Manip(const char *) hex( const char * s ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
    261         _Ostream_Manip(const char *) wd( unsigned int w, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
    262         _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char * s ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
     268        _Ostream_Manip(const char *) bin( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'b', { .all : 0 } }; }
     269        _Ostream_Manip(const char *) oct( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'o', { .all : 0 } }; }
     270        _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
     271        _Ostream_Manip(const char *) wd( unsigned int w, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
     272        _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
    263273        _Ostream_Manip(const char *) & wd( unsigned int w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }
    264274        _Ostream_Manip(const char *) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
     
    281291        int fail( istype & );
    282292        int eof( istype & );
    283         void open( istype & is, const char * name );
     293        void open( istype & is, const char name[] );
    284294        void close( istype & is );
    285295        istype & read( istype &, char *, size_t );
     
    316326        istype & ?|?( istype &, long double _Complex & );
    317327
    318 //      istype & ?|?( istype &, const char * );
     328//      istype & ?|?( istype &, const char [] );
    319329        istype & ?|?( istype &, char * );
    320330
     
    343353static inline {
    344354        _Istream_Cstr skip( unsigned int n ) { return (_Istream_Cstr){ 0p, 0p, n, { .all : 0 } }; }
    345         _Istream_Cstr skip( const char * scanset ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
    346         _Istream_Cstr incl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
    347         _Istream_Cstr & incl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
    348         _Istream_Cstr excl( const char * scanset, char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
    349         _Istream_Cstr & excl( const char * scanset, _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
    350         _Istream_Cstr ignore( const char * s ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
     355        _Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
     356        _Istream_Cstr incl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
     357        _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
     358        _Istream_Cstr excl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : true } }; }
     359        _Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
     360        _Istream_Cstr ignore( const char s[] ) { return (_Istream_Cstr)@{ s, 0p, -1, { .flags.ignore : true } }; }
    351361        _Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
    352         _Istream_Cstr wdi( unsigned int w, char * s ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
     362        _Istream_Cstr wdi( unsigned int w, char s[] ) { return (_Istream_Cstr)@{ s, 0p, w, { .all : 0 } }; }
    353363        _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; }
    354364} // distribution
  • libcfa/src/math.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 13 11:02:15 2018
    13 // Update Count     : 116
     12// Last Modified On : Tue Feb  4 10:27:11 2020
     13// Update Count     : 117
    1414//
    1515
     
    5151static inline long double fdim( long double x, long double y ) { return fdiml( x, y ); }
    5252
    53 static inline float nan( const char * tag ) { return nanf( tag ); }
    54 // extern "C" { double nan( const char * ); }
    55 static inline long double nan( const char * tag ) { return nanl( tag ); }
     53static inline float nan( const char tag[] ) { return nanf( tag ); }
     54// extern "C" { double nan( const char [] ); }
     55static inline long double nan( const char tag[] ) { return nanl( tag ); }
    5656
    5757//---------------------- Exponential ----------------------
  • libcfa/src/rational.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 12 18:12:08 2019
    13 // Update Count     : 184
     12// Last Modified On : Sat Feb  8 17:56:36 2020
     13// Update Count     : 187
    1414//
    1515
     
    5656        } // rational
    5757
     58        void ?{}( Rational(RationalImpl) & r, zero_t ) {
     59                r{ (RationalImpl){0}, (RationalImpl){1} };
     60        } // rational
     61
     62        void ?{}( Rational(RationalImpl) & r, one_t ) {
     63                r{ (RationalImpl){1}, (RationalImpl){1} };
     64        } // rational
    5865
    5966        // getter for numerator/denominator
  • libcfa/src/startup.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jul 24 16:21:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Nov 30 07:07:56 2019
    13 // Update Count     : 13
     12// Last Modified On : Tue Feb  4 13:03:18 2020
     13// Update Count     : 30
    1414//
    1515
     16#include <time.h>                                                                               // tzset
    1617#include "startup.hfa"
    17 #include <time.h>                                                                               // tzset
    1818
    1919extern "C" {
    20     static void __cfaabi_appready_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_APPREADY ) ));
     20    void __cfaabi_appready_startup( void ) __attribute__(( constructor( STARTUP_PRIORITY_APPREADY ) ));
    2121    void __cfaabi_appready_startup( void ) {
    2222                tzset();                                                                                // initialize time global variables
     
    2727    } // __cfaabi_appready_startup
    2828
    29     static void __cfaabi_appready_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_APPREADY ) ));
     29    void __cfaabi_appready_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_APPREADY ) ));
    3030    void __cfaabi_appready_shutdown( void ) {
    3131                #ifdef __CFA_DEBUG__
     
    4141struct __spinlock_t;
    4242extern "C" {
    43         void __cfaabi_dbg_record(struct __spinlock_t & this, const char * prev_name) __attribute__(( weak )) {}
     43        void __cfaabi_dbg_record(struct __spinlock_t & this, const char prev_name[]) __attribute__(( weak )) {}
    4444}
    4545
  • libcfa/src/stdhdr/assert.h

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 31 23:09:32 2017
    13 // Update Count     : 13
     12// Last Modified On : Tue Feb  4 12:58:49 2020
     13// Update Count     : 15
    1414//
    1515
     
    2727        #define assertf( expr, fmt, ... ) ((expr) ? ((void)0) : __assert_fail_f(__VSTRINGIFY__(expr), __FILE__, __LINE__, __PRETTY_FUNCTION__, fmt, ## __VA_ARGS__ ))
    2828
    29         void __assert_fail_f( const char *assertion, const char *file, unsigned int line, const char *function, const char *fmt, ... ) __attribute__((noreturn, format( printf, 5, 6) ));
     29        void __assert_fail_f( const char assertion[], const char file[], unsigned int line, const char function[], const char fmt[], ... ) __attribute__((noreturn, format( printf, 5, 6) ));
    3030#endif
    3131
  • libcfa/src/stdhdr/bfdlink.h

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jul 18 07:26:04 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:49:30 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:08 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "with".
    1717#if ! defined( with )                                                                   // nesting ?
    18 #define with `with`                                                                             // make keyword an identifier
     18#define with ``with                                                                             // make keyword an identifier
    1919#define __CFA_BFDLINK_H__
    2020#endif
  • libcfa/src/stdhdr/hwloc.h

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jul 18 07:45:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:49:58 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:18 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "thread".
    1717#if ! defined( thread )                                                                 // nesting ?
    18 #define thread `thread`                                                                 // make keyword an identifier
     18#define thread ``thread                                                                 // make keyword an identifier
    1919#define __CFA_HWLOC_H__
    2020#endif
  • libcfa/src/stdhdr/krb5.h

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Jul 18 07:55:44 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 22 13:50:24 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:35 2020
     13// Update Count     : 6
    1414//
    1515
    1616// include file uses the CFA keyword "enable".
    1717#if ! defined( enable )                                                                 // nesting ?
    18 #define enable `enable`                                                                 // make keyword an identifier
     18#define enable ``enable                                                                 // make keyword an identifier
    1919#define __CFA_KRB5_H__
    2020#endif
  • libcfa/src/stdhdr/math.h

    rdca5802 rb7d6a36  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 22 18:16:07 2018
    13 // Update Count     : 13
     12// Last Modified On : Fri Feb  7 19:05:27 2020
     13// Update Count     : 15
    1414//
    1515
    1616extern "C" {
    1717#if ! defined( exception )                                                              // nesting ?
    18 #define exception `exception`                                                   // make keyword an identifier
     18#define exception ``exception                                                   // make keyword an identifier
    1919#define __CFA_MATH_H__
    2020#endif
  • libcfa/src/stdhdr/sys/ucontext.h

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Feb  8 23:48:16 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 23:50:44 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Feb  7 19:05:41 2020
     13// Update Count     : 6
    1414//
    1515
    1616#if ! defined( ftype )                                                                  // nesting ?
    17 #define ftype `ftype`                                                                   // make keyword an identifier
     17#define ftype ``ftype                                                                   // make keyword an identifier
    1818#define __CFA_UCONTEXT_H__
    1919#endif
  • libcfa/src/stdlib.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Nov 20 17:22:47 2019
    13 // Update Count     : 485
     12// Last Modified On : Tue Feb  4 08:27:08 2020
     13// Update Count     : 486
    1414//
    1515
     
    107107//---------------------------------------
    108108
    109 float _Complex strto( const char * sptr, char ** eptr ) {
     109float _Complex strto( const char sptr[], char ** eptr ) {
    110110        float re, im;
    111111        char * eeptr;
     
    118118} // strto
    119119
    120 double _Complex strto( const char * sptr, char ** eptr ) {
     120double _Complex strto( const char sptr[], char ** eptr ) {
    121121        double re, im;
    122122        char * eeptr;
     
    129129} // strto
    130130
    131 long double _Complex strto( const char * sptr, char ** eptr ) {
     131long double _Complex strto( const char sptr[], char ** eptr ) {
    132132        long double re, im;
    133133        char * eeptr;
  • libcfa/src/stdlib.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 29 23:08:02 2019
    13 // Update Count     : 400
     12// Last Modified On : Tue Feb  4 08:27:01 2020
     13// Update Count     : 401
    1414//
    1515
     
    193193
    194194static inline {
    195         int strto( const char * sptr, char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
    196         unsigned int strto( const char * sptr, char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
    197         long int strto( const char * sptr, char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
    198         unsigned long int strto( const char * sptr, char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
    199         long long int strto( const char * sptr, char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
    200         unsigned long long int strto( const char * sptr, char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
    201 
    202         float strto( const char * sptr, char ** eptr ) { return strtof( sptr, eptr ); }
    203         double strto( const char * sptr, char ** eptr ) { return strtod( sptr, eptr ); }
    204         long double strto( const char * sptr, char ** eptr ) { return strtold( sptr, eptr ); }
    205 } // distribution
    206 
    207 float _Complex strto( const char * sptr, char ** eptr );
    208 double _Complex strto( const char * sptr, char ** eptr );
    209 long double _Complex strto( const char * sptr, char ** eptr );
     195        int strto( const char sptr[], char ** eptr, int base ) { return (int)strtol( sptr, eptr, base ); }
     196        unsigned int strto( const char sptr[], char ** eptr, int base ) { return (unsigned int)strtoul( sptr, eptr, base ); }
     197        long int strto( const char sptr[], char ** eptr, int base ) { return strtol( sptr, eptr, base ); }
     198        unsigned long int strto( const char sptr[], char ** eptr, int base ) { return strtoul( sptr, eptr, base ); }
     199        long long int strto( const char sptr[], char ** eptr, int base ) { return strtoll( sptr, eptr, base ); }
     200        unsigned long long int strto( const char sptr[], char ** eptr, int base ) { return strtoull( sptr, eptr, base ); }
     201
     202        float strto( const char sptr[], char ** eptr ) { return strtof( sptr, eptr ); }
     203        double strto( const char sptr[], char ** eptr ) { return strtod( sptr, eptr ); }
     204        long double strto( const char sptr[], char ** eptr ) { return strtold( sptr, eptr ); }
     205} // distribution
     206
     207float _Complex strto( const char sptr[], char ** eptr );
     208double _Complex strto( const char sptr[], char ** eptr );
     209long double _Complex strto( const char sptr[], char ** eptr );
    210210
    211211static inline {
    212         int ato( const char * sptr ) { return (int)strtol( sptr, 0p, 10 ); }
    213         unsigned int ato( const char * sptr ) { return (unsigned int)strtoul( sptr, 0p, 10 ); }
    214         long int ato( const char * sptr ) { return strtol( sptr, 0p, 10 ); }
    215         unsigned long int ato( const char * sptr ) { return strtoul( sptr, 0p, 10 ); }
    216         long long int ato( const char * sptr ) { return strtoll( sptr, 0p, 10 ); }
    217         unsigned long long int ato( const char * sptr ) { return strtoull( sptr, 0p, 10 ); }
    218 
    219         float ato( const char * sptr ) { return strtof( sptr, 0p ); }
    220         double ato( const char * sptr ) { return strtod( sptr, 0p ); }
    221         long double ato( const char * sptr ) { return strtold( sptr, 0p ); }
    222 
    223         float _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
    224         double _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
    225         long double _Complex ato( const char * sptr ) { return strto( sptr, 0p ); }
     212        int ato( const char sptr[] ) { return (int)strtol( sptr, 0p, 10 ); }
     213        unsigned int ato( const char sptr[] ) { return (unsigned int)strtoul( sptr, 0p, 10 ); }
     214        long int ato( const char sptr[] ) { return strtol( sptr, 0p, 10 ); }
     215        unsigned long int ato( const char sptr[] ) { return strtoul( sptr, 0p, 10 ); }
     216        long long int ato( const char sptr[] ) { return strtoll( sptr, 0p, 10 ); }
     217        unsigned long long int ato( const char sptr[] ) { return strtoull( sptr, 0p, 10 ); }
     218
     219        float ato( const char sptr[] ) { return strtof( sptr, 0p ); }
     220        double ato( const char sptr[] ) { return strtod( sptr, 0p ); }
     221        long double ato( const char sptr[] ) { return strtold( sptr, 0p ); }
     222
     223        float _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
     224        double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
     225        long double _Complex ato( const char sptr[] ) { return strto( sptr, 0p ); }
    226226} // distribution
    227227
  • libcfa/src/time.cfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 13 08:41:55 2019
    13 // Update Count     : 65
     12// Last Modified On : Tue Feb  4 08:24:18 2020
     13// Update Count     : 70
    1414//
    1515
     
    3333forall( dtype ostype | ostream( ostype ) ) {
    3434        ostype & ?|?( ostype & os, Duration dur ) with( dur ) {
    35                 (ostype &)(os | tv / TIMEGRAN);                                 // print seconds
    36                 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
     35                (ostype &)(os | tn / TIMEGRAN);                                 // print seconds
     36                long int ns = (tn < 0 ? -tn : tn) % TIMEGRAN;   // compute nanoseconds
    3737                if ( ns != 0 ) {                                                                // some ?
    3838                        char buf[16];
     
    5252
    5353#ifdef __CFA_DEBUG__
    54 static void tabort( int year, int month, int day, int hour, int min, int sec, int nsec ) {
     54static void tabort( int year, int month, int day, int hour, int min, int sec, int64_t nsec ) {
    5555        abort | "Attempt to create Time( year=" | year | "(>=1970), month=" | month | "(1-12), day=" | day | "(1-31), hour=" | hour | "(0-23), min=" | min | "(0-59), sec=" | sec
    56                   | "(0-60), nsec=" | nsec | "(0-999_999_999), which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038.";
     56                  | "(0-60), nsec=" | nsec | "(0-999_999_999), which is not in the range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038, where month and day have 1 origin.";
    5757} // tabort
    5858#endif // __CFA_DEBUG__
    5959
    60 void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, int nsec ) with( time ) {
     60void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, int64_t nsec ) with( time ) {
    6161        tm tm;
    6262
    63         tm.tm_isdst = -1;                                                                       // let mktime determine if alternate timezone is in effect
     63        // Values can be in any range (+/-) but result must be in the epoch.
    6464        tm.tm_year = year - 1900;                                                       // mktime uses 1900 as its starting point
    65 #ifdef __CFA_DEBUG__
    66         if ( month < 1 || 12 < month ) {
    67                 tabort( year, month, day, hour, min, sec, nsec );
    68         } // if
    69 #endif // __CFA_DEBUG__
     65        // Make month in range 1-12 to match with day.
    7066        tm.tm_mon = month - 1;                                                          // mktime uses range 0-11
    71 #ifdef __CFA_DEBUG__
    72         if ( day < 1 || 31 < day ) {
    73                 tabort( year, month, day, hour, min, sec, nsec );
    74         } // if
    75 #endif // __CFA_DEBUG__
    7667        tm.tm_mday = day;                                                                       // mktime uses range 1-31
    7768        tm.tm_hour = hour;
    7869        tm.tm_min = min;
    7970        tm.tm_sec = sec;
     71        tm.tm_isdst = -1;                                                                       // let mktime determine if alternate timezone is in effect
    8072        time_t epochsec = mktime( &tm );
    8173#ifdef __CFA_DEBUG__
    82         if ( epochsec == (time_t)-1 ) {
     74        if ( epochsec <= (time_t)-1 ) {                                         // MUST BE LESS THAN OR EQUAL!
    8375                tabort( year, month, day, hour, min, sec, nsec );
    8476        } // if
    8577#endif // __CFA_DEBUG__
    86         tv = (int64_t)(epochsec) * TIMEGRAN + nsec;                     // convert to nanoseconds
     78        tn = (int64_t)(epochsec) * TIMEGRAN + nsec;                     // convert to nanoseconds
    8779#ifdef __CFA_DEBUG__
    88         if ( tv > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
     80        if ( tn > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
    8981                tabort( year, month, day, hour, min, sec, nsec );
    9082        } // if
     
    9385
    9486char * yy_mm_dd( Time time, char * buf ) with( time ) {
    95         time_t s = tv / TIMEGRAN;
     87        time_t s = tn / TIMEGRAN;
    9688        tm tm;
    9789        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    108100
    109101char * mm_dd_yy( Time time, char * buf ) with( time ) {
    110         time_t s = tv / TIMEGRAN;
     102        time_t s = tn / TIMEGRAN;
    111103        tm tm;
    112104        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    123115
    124116char * dd_mm_yy( Time time, char * buf ) with( time ) {
    125         time_t s = tv / TIMEGRAN;
     117        time_t s = tn / TIMEGRAN;
    126118        tm tm;
    127119        gmtime_r( &s, &tm );                                                            // tm_mon <= 11, tm_mday <= 31
     
    137129} // dd_mm_yy
    138130
    139 size_t strftime( char * buf, size_t size, const char * fmt, Time time ) with( time ) {
    140         time_t s = tv / TIMEGRAN;
     131size_t strftime( char buf[], size_t size, const char fmt[], Time time ) with( time ) {
     132        time_t s = tn / TIMEGRAN;
    141133        tm tm;
    142134        gmtime_r( &s, &tm );
     
    147139        ostype & ?|?( ostype & os, Time time ) with( time ) {
    148140                char buf[32];                                                                   // at least 26
    149                 time_t s = tv / TIMEGRAN;
     141                time_t s = tn / TIMEGRAN;
    150142                ctime_r( &s, (char *)&buf );                                    // 26 characters: "Wed Jun 30 21:49:08 1993\n"
    151143                buf[24] = '\0';                                                                 // remove trailing '\n'
    152                 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;   // compute nanoseconds
     144                long int ns = (tn < 0 ? -tn : tn) % TIMEGRAN;   // compute nanoseconds
    153145                if ( ns == 0 ) {                                                                // none ?
    154146                        (ostype &)(os | buf);                                           // print date/time/year
  • libcfa/src/time.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Wed Mar 14 23:18:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 22 12:25:34 2018
    13 // Update Count     : 643
     12// Last Modified On : Tue Feb  4 08:24:32 2020
     13// Update Count     : 654
    1414//
    1515
     
    3232        Duration ?=?( Duration & dur, __attribute__((unused)) zero_t ) { return dur{ 0 }; }
    3333
    34         Duration +?( Duration rhs ) with( rhs ) {       return (Duration)@{ +tv }; }
    35         Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
     34        Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tn }; }
     35        Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tn + rhs.tn }; }
    3636        Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    3737
    38         Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
    39         Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
     38        Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tn }; }
     39        Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tn - rhs.tn }; }
    4040        Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    4141
    42         Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
    43         Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
     42        Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tn * rhs }; }
     43        Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tn }; }
    4444        Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
    4545
    46         int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
    47         Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
     46        int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tn / rhs.tn; }
     47        Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tn / rhs }; }
    4848        Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
    49         double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; }
    50 
    51         Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; }
     49        double div( Duration lhs, Duration rhs ) { return (double)lhs.tn / (double)rhs.tn; }
     50
     51        Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tn % rhs.tn }; }
    5252        Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; }
    5353
    54         bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
    55         bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
    56         bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv <  rhs.tv; }
    57         bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
    58         bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv >  rhs.tv; }
    59         bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
    60 
    61         bool ?==?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv == 0; }
    62         bool ?!=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv != 0; }
    63         bool ?<? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv <  0; }
    64         bool ?<=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv <= 0; }
    65         bool ?>? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv >  0; }
    66         bool ?>=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tv >= 0; }
    67 
    68         Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; }
     54        bool ?==?( Duration lhs, Duration rhs ) { return lhs.tn == rhs.tn; }
     55        bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tn != rhs.tn; }
     56        bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tn <  rhs.tn; }
     57        bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tn <= rhs.tn; }
     58        bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tn >  rhs.tn; }
     59        bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tn >= rhs.tn; }
     60
     61        bool ?==?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn == 0; }
     62        bool ?!=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn != 0; }
     63        bool ?<? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn <  0; }
     64        bool ?<=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn <= 0; }
     65        bool ?>? ( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn >  0; }
     66        bool ?>=?( Duration lhs, __attribute__((unused)) zero_t ) { return lhs.tn >= 0; }
     67
     68        Duration abs( Duration rhs ) { return rhs.tn >= 0 ? rhs : -rhs; }
    6969
    7070        Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
     
    8282        Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
    8383
    84         int64_t ?`ns( Duration dur ) { return dur.tv; }
    85         int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); }
    86         int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); }
    87         int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; }
    88         int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); }
    89         int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); }
    90         int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); }
    91         int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
    92 
    93         Duration max( Duration lhs, Duration rhs ) { return  (lhs.tv < rhs.tv) ? rhs : lhs;}
    94         Duration min( Duration lhs, Duration rhs ) { return !(rhs.tv < lhs.tv) ? lhs : rhs;}
     84        int64_t ?`ns( Duration dur ) { return dur.tn; }
     85        int64_t ?`us( Duration dur ) { return dur.tn / (TIMEGRAN / 1_000_000LL); }
     86        int64_t ?`ms( Duration dur ) { return dur.tn / (TIMEGRAN / 1_000LL); }
     87        int64_t ?`s( Duration dur ) { return dur.tn / TIMEGRAN; }
     88        int64_t ?`m( Duration dur ) { return dur.tn / (60LL * TIMEGRAN); }
     89        int64_t ?`h( Duration dur ) { return dur.tn / (60LL * 60LL * TIMEGRAN); }
     90        int64_t ?`d( Duration dur ) { return dur.tn / (24LL * 60LL * 60LL * TIMEGRAN); }
     91        int64_t ?`w( Duration dur ) { return dur.tn / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
     92
     93        Duration max( Duration lhs, Duration rhs ) { return  (lhs.tn < rhs.tn) ? rhs : lhs;}
     94        Duration min( Duration lhs, Duration rhs ) { return !(rhs.tn < lhs.tn) ? lhs : rhs;}
    9595} // distribution
    9696
     
    143143//######################### Time #########################
    144144
    145 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 );
     145void ?{}( Time & time, int year, int month = 1, int day = 1, int hour = 0, int min = 0, int sec = 0, int64_t nsec = 0 );
    146146static inline {
    147147        Time ?=?( Time & time, __attribute__((unused)) zero_t ) { return time{ 0 }; }
    148148
    149         void ?{}( Time & time, timeval t ) with( time ) { tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000; }
     149        void ?{}( Time & time, timeval t ) with( time ) { tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000; }
    150150        Time ?=?( Time & time, timeval t ) with( time ) {
    151                 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
     151                tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
    152152                return time;
    153153        } // ?=?
    154154
    155         void ?{}( Time & time, timespec t ) with( time ) { tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; }
     155        void ?{}( Time & time, timespec t ) with( time ) { tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; }
    156156        Time ?=?( Time & time, timespec t ) with( time ) {
    157                 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
     157                tn = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
    158158                return time;
    159159        } // ?=?
    160160
    161         Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; }
     161        Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tn + rhs.tn }; }
    162162        Time ?+?( Duration lhs, Time rhs ) { return rhs + lhs; }
    163163        Time ?+=?( Time & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    164164
    165         Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
    166         Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tv - rhs.tv }; }
     165        Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tn - rhs.tn }; }
     166        Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tn - rhs.tn }; }
    167167        Time ?-=?( Time & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    168         bool ?==?( Time lhs, Time rhs ) { return lhs.tv == rhs.tv; }
    169         bool ?!=?( Time lhs, Time rhs ) { return lhs.tv != rhs.tv; }
    170         bool ?<?( Time lhs, Time rhs ) { return lhs.tv < rhs.tv; }
    171         bool ?<=?( Time lhs, Time rhs ) { return lhs.tv <= rhs.tv; }
    172         bool ?>?( Time lhs, Time rhs ) { return lhs.tv > rhs.tv; }
    173         bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; }
     168        bool ?==?( Time lhs, Time rhs ) { return lhs.tn == rhs.tn; }
     169        bool ?!=?( Time lhs, Time rhs ) { return lhs.tn != rhs.tn; }
     170        bool ?<?( Time lhs, Time rhs ) { return lhs.tn < rhs.tn; }
     171        bool ?<=?( Time lhs, Time rhs ) { return lhs.tn <= rhs.tn; }
     172        bool ?>?( Time lhs, Time rhs ) { return lhs.tn > rhs.tn; }
     173        bool ?>=?( Time lhs, Time rhs ) { return lhs.tn >= rhs.tn; }
     174
     175        int64_t ?`ns( Time t ) { return t.tn; }
    174176} // distribution
    175177
     
    189191} // dmy
    190192
    191 size_t strftime( char * buf, size_t size, const char * fmt, Time time );
     193size_t strftime( char buf[], size_t size, const char fmt[], Time time );
    192194
    193195//------------------------- timeval (cont) -------------------------
    194196
    195197static inline void ?{}( timeval & t, Time time ) with( t, time ) {
    196         tv_sec = tv / TIMEGRAN;                                                         // seconds
    197         tv_usec = tv % TIMEGRAN / (TIMEGRAN / 1_000_000LL);     // microseconds
     198        tv_sec = tn / TIMEGRAN;                                                         // seconds
     199        tv_usec = tn % TIMEGRAN / (TIMEGRAN / 1_000_000LL);     // microseconds
    198200} // ?{}
    199201
     
    201203
    202204static inline void ?{}( timespec & t, Time time ) with( t, time ) {
    203         tv_sec = tv / TIMEGRAN;                                                         // seconds
    204         tv_nsec = tv % TIMEGRAN;                                                        // nanoseconds
     205        tv_sec = tn / TIMEGRAN;                                                         // seconds
     206        tv_nsec = tn % TIMEGRAN;                                                        // nanoseconds
    205207} // ?{}
    206208
  • libcfa/src/time_t.hfa

    rdca5802 rb7d6a36  
    1010// Created On       : Tue Apr 10 14:42:03 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr 13 07:51:47 2018
    13 // Update Count     : 6
     12// Last Modified On : Sun Jan  5 08:22:46 2020
     13// Update Count     : 7
    1414//
    1515
     
    2020
    2121struct Duration {                                                                               // private
    22         int64_t tv;                                                                                     // nanoseconds
     22        int64_t tn;                                                                                     // nanoseconds
    2323}; // Duration
    2424
    25 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
    26 static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tv = 0; }
     25static inline void ?{}( Duration & dur ) with( dur ) { tn = 0; }
     26static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tn = 0; }
    2727
    2828
     
    3030
    3131struct Time {                                                                                   // private
    32         uint64_t tv;                                                                            // nanoseconds since UNIX epoch
     32        uint64_t tn;                                                                            // nanoseconds since UNIX epoch
    3333}; // Time
    3434
    35 static inline void ?{}( Time & time ) with( time ) { tv = 0; }
    36 static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tv = 0; }
     35static inline void ?{}( Time & time ) with( time ) { tn = 0; }
     36static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tn = 0; }
    3737
    3838// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.