Changeset bdfc032 for libcfa/src


Ignore:
Timestamp:
Feb 4, 2020, 11:35:26 AM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
eef8dfb
Parents:
aefb247 (diff), 4f7b418 (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 dkobets-vector

Location:
libcfa/src
Files:
26 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.in

    raefb247 rbdfc032  
    425425am__v_CFA_0 = @echo "  CFA     " $@;
    426426am__v_CFA_1 =
    427 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
    428 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
    429 am__v_JAVAC_0 = @echo "  JAVAC   " $@;
    430 am__v_JAVAC_1 =
    431 AM_V_GOC = $(am__v_GOC_@AM_V@)
    432 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
    433 am__v_GOC_0 = @echo "  GOC     " $@;
    434 am__v_GOC_1 =
    435427UPPCC = u++
    436428UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS)
     
    439431am__v_UPP_0 = @echo "  UPP     " $@;
    440432am__v_UPP_1 =
     433AM_V_GOC = $(am__v_GOC_@AM_V@)
     434am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@)
     435am__v_GOC_0 = @echo "  GOC     " $@;
     436am__v_GOC_1 =
     437AM_V_RUST = $(am__v_RUST_@AM_V@)
     438am__v_RUST_ = $(am__v_RUST_@AM_DEFAULT_V@)
     439am__v_RUST_0 = @echo "  RUST     " $@;
     440am__v_RUST_1 =
     441AM_V_NODEJS = $(am__v_NODEJS_@AM_V@)
     442am__v_NODEJS_ = $(am__v_NODEJS_@AM_DEFAULT_V@)
     443am__v_NODEJS_0 = @echo "  NODEJS     " $@;
     444am__v_NODEJS_1 =
     445AM_V_JAVAC = $(am__v_JAVAC_@AM_V@)
     446am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@)
     447am__v_JAVAC_0 = @echo "  JAVAC   " $@;
     448am__v_JAVAC_1 =
    441449lib_LTLIBRARIES = libcfa.la libcfathread.la
    442450gdbwaittarget = ""
  • libcfa/src/bits/containers.hfa

    raefb247 rbdfc032  
    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/defs.hfa

    raefb247 rbdfc032  
    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/signal.hfa

    raefb247 rbdfc032  
    4040        sigaddset( &act.sa_mask, SIGALRM );             // disabled during signal handler
    4141        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 );
    4249        act.sa_flags = flags;
    4350
    44         if ( sigaction( sig, &act, NULL ) == -1 ) {
     51        if ( sigaction( sig, &act, 0p ) == -1 ) {
    4552                __cfaabi_dbg_print_buffer_decl(
    4653                        " __cfaabi_sigaction( sig:%d, handler:%p, flags:%d ), problem installing signal handler, error(%d) %s.\n",
     
    4855                );
    4956                _exit( EXIT_FAILURE );
    50         }
     57        } // if
    5158}
    52 
    53 // Sigaction wrapper : restore default handler
    54 static void __cfaabi_sigdefault( int sig ) {
    55         struct sigaction act;
    56 
    57         act.sa_handler = SIG_DFL;
    58         act.sa_flags = 0;
    59         sigemptyset( &act.sa_mask );
    60 
    61         if ( sigaction( sig, &act, NULL ) == -1 ) {
    62                 __cfaabi_dbg_print_buffer_decl(
    63                         " __cfaabi_sigdefault( sig:%d ), problem reseting signal handler, error(%d) %s.\n",
    64                         sig, errno, strerror( errno )
    65                 );
    66                 _exit( EXIT_FAILURE );
    67         }
    68 }
  • libcfa/src/clock.hfa

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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 : Thu Jan 30 22:55:50 2020
     13// Update Count     : 56
    1414//
    1515
     
    469469        );
    470470
    471         Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" ); 
     471        Abort( pthread_attr_setstack( &attr, stack, stacksize ), "pthread_attr_setstack" );
    472472
    473473        Abort( pthread_create( pthread, &attr, start, arg ), "pthread_create" );
     
    490490        verify( ! kernelTLS.preemption_state.enabled );
    491491
     492        kernelTLS.this_thread->curr_cor = dst;
    492493        __stack_prepare( &dst->stack, 65000 );
    493         CtxStart(&this->runner, CtxInvokeCoroutine);
     494        CtxStart(main, dst, this->runner, CtxInvokeCoroutine);
    494495
    495496        verify( ! kernelTLS.preemption_state.enabled );
     
    505506        CtxSwitch( &src->context, &dst->context );
    506507        // when CtxSwitch returns we are back in the src coroutine
     508
     509        mainThread->curr_cor = &mainThread->self_cor;
    507510
    508511        // set state of new coroutine to active
     
    841844                sigemptyset( &mask );
    842845                sigaddset( &mask, SIGALRM );            // block SIGALRM signals
    843                 sigsuspend( &mask );                    // block the processor to prevent further damage during abort
    844                 _exit( EXIT_FAILURE );                  // if processor unblocks before it is killed, terminate it
     846                sigaddset( &mask, SIGUSR1 );            // block SIGALRM signals
     847                sigsuspend( &mask );                            // block the processor to prevent further damage during abort
     848                _exit( EXIT_FAILURE );                          // if processor unblocks before it is killed, terminate it
    845849        }
    846850        else {
  • libcfa/src/concurrency/kernel_private.hfa

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    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

    raefb247 rbdfc032  
    5858void ?{}( scoped(T)& this ) with( this ) {
    5959        handle{};
    60         __thrd_start(handle);
     60        __thrd_start(handle, main);
    6161}
    6262
     
    6464void ?{}( scoped(T)& this, P params ) with( this ) {
    6565        handle{ params };
    66         __thrd_start(handle);
     66        __thrd_start(handle, main);
    6767}
    6868
     
    7575// Starting and stopping threads
    7676forall( dtype T | is_thread(T) )
    77 void __thrd_start( T& this ) {
     77void __thrd_start( T & this, void (*main_p)(T &) ) {
    7878        thread_desc * this_thrd = get_thread(this);
    7979        thread_desc * curr_thrd = TL_GET( this_thread );
    8080
    8181        disable_interrupts();
    82         CtxStart(&this, CtxInvokeThread);
     82        CtxStart(main_p, get_coroutine(this), this, CtxInvokeThread);
     83
    8384        this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP];
    8485        verify( this_thrd->context.SP );
    85         CtxSwitch( &curr_thrd->context, &this_thrd->context );
     86        // CtxSwitch( &curr_thrd->context, &this_thrd->context );
    8687
    8788        ScheduleThread(this_thrd);
    8889        enable_interrupts( __cfaabi_dbg_ctx );
    89 }
    90 
    91 extern "C" {
    92         // KERNEL ONLY
    93         void __finish_creation(thread_desc * this) {
    94                 // set new coroutine that the processor is executing
    95                 // and context switch to it
    96                 verify( kernelTLS.this_thread != this );
    97                 verify( kernelTLS.this_thread->context.SP );
    98                 CtxSwitch( &this->context, &kernelTLS.this_thread->context );
    99         }
    10090}
    10191
  • libcfa/src/concurrency/thread.hfa

    raefb247 rbdfc032  
    5454
    5555forall( dtype T | is_thread(T) )
    56 void __thrd_start( T & this );
     56void __thrd_start( T & this, void (*)(T &) );
    5757
    5858//-----------------------------------------------------------------------------
  • libcfa/src/executor.cfa

    raefb247 rbdfc032  
    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/interpose.cfa

    raefb247 rbdfc032  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec 13 13:45:21 2019
    13 // Update Count     : 121
     12// Last Modified On : Thu Jan 30 17:47:32 2020
     13// Update Count     : 156
    1414//
    1515
     
    9595        void __cfaabi_interpose_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_CORE ) ));
    9696        void __cfaabi_interpose_startup( void ) {
    97                 const char *version = NULL;
     97                const char *version = 0p;
    9898
    9999                preload_libgcc();
     
    105105#pragma GCC diagnostic pop
    106106
     107                // As a precaution (and necessity), errors that result in termination are delivered on a separate stack because
     108                // task stacks might be very small (4K) and the signal delivery corrupts memory to the point that a clean
     109                // shutdown is impossible. Also, when a stack overflow encounters the non-accessible sentinel page (debug only)
     110                // and generates a segment fault, the signal cannot be delivered on the sentinel page. Finally, calls to abort
     111                // print a stack trace that uses substantial stack space.
     112
     113                #define MINSTKSZ SIGSTKSZ * 8
     114                static char stack[MINSTKSZ] __attribute__(( aligned (16) ));
     115                static stack_t ss;
     116
     117                ss.ss_sp = stack;
     118                ss.ss_size = MINSTKSZ;
     119                ss.ss_flags = 0;
     120                if ( sigaltstack( &ss, 0p ) == -1 ) {
     121                        abort( "__cfaabi_interpose_startup : internal error, sigaltstack error(%d) %s.", errno, strerror( errno ) );
     122                } // if
     123
    107124                // 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 );
     125                __cfaabi_sigaction( SIGSEGV, sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     126                __cfaabi_sigaction( SIGBUS , sigHandler_segv, SA_SIGINFO | SA_ONSTACK );
     127                __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO | SA_ONSTACK );
     128                __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO | SA_ONSTACK );
     129                __cfaabi_sigaction( SIGTERM, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // one shot handler, return to default
     130                __cfaabi_sigaction( SIGINT , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     131                __cfaabi_sigaction( SIGABRT, sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND );
     132                __cfaabi_sigaction( SIGHUP , sigHandler_term, SA_SIGINFO | SA_ONSTACK | SA_RESETHAND ); // terminal hangup
    115133        }
    116134}
     
    123141void exit( int status, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    124142void abort( const char fmt[], ... ) __attribute__(( format(printf, 1, 2), __nothrow__, __leaf__, __noreturn__ ));
     143void abort( bool signalAbort, const char fmt[], ... ) __attribute__(( format(printf, 2, 3), __nothrow__, __leaf__, __noreturn__ ));
    125144
    126145extern "C" {
    127146        void abort( void ) __attribute__(( __nothrow__, __leaf__, __noreturn__ )) {
    128                 abort( NULL );
     147                abort( false, NULL ); // FIX ME: 0p does not work
    129148        }
    130149
     
    132151                va_list argp;
    133152                va_start( argp, fmt );
    134                 abort( fmt, argp );
     153                abort( false, fmt, argp );
    135154                va_end( argp );
    136155        }
     
    141160}
    142161
    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__ )) {}
     162void * kernel_abort( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 0p; }
     163void kernel_abort_msg( void * data, char * buffer, int size ) __attribute__(( __nothrow__, __leaf__, __weak__ )) {}
     164// See concurrency/kernel.cfa for strong definition used in multi-processor mode.
    145165int kernel_abort_lastframe( void ) __attribute__(( __nothrow__, __leaf__, __weak__ )) { return 4; }
    146166
    147167enum { abort_text_size = 1024 };
    148168static 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() {
     169
     170static void __cfaabi_backtrace( int start ) {
    185171        enum {
    186172                Frames = 50,                                                                    // maximum number of stack frames
    187                 Start = 8,                                                                              // skip first N stack frames
    188173        };
     174        int last = kernel_abort_lastframe();                            // skip last N stack frames
    189175
    190176        void * array[Frames];
     
    192178        char ** messages = backtrace_symbols( array, size );
    193179
    194         // find executable name
    195         *index( messages[0], '(' ) = '\0';
     180        *index( messages[0], '(' ) = '\0';                                      // find executable name
    196181        __cfaabi_bits_print_nolock( STDERR_FILENO, "Stack back trace for: %s\n", messages[0]);
    197182
    198         for ( int i = Start; i < size - abort_lastframe && messages != 0p; i += 1 ) {
     183        for ( unsigned int i = start; i < size - last && messages != 0p; i += 1 ) {
    199184                char * name = 0p, * offset_begin = 0p, * offset_end = 0p;
    200185
    201                 for ( char * p = messages[i]; *p; ++p ) {
     186                for ( char * p = messages[i]; *p; ++p ) {               // find parantheses and +offset
    202187                        //__cfaabi_bits_print_nolock( "X %s\n", p);
    203                         // find parantheses and +offset
    204188                        if ( *p == '(' ) {
    205189                                name = p;
     
    212196                }
    213197
    214                 // if line contains symbol print it
    215                 int frameNo = i - Start;
     198                // if line contains symbol, print it
     199                int frameNo = i - start;
    216200                if ( name && offset_begin && offset_end && name < offset_begin ) {
    217                         // delimit strings
    218                         *name++ = '\0';
     201                        *name++ = '\0';                                                         // delimit strings
    219202                        *offset_begin++ = '\0';
    220203                        *offset_end++ = '\0';
     
    228211}
    229212
     213void exit( int status, const char fmt[], ... ) {
     214        va_list args;
     215        va_start( args, fmt );
     216        vfprintf( stderr, fmt, args );
     217        va_end( args );
     218        __cabi_libc.exit( status );
     219}
     220
     221void abort( bool signalAbort, const char fmt[], ... ) {
     222        void * kernel_data = kernel_abort();                            // must be done here to lock down kernel
     223        int len;
     224
     225        signal( SIGABRT, SIG_DFL );                                                     // prevent final "real" abort from recursing to handler
     226
     227        len = snprintf( abort_text, abort_text_size, "Cforall Runtime error (UNIX pid:%ld) ", (long int)getpid() ); // use UNIX pid (versus getPid)
     228        __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     229
     230        if ( fmt ) {
     231                va_list args;
     232                va_start( args, fmt );
     233
     234                len = vsnprintf( abort_text, abort_text_size, fmt, args );
     235                va_end( args );
     236                __cfaabi_bits_write( STDERR_FILENO, abort_text, len );
     237
     238                if ( fmt[strlen( fmt ) - 1] != '\n' ) {                 // add optional newline if missing at the end of the format text
     239                        __cfaabi_dbg_write( "\n", 1 );
     240                }
     241        }
     242
     243        kernel_abort_msg( kernel_data, abort_text, abort_text_size );
     244        __cfaabi_backtrace( signalAbort ? 4 : 3 );
     245
     246        __cabi_libc.abort();                                                            // print stack trace in handler
     247}
     248
     249void abort( const char fmt[], ... ) {
     250        va_list args;
     251        va_start( args, fmt );
     252        abort( false, fmt, args );
     253        va_end( args );
     254}
     255
    230256void sigHandler_segv( __CFA_SIGPARMS__ ) {
    231                 if ( sfp->si_addr == NULL ) {
    232                         abort( "Null pointer (0p) dereference.\n" );
     257                if ( sfp->si_addr == 0p ) {
     258                        abort( true, "Null pointer (0p) dereference.\n" );
    233259                } else {
    234                         abort( "%s at memory location %p.\n"
     260                        abort( true, "%s at memory location %p.\n"
    235261                                   "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",
    236262                                   (sig == SIGSEGV ? "Segment fault" : "Bus error"), sfp->si_addr );
     
    239265
    240266void sigHandler_ill( __CFA_SIGPARMS__ ) {
    241         abort( "Executing illegal instruction at location %p.\n"
     267        abort( true, "Executing illegal instruction at location %p.\n"
    242268                        "Possible cause is stack corruption.\n",
    243269                        sfp->si_addr );
     
    255281          default: msg = "unknown";
    256282        } // choose
    257         abort( "Computation error %s at location %p.\n", msg, sfp->si_addr );
    258 }
    259 
    260 void sigHandler_abrt( __CFA_SIGPARMS__ ) {
    261         __cfaabi_backtrace();
    262 
    263         // reset default signal handler
    264         __cfaabi_sigdefault( SIGABRT );
    265 
    266         raise( SIGABRT );
     283        abort( true, "Computation error %s at location %p.\n", msg, sfp->si_addr );
    267284}
    268285
    269286void sigHandler_term( __CFA_SIGPARMS__ ) {
    270         abort( "Application stopped by %s signal.", sig == SIGINT ? "an interrupt (SIGINT)" : "a terminate (SIGTERM)" );
     287        abort( true, "Application interrupted by signal: %s.\n", strsignal( sig ) );
    271288}
    272289
  • libcfa/src/startup.cfa

    raefb247 rbdfc032  
    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 : Fri Dec 13 13:16:45 2019
     13// Update Count     : 29
    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__
  • libcfa/src/stdhdr/bfdlink.h

    raefb247 rbdfc032  
    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 : Sat Feb  1 07:15:29 2020
     13// Update Count     : 5
    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

    raefb247 rbdfc032  
    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 : Sat Feb  1 07:15:39 2020
     13// Update Count     : 5
    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

    raefb247 rbdfc032  
    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 : Sat Feb  1 07:15:47 2020
     13// Update Count     : 5
    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

    raefb247 rbdfc032  
    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 : Sat Feb  1 07:15:58 2020
     13// Update Count     : 14
    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

    raefb247 rbdfc032  
    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 : Sat Feb  1 07:16:05 2020
     13// Update Count     : 5
    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/time.cfa

    raefb247 rbdfc032  
    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 : Sun Jan  5 17:27:40 2020
     13// Update Count     : 69
    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
     
    138130
    139131size_t strftime( char * buf, size_t size, const char * fmt, Time time ) with( time ) {
    140         time_t s = tv / TIMEGRAN;
     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

    raefb247 rbdfc032  
    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 : Mon Jan  6 12:50:16 2020
     13// Update Count     : 653
    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
     
    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

    raefb247 rbdfc032  
    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.