Changes in / [ca37445:9d1e3f7]


Ignore:
Location:
src
Files:
1 added
4 deleted
33 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/lex.ll

    rca37445 r9d1e3f7  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Fri Apr  6 15:16:15 2018
    13  * Update Count     : 670
     12 * Last Modified On : Thu Mar 22 16:47:06 2018
     13 * Update Count     : 668
    1414 */
    1515
     
    198198__asm                   { KEYWORD_RETURN(ASM); }                                // GCC
    199199__asm__                 { KEYWORD_RETURN(ASM); }                                // GCC
     200_At                             { KEYWORD_RETURN(AT); }                                 // CFA
    200201_Atomic                 { KEYWORD_RETURN(ATOMIC); }                             // C11
    201202__attribute             { KEYWORD_RETURN(ATTRIBUTE); }                  // GCC
     
    228229exception               { KEYWORD_RETURN(EXCEPTION); }                  // CFA
    229230extern                  { KEYWORD_RETURN(EXTERN); }
     231fallthru                { KEYWORD_RETURN(FALLTHRU); }                   // CFA
    230232fallthrough             { KEYWORD_RETURN(FALLTHROUGH); }                // CFA
    231 fallthru                { KEYWORD_RETURN(FALLTHRU); }                   // CFA
    232233finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    233234float                   { KEYWORD_RETURN(FLOAT); }
     
    259260__builtin_offsetof { KEYWORD_RETURN(OFFSETOF); }                // GCC
    260261one_t                   { NUMERIC_RETURN(ONE_T); }                              // CFA
    261 or                              { QKEYWORD_RETURN(WOR); }                               // CFA
    262262otype                   { KEYWORD_RETURN(OTYPE); }                              // CFA
    263263register                { KEYWORD_RETURN(REGISTER); }
     
    296296__volatile__    { KEYWORD_RETURN(VOLATILE); }                   // GCC
    297297waitfor                 { KEYWORD_RETURN(WAITFOR); }
     298or                              { QKEYWORD_RETURN(WOR); }                               // CFA
    298299when                    { KEYWORD_RETURN(WHEN); }
    299300while                   { KEYWORD_RETURN(WHILE); }
  • src/Parser/parser.yy

    rca37445 r9d1e3f7  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 28 17:52:24 2018
    13 // Update Count     : 3130
     12// Last Modified On : Thu Mar 22 16:56:21 2018
     13// Update Count     : 3125
    1414//
    1515
     
    497497                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    498498        | type_name '.' no_attr_identifier                                      // CFA, nested type
    499                 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
     499                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME
    500500        | type_name '.' '[' push field_list pop ']'                     // CFA, nested type / tuple field selector
    501                 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
     501                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME
    502502        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
     503                { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } // FIX ME
    504504        ;
    505505
     
    687687        | '(' type_no_function ')' cast_expression
    688688                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    689         | '(' COROUTINE '&' ')' cast_expression                         // CFA
    690                 { SemanticError( yylloc, "coroutine cast is currently unimplemented." ); $$ = nullptr; }
    691         | '(' THREAD '&' ')' cast_expression                            // CFA
    692                 { SemanticError( yylloc, "monitor cast is currently unimplemented." ); $$ = nullptr; }
    693         | '(' MONITOR '&' ')' cast_expression                           // CFA
    694                 { SemanticError( yylloc, "thread cast is currently unimplemented." ); $$ = nullptr; }
    695689                // VIRTUAL cannot be opt because of look ahead issues
    696         | '(' VIRTUAL ')' cast_expression                                       // CFA
     690        | '(' VIRTUAL ')' cast_expression
    697691                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    698         | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
     692        | '(' VIRTUAL type_no_function ')' cast_expression
    699693                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
    700694//      | '(' type_no_function ')' tuple
     
    788782        | logical_OR_expression '?' comma_expression ':' conditional_expression
    789783                { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
    790                 // FIX ME: computes $1 twice
     784                // FIX ME: this hack computes $1 twice
    791785        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    792786                { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     
    803797                { $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
    804798        | unary_expression '=' '{' initializer_list comma_opt '}'
    805                 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; }
     799                { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } // FIX ME
    806800        ;
    807801
     
    873867        | exception_statement
    874868        | enable_disable_statement
    875                 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; }
     869                { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } // FIX ME
    876870        | asm_statement
    877871        ;
     
    10681062                { $$ = new StatementNode( build_return( $2 ) ); }
    10691063        | RETURN '{' initializer_list comma_opt '}'
    1070                 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
     1064                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } // FIX ME
    10711065        | THROW assignment_expression_opt ';'                           // handles rethrow
    10721066                { $$ = new StatementNode( build_throw( $2 ) ); }
     
    10921086mutex_statement:
    10931087        MUTEX '(' argument_expression_list ')' statement
    1094                 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; }
     1088                { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } // FIX ME
    10951089        ;
    10961090
  • src/benchmark/bench.h

    rca37445 r9d1e3f7  
    1010#if defined(__cforall)
    1111}
    12 //#include <bits/cfatime.h>
     12#include <bits/cfatime.h>
    1313#endif
    1414
  • src/libcfa/Makefile.am

    rca37445 r9d1e3f7  
    1111## Created On       : Sun May 31 08:54:01 2015
    1212## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Sun Apr  8 23:49:34 2018
    14 ## Update Count     : 227
     13## Last Modified On : Thu Mar 22 17:14:15 2018
     14## Update Count     : 224
    1515###############################################################################
    1616
     
    4646CC = ${abs_top_srcdir}/src/driver/cfa
    4747
    48 headers = fstream iostream iterator limits rational time stdlib \
     48headers = fstream iostream iterator limits rational stdlib \
    4949          containers/maybe containers/pair containers/result containers/vector
    5050
     
    9999        ${stdhdr}                       \
    100100        math                            \
     101        time                            \
    101102        gmp                             \
    102103        bits/align.h            \
     104        bits/cfatime.h          \
    103105        bits/containers.h               \
    104106        bits/defs.h             \
  • src/libcfa/Makefile.in

    rca37445 r9d1e3f7  
    150150am__libcfa_d_a_SOURCES_DIST = libcfa-prelude.c interpose.c \
    151151        bits/debug.c fstream.c iostream.c iterator.c limits.c \
    152         rational.c time.c stdlib.c containers/maybe.c \
    153         containers/pair.c containers/result.c containers/vector.c \
     152        rational.c stdlib.c containers/maybe.c containers/pair.c \
     153        containers/result.c containers/vector.c \
    154154        concurrency/coroutine.c concurrency/thread.c \
    155155        concurrency/kernel.c concurrency/monitor.c assert.c \
     
    165165        libcfa_d_a-iostream.$(OBJEXT) libcfa_d_a-iterator.$(OBJEXT) \
    166166        libcfa_d_a-limits.$(OBJEXT) libcfa_d_a-rational.$(OBJEXT) \
    167         libcfa_d_a-time.$(OBJEXT) libcfa_d_a-stdlib.$(OBJEXT) \
     167        libcfa_d_a-stdlib.$(OBJEXT) \
    168168        containers/libcfa_d_a-maybe.$(OBJEXT) \
    169169        containers/libcfa_d_a-pair.$(OBJEXT) \
     
    184184libcfa_a_LIBADD =
    185185am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c bits/debug.c \
    186         fstream.c iostream.c iterator.c limits.c rational.c time.c \
    187         stdlib.c containers/maybe.c containers/pair.c \
    188         containers/result.c containers/vector.c \
    189         concurrency/coroutine.c concurrency/thread.c \
    190         concurrency/kernel.c concurrency/monitor.c assert.c \
    191         exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \
    192         concurrency/alarm.c concurrency/invoke.c \
    193         concurrency/preemption.c
     186        fstream.c iostream.c iterator.c limits.c rational.c stdlib.c \
     187        containers/maybe.c containers/pair.c containers/result.c \
     188        containers/vector.c concurrency/coroutine.c \
     189        concurrency/thread.c concurrency/kernel.c \
     190        concurrency/monitor.c assert.c exception.c virtual.c \
     191        concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \
     192        concurrency/invoke.c concurrency/preemption.c
    194193@BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
    195194@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-thread.$(OBJEXT) \
     
    198197am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \
    199198        libcfa_a-iterator.$(OBJEXT) libcfa_a-limits.$(OBJEXT) \
    200         libcfa_a-rational.$(OBJEXT) libcfa_a-time.$(OBJEXT) \
    201         libcfa_a-stdlib.$(OBJEXT) containers/libcfa_a-maybe.$(OBJEXT) \
     199        libcfa_a-rational.$(OBJEXT) libcfa_a-stdlib.$(OBJEXT) \
     200        containers/libcfa_a-maybe.$(OBJEXT) \
    202201        containers/libcfa_a-pair.$(OBJEXT) \
    203202        containers/libcfa_a-result.$(OBJEXT) \
     
    261260  esac
    262261am__nobase_cfa_include_HEADERS_DIST = fstream iostream iterator limits \
    263         rational time stdlib containers/maybe containers/pair \
     262        rational stdlib containers/maybe containers/pair \
    264263        containers/result containers/vector concurrency/coroutine \
    265264        concurrency/thread concurrency/kernel concurrency/monitor \
    266         ${shell find stdhdr -type f -printf "%p "} math gmp \
    267         bits/align.h bits/containers.h bits/defs.h bits/debug.h \
    268         bits/locks.h concurrency/invoke.h
     265        ${shell find stdhdr -type f -printf "%p "} math time gmp \
     266        bits/align.h bits/cfatime.h bits/containers.h bits/defs.h \
     267        bits/debug.h bits/locks.h concurrency/invoke.h
    269268HEADERS = $(nobase_cfa_include_HEADERS)
    270269am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    420419EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    421420AM_CCASFLAGS = @CFA_FLAGS@
    422 headers = fstream iostream iterator limits rational time stdlib \
     421headers = fstream iostream iterator limits rational stdlib \
    423422        containers/maybe containers/pair containers/result \
    424423        containers/vector $(am__append_3)
     
    436435        ${stdhdr}                       \
    437436        math                            \
     437        time                            \
    438438        gmp                             \
    439439        bits/align.h            \
     440        bits/cfatime.h          \
    440441        bits/containers.h               \
    441442        bits/defs.h             \
     
    611612@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@
    612613@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@
    613 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-time.Po@am__quote@
    614614@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-virtual.Po@am__quote@
    615615@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@
     
    623623@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@
    624624@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@
    625 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-time.Po@am__quote@
    626625@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@
    627626@AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@
     
    788787@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-rational.obj `if test -f 'rational.c'; then $(CYGPATH_W) 'rational.c'; else $(CYGPATH_W) '$(srcdir)/rational.c'; fi`
    789788
    790 libcfa_d_a-time.o: time.c
    791 @am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-time.o -MD -MP -MF $(DEPDIR)/libcfa_d_a-time.Tpo -c -o libcfa_d_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c
    792 @am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po
    793 @AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='time.c' object='libcfa_d_a-time.o' libtool=no @AMDEPBACKSLASH@
    794 @AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    795 @am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c
    796 
    797 libcfa_d_a-time.obj: time.c
    798 @am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-time.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-time.Tpo -c -o libcfa_d_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi`
    799 @am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po
    800 @AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='time.c' object='libcfa_d_a-time.obj' libtool=no @AMDEPBACKSLASH@
    801 @AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    802 @am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi`
    803 
    804789libcfa_d_a-stdlib.o: stdlib.c
    805790@am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-stdlib.o -MD -MP -MF $(DEPDIR)/libcfa_d_a-stdlib.Tpo -c -o libcfa_d_a-stdlib.o `test -f 'stdlib.c' || echo '$(srcdir)/'`stdlib.c
     
    10951080@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    10961081@am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-rational.obj `if test -f 'rational.c'; then $(CYGPATH_W) 'rational.c'; else $(CYGPATH_W) '$(srcdir)/rational.c'; fi`
    1097 
    1098 libcfa_a-time.o: time.c
    1099 @am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-time.o -MD -MP -MF $(DEPDIR)/libcfa_a-time.Tpo -c -o libcfa_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c
    1100 @am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po
    1101 @AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='time.c' object='libcfa_a-time.o' libtool=no @AMDEPBACKSLASH@
    1102 @AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1103 @am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c
    1104 
    1105 libcfa_a-time.obj: time.c
    1106 @am__fastdepCC_TRUE@    $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-time.obj -MD -MP -MF $(DEPDIR)/libcfa_a-time.Tpo -c -o libcfa_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi`
    1107 @am__fastdepCC_TRUE@    $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po
    1108 @AMDEP_TRUE@@am__fastdepCC_FALSE@       $(AM_V_CC)source='time.c' object='libcfa_a-time.obj' libtool=no @AMDEPBACKSLASH@
    1109 @AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1110 @am__fastdepCC_FALSE@   $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi`
    11111082
    11121083libcfa_a-stdlib.o: stdlib.c
  • src/libcfa/bits/locks.h

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:18:13 2018
    13 // Update Count     : 9
     12// Last Modified On : Fri Dec  8 16:02:22 2017
     13// Update Count     : 1
    1414//
    1515
     
    6464
    6565        extern void yield( unsigned int );
     66        extern thread_local struct thread_desc *    volatile this_thread;
     67        extern thread_local struct processor *      volatile this_processor;
    6668
    6769        static inline void ?{}( __spinlock_t & this ) {
     
    7476                if( result ) {
    7577                        disable_interrupts();
    76                         // __cfaabi_dbg_debug_do(
    77                         //      this.prev_name = caller;
    78                         //      this.prev_thrd = TL_GET( this_thread );
    79                         // )
     78                        __cfaabi_dbg_debug_do(
     79                                this.prev_name = caller;
     80                                this.prev_thrd = this_thread;
     81                        )
    8082                }
    8183                return result;
     
    105107                }
    106108                disable_interrupts();
    107                 // __cfaabi_dbg_debug_do(
    108                 //      this.prev_name = caller;
    109                 //      this.prev_thrd = TL_GET( this_thread );
    110                 // )
     109                __cfaabi_dbg_debug_do(
     110                        this.prev_name = caller;
     111                        this.prev_thrd = this_thread;
     112                )
    111113        }
    112114
  • src/libcfa/concurrency/alarm.c

    rca37445 r9d1e3f7  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 13:36:18 2018
    13 // Update Count     : 61
     12// Last Modified On : Fri Jul 21 22:35:18 2017
     13// Update Count     : 1
    1414//
    1515
     
    2626#include "preemption.h"
    2727
     28
     29static inline void ?{}( itimerval & this, __cfa_time_t * alarm ) with( this ) {
     30        it_value.tv_sec = alarm->val / (1`cfa_s).val;                   // seconds
     31        it_value.tv_usec = max( (alarm->val % (1`cfa_s).val) / (1`cfa_us).val, 1000 ); // microseconds
     32        it_interval.tv_sec = 0;
     33        it_interval.tv_usec = 0;
     34}
     35
     36static inline void ?{}( __cfa_time_t & this, timespec * curr ) {
     37        uint64_t secs  = curr->tv_sec;
     38        uint64_t nsecs = curr->tv_nsec;
     39        this.val = from_s(secs).val + nsecs;
     40}
     41
    2842//=============================================================================================
    2943// Clock logic
    3044//=============================================================================================
    3145
    32 Time __kernel_get_time() {
     46__cfa_time_t __kernel_get_time() {
    3347        timespec curr;
    34         clock_gettime( CLOCK_MONOTONIC_RAW, &curr );            // CLOCK_REALTIME
    35         return (Time){ curr };
     48        clock_gettime( CLOCK_REALTIME, &curr );
     49        return (__cfa_time_t){ &curr };
    3650}
    3751
    38 void __kernel_set_timer( Duration alarm ) {
    39         setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL );
     52void __kernel_set_timer( __cfa_time_t alarm ) {
     53        itimerval val = { &alarm };
     54        setitimer( ITIMER_REAL, &val, NULL );
    4055}
    4156
     
    4459//=============================================================================================
    4560
    46 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period ) with( this ) {
     61void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
    4762        this.thrd = thrd;
    4863        this.alarm = alarm;
     
    5368}
    5469
    55 void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period ) with( this ) {
     70void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
    5671        this.proc = proc;
    5772        this.alarm = alarm;
  • src/libcfa/concurrency/alarm.h

    rca37445 r9d1e3f7  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Mar 26 16:25:41 2018
    13 // Update Count     : 11
     12// Last Modified On : Sat Jul 22 09:59:27 2017
     13// Update Count     : 3
    1414//
    1515
     
    2121#include <assert.h>
    2222
    23 #include "time"
     23#include "bits/cfatime.h"
    2424
    2525struct thread_desc;
     
    3030//=============================================================================================
    3131
    32 Time __kernel_get_time();
    33 void __kernel_set_timer( Duration alarm );
     32__cfa_time_t __kernel_get_time();
     33void __kernel_set_timer( __cfa_time_t alarm );
    3434
    3535//=============================================================================================
     
    3838
    3939struct alarm_node_t {
    40         Time alarm;                             // time when alarm goes off
    41         Duration period;                        // if > 0 => period of alarm
     40        __cfa_time_t alarm;             // time when alarm goes off
     41        __cfa_time_t period;            // if > 0 => period of alarm
    4242        alarm_node_t * next;            // intrusive link list field
    4343
     
    5353typedef alarm_node_t ** __alarm_it_t;
    5454
    55 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period );
    56 void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period );
     55void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s );
     56void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s );
    5757void ^?{}( alarm_node_t & this );
    5858
  • src/libcfa/concurrency/coroutine

    rca37445 r9d1e3f7  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:23:45 2018
    13 // Update Count     : 8
     12// Last Modified On : Wed Aug 30 07:58:29 2017
     13// Update Count     : 3
    1414//
    1515
     
    6060}
    6161
     62// Get current coroutine
     63extern thread_local coroutine_desc * volatile this_coroutine;
     64
    6265// Private wrappers for context switch and stack creation
    6366extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst);
     
    6669// Suspend implementation inlined for performance
    6770static inline void suspend() {
    68         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     71        coroutine_desc * src = this_coroutine;          // optimization
    6972
    7073        assertf( src->last != 0,
     
    8386forall(dtype T | is_coroutine(T))
    8487static inline void resume(T & cor) {
    85         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     88        coroutine_desc * src = this_coroutine;          // optimization
    8689        coroutine_desc * dst = get_coroutine(cor);
    8790
     
    108111
    109112static inline void resume(coroutine_desc * dst) {
    110         coroutine_desc * src = TL_GET( this_coroutine );                        // optimization
     113        coroutine_desc * src = this_coroutine;          // optimization
    111114
    112115        // not resuming self ?
  • src/libcfa/concurrency/coroutine.c

    rca37445 r9d1e3f7  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 17:20:57 2018
    13 // Update Count     : 9
     12// Last Modified On : Thu Feb  8 16:10:31 2018
     13// Update Count     : 4
    1414//
    1515
     
    9999// Wrapper for co
    100100void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    101         verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     101        verify( preemption_state.enabled || this_processor->do_terminate );
    102102        disable_interrupts();
    103103
     
    106106
    107107        // set new coroutine that task is executing
    108         TL_SET( this_coroutine, dst );
     108        this_coroutine = dst;
    109109
    110110        // context switch to specified coroutine
     
    117117
    118118        enable_interrupts( __cfaabi_dbg_ctx );
    119         verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );
     119        verify( preemption_state.enabled || this_processor->do_terminate );
    120120} //ctxSwitchDirect
    121121
     
    172172
    173173        void __leave_coroutine(void) {
    174                 coroutine_desc * src = TL_GET( this_coroutine ); // optimization
     174                coroutine_desc * src = this_coroutine;          // optimization
    175175
    176176                assertf( src->starter != 0,
  • src/libcfa/concurrency/invoke.h

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 22:33:59 2018
    13 // Update Count     : 30
     12// Last Modified On : Fri Feb  9 14:41:55 2018
     13// Update Count     : 6
    1414//
    1515
     
    1717#include "bits/defs.h"
    1818#include "bits/locks.h"
    19 
    20 #define TL_GET( member ) kernelThreadData.member
    21 #define TL_SET( member, value ) kernelThreadData.member = value;
    2219
    2320#ifdef __cforall
     
    3330                static inline struct thread_desc             * & get_next( struct thread_desc             & this );
    3431                static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    35 
    36                 extern thread_local struct KernelThreadData {
    37                         struct coroutine_desc * volatile this_coroutine;
    38                         struct thread_desc    * volatile this_thread;
    39                         struct processor      * volatile this_processor;
    40 
    41                         struct {
    42                                 volatile unsigned short disable_count;
    43                                 volatile bool enabled;
    44                                 volatile bool in_progress;
    45                         } preemption_state;
    46                 } kernelThreadData;
    4732        }
    48 
    49         static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_coroutine ); }
    50         static inline struct thread_desc * volatile active_thread() { return TL_GET( this_thread ); }
    51         static inline struct processor * volatile active_processor() { return TL_GET( this_processor ); }
    5233        #endif
    5334
    5435        struct coStack_t {
    55                 size_t size;                                                                    // size of stack
    56                 void * storage;                                                                 // pointer to stack
    57                 void * limit;                                                                   // stack grows towards stack limit
    58                 void * base;                                                                    // base of stack
    59                 void * context;                                                                 // address of cfa_context_t
    60                 void * top;                                                                             // address of top of storage
    61                 bool userStack;                                                                 // whether or not the user allocated the stack
     36                // size of stack
     37                size_t size;
     38
     39                // pointer to stack
     40                void *storage;
     41
     42                // stack grows towards stack limit
     43                void *limit;
     44
     45                // base of stack
     46                void *base;
     47
     48                // address of cfa_context_t
     49                void *context;
     50
     51                // address of top of storage
     52                void *top;
     53
     54                // whether or not the user allocated the stack
     55                bool userStack;
    6256        };
    6357
     
    6559
    6660        struct coroutine_desc {
    67                 struct coStack_t stack;                                                 // stack information of the coroutine
    68                 const char * name;                                                              // textual name for coroutine/task, initialized by uC++ generated code
    69                 int errno_;                                                                             // copy of global UNIX variable errno
    70                 enum coroutine_state state;                                             // current execution status for coroutine
    71                 struct coroutine_desc * starter;                                // first coroutine to resume this one
    72                 struct coroutine_desc * last;                                   // last coroutine to resume this one
     61                // stack information of the coroutine
     62                struct coStack_t stack;
     63
     64                // textual name for coroutine/task, initialized by uC++ generated code
     65                const char *name;
     66
     67                // copy of global UNIX variable errno
     68                int errno_;
     69
     70                // current execution status for coroutine
     71                enum coroutine_state state;
     72
     73                // first coroutine to resume this one
     74                struct coroutine_desc * starter;
     75
     76                // last coroutine to resume this one
     77                struct coroutine_desc * last;
    7378        };
    7479
  • src/libcfa/concurrency/kernel

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 23 17:08:20 2018
    13 // Update Count     : 3
     12// Last Modified On : Sat Jul 22 09:58:39 2017
     13// Update Count     : 2
    1414//
    1515
     
    1919
    2020#include "invoke.h"
    21 #include "time"
     21#include "bits/cfatime.h"
    2222
    2323extern "C" {
     
    4949
    5050        // Preemption rate on this cluster
    51         Duration preemption_rate;
     51        __cfa_time_t preemption_rate;
    5252};
    5353
    54 extern Duration default_preemption();
     54extern __cfa_time_t default_preemption();
    5555
    5656void ?{} (cluster & this);
  • src/libcfa/concurrency/kernel.c

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:26:11 2018
    13 // Update Count     : 23
     12// Last Modified On : Thu Feb  8 23:52:19 2018
     13// Update Count     : 5
    1414//
    1515
     
    5252// Global state
    5353
     54thread_local coroutine_desc * volatile this_coroutine;
     55thread_local thread_desc *    volatile this_thread;
     56thread_local processor *      volatile this_processor;
     57
    5458// volatile thread_local bool preemption_in_progress = 0;
    5559// volatile thread_local bool preemption_enabled = false;
    5660// volatile thread_local unsigned short disable_preempt_count = 1;
    5761
    58 thread_local struct KernelThreadData kernelThreadData = {
    59         NULL,
    60         NULL,
    61         NULL,
    62         { 1, false, false }
    63 };
     62volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 };
    6463
    6564//-----------------------------------------------------------------------------
     
    173172                terminate(&this);
    174173                verify(this.do_terminate);
    175                 verify(TL_GET( this_processor ) != &this);
     174                verify(this_processor != &this);
    176175                P( terminated );
    177                 verify(TL_GET( this_processor ) != &this);
     176                verify(this_processor != &this);
    178177                pthread_join( kernel_thread, NULL );
    179178        }
     
    214213                        if(readyThread)
    215214                        {
    216                                 verify( ! TL_GET( preemption_state ).enabled );
     215                                verify( !preemption_state.enabled );
    217216
    218217                                runThread(this, readyThread);
    219218
    220                                 verify( ! TL_GET( preemption_state ).enabled );
     219                                verify( !preemption_state.enabled );
    221220
    222221                                //Some actions need to be taken from the kernel
     
    250249
    251250        //Update global state
    252         TL_SET( this_thread, dst );
     251        this_thread = dst;
    253252
    254253        // Context Switch to the thread
     
    258257
    259258void returnToKernel() {
    260         coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner);
    261         coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );
     259        coroutine_desc * proc_cor = get_coroutine(this_processor->runner);
     260        coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
    262261        ThreadCtxSwitch(thrd_cor, proc_cor);
    263262}
     
    267266void finishRunning(processor * this) with( this->finish ) {
    268267        if( action_code == Release ) {
    269                 verify( ! TL_GET( preemption_state ).enabled );
     268                verify( !preemption_state.enabled );
    270269                unlock( *lock );
    271270        }
     
    274273        }
    275274        else if( action_code == Release_Schedule ) {
    276                 verify( ! TL_GET( preemption_state ).enabled );
     275                verify( !preemption_state.enabled );
    277276                unlock( *lock );
    278277                ScheduleThread( thrd );
    279278        }
    280279        else if( action_code == Release_Multi ) {
    281                 verify( ! TL_GET( preemption_state ).enabled );
     280                verify( !preemption_state.enabled );
    282281                for(int i = 0; i < lock_count; i++) {
    283282                        unlock( *locks[i] );
     
    308307void * CtxInvokeProcessor(void * arg) {
    309308        processor * proc = (processor *) arg;
    310         TL_SET( this_processor, proc );
    311         TL_SET( this_coroutine, NULL );
    312         TL_SET( this_thread, NULL );
    313         TL_GET( preemption_state ).enabled = false;
    314         TL_GET( preemption_state ).disable_count = 1;
     309        this_processor = proc;
     310        this_coroutine = NULL;
     311        this_thread = NULL;
     312        preemption_state.enabled = false;
     313        preemption_state.disable_count = 1;
    315314        // SKULLDUGGERY: We want to create a context for the processor coroutine
    316315        // which is needed for the 2-step context switch. However, there is no reason
     
    324323
    325324        //Set global state
    326         TL_SET( this_coroutine, get_coroutine(proc->runner) );
    327         TL_SET( this_thread, NULL );
     325        this_coroutine = get_coroutine(proc->runner);
     326        this_thread = NULL;
    328327
    329328        //We now have a proper context from which to schedule threads
     
    353352
    354353void kernel_first_resume(processor * this) {
    355         coroutine_desc * src = TL_GET( this_coroutine );
     354        coroutine_desc * src = this_coroutine;
    356355        coroutine_desc * dst = get_coroutine(this->runner);
    357356
    358         verify( ! TL_GET( preemption_state ).enabled );
     357        verify( !preemption_state.enabled );
    359358
    360359        create_stack(&dst->stack, dst->stack.size);
    361360        CtxStart(&this->runner, CtxInvokeCoroutine);
    362361
    363         verify( ! TL_GET( preemption_state ).enabled );
     362        verify( !preemption_state.enabled );
    364363
    365364        dst->last = src;
     
    370369
    371370        // set new coroutine that task is executing
    372         TL_SET( this_coroutine, dst );
     371        this_coroutine = dst;
    373372
    374373        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    387386        src->state = Active;
    388387
    389         verify( ! TL_GET( preemption_state ).enabled );
     388        verify( !preemption_state.enabled );
    390389}
    391390
     
    393392// Scheduler routines
    394393void ScheduleThread( thread_desc * thrd ) {
    395         // if( ! thrd ) return;
     394        // if( !thrd ) return;
    396395        verify( thrd );
    397396        verify( thrd->self_cor.state != Halted );
    398397
    399         verify( ! TL_GET( preemption_state ).enabled );
     398        verify( !preemption_state.enabled );
    400399
    401400        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    402401
    403         with( *TL_GET( this_processor )->cltr ) {
     402        with( *this_processor->cltr ) {
    404403                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    405404                append( ready_queue, thrd );
     
    407406        }
    408407
    409         verify( ! TL_GET( preemption_state ).enabled );
     408        verify( !preemption_state.enabled );
    410409}
    411410
    412411thread_desc * nextThread(cluster * this) with( *this ) {
    413         verify( ! TL_GET( preemption_state ).enabled );
     412        verify( !preemption_state.enabled );
    414413        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    415414        thread_desc * head = pop_head( ready_queue );
    416415        unlock( ready_queue_lock );
    417         verify( ! TL_GET( preemption_state ).enabled );
     416        verify( !preemption_state.enabled );
    418417        return head;
    419418}
     
    421420void BlockInternal() {
    422421        disable_interrupts();
    423         verify( ! TL_GET( preemption_state ).enabled );
     422        verify( !preemption_state.enabled );
    424423        returnToKernel();
    425         verify( ! TL_GET( preemption_state ).enabled );
     424        verify( !preemption_state.enabled );
    426425        enable_interrupts( __cfaabi_dbg_ctx );
    427426}
     
    429428void BlockInternal( __spinlock_t * lock ) {
    430429        disable_interrupts();
    431         TL_GET( this_processor )->finish.action_code = Release;
    432         TL_GET( this_processor )->finish.lock        = lock;
    433 
    434         verify( ! TL_GET( preemption_state ).enabled );
     430        this_processor->finish.action_code = Release;
     431        this_processor->finish.lock        = lock;
     432
     433        verify( !preemption_state.enabled );
    435434        returnToKernel();
    436         verify( ! TL_GET( preemption_state ).enabled );
     435        verify( !preemption_state.enabled );
    437436
    438437        enable_interrupts( __cfaabi_dbg_ctx );
     
    441440void BlockInternal( thread_desc * thrd ) {
    442441        disable_interrupts();
    443         TL_GET( this_processor )->finish.action_code = Schedule;
    444         TL_GET( this_processor )->finish.thrd        = thrd;
    445 
    446         verify( ! TL_GET( preemption_state ).enabled );
     442        this_processor->finish.action_code = Schedule;
     443        this_processor->finish.thrd        = thrd;
     444
     445        verify( !preemption_state.enabled );
    447446        returnToKernel();
    448         verify( ! TL_GET( preemption_state ).enabled );
     447        verify( !preemption_state.enabled );
    449448
    450449        enable_interrupts( __cfaabi_dbg_ctx );
     
    454453        assert(thrd);
    455454        disable_interrupts();
    456         TL_GET( this_processor )->finish.action_code = Release_Schedule;
    457         TL_GET( this_processor )->finish.lock        = lock;
    458         TL_GET( this_processor )->finish.thrd        = thrd;
    459 
    460         verify( ! TL_GET( preemption_state ).enabled );
     455        this_processor->finish.action_code = Release_Schedule;
     456        this_processor->finish.lock        = lock;
     457        this_processor->finish.thrd        = thrd;
     458
     459        verify( !preemption_state.enabled );
    461460        returnToKernel();
    462         verify( ! TL_GET( preemption_state ).enabled );
     461        verify( !preemption_state.enabled );
    463462
    464463        enable_interrupts( __cfaabi_dbg_ctx );
     
    467466void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    468467        disable_interrupts();
    469         TL_GET( this_processor )->finish.action_code = Release_Multi;
    470         TL_GET( this_processor )->finish.locks       = locks;
    471         TL_GET( this_processor )->finish.lock_count  = count;
    472 
    473         verify( ! TL_GET( preemption_state ).enabled );
     468        this_processor->finish.action_code = Release_Multi;
     469        this_processor->finish.locks       = locks;
     470        this_processor->finish.lock_count  = count;
     471
     472        verify( !preemption_state.enabled );
    474473        returnToKernel();
    475         verify( ! TL_GET( preemption_state ).enabled );
     474        verify( !preemption_state.enabled );
    476475
    477476        enable_interrupts( __cfaabi_dbg_ctx );
     
    480479void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    481480        disable_interrupts();
    482         TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;
    483         TL_GET( this_processor )->finish.locks       = locks;
    484         TL_GET( this_processor )->finish.lock_count  = lock_count;
    485         TL_GET( this_processor )->finish.thrds       = thrds;
    486         TL_GET( this_processor )->finish.thrd_count  = thrd_count;
    487 
    488         verify( ! TL_GET( preemption_state ).enabled );
     481        this_processor->finish.action_code = Release_Multi_Schedule;
     482        this_processor->finish.locks       = locks;
     483        this_processor->finish.lock_count  = lock_count;
     484        this_processor->finish.thrds       = thrds;
     485        this_processor->finish.thrd_count  = thrd_count;
     486
     487        verify( !preemption_state.enabled );
    489488        returnToKernel();
    490         verify( ! TL_GET( preemption_state ).enabled );
     489        verify( !preemption_state.enabled );
    491490
    492491        enable_interrupts( __cfaabi_dbg_ctx );
     
    494493
    495494void LeaveThread(__spinlock_t * lock, thread_desc * thrd) {
    496         verify( ! TL_GET( preemption_state ).enabled );
    497         TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;
    498         TL_GET( this_processor )->finish.lock        = lock;
    499         TL_GET( this_processor )->finish.thrd        = thrd;
     495        verify( !preemption_state.enabled );
     496        this_processor->finish.action_code = thrd ? Release_Schedule : Release;
     497        this_processor->finish.lock        = lock;
     498        this_processor->finish.thrd        = thrd;
    500499
    501500        returnToKernel();
     
    508507// Kernel boot procedures
    509508void kernel_startup(void) {
    510         verify( ! TL_GET( preemption_state ).enabled );
     509        verify( !preemption_state.enabled );
    511510        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    512511
     
    532531
    533532        //initialize the global state variables
    534         TL_SET( this_processor, mainProcessor );
    535         TL_SET( this_thread, mainThread );
    536         TL_SET( this_coroutine, &mainThread->self_cor );
     533        this_processor = mainProcessor;
     534        this_thread = mainThread;
     535        this_coroutine = &mainThread->self_cor;
    537536
    538537        // Enable preemption
     
    546545        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    547546        // mainThread is on the ready queue when this call is made.
    548         kernel_first_resume( TL_GET( this_processor ) );
     547        kernel_first_resume( this_processor );
    549548
    550549
     
    553552        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    554553
    555         verify( ! TL_GET( preemption_state ).enabled );
     554        verify( !preemption_state.enabled );
    556555        enable_interrupts( __cfaabi_dbg_ctx );
    557         verify( TL_GET( preemption_state ).enabled );
     556        verify( preemption_state.enabled );
    558557}
    559558
     
    561560        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    562561
    563         verify( TL_GET( preemption_state ).enabled );
     562        verify( preemption_state.enabled );
    564563        disable_interrupts();
    565         verify( ! TL_GET( preemption_state ).enabled );
     564        verify( !preemption_state.enabled );
    566565
    567566        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    603602
    604603        // first task to abort ?
    605         if ( ! kernel_abort_called ) {                  // not first task to abort ?
     604        if ( !kernel_abort_called ) {                   // not first task to abort ?
    606605                kernel_abort_called = true;
    607606                unlock( kernel_abort_lock );
     
    618617        }
    619618
    620         return TL_GET( this_thread );
     619        return this_thread;
    621620}
    622621
     
    627626        __cfaabi_dbg_bits_write( abort_text, len );
    628627
    629         if ( thrd != TL_GET( this_coroutine ) ) {
    630                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) );
     628        if ( thrd != this_coroutine ) {
     629                len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
    631630                __cfaabi_dbg_bits_write( abort_text, len );
    632631        }
     
    637636
    638637int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    639         return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
     638        return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2;
    640639}
    641640
     
    667666        if ( count < 0 ) {
    668667                // queue current task
    669                 append( waiting, (thread_desc *)TL_GET( this_thread ) );
     668                append( waiting, (thread_desc *)this_thread );
    670669
    671670                // atomically release spin lock and block
  • src/libcfa/concurrency/kernel_private.h

    rca37445 r9d1e3f7  
    1010// Created On       : Mon Feb 13 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 29 14:06:40 2018
    13 // Update Count     : 3
     12// Last Modified On : Sat Jul 22 09:58:09 2017
     13// Update Count     : 2
    1414//
    1515
     
    6666extern event_kernel_t * event_kernel;
    6767
    68 //extern thread_local coroutine_desc * volatile this_coroutine;
    69 //extern thread_local thread_desc *    volatile this_thread;
    70 //extern thread_local processor *      volatile this_processor;
     68extern thread_local coroutine_desc * volatile this_coroutine;
     69extern thread_local thread_desc *    volatile this_thread;
     70extern thread_local processor *      volatile this_processor;
    7171
    7272// extern volatile thread_local bool preemption_in_progress;
  • src/libcfa/concurrency/monitor.c

    rca37445 r9d1e3f7  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 14:30:26 2018
    13 // Update Count     : 9
     12// Last Modified On : Fri Feb 16 14:49:53 2018
     13// Update Count     : 5
    1414//
    1515
     
    8585                // Lock the monitor spinlock
    8686                lock( this->lock __cfaabi_dbg_ctx2 );
    87                 thread_desc * thrd = TL_GET( this_thread );
     87                thread_desc * thrd = this_thread;
    8888
    8989                __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner);
     
    134134                // Lock the monitor spinlock
    135135                lock( this->lock __cfaabi_dbg_ctx2 );
    136                 thread_desc * thrd = TL_GET( this_thread );
     136                thread_desc * thrd = this_thread;
    137137
    138138                __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner);
     
    168168
    169169                        // Create the node specific to this wait operation
    170                         wait_ctx_primed( TL_GET( this_thread ), 0 )
     170                        wait_ctx_primed( this_thread, 0 )
    171171
    172172                        // Some one else has the monitor, wait for him to finish and then run
     
    179179                        __cfaabi_dbg_print_safe( "Kernel :  blocking \n" );
    180180
    181                         wait_ctx( TL_GET( this_thread ), 0 )
     181                        wait_ctx( this_thread, 0 )
    182182                        this->dtor_node = &waiter;
    183183
     
    199199                lock( this->lock __cfaabi_dbg_ctx2 );
    200200
    201                 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", TL_GET( this_thread ), this, this->owner);
    202 
    203                 verifyf( TL_GET( this_thread ) == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", TL_GET( this_thread ), this->owner, this->recursion, this );
     201                __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner);
     202
     203                verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this );
    204204
    205205                // Leaving a recursion level, decrement the counter
     
    227227        void __leave_dtor_monitor_desc( monitor_desc * this ) {
    228228                __cfaabi_dbg_debug_do(
    229                         if( TL_GET( this_thread ) != this->owner ) {
    230                                 abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);
     229                        if( this_thread != this->owner ) {
     230                                abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
    231231                        }
    232232                        if( this->recursion != 1 ) {
     
    297297
    298298        // Save previous thread context
    299         this.prev = TL_GET( this_thread )->monitors;
     299        this.prev = this_thread->monitors;
    300300
    301301        // Update thread context (needed for conditions)
    302         (TL_GET( this_thread )->monitors){m, count, func};
     302        (this_thread->monitors){m, count, func};
    303303
    304304        // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count);
     
    322322
    323323        // Restore thread context
    324         TL_GET( this_thread )->monitors = this.prev;
     324        this_thread->monitors = this.prev;
    325325}
    326326
     
    332332
    333333        // Save previous thread context
    334         this.prev = TL_GET( this_thread )->monitors;
     334        this.prev = this_thread->monitors;
    335335
    336336        // Update thread context (needed for conditions)
    337         (TL_GET( this_thread )->monitors){m, 1, func};
     337        (this_thread->monitors){m, 1, func};
    338338
    339339        __enter_monitor_dtor( this.m, func );
     
    346346
    347347        // Restore thread context
    348         TL_GET( this_thread )->monitors = this.prev;
     348        this_thread->monitors = this.prev;
    349349}
    350350
     
    386386
    387387        // Create the node specific to this wait operation
    388         wait_ctx( TL_GET( this_thread ), user_info );
     388        wait_ctx( this_thread, user_info );
    389389
    390390        // Append the current wait operation to the ones already queued on the condition
     
    425425        //Some more checking in debug
    426426        __cfaabi_dbg_debug_do(
    427                 thread_desc * this_thrd = TL_GET( this_thread );
     427                thread_desc * this_thrd = this_thread;
    428428                if ( this.monitor_count != this_thrd->monitors.size ) {
    429429                        abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size );
     
    473473
    474474        // Create the node specific to this wait operation
    475         wait_ctx_primed( TL_GET( this_thread ), 0 )
     475        wait_ctx_primed( this_thread, 0 )
    476476
    477477        //save contexts
     
    566566
    567567                                // Create the node specific to this wait operation
    568                                 wait_ctx_primed( TL_GET( this_thread ), 0 );
     568                                wait_ctx_primed( this_thread, 0 );
    569569
    570570                                // Save monitor states
     
    612612
    613613        // Create the node specific to this wait operation
    614         wait_ctx_primed( TL_GET( this_thread ), 0 );
     614        wait_ctx_primed( this_thread, 0 );
    615615
    616616        monitor_save;
     
    618618
    619619        for( __lock_size_t i = 0; i < count; i++) {
    620                 verify( monitors[i]->owner == TL_GET( this_thread ) );
     620                verify( monitors[i]->owner == this_thread );
    621621        }
    622622
     
    812812
    813813static inline void brand_condition( condition & this ) {
    814         thread_desc * thrd = TL_GET( this_thread );
     814        thread_desc * thrd = this_thread;
    815815        if( !this.monitors ) {
    816816                // __cfaabi_dbg_print_safe( "Branding\n" );
  • src/libcfa/concurrency/preemption.c

    rca37445 r9d1e3f7  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 13:52:39 2018
    13 // Update Count     : 36
     12// Last Modified On : Fri Feb  9 16:38:13 2018
     13// Update Count     : 14
    1414//
    1515
     
    2323}
    2424
     25#include "bits/cfatime.h"
    2526#include "bits/signal.h"
    2627
    2728#if !defined(__CFA_DEFAULT_PREEMPTION__)
    28 #define __CFA_DEFAULT_PREEMPTION__ 10`ms
     29#define __CFA_DEFAULT_PREEMPTION__ 10`cfa_ms
    2930#endif
    3031
    31 Duration default_preemption() __attribute__((weak)) {
     32__cfa_time_t default_preemption() __attribute__((weak)) {
    3233        return __CFA_DEFAULT_PREEMPTION__;
    3334}
     
    7778
    7879// Get next expired node
    79 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
     80static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_t currtime ) {
    8081        if( !alarms->head ) return NULL;                          // If no alarms return null
    8182        if( alarms->head->alarm >= currtime ) return NULL;        // If alarms head not expired return null
     
    8788        alarm_node_t * node = NULL;                     // Used in the while loop but cannot be declared in the while condition
    8889        alarm_list_t * alarms = &event_kernel->alarms;  // Local copy for ease of reading
    89         Time currtime = __kernel_get_time();                    // Check current time once so we everything "happens at once"
     90        __cfa_time_t currtime = __kernel_get_time();    // Check current time once so we everything "happens at once"
    9091
    9192        //Loop throught every thing expired
     
    101102
    102103                // Check if this is a periodic alarm
    103                 Duration period = node->period;
     104                __cfa_time_t period = node->period;
    104105                if( period > 0 ) {
    105106                        node->alarm = currtime + period;    // Alarm is periodic, add currtime to it (used cached current time)
     
    116117
    117118// Update the preemption of a processor and notify interested parties
    118 void update_preemption( processor * this, Duration duration ) {
     119void update_preemption( processor * this, __cfa_time_t duration ) {
    119120        alarm_node_t * alarm = this->preemption_alarm;
    120121
    121122        // Alarms need to be enabled
    122         if ( duration > 0 && ! alarm->set ) {
     123        if ( duration > 0 && !alarm->set ) {
    123124                alarm->alarm = __kernel_get_time() + duration;
    124125                alarm->period = duration;
    125126                register_self( alarm );
    126127        }
    127         // Zero duration but alarm is set
     128        // Zero duraction but alarm is set
    128129        else if ( duration == 0 && alarm->set ) {
    129130                unregister_self( alarm );
     
    149150        // Disable interrupts by incrementing the counter
    150151        void disable_interrupts() {
    151                 TL_GET( preemption_state ).enabled = false;
    152                 __attribute__((unused)) unsigned short new_val = TL_GET( preemption_state ).disable_count + 1;
    153                 TL_GET( preemption_state ).disable_count = new_val;
     152                preemption_state.enabled = false;
     153                __attribute__((unused)) unsigned short new_val = preemption_state.disable_count + 1;
     154                preemption_state.disable_count = new_val;
    154155                verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
    155156        }
     
    158159        // If counter reaches 0, execute any pending CtxSwitch
    159160        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    160                 processor   * proc = TL_GET( this_processor ); // Cache the processor now since interrupts can start happening after the atomic add
    161                 thread_desc * thrd = TL_GET( this_thread );       // Cache the thread now since interrupts can start happening after the atomic add
    162 
    163                 unsigned short prev = TL_GET( preemption_state ).disable_count;
    164                 TL_GET( preemption_state ).disable_count -= 1;
     161                processor   * proc = this_processor;      // Cache the processor now since interrupts can start happening after the atomic add
     162                thread_desc * thrd = this_thread;         // Cache the thread now since interrupts can start happening after the atomic add
     163
     164                unsigned short prev = preemption_state.disable_count;
     165                preemption_state.disable_count -= 1;
    165166                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
    166167
    167168                // Check if we need to prempt the thread because an interrupt was missed
    168169                if( prev == 1 ) {
    169                         TL_GET( preemption_state ).enabled = true;
     170                        preemption_state.enabled = true;
    170171                        if( proc->pending_preemption ) {
    171172                                proc->pending_preemption = false;
     
    181182        // Don't execute any pending CtxSwitch even if counter reaches 0
    182183        void enable_interrupts_noPoll() {
    183                 unsigned short prev = TL_GET( preemption_state ).disable_count;
    184                 TL_GET( preemption_state ).disable_count -= 1;
     184                unsigned short prev = preemption_state.disable_count;
     185                preemption_state.disable_count -= 1;
    185186                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    186187                if( prev == 1 ) {
    187                         TL_GET( preemption_state ).enabled = true;
     188                        preemption_state.enabled = true;
    188189                }
    189190        }
     
    235236// If false : preemption is unsafe and marked as pending
    236237static inline bool preemption_ready() {
    237         bool ready = TL_GET( preemption_state ).enabled && !TL_GET( preemption_state ).in_progress; // Check if preemption is safe
    238         TL_GET( this_processor )->pending_preemption = !ready;                  // Adjust the pending flag accordingly
     238        bool ready = preemption_state.enabled && !preemption_state.in_progress; // Check if preemption is safe
     239        this_processor->pending_preemption = !ready;                        // Adjust the pending flag accordingly
    239240        return ready;
    240241}
     
    250251
    251252        // Start with preemption disabled until ready
    252         TL_GET( preemption_state ).enabled = false;
    253         TL_GET( preemption_state ).disable_count = 1;
     253        preemption_state.enabled = false;
     254        preemption_state.disable_count = 1;
    254255
    255256        // Initialize the event kernel
     
    290291// Used by thread to control when they want to receive preemption signals
    291292void ?{}( preemption_scope & this, processor * proc ) {
    292         (this.alarm){ proc, (Time){ 0 }, 0`s };
     293        (this.alarm){ proc, 0`cfa_s, 0`cfa_s };
    293294        this.proc = proc;
    294295        this.proc->preemption_alarm = &this.alarm;
     
    300301        disable_interrupts();
    301302
    302         update_preemption( this.proc, 0`s );
     303        update_preemption( this.proc, 0`cfa_s );
    303304}
    304305
     
    316317        // before the kernel thread has even started running. When that happens an iterrupt
    317318        // we a null 'this_processor' will be caught, just ignore it.
    318         if(!TL_GET( this_processor )) return;
     319        if(!this_processor) return;
    319320
    320321        choose(sfp->si_value.sival_int) {
    321322                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    322                 case PREEMPT_TERMINATE: verify(TL_GET( this_processor )->do_terminate);
     323                case PREEMPT_TERMINATE: verify(this_processor->do_terminate);
    323324                default:
    324325                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    330331        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    331332
    332         TL_GET( preemption_state ).in_progress = true;  // Sync flag : prevent recursive calls to the signal handler
     333        preemption_state.in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
    333334        signal_unblock( SIGUSR1 );                          // We are about to CtxSwitch out of the signal handler, let other handlers in
    334         TL_GET( preemption_state ).in_progress = false; // Clear the in progress flag
     335        preemption_state.in_progress = false;                    // Clear the in progress flag
    335336
    336337        // Preemption can occur here
    337338
    338         BlockInternal( (thread_desc*)TL_GET( this_thread ) ); // Do the actual CtxSwitch
     339        BlockInternal( (thread_desc*)this_thread );        // Do the actual CtxSwitch
    339340}
    340341
  • src/libcfa/concurrency/preemption.h

    rca37445 r9d1e3f7  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 23 17:18:53 2018
    13 // Update Count     : 2
     12// Last Modified On : Fri Jul 21 22:34:25 2017
     13// Update Count     : 1
    1414//
    1515
     
    2121void kernel_start_preemption();
    2222void kernel_stop_preemption();
    23 void update_preemption( processor * this, Duration duration );
     23void update_preemption( processor * this, __cfa_time_t duration );
    2424void tick_preemption();
    2525
  • src/libcfa/concurrency/thread

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 29 14:07:11 2018
    13 // Update Count     : 4
     12// Last Modified On : Sat Jul 22 09:59:40 2017
     13// Update Count     : 3
    1414//
    1515
     
    5252}
    5353
    54 //extern thread_local thread_desc * volatile this_thread;
     54extern thread_local thread_desc * volatile this_thread;
    5555
    5656forall( dtype T | is_thread(T) )
  • src/libcfa/concurrency/thread.c

    rca37445 r9d1e3f7  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 17:19:52 2018
    13 // Update Count     : 8
     12// Last Modified On : Fri Jul 21 22:34:46 2017
     13// Update Count     : 1
    1414//
    1515
     
    2626}
    2727
    28 //extern volatile thread_local processor * this_processor;
     28extern volatile thread_local processor * this_processor;
    2929
    3030//-----------------------------------------------------------------------------
     
    7575        coroutine_desc* thrd_c = get_coroutine(this);
    7676        thread_desc   * thrd_h = get_thread   (this);
    77         thrd_c->last = TL_GET( this_coroutine );
     77        thrd_c->last = this_coroutine;
    7878
    7979        // __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h);
     
    8181        disable_interrupts();
    8282        create_stack(&thrd_c->stack, thrd_c->stack.size);
    83         TL_SET( this_coroutine, thrd_c );
     83        this_coroutine = thrd_c;
    8484        CtxStart(&this, CtxInvokeThread);
    8585        assert( thrd_c->last->stack.context );
     
    9292extern "C" {
    9393        void __finish_creation(void) {
    94                 coroutine_desc* thrd_c = TL_GET( this_coroutine );
     94                coroutine_desc* thrd_c = this_coroutine;
    9595                ThreadCtxSwitch( thrd_c, thrd_c->last );
    9696        }
     
    9898
    9999void yield( void ) {
    100         verify( TL_GET( preemption_state ).enabled );
    101         BlockInternal( TL_GET( this_thread ) );
    102         verify( TL_GET( preemption_state ).enabled );
     100        verify( preemption_state.enabled );
     101        BlockInternal( this_thread );
     102        verify( preemption_state.enabled );
    103103}
    104104
     
    116116        // set new coroutine that the processor is executing
    117117        // and context switch to it
    118         TL_SET( this_coroutine, dst );
     118        this_coroutine = dst;
    119119        assert( src->stack.context );
    120120        CtxSwitch( src->stack.context, dst->stack.context );
    121         TL_SET( this_coroutine, src );
     121        this_coroutine = src;
    122122
    123123        // set state of new coroutine to active
  • src/libcfa/time

    rca37445 r9d1e3f7  
    11//
    2 // Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
     2// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    33//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // time --
     7// calendar --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Mar 14 23:18:57 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 13:10:23 2018
    13 // Update Count     : 616
     12// Last Modified On : Thu Mar 22 17:11:19 2018
     13// Update Count     : 495
    1414//
    1515
     
    1919// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r5.html#refcc
    2020
    21 #include <time.h>                                                                               // timespec
     21#include <time.h>
    2222extern "C" {
    23 #include <sys/time.h>                                                                   // timeval
     23#include <sys/time.h>
     24int snprintf( char * buf, size_t size, const char * fmt, ... );
    2425}
    25 #include <iostream>                                                                             // istype/ostype
    26 
    27 enum { TIMEGRAN = 1_000_000_000LL };                                    // nanosecond granularity, except for timeval
    28 
    29 
    30 //######################### Duration #########################
    31 
    32 struct Duration {                                                                               // private
    33         int64_t tv;                                                                                     // nanoseconds
    34 }; // Duration
    35 
    36 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
    37 static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; }
    38 
    39 static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; }
    40 static inline Duration ?=?( Duration & dur, zero_t ) { return dur{ 0 }; }
    41 
    42 static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; }
    43 static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
    44 static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    45 
    46 static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
    47 static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
    48 static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    49 
    50 static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
    51 static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
    52 static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
    53 
    54 static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
    55 static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
    56 static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
    57 static inline double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; }
    58 
    59 static inline Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; }
    60 static inline Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; }
    61 
    62 static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
    63 static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
    64 static inline _Bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv <  rhs.tv; }
    65 static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
    66 static inline _Bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv >  rhs.tv; }
    67 static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
    68 
    69 static inline _Bool ?==?( Duration lhs, zero_t ) { return lhs.tv == 0; }
    70 static inline _Bool ?!=?( Duration lhs, zero_t ) { return lhs.tv != 0; }
    71 static inline _Bool ?<? ( Duration lhs, zero_t ) { return lhs.tv <  0; }
    72 static inline _Bool ?<=?( Duration lhs, zero_t ) { return lhs.tv <= 0; }
    73 static inline _Bool ?>? ( Duration lhs, zero_t ) { return lhs.tv >  0; }
    74 static inline _Bool ?>=?( Duration lhs, zero_t ) { return lhs.tv >= 0; }
    75 
    76 static inline Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; }
    77 
    78 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur );
    79 
    80 static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
    81 static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000_000LL) }; }
    82 static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000LL) }; }
    83 static inline Duration ?`s( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; }
    84 static inline Duration ?`s( double sec ) { return (Duration)@{ sec * TIMEGRAN }; }
    85 static inline Duration ?`m( int64_t min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; }
    86 static inline Duration ?`m( double min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; }
    87 static inline Duration ?`h( int64_t hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; }
    88 static inline Duration ?`h( double hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; }
    89 static inline Duration ?`d( int64_t days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; }
    90 static inline Duration ?`d( double days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; }
    91 static inline Duration ?`w( int64_t weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
    92 static inline Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
    93 
    94 static inline int64_t ?`ns( Duration dur ) { return dur.tv; }
    95 static inline int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); }
    96 static inline int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); }
    97 static inline int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; }
    98 static inline int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); }
    99 static inline int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); }
    100 static inline int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); }
    101 static inline int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
    102 
    103 
    104 //######################### C timeval #########################
    105 
     26#include <fstream>
     27
     28enum {
     29        CLOCKGRAN = 15_000_000L,                                                        // ALWAYS in nanoseconds, MUST BE less than 1 second
     30        TIMEGRAN = 1_000_000_000L                                                       // nanosecond granularity, except for timeval
     31};
     32
     33
     34#if defined( REALTIME_POSIX )
     35#define tv_XSEC tv_nsec
     36#else
     37#define tv_XSEC tv_usec
     38#endif
     39
     40
     41#if defined( __linux__ )
     42// fake a few things
     43#define CLOCK_REALTIME  0                                                               // real (clock on the wall) time
     44#endif
     45
     46// conversions for existing time types
    10647static inline void ?{}( timeval & t ) {}
     48static inline void ?{}( timeval & t, time_t sec ) { t.tv_sec = sec; t.tv_usec = 0; }
    10749static inline void ?{}( timeval & t, time_t sec, suseconds_t usec ) { t.tv_sec = sec; t.tv_usec = usec; }
    108 static inline void ?{}( timeval & t, time_t sec ) { t{ sec, 0 }; }
    109 static inline void ?{}( timeval & t, zero_t ) { t{ 0, 0 }; }
    110 static inline timeval ?=?( timeval & t, zero_t ) { return t{ 0 }; }
    111 static inline timeval ?+?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_usec + rhs.tv_usec }; }
    112 static inline timeval ?-?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_usec - rhs.tv_usec }; }
    113 static inline _Bool ?==?( timeval lhs, timeval rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_usec == rhs.tv_usec; }
    114 static inline _Bool ?!=?( timeval lhs, timeval rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_usec != rhs.tv_usec; }
    115 
    116 
    117 //######################### C timespec #########################
    11850
    11951static inline void ?{}( timespec & t ) {}
     52static inline void ?{}( timespec & t, time_t sec ) { t.tv_sec = sec; t.tv_nsec = 0; }
    12053static inline void ?{}( timespec & t, time_t sec, __syscall_slong_t nsec ) { t.tv_sec = sec; t.tv_nsec = nsec; }
    121 static inline void ?{}( timespec & t, time_t sec ) { t{ sec, 0}; }
    122 static inline void ?{}( timespec & t, zero_t ) { t{ 0, 0 }; }
    123 static inline timespec ?=?( timespec & t, zero_t ) { return t{ 0 }; }
    124 static inline timespec ?+?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec }; }
    125 static inline timespec ?-?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec }; }
    126 static inline _Bool ?==?( timespec lhs, timespec rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec; }
    127 static inline _Bool ?!=?( timespec lhs, timespec rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_nsec != rhs.tv_nsec; }
    128 
    129 
    130 //######################### C itimerval #########################
    131 
    132 static inline void ?{}( itimerval & itv, Duration alarm ) with( itv ) {
    133         // itimerval contains durations but but uses time data-structure timeval.
    134         it_value{ alarm`s, (alarm % 1`s)`us };                          // seconds, microseconds
    135         it_interval{ 0 };                                                                       // 0 seconds, 0 microseconds
    136 } // itimerval
    137 
    138 static inline void ?{}( itimerval & itv, Duration alarm, Duration interval ) with( itv ) {
    139         // itimerval contains durations but but uses time data-structure timeval.
    140         it_value{ alarm`s, (alarm % 1`s)`us };                          // seconds, microseconds
    141         it_interval{ interval`s, interval`us };                         // seconds, microseconds
    142 } // itimerval
    143 
    144 
    145 //######################### C time #########################
    14654
    14755static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; }
     
    15361
    15462
     63//######################### Duration #########################
     64
     65struct Duration {
     66        int64_t tv;
     67};
     68
     69static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
     70static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; }
     71
     72static inline void ?{}( Duration & dur, timeval t ) with( dur ) {
     73        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;
     74} // Duration
     75
     76static inline void ?{}( Duration & dur, timespec t ) with( dur ) {
     77        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
     78} // Duration
     79
     80static inline Duration ?=?( Duration & dur, timeval t ) with( dur ) {
     81        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;
     82        return dur;
     83} // ?=?
     84
     85static inline Duration ?=?( Duration & dur, timespec t ) with( dur ) {
     86        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
     87        return dur;
     88} // ?=? timespec
     89
     90static inline void ?{}( timeval & t, Duration dur ) with( dur ) {
     91        t.tv_sec = tv / TIMEGRAN;                                                       // seconds
     92        t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1000000L ); // microseconds
     93} // ?{}
     94
     95static inline void ?{}( timespec & t, Duration dur ) with( dur ) {
     96        t.tv_sec = tv / TIMEGRAN;                                                       // seconds
     97        t.tv_nsec = tv % TIMEGRAN;                                                      // nanoseconds
     98} // Timespec
     99
     100static inline int64_t nsecs( Duration dur ) with( dur ) { return tv; }
     101
     102static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; }
     103static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
     104static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
     105
     106static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
     107static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
     108static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
     109
     110static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
     111static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
     112static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
     113
     114static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
     115static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
     116static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
     117
     118static inline Duration ?%?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv % rhs }; }
     119static inline int64_t ?%?( int64_t lhs, Duration rhs ) { return lhs % (rhs.tv / TIMEGRAN); }
     120static inline int64_t ?%?( Duration lhs, Duration rhs ) { return lhs.tv % rhs.tv; }
     121
     122static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
     123static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
     124static inline _Bool ?<?( Duration lhs, Duration rhs ) { return lhs.tv < rhs.tv; }
     125static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
     126static inline _Bool ?>?( Duration lhs, Duration rhs ) { return lhs.tv > rhs.tv; }
     127static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
     128
     129static inline Duration abs( Duration lhs ) {
     130        return lhs.tv >= 0 ? lhs : -lhs;
     131} // abs
     132
     133static inline forall( dtype ostype | ostream( ostype ) )
     134ostype & ?|?( ostype & os, Duration dur ) with( dur ) {
     135        os | tv / TIMEGRAN;
     136        char buf[16];
     137        snprintf( buf, 16, "%09ld", ((tv < 0 ? -tv : tv) % TIMEGRAN) );
     138        int i;
     139        for ( i = 8; i >= 0 && buf[i] == '0' ; i -= 1 );        // find least significant digit
     140        if ( i != -1 ) { buf[i + 1] = '\0';     os | '.' | buf; }
     141        return os;
     142}
     143
     144static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
     145static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000l) }; }
     146static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000_000l) }; }
     147static inline Duration ?`s ( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; }
     148static inline Duration ?`s ( double  sec ) { return (Duration)@{ sec * TIMEGRAN }; }
     149static inline Duration ?`m ( int64_t min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }
     150static inline Duration ?`m ( double  min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }
     151static inline Duration ?`h ( int64_t hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }
     152static inline Duration ?`h ( double  hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }
     153static inline Duration ?`d ( int64_t days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }
     154static inline Duration ?`d ( double  days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }
     155static inline Duration ?`w ( int64_t weeks ) { return (Duration)@{ weeks * (7L * 24L * 3600L * TIMEGRAN) }; }
     156static inline Duration ?`f ( int64_t fortnight ) { return (Duration)@{ fortnight * (14L * 24L * 3600L * TIMEGRAN) }; }
     157
     158static inline int64_t ?`s ( Duration dur ) { return dur.tv / TIMEGRAN; }
     159static inline int64_t ?`m ( Duration dur ) { return dur.tv / (60L * TIMEGRAN); }
     160static inline int64_t ?`h ( Duration dur ) { return dur.tv / (3600L * TIMEGRAN); }
     161static inline int64_t ?`d ( Duration dur ) { return dur.tv / (24L * 3600L * TIMEGRAN); }
     162static inline int64_t ?`w ( Duration dur ) { return dur.tv / (7L * 24L * 3600L * TIMEGRAN); }
     163static inline int64_t ?`f ( Duration dur ) { return dur.tv / (14L * 24L * 3600L * TIMEGRAN); }
     164
     165
    155166//######################### Time #########################
    156167
    157 struct Time {                                                                                   // private
    158         uint64_t tv;                                                                            // nanoseconds since UNIX epoch
    159 }; // Time
    160 
    161 static inline void ?{}( Time & t ) with( t ) { tv = 0; } // fast
    162 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 ); // slow
    163 
    164 static inline void ?{}( Time & t, zero_t ) { t.tv = 0; }
    165 static inline Time ?=?( Time & t, zero_t ) { return t{ 0 }; }
     168
     169struct Time {
     170        uint64_t tv;
     171};
     172
     173#ifdef __CFA_DEBUG__
     174#define CreateFmt "Attempt to create Time( year=%d, month=%d, day=%d, hour=%d, min=%d, sec=%d, nsec=%d ), " \
     175        "which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038."
     176#endif // __CFA_DEBUG__
     177
     178void mktime( Time & time, int year, int month, int day, int hour, int min, int sec, int nsec ) with( time ) {
     179        tm tm;
     180
     181//      tzset();                                                                                        // initialize time global variables
     182        tm.tm_isdst = -1;                                                                       // let mktime determine if alternate timezone is in effect
     183        tm.tm_year = year - 1900;                                                       // mktime uses 1900 as its starting point
     184        tm.tm_mon = month - 1;
     185        tm.tm_mday = day;                                                                       // mktime uses range 1-31
     186        tm.tm_hour = hour;
     187        tm.tm_min = min;
     188        tm.tm_sec = sec;
     189        time_t epochsec = mktime( &tm );
     190#ifdef __CFA_DEBUG__
     191        if ( epochsec == (time_t)-1 ) {
     192                abort( CreateFmt, year, month, day, hour, min, sec, nsec );
     193        } // if
     194#endif // __CFA_DEBUG__
     195        tv = (int64_t)(epochsec) * TIMEGRAN + nsec;                     // convert to nanoseconds
     196#ifdef __CFA_DEBUG__
     197        if ( tv > 2147483647LL * TIMEGRAN ) {                           // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
     198                abort( CreateFmt, year, month, day, hour, min, sec, nsec );
     199        } // if
     200#endif // __CFA_DEBUG__
     201} // mktime
     202
     203static inline void ?{}( Time & t ) with( t ) {
     204        tv = 0;
     205} // Time
     206
     207// These two constructors must not call mktime because it calls malloc. The malloc calls lead to recursion problems
     208// because Time values are created from the sigalrm handler in composing the next context switch event.
     209
     210static inline void ?{}( Time & t, int sec ) with( t ) {
     211#ifdef __CFA_DEBUG__
     212        if ( tv < 0 || tv > 2147483647LL ) {                            // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
     213            abort( CreateFmt, 1970, 0, 0, 0, 0, sec, 0 );
     214        } // if
     215#endif // __CFA_DEBUG__
     216        tv = (int64_t)sec * TIMEGRAN;
     217} // Time
     218
     219static inline void ?{}( Time & t, int sec, int nsec ) with( t ) {
     220#ifdef __U_DEBUG__
     221        if ( tv < 0 || tv > 2147483647LL || nsec < 0 ) {        // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038.
     222            abort( CreateFmt, 1970, 0, 0, 0, 0, sec, nsec );
     223        } // if
     224#endif // __U_DEBUG__
     225        tv = (int64_t)sec * TIMEGRAN + nsec;
     226} // Time
     227
     228static inline void ?{}( Time & time, int min, int sec, long int nsec ) {
     229        mktime( time, 1970, 1, 1, 0, min, sec, nsec );
     230} // Time
     231
     232static inline void ?{}( Time & time, int hour, int min, int sec, long int nsec ) {
     233        mktime( time, 1970, 1, 1, hour, min, sec, nsec );
     234} // Time
     235
     236static inline void ?{}( Time & time, int day, int hour, int min, int sec, long int nsec ) {
     237        mktime( time, 1970, 1, day, hour, min, sec, nsec );
     238} // Time
     239
     240static inline void ?{}( Time & time, int month, int day, int hour, int min, int sec, long int nsec ) {
     241        mktime( time, 1970, month, day, hour, min, sec, nsec );
     242} // Time
     243
     244static inline void ?{}( Time & time, int year, int month, int day, int hour, int min, int sec, long int nsec ) {
     245        mktime( time, year, month, day, hour, min, sec, nsec );
     246} // Time
    166247
    167248static inline void ?{}( Time & time, timeval t ) with( time ) {
     
    169250} // Time
    170251
     252static inline void ?{}( Time & time, timespec t ) with( time ) {
     253        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
     254} // Time
     255
    171256static inline Time ?=?( Time & time, timeval t ) with( time ) {
    172         tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
     257        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;
    173258        return time;
    174259} // ?=?
    175 
    176 static inline void ?{}( Time & time, timespec t ) with( time ) {
    177         tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
    178 } // Time
    179260
    180261static inline Time ?=?( Time & time, timespec t ) with( time ) {
     
    182263        return time;
    183264} // ?=?
     265
     266static inline void ?{}( timeval & t, Time time ) with( time ) {
     267        t.tv_sec = tv / TIMEGRAN;                                                       // seconds
     268        t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1_000_000L ); // microseconds
     269} // ?{}
     270
     271static inline void ?{}( timespec & t, Time time ) with( time ) {
     272        t.tv_sec = tv / TIMEGRAN;                                                       // seconds
     273        t.tv_nsec = tv % TIMEGRAN;                                                      // nanoseconds
     274} // ?{}
     275
     276static inline int64_t nsec( Time time ) with( time ) { return tv; }
    184277
    185278static inline Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; }
     
    197290static inline _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; }
    198291
    199 char * yy_mm_dd( Time time, char * buf );
    200 static inline char * ?`ymd( Time time, char * buf ) {   // short form
    201         return yy_mm_dd( time, buf );
    202 } // ymd
    203 
    204 char * mm_dd_yy( Time time, char * buf );
    205 static inline char * ?`mdy( Time time, char * buf ) {   // short form
    206         return mm_dd_yy( time, buf );
    207 } // mdy
    208 
    209 char * dd_mm_yy( Time time, char * buf );
    210 static inline char * ?`dmy( Time time, char * buf ) {   // short form
    211         return dd_mm_yy( time, buf );;
    212 } // dmy
    213 
    214 size_t strftime( char * buf, size_t size, const char * fmt, Time time );
    215 
    216 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time );
    217 
    218 //------------------------- timeval (cont) -------------------------
    219 
    220 static inline void ?{}( timeval & t, Time time ) with( t, time ) {
    221         tv_sec = tv / TIMEGRAN;                                                         // seconds
    222         tv_usec = tv % TIMEGRAN / (TIMEGRAN / 1_000_000LL);     // microseconds
    223 } // ?{}
    224 
    225 //------------------------- timespec (cont) -------------------------
    226 
    227 static inline void ?{}( timespec & t, Time time ) with( t, time ) {
    228         tv_sec = tv / TIMEGRAN;                                                         // seconds
    229         tv_nsec = tv % TIMEGRAN;                                                        // nanoseconds
    230 } // ?{}
    231 
     292static inline char * yymmd( Time time, char * buf ) with( time ) {
     293        tm tm;
     294        time_t s = tv / TIMEGRAN;
     295        gmtime_r( &s, &tm );
     296        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_year % 99, tm.tm_mon, tm.tm_mday );
     297        return buf;
     298} // yymmd
     299
     300static inline char * mmyyd( Time time, char * buf ) with( time ) {
     301        tm tm;
     302        time_t s = tv / TIMEGRAN;
     303        gmtime_r( &s, &tm );
     304        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mon, tm.tm_year % 99, tm.tm_mday );
     305        return buf;
     306} // yymmd
     307
     308static inline char * dmmyy( Time time, char * buf ) with( time ) {
     309        tm tm;
     310        time_t s = tv / TIMEGRAN;
     311        gmtime_r( &s, &tm );
     312        snprintf( buf, 9, "%02d/%02d/%02d", tm.tm_mday, tm.tm_mon, tm.tm_year % 99 );
     313        return buf;
     314} // yymmd
     315
     316static inline forall( dtype ostype | ostream( ostype ) )
     317ostype & ?|?( ostype & os, Time time ) with( time ) {
     318        char buf[32];                                                                           // at least 26
     319        time_t s = tv / TIMEGRAN;
     320        tm tm;
     321        gmtime_r( &s, &tm );                                                            // ctime_r adjusts for timezone
     322        asctime_r( &tm, (char *)&buf );
     323        buf[24] = '\0';                                                                         // remove trailing '\n'
     324        long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN;
     325        if ( ns == 0 ) {
     326                os | buf;
     327        } else {
     328                buf[19] = '\0';
     329                os | buf;
     330                char buf2[16];
     331                snprintf( buf2, 16, "%09ld", ns );
     332                int i;
     333                for ( i = 8; i >= 0 && buf2[i] == '0' ; i -= 1 ); // find least significant digit
     334                if ( i != -1 ) { buf2[i + 1] = '\0'; os | '.' | buf2; }
     335                os | ' ' | &buf[20];
     336        } // if
     337        return os;
     338} // ?|?
    232339
    233340//######################### Clock #########################
    234341
    235 struct Clock {                                                                                  // private
     342
     343struct Clock {
    236344        Duration offset;                                                                        // for virtual clock: contains offset from real-time
    237345        int clocktype;                                                                          // implementation only -1 (virtual), CLOCK_REALTIME
    238346};
    239347
    240 static inline void resetClock( Clock & clk ) with( clk ) {
    241         clocktype = CLOCK_REALTIME_COARSE;
     348void resetClock( Clock & clk ) with( clk ) {
     349        clocktype = CLOCK_REALTIME;
    242350} // Clock::resetClock
    243351
    244 static inline void resetClock( Clock & clk, Duration adj ) with( clk ) {
     352void resetClock( Clock & clk, Duration adj ) with( clk ) {
    245353        clocktype = -1;
    246         offset = adj + timezone`s;                                                      // timezone (global) is (UTC - local time) in seconds
     354        Duration tz = (timeval){ timezone, 0 };
     355        offset = adj + tz;
    247356} // resetClock
    248357
    249 static inline void ?{}( Clock & clk ) {
     358void ?{}( Clock & clk ) {
    250359        resetClock( clk );
    251360} // Clock
    252361
    253 static inline void ?{}( Clock & clk, Duration adj ) {
     362void ?{}( Clock & clk, Duration adj ) {
    254363        resetClock( clk, adj );
    255364} // Clock
    256365
    257 static inline Duration getRes() {
     366Duration getRes() {
    258367        struct timespec res;
    259         clock_getres( CLOCK_REALTIME_COARSE, &res );
    260         return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns;
     368        clock_getres( CLOCK_REALTIME, &res );
     369        return (Duration){ res };
    261370} // getRes
    262371
    263 static inline Time getTimeNsec() {                                              // with nanoseconds
     372Time getTime() {
    264373        timespec curr;
    265374        clock_gettime( CLOCK_REALTIME_COARSE, &curr );
     
    267376} // getTime
    268377
    269 static inline Time getTime() {                                                  // without nanoseconds
    270         timespec curr;
    271         clock_gettime( CLOCK_REALTIME_COARSE, &curr );
    272         curr.tv_nsec = 0;
    273         return (Time){ curr };
    274 } // getTime
    275 
    276 static inline Time getTime( Clock & clk ) with( clk ) {
     378Time getTime( Clock & clk ) with( clk ) {
    277379        return getTime() + offset;
    278380} // getTime
    279381
    280 static inline Time ?()( Clock & clk ) with( clk ) {             // alternative syntax
     382Time ?()( Clock & clk ) with( clk ) {                                   // alternative syntax
    281383        return getTime() + offset;
    282384} // getTime
    283385
    284 static inline timeval getTime( Clock & clk ) {
     386timeval getTime( Clock & clk ) {
    285387        return (timeval){ clk() };
    286388} // getTime
    287389
    288 static inline tm getTime( Clock & clk ) with( clk ) {
     390tm getTime( Clock & clk ) with( clk ) {
    289391        tm ret;
    290392        localtime_r( getTime( clk ).tv_sec, &ret );
     
    296398// tab-width: 4 //
    297399// End: //
     400
  • src/tests/concurrent/examples/datingService.c

    rca37445 r9d1e3f7  
    88// Created On       : Mon Oct 30 12:56:20 2017
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Wed Mar 14 22:48:40 2018
    11 // Update Count     : 23
     10// Last Modified On : Tue Jan  2 12:19:01 2018
     11// Update Count     : 22
    1212//
    1313
     
    8888int main() {
    8989        DatingService TheExchange;
    90         Girl * girls[NoOfPairs];
    91         Boy  * boys[NoOfPairs];
     90        Girl *girls[NoOfPairs];
     91        Boy  *boys[NoOfPairs];
    9292
    9393        srandom( /*getpid()*/ 103 );
  • src/tests/concurrent/preempt.c

    rca37445 r9d1e3f7  
    33
    44#ifndef PREEMPTION_RATE
    5 #define PREEMPTION_RATE 10`ms
     5#define PREEMPTION_RATE 10_000ul
    66#endif
    77
    8 Duration default_preemption() {
     8unsigned int default_preemption() {
    99        return PREEMPTION_RATE;
    1010}
  • src/tests/concurrent/signal/barge.c

    rca37445 r9d1e3f7  
    1616
    1717#ifndef PREEMPTION_RATE
    18 #define PREEMPTION_RATE 10`ms
     18#define PREEMPTION_RATE 10_000ul
    1919#endif
    2020
    21 Duration default_preemption() {
     21unsigned int default_preemption() {
    2222        return 0;
    2323}
  • src/tests/concurrent/signal/block.c

    rca37445 r9d1e3f7  
    2222
    2323#ifndef PREEMPTION_RATE
    24 #define PREEMPTION_RATE 10`ms
     24#define PREEMPTION_RATE 10_000ul
    2525#endif
    2626
    27 Duration default_preemption() {
     27unsigned int default_preemption() {
    2828        return PREEMPTION_RATE;
    2929}
     
    5151//------------------------------------------------------------------------------
    5252void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) {
    53     wait( cond, (uintptr_t)active_thread() );
     53        wait( cond, (uintptr_t)this_thread );
    5454
    5555        yield( random( 10 ) );
     
    6060        }
    6161
    62         a.last_thread = b.last_thread = active_thread();
     62        a.last_thread = b.last_thread = this_thread;
    6363
    6464        yield( random( 10 ) );
     
    7676        yield( random( 10 ) );
    7777
    78         [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = active_thread();
     78        [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = this_thread;
    7979
    8080        if( !is_empty( cond ) ) {
     
    106106//------------------------------------------------------------------------------
    107107void barge_op( global_data_t & mutex a ) {
    108         a.last_thread = active_thread();
     108        a.last_thread = this_thread;
    109109}
    110110
  • src/tests/concurrent/signal/disjoint.c

    rca37445 r9d1e3f7  
    1313
    1414#ifndef PREEMPTION_RATE
    15 #define PREEMPTION_RATE 10`ms
     15#define PREEMPTION_RATE 10_000ul
    1616#endif
    1717
    18 Duration default_preemption() {
     18unsigned int default_preemption() {
    1919        return PREEMPTION_RATE;
    2020}
  • src/tests/concurrent/signal/wait.c

    rca37445 r9d1e3f7  
    2020
    2121#ifndef PREEMPTION_RATE
    22 #define PREEMPTION_RATE 10`ms
     22#define PREEMPTION_RATE 10_000ul
    2323#endif
    2424
    25 Duration default_preemption() {
     25unsigned int default_preemption() {
    2626        return PREEMPTION_RATE;
    2727}
  • src/tests/concurrent/waitfor/simple.c

    rca37445 r9d1e3f7  
    1010
    1111#ifndef PREEMPTION_RATE
    12 #define PREEMPTION_RATE 10`ms
     12#define PREEMPTION_RATE 10_000ul
    1313#endif
    1414
    15 Duration default_preemption() {
     15unsigned int default_preemption() {
    1616        return PREEMPTION_RATE;
    1717}
  • src/tests/preempt_longrun/create.c

    rca37445 r9d1e3f7  
    55
    66#ifndef PREEMPTION_RATE
    7 #define PREEMPTION_RATE 10`ms
     7#define PREEMPTION_RATE 10_000ul
    88#endif
    99
    10 Duration default_preemption() {
     10unsigned int default_preemption() {
    1111        return PREEMPTION_RATE;
    1212}
  • src/tests/preempt_longrun/enter.c

    rca37445 r9d1e3f7  
    66
    77#ifndef PREEMPTION_RATE
    8 #define PREEMPTION_RATE 10`ms
     8#define PREEMPTION_RATE 10_000ul
    99#endif
    1010
    11 Duration default_preemption() {
     11unsigned int default_preemption() {
    1212        return PREEMPTION_RATE;
    1313}
  • src/tests/preempt_longrun/enter3.c

    rca37445 r9d1e3f7  
    66
    77#ifndef PREEMPTION_RATE
    8 #define PREEMPTION_RATE 10`ms
     8#define PREEMPTION_RATE 10_000ul
    99#endif
    1010
    11 Duration default_preemption() {
     11unsigned int default_preemption() {
    1212        return PREEMPTION_RATE;
    1313}
  • src/tests/preempt_longrun/processor.c

    rca37445 r9d1e3f7  
    55
    66#ifndef PREEMPTION_RATE
    7 #define PREEMPTION_RATE 10`ms
     7#define PREEMPTION_RATE 10_000ul
    88#endif
    99
    10 Duration default_preemption() {
     10unsigned int default_preemption() {
    1111        return PREEMPTION_RATE;
    1212}
  • src/tests/preempt_longrun/stack.c

    rca37445 r9d1e3f7  
    55
    66#ifndef PREEMPTION_RATE
    7 #define PREEMPTION_RATE 10`ms
     7#define PREEMPTION_RATE 10_000ul
    88#endif
    99
    10 Duration default_preemption() {
     10unsigned int default_preemption() {
    1111        return PREEMPTION_RATE;
    1212}
  • src/tests/preempt_longrun/yield.c

    rca37445 r9d1e3f7  
    99
    1010#ifndef PREEMPTION_RATE
    11 #define PREEMPTION_RATE 10`ms
     11#define PREEMPTION_RATE 10_000ul
    1212#endif
    1313
    14 Duration default_preemption() {
     14unsigned int default_preemption() {
    1515        return PREEMPTION_RATE;
    1616}
Note: See TracChangeset for help on using the changeset viewer.