Changeset ca37445


Ignore:
Timestamp:
Apr 10, 2018, 3:31:07 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, with_gc
Children:
33f5b57
Parents:
9d1e3f7 (diff), 8ad6533 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Location:
src
Files:
4 added
1 deleted
33 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/lex.ll

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

    r9d1e3f7 rca37445  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 22 16:56:21 2018
    13 // Update Count     : 3125
     12// Last Modified On : Wed Mar 28 17:52:24 2018
     13// Update Count     : 3130
    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; } // FIX ME
     499                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
    500500        | type_name '.' '[' push field_list pop ']'                     // CFA, nested type / tuple field selector
    501                 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME
     501                { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; }
    502502        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    503                 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } // FIX ME
     503                { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; }
    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; }
    689695                // VIRTUAL cannot be opt because of look ahead issues
    690         | '(' VIRTUAL ')' cast_expression
     696        | '(' VIRTUAL ')' cast_expression                                       // CFA
    691697                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    692         | '(' VIRTUAL type_no_function ')' cast_expression
     698        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    693699                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
    694700//      | '(' type_no_function ')' tuple
     
    782788        | logical_OR_expression '?' comma_expression ':' conditional_expression
    783789                { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
    784                 // FIX ME: this hack computes $1 twice
     790                // FIX ME: computes $1 twice
    785791        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    786792                { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     
    797803                { $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); }
    798804        | unary_expression '=' '{' initializer_list comma_opt '}'
    799                 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } // FIX ME
     805                { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; }
    800806        ;
    801807
     
    867873        | exception_statement
    868874        | enable_disable_statement
    869                 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } // FIX ME
     875                { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; }
    870876        | asm_statement
    871877        ;
     
    10621068                { $$ = new StatementNode( build_return( $2 ) ); }
    10631069        | RETURN '{' initializer_list comma_opt '}'
    1064                 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } // FIX ME
     1070                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    10651071        | THROW assignment_expression_opt ';'                           // handles rethrow
    10661072                { $$ = new StatementNode( build_throw( $2 ) ); }
     
    10861092mutex_statement:
    10871093        MUTEX '(' argument_expression_list ')' statement
    1088                 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } // FIX ME
     1094                { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; }
    10891095        ;
    10901096
  • src/benchmark/bench.h

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

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

    r9d1e3f7 rca37445  
    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 stdlib.c containers/maybe.c containers/pair.c \
    153         containers/result.c containers/vector.c \
     152        rational.c time.c stdlib.c containers/maybe.c \
     153        containers/pair.c 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-stdlib.$(OBJEXT) \
     167        libcfa_d_a-time.$(OBJEXT) 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 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
     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
    193194@BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \
    194195@BUILD_CONCURRENCY_TRUE@        concurrency/libcfa_a-thread.$(OBJEXT) \
     
    197198am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \
    198199        libcfa_a-iterator.$(OBJEXT) libcfa_a-limits.$(OBJEXT) \
    199         libcfa_a-rational.$(OBJEXT) libcfa_a-stdlib.$(OBJEXT) \
    200         containers/libcfa_a-maybe.$(OBJEXT) \
     200        libcfa_a-rational.$(OBJEXT) libcfa_a-time.$(OBJEXT) \
     201        libcfa_a-stdlib.$(OBJEXT) containers/libcfa_a-maybe.$(OBJEXT) \
    201202        containers/libcfa_a-pair.$(OBJEXT) \
    202203        containers/libcfa_a-result.$(OBJEXT) \
     
    260261  esac
    261262am__nobase_cfa_include_HEADERS_DIST = fstream iostream iterator limits \
    262         rational stdlib containers/maybe containers/pair \
     263        rational time stdlib containers/maybe containers/pair \
    263264        containers/result containers/vector concurrency/coroutine \
    264265        concurrency/thread concurrency/kernel concurrency/monitor \
    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
     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
    268269HEADERS = $(nobase_cfa_include_HEADERS)
    269270am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     
    419420EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@
    420421AM_CCASFLAGS = @CFA_FLAGS@
    421 headers = fstream iostream iterator limits rational stdlib \
     422headers = fstream iostream iterator limits rational time stdlib \
    422423        containers/maybe containers/pair containers/result \
    423424        containers/vector $(am__append_3)
     
    435436        ${stdhdr}                       \
    436437        math                            \
    437         time                            \
    438438        gmp                             \
    439439        bits/align.h            \
    440         bits/cfatime.h          \
    441440        bits/containers.h               \
    442441        bits/defs.h             \
     
    612611@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@
    613612@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@
    625626@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@
    626627@AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@
     
    787788@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`
    788789
     790libcfa_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
     797libcfa_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
    789804libcfa_d_a-stdlib.o: stdlib.c
    790805@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
     
    10801095@AMDEP_TRUE@@am__fastdepCC_FALSE@       DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    10811096@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
     1098libcfa_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
     1105libcfa_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`
    10821111
    10831112libcfa_a-stdlib.o: stdlib.c
  • src/libcfa/bits/locks.h

    r9d1e3f7 rca37445  
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Dec  8 16:02:22 2017
    13 // Update Count     : 1
     12// Last Modified On : Fri Mar 30 18:18:13 2018
     13// Update Count     : 9
    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;
    6866
    6967        static inline void ?{}( __spinlock_t & this ) {
     
    7674                if( result ) {
    7775                        disable_interrupts();
    78                         __cfaabi_dbg_debug_do(
    79                                 this.prev_name = caller;
    80                                 this.prev_thrd = this_thread;
    81                         )
     76                        // __cfaabi_dbg_debug_do(
     77                        //      this.prev_name = caller;
     78                        //      this.prev_thrd = TL_GET( this_thread );
     79                        // )
    8280                }
    8381                return result;
     
    107105                }
    108106                disable_interrupts();
    109                 __cfaabi_dbg_debug_do(
    110                         this.prev_name = caller;
    111                         this.prev_thrd = this_thread;
    112                 )
     107                // __cfaabi_dbg_debug_do(
     108                //      this.prev_name = caller;
     109                //      this.prev_thrd = TL_GET( this_thread );
     110                // )
    113111        }
    114112
  • src/libcfa/concurrency/alarm.c

    r9d1e3f7 rca37445  
    1010// Created On       : Fri Jun 2 11:31:25 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:35:18 2017
    13 // Update Count     : 1
     12// Last Modified On : Mon Apr  9 13:36:18 2018
     13// Update Count     : 61
    1414//
    1515
     
    2626#include "preemption.h"
    2727
    28 
    29 static 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 
    36 static 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 
    4228//=============================================================================================
    4329// Clock logic
    4430//=============================================================================================
    4531
    46 __cfa_time_t __kernel_get_time() {
     32Time __kernel_get_time() {
    4733        timespec curr;
    48         clock_gettime( CLOCK_REALTIME, &curr );
    49         return (__cfa_time_t){ &curr };
     34        clock_gettime( CLOCK_MONOTONIC_RAW, &curr );            // CLOCK_REALTIME
     35        return (Time){ curr };
    5036}
    5137
    52 void __kernel_set_timer( __cfa_time_t alarm ) {
    53         itimerval val = { &alarm };
    54         setitimer( ITIMER_REAL, &val, NULL );
     38void __kernel_set_timer( Duration alarm ) {
     39        setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL );
    5540}
    5641
     
    5944//=============================================================================================
    6045
    61 void ?{}( alarm_node_t & this, thread_desc * thrd, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
     46void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period ) with( this ) {
    6247        this.thrd = thrd;
    6348        this.alarm = alarm;
     
    6853}
    6954
    70 void ?{}( alarm_node_t & this, processor   * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) {
     55void ?{}( alarm_node_t & this, processor   * proc, Time alarm, Duration period ) with( this ) {
    7156        this.proc = proc;
    7257        this.alarm = alarm;
  • src/libcfa/concurrency/alarm.h

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

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

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

    r9d1e3f7 rca37445  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  9 14:41:55 2018
    13 // Update Count     : 6
     12// Last Modified On : Fri Mar 30 22:33:59 2018
     13// Update Count     : 30
    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;
    1922
    2023#ifdef __cforall
     
    3033                static inline struct thread_desc             * & get_next( struct thread_desc             & this );
    3134                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;
    3247        }
     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 ); }
    3352        #endif
    3453
    3554        struct coStack_t {
    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;
     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
    5662        };
    5763
     
    5965
    6066        struct coroutine_desc {
    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;
     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
    7873        };
    7974
  • src/libcfa/concurrency/kernel

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

    r9d1e3f7 rca37445  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  8 23:52:19 2018
    13 // Update Count     : 5
     12// Last Modified On : Fri Mar 30 18:26:11 2018
     13// Update Count     : 23
    1414//
    1515
     
    5252// Global state
    5353
    54 thread_local coroutine_desc * volatile this_coroutine;
    55 thread_local thread_desc *    volatile this_thread;
    56 thread_local processor *      volatile this_processor;
    57 
    5854// volatile thread_local bool preemption_in_progress = 0;
    5955// volatile thread_local bool preemption_enabled = false;
    6056// volatile thread_local unsigned short disable_preempt_count = 1;
    6157
    62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 };
     58thread_local struct KernelThreadData kernelThreadData = {
     59        NULL,
     60        NULL,
     61        NULL,
     62        { 1, false, false }
     63};
    6364
    6465//-----------------------------------------------------------------------------
     
    172173                terminate(&this);
    173174                verify(this.do_terminate);
    174                 verify(this_processor != &this);
     175                verify(TL_GET( this_processor ) != &this);
    175176                P( terminated );
    176                 verify(this_processor != &this);
     177                verify(TL_GET( this_processor ) != &this);
    177178                pthread_join( kernel_thread, NULL );
    178179        }
     
    213214                        if(readyThread)
    214215                        {
    215                                 verify( !preemption_state.enabled );
     216                                verify( ! TL_GET( preemption_state ).enabled );
    216217
    217218                                runThread(this, readyThread);
    218219
    219                                 verify( !preemption_state.enabled );
     220                                verify( ! TL_GET( preemption_state ).enabled );
    220221
    221222                                //Some actions need to be taken from the kernel
     
    249250
    250251        //Update global state
    251         this_thread = dst;
     252        TL_SET( this_thread, dst );
    252253
    253254        // Context Switch to the thread
     
    257258
    258259void returnToKernel() {
    259         coroutine_desc * proc_cor = get_coroutine(this_processor->runner);
    260         coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
     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 );
    261262        ThreadCtxSwitch(thrd_cor, proc_cor);
    262263}
     
    266267void finishRunning(processor * this) with( this->finish ) {
    267268        if( action_code == Release ) {
    268                 verify( !preemption_state.enabled );
     269                verify( ! TL_GET( preemption_state ).enabled );
    269270                unlock( *lock );
    270271        }
     
    273274        }
    274275        else if( action_code == Release_Schedule ) {
    275                 verify( !preemption_state.enabled );
     276                verify( ! TL_GET( preemption_state ).enabled );
    276277                unlock( *lock );
    277278                ScheduleThread( thrd );
    278279        }
    279280        else if( action_code == Release_Multi ) {
    280                 verify( !preemption_state.enabled );
     281                verify( ! TL_GET( preemption_state ).enabled );
    281282                for(int i = 0; i < lock_count; i++) {
    282283                        unlock( *locks[i] );
     
    307308void * CtxInvokeProcessor(void * arg) {
    308309        processor * proc = (processor *) arg;
    309         this_processor = proc;
    310         this_coroutine = NULL;
    311         this_thread = NULL;
    312         preemption_state.enabled = false;
    313         preemption_state.disable_count = 1;
     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;
    314315        // SKULLDUGGERY: We want to create a context for the processor coroutine
    315316        // which is needed for the 2-step context switch. However, there is no reason
     
    323324
    324325        //Set global state
    325         this_coroutine = get_coroutine(proc->runner);
    326         this_thread = NULL;
     326        TL_SET( this_coroutine, get_coroutine(proc->runner) );
     327        TL_SET( this_thread, NULL );
    327328
    328329        //We now have a proper context from which to schedule threads
     
    352353
    353354void kernel_first_resume(processor * this) {
    354         coroutine_desc * src = this_coroutine;
     355        coroutine_desc * src = TL_GET( this_coroutine );
    355356        coroutine_desc * dst = get_coroutine(this->runner);
    356357
    357         verify( !preemption_state.enabled );
     358        verify( ! TL_GET( preemption_state ).enabled );
    358359
    359360        create_stack(&dst->stack, dst->stack.size);
    360361        CtxStart(&this->runner, CtxInvokeCoroutine);
    361362
    362         verify( !preemption_state.enabled );
     363        verify( ! TL_GET( preemption_state ).enabled );
    363364
    364365        dst->last = src;
     
    369370
    370371        // set new coroutine that task is executing
    371         this_coroutine = dst;
     372        TL_SET( this_coroutine, dst );
    372373
    373374        // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.
     
    386387        src->state = Active;
    387388
    388         verify( !preemption_state.enabled );
     389        verify( ! TL_GET( preemption_state ).enabled );
    389390}
    390391
     
    392393// Scheduler routines
    393394void ScheduleThread( thread_desc * thrd ) {
    394         // if( !thrd ) return;
     395        // if( ! thrd ) return;
    395396        verify( thrd );
    396397        verify( thrd->self_cor.state != Halted );
    397398
    398         verify( !preemption_state.enabled );
     399        verify( ! TL_GET( preemption_state ).enabled );
    399400
    400401        verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );
    401402
    402         with( *this_processor->cltr ) {
     403        with( *TL_GET( this_processor )->cltr ) {
    403404                lock  ( ready_queue_lock __cfaabi_dbg_ctx2 );
    404405                append( ready_queue, thrd );
     
    406407        }
    407408
    408         verify( !preemption_state.enabled );
     409        verify( ! TL_GET( preemption_state ).enabled );
    409410}
    410411
    411412thread_desc * nextThread(cluster * this) with( *this ) {
    412         verify( !preemption_state.enabled );
     413        verify( ! TL_GET( preemption_state ).enabled );
    413414        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    414415        thread_desc * head = pop_head( ready_queue );
    415416        unlock( ready_queue_lock );
    416         verify( !preemption_state.enabled );
     417        verify( ! TL_GET( preemption_state ).enabled );
    417418        return head;
    418419}
     
    420421void BlockInternal() {
    421422        disable_interrupts();
    422         verify( !preemption_state.enabled );
     423        verify( ! TL_GET( preemption_state ).enabled );
    423424        returnToKernel();
    424         verify( !preemption_state.enabled );
     425        verify( ! TL_GET( preemption_state ).enabled );
    425426        enable_interrupts( __cfaabi_dbg_ctx );
    426427}
     
    428429void BlockInternal( __spinlock_t * lock ) {
    429430        disable_interrupts();
    430         this_processor->finish.action_code = Release;
    431         this_processor->finish.lock        = lock;
    432 
    433         verify( !preemption_state.enabled );
     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 );
    434435        returnToKernel();
    435         verify( !preemption_state.enabled );
     436        verify( ! TL_GET( preemption_state ).enabled );
    436437
    437438        enable_interrupts( __cfaabi_dbg_ctx );
     
    440441void BlockInternal( thread_desc * thrd ) {
    441442        disable_interrupts();
    442         this_processor->finish.action_code = Schedule;
    443         this_processor->finish.thrd        = thrd;
    444 
    445         verify( !preemption_state.enabled );
     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 );
    446447        returnToKernel();
    447         verify( !preemption_state.enabled );
     448        verify( ! TL_GET( preemption_state ).enabled );
    448449
    449450        enable_interrupts( __cfaabi_dbg_ctx );
     
    453454        assert(thrd);
    454455        disable_interrupts();
    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 );
     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 );
    460461        returnToKernel();
    461         verify( !preemption_state.enabled );
     462        verify( ! TL_GET( preemption_state ).enabled );
    462463
    463464        enable_interrupts( __cfaabi_dbg_ctx );
     
    466467void BlockInternal(__spinlock_t * locks [], unsigned short count) {
    467468        disable_interrupts();
    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 );
     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 );
    473474        returnToKernel();
    474         verify( !preemption_state.enabled );
     475        verify( ! TL_GET( preemption_state ).enabled );
    475476
    476477        enable_interrupts( __cfaabi_dbg_ctx );
     
    479480void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) {
    480481        disable_interrupts();
    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 );
     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 );
    488489        returnToKernel();
    489         verify( !preemption_state.enabled );
     490        verify( ! TL_GET( preemption_state ).enabled );
    490491
    491492        enable_interrupts( __cfaabi_dbg_ctx );
     
    493494
    494495void LeaveThread(__spinlock_t * lock, thread_desc * 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;
     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;
    499500
    500501        returnToKernel();
     
    507508// Kernel boot procedures
    508509void kernel_startup(void) {
    509         verify( !preemption_state.enabled );
     510        verify( ! TL_GET( preemption_state ).enabled );
    510511        __cfaabi_dbg_print_safe("Kernel : Starting\n");
    511512
     
    531532
    532533        //initialize the global state variables
    533         this_processor = mainProcessor;
    534         this_thread = mainThread;
    535         this_coroutine = &mainThread->self_cor;
     534        TL_SET( this_processor, mainProcessor );
     535        TL_SET( this_thread, mainThread );
     536        TL_SET( this_coroutine, &mainThread->self_cor );
    536537
    537538        // Enable preemption
     
    545546        // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that
    546547        // mainThread is on the ready queue when this call is made.
    547         kernel_first_resume( this_processor );
     548        kernel_first_resume( TL_GET( this_processor ) );
    548549
    549550
     
    552553        __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n");
    553554
    554         verify( !preemption_state.enabled );
     555        verify( ! TL_GET( preemption_state ).enabled );
    555556        enable_interrupts( __cfaabi_dbg_ctx );
    556         verify( preemption_state.enabled );
     557        verify( TL_GET( preemption_state ).enabled );
    557558}
    558559
     
    560561        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    561562
    562         verify( preemption_state.enabled );
     563        verify( TL_GET( preemption_state ).enabled );
    563564        disable_interrupts();
    564         verify( !preemption_state.enabled );
     565        verify( ! TL_GET( preemption_state ).enabled );
    565566
    566567        // SKULLDUGGERY: Notify the mainProcessor it needs to terminates.
     
    602603
    603604        // first task to abort ?
    604         if ( !kernel_abort_called ) {                   // not first task to abort ?
     605        if ( ! kernel_abort_called ) {                  // not first task to abort ?
    605606                kernel_abort_called = true;
    606607                unlock( kernel_abort_lock );
     
    617618        }
    618619
    619         return this_thread;
     620        return TL_GET( this_thread );
    620621}
    621622
     
    626627        __cfaabi_dbg_bits_write( abort_text, len );
    627628
    628         if ( thrd != this_coroutine ) {
    629                 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine );
     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 ) );
    630631                __cfaabi_dbg_bits_write( abort_text, len );
    631632        }
     
    636637
    637638int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) {
    638         return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2;
     639        return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;
    639640}
    640641
     
    666667        if ( count < 0 ) {
    667668                // queue current task
    668                 append( waiting, (thread_desc *)this_thread );
     669                append( waiting, (thread_desc *)TL_GET( this_thread ) );
    669670
    670671                // atomically release spin lock and block
  • src/libcfa/concurrency/kernel_private.h

    r9d1e3f7 rca37445  
    1010// Created On       : Mon Feb 13 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:58:09 2017
    13 // Update Count     : 2
     12// Last Modified On : Thu Mar 29 14:06:40 2018
     13// Update Count     : 3
    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;
     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;
    7171
    7272// extern volatile thread_local bool preemption_in_progress;
  • src/libcfa/concurrency/monitor.c

    r9d1e3f7 rca37445  
    1010// Created On       : Thd Feb 23 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 16 14:49:53 2018
    13 // Update Count     : 5
     12// Last Modified On : Fri Mar 30 14:30:26 2018
     13// Update Count     : 9
    1414//
    1515
     
    8585                // Lock the monitor spinlock
    8686                lock( this->lock __cfaabi_dbg_ctx2 );
    87                 thread_desc * thrd = this_thread;
     87                thread_desc * thrd = TL_GET( 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 = this_thread;
     136                thread_desc * thrd = TL_GET( 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( this_thread, 0 )
     170                        wait_ctx_primed( TL_GET( 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( this_thread, 0 )
     181                        wait_ctx( TL_GET( 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", 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 );
     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 );
    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( this_thread != this->owner ) {
    230                                 abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner);
     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);
    231231                        }
    232232                        if( this->recursion != 1 ) {
     
    297297
    298298        // Save previous thread context
    299         this.prev = this_thread->monitors;
     299        this.prev = TL_GET( this_thread )->monitors;
    300300
    301301        // Update thread context (needed for conditions)
    302         (this_thread->monitors){m, count, func};
     302        (TL_GET( this_thread )->monitors){m, count, func};
    303303
    304304        // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count);
     
    322322
    323323        // Restore thread context
    324         this_thread->monitors = this.prev;
     324        TL_GET( this_thread )->monitors = this.prev;
    325325}
    326326
     
    332332
    333333        // Save previous thread context
    334         this.prev = this_thread->monitors;
     334        this.prev = TL_GET( this_thread )->monitors;
    335335
    336336        // Update thread context (needed for conditions)
    337         (this_thread->monitors){m, 1, func};
     337        (TL_GET( this_thread )->monitors){m, 1, func};
    338338
    339339        __enter_monitor_dtor( this.m, func );
     
    346346
    347347        // Restore thread context
    348         this_thread->monitors = this.prev;
     348        TL_GET( this_thread )->monitors = this.prev;
    349349}
    350350
     
    386386
    387387        // Create the node specific to this wait operation
    388         wait_ctx( this_thread, user_info );
     388        wait_ctx( TL_GET( 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 = this_thread;
     427                thread_desc * this_thrd = TL_GET( 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( this_thread, 0 )
     475        wait_ctx_primed( TL_GET( this_thread ), 0 )
    476476
    477477        //save contexts
     
    566566
    567567                                // Create the node specific to this wait operation
    568                                 wait_ctx_primed( this_thread, 0 );
     568                                wait_ctx_primed( TL_GET( this_thread ), 0 );
    569569
    570570                                // Save monitor states
     
    612612
    613613        // Create the node specific to this wait operation
    614         wait_ctx_primed( this_thread, 0 );
     614        wait_ctx_primed( TL_GET( this_thread ), 0 );
    615615
    616616        monitor_save;
     
    618618
    619619        for( __lock_size_t i = 0; i < count; i++) {
    620                 verify( monitors[i]->owner == this_thread );
     620                verify( monitors[i]->owner == TL_GET( this_thread ) );
    621621        }
    622622
     
    812812
    813813static inline void brand_condition( condition & this ) {
    814         thread_desc * thrd = this_thread;
     814        thread_desc * thrd = TL_GET( this_thread );
    815815        if( !this.monitors ) {
    816816                // __cfaabi_dbg_print_safe( "Branding\n" );
  • src/libcfa/concurrency/preemption.c

    r9d1e3f7 rca37445  
    1010// Created On       : Mon Jun 5 14:20:42 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  9 16:38:13 2018
    13 // Update Count     : 14
     12// Last Modified On : Mon Apr  9 13:52:39 2018
     13// Update Count     : 36
    1414//
    1515
     
    2323}
    2424
    25 #include "bits/cfatime.h"
    2625#include "bits/signal.h"
    2726
    2827#if !defined(__CFA_DEFAULT_PREEMPTION__)
    29 #define __CFA_DEFAULT_PREEMPTION__ 10`cfa_ms
     28#define __CFA_DEFAULT_PREEMPTION__ 10`ms
    3029#endif
    3130
    32 __cfa_time_t default_preemption() __attribute__((weak)) {
     31Duration default_preemption() __attribute__((weak)) {
    3332        return __CFA_DEFAULT_PREEMPTION__;
    3433}
     
    7877
    7978// Get next expired node
    80 static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_t currtime ) {
     79static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) {
    8180        if( !alarms->head ) return NULL;                          // If no alarms return null
    8281        if( alarms->head->alarm >= currtime ) return NULL;        // If alarms head not expired return null
     
    8887        alarm_node_t * node = NULL;                     // Used in the while loop but cannot be declared in the while condition
    8988        alarm_list_t * alarms = &event_kernel->alarms;  // Local copy for ease of reading
    90         __cfa_time_t currtime = __kernel_get_time();    // Check current time once so we everything "happens at once"
     89        Time currtime = __kernel_get_time();                    // Check current time once so we everything "happens at once"
    9190
    9291        //Loop throught every thing expired
     
    102101
    103102                // Check if this is a periodic alarm
    104                 __cfa_time_t period = node->period;
     103                Duration period = node->period;
    105104                if( period > 0 ) {
    106105                        node->alarm = currtime + period;    // Alarm is periodic, add currtime to it (used cached current time)
     
    117116
    118117// Update the preemption of a processor and notify interested parties
    119 void update_preemption( processor * this, __cfa_time_t duration ) {
     118void update_preemption( processor * this, Duration duration ) {
    120119        alarm_node_t * alarm = this->preemption_alarm;
    121120
    122121        // Alarms need to be enabled
    123         if ( duration > 0 && !alarm->set ) {
     122        if ( duration > 0 && ! alarm->set ) {
    124123                alarm->alarm = __kernel_get_time() + duration;
    125124                alarm->period = duration;
    126125                register_self( alarm );
    127126        }
    128         // Zero duraction but alarm is set
     127        // Zero duration but alarm is set
    129128        else if ( duration == 0 && alarm->set ) {
    130129                unregister_self( alarm );
     
    150149        // Disable interrupts by incrementing the counter
    151150        void disable_interrupts() {
    152                 preemption_state.enabled = false;
    153                 __attribute__((unused)) unsigned short new_val = preemption_state.disable_count + 1;
    154                 preemption_state.disable_count = new_val;
     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;
    155154                verify( new_val < 65_000u );              // If this triggers someone is disabling interrupts without enabling them
    156155        }
     
    159158        // If counter reaches 0, execute any pending CtxSwitch
    160159        void enable_interrupts( __cfaabi_dbg_ctx_param ) {
    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;
     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;
    166165                verify( prev != 0u );                     // If this triggers someone is enabled already enabled interruptsverify( prev != 0u );
    167166
    168167                // Check if we need to prempt the thread because an interrupt was missed
    169168                if( prev == 1 ) {
    170                         preemption_state.enabled = true;
     169                        TL_GET( preemption_state ).enabled = true;
    171170                        if( proc->pending_preemption ) {
    172171                                proc->pending_preemption = false;
     
    182181        // Don't execute any pending CtxSwitch even if counter reaches 0
    183182        void enable_interrupts_noPoll() {
    184                 unsigned short prev = preemption_state.disable_count;
    185                 preemption_state.disable_count -= 1;
     183                unsigned short prev = TL_GET( preemption_state ).disable_count;
     184                TL_GET( preemption_state ).disable_count -= 1;
    186185                verifyf( prev != 0u, "Incremented from %u\n", prev );                     // If this triggers someone is enabled already enabled interrupts
    187186                if( prev == 1 ) {
    188                         preemption_state.enabled = true;
     187                        TL_GET( preemption_state ).enabled = true;
    189188                }
    190189        }
     
    236235// If false : preemption is unsafe and marked as pending
    237236static inline bool preemption_ready() {
    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
     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
    240239        return ready;
    241240}
     
    251250
    252251        // Start with preemption disabled until ready
    253         preemption_state.enabled = false;
    254         preemption_state.disable_count = 1;
     252        TL_GET( preemption_state ).enabled = false;
     253        TL_GET( preemption_state ).disable_count = 1;
    255254
    256255        // Initialize the event kernel
     
    291290// Used by thread to control when they want to receive preemption signals
    292291void ?{}( preemption_scope & this, processor * proc ) {
    293         (this.alarm){ proc, 0`cfa_s, 0`cfa_s };
     292        (this.alarm){ proc, (Time){ 0 }, 0`s };
    294293        this.proc = proc;
    295294        this.proc->preemption_alarm = &this.alarm;
     
    301300        disable_interrupts();
    302301
    303         update_preemption( this.proc, 0`cfa_s );
     302        update_preemption( this.proc, 0`s );
    304303}
    305304
     
    317316        // before the kernel thread has even started running. When that happens an iterrupt
    318317        // we a null 'this_processor' will be caught, just ignore it.
    319         if(!this_processor) return;
     318        if(!TL_GET( this_processor )) return;
    320319
    321320        choose(sfp->si_value.sival_int) {
    322321                case PREEMPT_NORMAL   : ;// Normal case, nothing to do here
    323                 case PREEMPT_TERMINATE: verify(this_processor->do_terminate);
     322                case PREEMPT_TERMINATE: verify(TL_GET( this_processor )->do_terminate);
    324323                default:
    325324                        abort( "internal error, signal value is %d", sfp->si_value.sival_int );
     
    331330        __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread);
    332331
    333         preemption_state.in_progress = true;                      // Sync flag : prevent recursive calls to the signal handler
     332        TL_GET( preemption_state ).in_progress = true;  // Sync flag : prevent recursive calls to the signal handler
    334333        signal_unblock( SIGUSR1 );                          // We are about to CtxSwitch out of the signal handler, let other handlers in
    335         preemption_state.in_progress = false;                    // Clear the in progress flag
     334        TL_GET( preemption_state ).in_progress = false; // Clear the in progress flag
    336335
    337336        // Preemption can occur here
    338337
    339         BlockInternal( (thread_desc*)this_thread );        // Do the actual CtxSwitch
     338        BlockInternal( (thread_desc*)TL_GET( this_thread ) ); // Do the actual CtxSwitch
    340339}
    341340
  • src/libcfa/concurrency/preemption.h

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

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

    r9d1e3f7 rca37445  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:34:46 2017
    13 // Update Count     : 1
     12// Last Modified On : Fri Mar 30 17:19:52 2018
     13// Update Count     : 8
    1414//
    1515
     
    2626}
    2727
    28 extern volatile thread_local processor * this_processor;
     28//extern 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 = this_coroutine;
     77        thrd_c->last = TL_GET( 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         this_coroutine = thrd_c;
     83        TL_SET( 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 = this_coroutine;
     94                coroutine_desc* thrd_c = TL_GET( this_coroutine );
    9595                ThreadCtxSwitch( thrd_c, thrd_c->last );
    9696        }
     
    9898
    9999void yield( void ) {
    100         verify( preemption_state.enabled );
    101         BlockInternal( this_thread );
    102         verify( preemption_state.enabled );
     100        verify( TL_GET( preemption_state ).enabled );
     101        BlockInternal( TL_GET( this_thread ) );
     102        verify( TL_GET( preemption_state ).enabled );
    103103}
    104104
     
    116116        // set new coroutine that the processor is executing
    117117        // and context switch to it
    118         this_coroutine = dst;
     118        TL_SET( this_coroutine, dst );
    119119        assert( src->stack.context );
    120120        CtxSwitch( src->stack.context, dst->stack.context );
    121         this_coroutine = src;
     121        TL_SET( this_coroutine, src );
    122122
    123123        // set state of new coroutine to active
  • src/libcfa/time

    r9d1e3f7 rca37445  
    11//
    2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
     2// Cforall Version 1.0.0 Copyright (C) 2018 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 // calendar --
     7// time --
    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 : Thu Mar 22 17:11:19 2018
    13 // Update Count     : 495
     12// Last Modified On : Mon Apr  9 13:10:23 2018
     13// Update Count     : 616
    1414//
    1515
     
    1919// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r5.html#refcc
    2020
    21 #include <time.h>
     21#include <time.h>                                                                               // timespec
    2222extern "C" {
    23 #include <sys/time.h>
    24 int snprintf( char * buf, size_t size, const char * fmt, ... );
     23#include <sys/time.h>                                                                   // timeval
    2524}
    26 #include <fstream>
    27 
    28 enum {
    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
     25#include <iostream>                                                                             // istype/ostype
     26
     27enum { TIMEGRAN = 1_000_000_000LL };                                    // nanosecond granularity, except for timeval
     28
     29
     30//######################### Duration #########################
     31
     32struct Duration {                                                                               // private
     33        int64_t tv;                                                                                     // nanoseconds
     34}; // Duration
     35
     36static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
     37static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; }
     38
     39static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; }
     40static inline Duration ?=?( Duration & dur, zero_t ) { return dur{ 0 }; }
     41
     42static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; }
     43static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
     44static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
     45
     46static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
     47static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
     48static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
     49
     50static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
     51static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
     52static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
     53
     54static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
     55static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
     56static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
     57static inline double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; }
     58
     59static inline Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; }
     60static inline Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; }
     61
     62static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
     63static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
     64static inline _Bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv <  rhs.tv; }
     65static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
     66static inline _Bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv >  rhs.tv; }
     67static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
     68
     69static inline _Bool ?==?( Duration lhs, zero_t ) { return lhs.tv == 0; }
     70static inline _Bool ?!=?( Duration lhs, zero_t ) { return lhs.tv != 0; }
     71static inline _Bool ?<? ( Duration lhs, zero_t ) { return lhs.tv <  0; }
     72static inline _Bool ?<=?( Duration lhs, zero_t ) { return lhs.tv <= 0; }
     73static inline _Bool ?>? ( Duration lhs, zero_t ) { return lhs.tv >  0; }
     74static inline _Bool ?>=?( Duration lhs, zero_t ) { return lhs.tv >= 0; }
     75
     76static inline Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; }
     77
     78forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur );
     79
     80static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
     81static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000_000LL) }; }
     82static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000LL) }; }
     83static inline Duration ?`s( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; }
     84static inline Duration ?`s( double sec ) { return (Duration)@{ sec * TIMEGRAN }; }
     85static inline Duration ?`m( int64_t min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; }
     86static inline Duration ?`m( double min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; }
     87static inline Duration ?`h( int64_t hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; }
     88static inline Duration ?`h( double hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; }
     89static inline Duration ?`d( int64_t days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; }
     90static inline Duration ?`d( double days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; }
     91static inline Duration ?`w( int64_t weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
     92static inline Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; }
     93
     94static inline int64_t ?`ns( Duration dur ) { return dur.tv; }
     95static inline int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); }
     96static inline int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); }
     97static inline int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; }
     98static inline int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); }
     99static inline int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); }
     100static inline int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); }
     101static inline int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); }
     102
     103
     104//######################### C timeval #########################
     105
    47106static inline void ?{}( timeval & t ) {}
    48 static inline void ?{}( timeval & t, time_t sec ) { t.tv_sec = sec; t.tv_usec = 0; }
    49107static inline void ?{}( timeval & t, time_t sec, suseconds_t usec ) { t.tv_sec = sec; t.tv_usec = usec; }
     108static inline void ?{}( timeval & t, time_t sec ) { t{ sec, 0 }; }
     109static inline void ?{}( timeval & t, zero_t ) { t{ 0, 0 }; }
     110static inline timeval ?=?( timeval & t, zero_t ) { return t{ 0 }; }
     111static inline timeval ?+?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_usec + rhs.tv_usec }; }
     112static inline timeval ?-?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_usec - rhs.tv_usec }; }
     113static inline _Bool ?==?( timeval lhs, timeval rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_usec == rhs.tv_usec; }
     114static inline _Bool ?!=?( timeval lhs, timeval rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_usec != rhs.tv_usec; }
     115
     116
     117//######################### C timespec #########################
    50118
    51119static inline void ?{}( timespec & t ) {}
    52 static inline void ?{}( timespec & t, time_t sec ) { t.tv_sec = sec; t.tv_nsec = 0; }
    53120static inline void ?{}( timespec & t, time_t sec, __syscall_slong_t nsec ) { t.tv_sec = sec; t.tv_nsec = nsec; }
     121static inline void ?{}( timespec & t, time_t sec ) { t{ sec, 0}; }
     122static inline void ?{}( timespec & t, zero_t ) { t{ 0, 0 }; }
     123static inline timespec ?=?( timespec & t, zero_t ) { return t{ 0 }; }
     124static inline timespec ?+?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec }; }
     125static inline timespec ?-?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec }; }
     126static inline _Bool ?==?( timespec lhs, timespec rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec; }
     127static 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
     132static 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
     138static 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 #########################
    54146
    55147static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; }
     
    61153
    62154
    63 //######################### Duration #########################
    64 
    65 struct Duration {
    66         int64_t tv;
    67 };
    68 
    69 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
    70 static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; }
    71 
    72 static inline void ?{}( Duration & dur, timeval t ) with( dur ) {
    73         tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;
    74 } // Duration
    75 
    76 static inline void ?{}( Duration & dur, timespec t ) with( dur ) {
    77         tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
    78 } // Duration
    79 
    80 static 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 
    85 static 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 
    90 static 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 
    95 static 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 
    100 static inline int64_t nsecs( Duration dur ) with( dur ) { return tv; }
    101 
    102 static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; }
    103 static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; }
    104 static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    105 
    106 static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; }
    107 static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
    108 static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    109 
    110 static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; }
    111 static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; }
    112 static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; }
    113 
    114 static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; }
    115 static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; }
    116 static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; }
    117 
    118 static inline Duration ?%?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv % rhs }; }
    119 static inline int64_t ?%?( int64_t lhs, Duration rhs ) { return lhs % (rhs.tv / TIMEGRAN); }
    120 static inline int64_t ?%?( Duration lhs, Duration rhs ) { return lhs.tv % rhs.tv; }
    121 
    122 static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; }
    123 static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; }
    124 static inline _Bool ?<?( Duration lhs, Duration rhs ) { return lhs.tv < rhs.tv; }
    125 static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; }
    126 static inline _Bool ?>?( Duration lhs, Duration rhs ) { return lhs.tv > rhs.tv; }
    127 static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; }
    128 
    129 static inline Duration abs( Duration lhs ) {
    130         return lhs.tv >= 0 ? lhs : -lhs;
    131 } // abs
    132 
    133 static inline forall( dtype ostype | ostream( ostype ) )
    134 ostype & ?|?( 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 
    144 static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; }
    145 static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000l) }; }
    146 static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000_000l) }; }
    147 static inline Duration ?`s ( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; }
    148 static inline Duration ?`s ( double  sec ) { return (Duration)@{ sec * TIMEGRAN }; }
    149 static inline Duration ?`m ( int64_t min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }
    150 static inline Duration ?`m ( double  min ) { return (Duration)@{ min * (60L * TIMEGRAN) }; }
    151 static inline Duration ?`h ( int64_t hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }
    152 static inline Duration ?`h ( double  hours ) { return (Duration)@{ hours * (3600L * TIMEGRAN) }; }
    153 static inline Duration ?`d ( int64_t days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }
    154 static inline Duration ?`d ( double  days ) { return (Duration)@{ days * (24L * 3600L * TIMEGRAN) }; }
    155 static inline Duration ?`w ( int64_t weeks ) { return (Duration)@{ weeks * (7L * 24L * 3600L * TIMEGRAN) }; }
    156 static inline Duration ?`f ( int64_t fortnight ) { return (Duration)@{ fortnight * (14L * 24L * 3600L * TIMEGRAN) }; }
    157 
    158 static inline int64_t ?`s ( Duration dur ) { return dur.tv / TIMEGRAN; }
    159 static inline int64_t ?`m ( Duration dur ) { return dur.tv / (60L * TIMEGRAN); }
    160 static inline int64_t ?`h ( Duration dur ) { return dur.tv / (3600L * TIMEGRAN); }
    161 static inline int64_t ?`d ( Duration dur ) { return dur.tv / (24L * 3600L * TIMEGRAN); }
    162 static inline int64_t ?`w ( Duration dur ) { return dur.tv / (7L * 24L * 3600L * TIMEGRAN); }
    163 static inline int64_t ?`f ( Duration dur ) { return dur.tv / (14L * 24L * 3600L * TIMEGRAN); }
    164 
    165 
    166155//######################### Time #########################
    167156
    168 
    169 struct 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 
    178 void 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 
    203 static 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 
    210 static 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 
    219 static 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 
    228 static inline void ?{}( Time & time, int min, int sec, long int nsec ) {
    229         mktime( time, 1970, 1, 1, 0, min, sec, nsec );
    230 } // Time
    231 
    232 static 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 
    236 static 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 
    240 static 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 
    244 static 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
     157struct Time {                                                                                   // private
     158        uint64_t tv;                                                                            // nanoseconds since UNIX epoch
     159}; // Time
     160
     161static inline void ?{}( Time & t ) with( t ) { tv = 0; } // fast
     162void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 ); // slow
     163
     164static inline void ?{}( Time & t, zero_t ) { t.tv = 0; }
     165static inline Time ?=?( Time & t, zero_t ) { return t{ 0 }; }
    247166
    248167static inline void ?{}( Time & time, timeval t ) with( time ) {
     
    250169} // Time
    251170
     171static inline Time ?=?( Time & time, timeval t ) with( time ) {
     172        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);
     173        return time;
     174} // ?=?
     175
    252176static inline void ?{}( Time & time, timespec t ) with( time ) {
    253177        tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;
    254178} // Time
    255 
    256 static inline Time ?=?( Time & time, timeval t ) with( time ) {
    257         tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000;
    258         return time;
    259 } // ?=?
    260179
    261180static inline Time ?=?( Time & time, timespec t ) with( time ) {
     
    263182        return time;
    264183} // ?=?
    265 
    266 static 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 
    271 static inline void ?{}( timespec & t, Time time ) with( time ) {
    272         t.tv_sec = tv / TIMEGRAN;                                                       // seconds
    273         t.tv_nsec = tv % TIMEGRAN;                                                      // nanoseconds
    274 } // ?{}
    275 
    276 static inline int64_t nsec( Time time ) with( time ) { return tv; }
    277184
    278185static inline Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; }
     
    290197static inline _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; }
    291198
    292 static 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 
    300 static 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 
    308 static 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 
    316 static inline forall( dtype ostype | ostream( ostype ) )
    317 ostype & ?|?( 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 } // ?|?
     199char * yy_mm_dd( Time time, char * buf );
     200static inline char * ?`ymd( Time time, char * buf ) {   // short form
     201        return yy_mm_dd( time, buf );
     202} // ymd
     203
     204char * mm_dd_yy( Time time, char * buf );
     205static inline char * ?`mdy( Time time, char * buf ) {   // short form
     206        return mm_dd_yy( time, buf );
     207} // mdy
     208
     209char * dd_mm_yy( Time time, char * buf );
     210static inline char * ?`dmy( Time time, char * buf ) {   // short form
     211        return dd_mm_yy( time, buf );;
     212} // dmy
     213
     214size_t strftime( char * buf, size_t size, const char * fmt, Time time );
     215
     216forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time );
     217
     218//------------------------- timeval (cont) -------------------------
     219
     220static 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
     227static inline void ?{}( timespec & t, Time time ) with( t, time ) {
     228        tv_sec = tv / TIMEGRAN;                                                         // seconds
     229        tv_nsec = tv % TIMEGRAN;                                                        // nanoseconds
     230} // ?{}
     231
    339232
    340233//######################### Clock #########################
    341234
    342 
    343 struct Clock {
     235struct Clock {                                                                                  // private
    344236        Duration offset;                                                                        // for virtual clock: contains offset from real-time
    345237        int clocktype;                                                                          // implementation only -1 (virtual), CLOCK_REALTIME
    346238};
    347239
    348 void resetClock( Clock & clk ) with( clk ) {
    349         clocktype = CLOCK_REALTIME;
     240static inline void resetClock( Clock & clk ) with( clk ) {
     241        clocktype = CLOCK_REALTIME_COARSE;
    350242} // Clock::resetClock
    351243
    352 void resetClock( Clock & clk, Duration adj ) with( clk ) {
     244static inline void resetClock( Clock & clk, Duration adj ) with( clk ) {
    353245        clocktype = -1;
    354         Duration tz = (timeval){ timezone, 0 };
    355         offset = adj + tz;
     246        offset = adj + timezone`s;                                                      // timezone (global) is (UTC - local time) in seconds
    356247} // resetClock
    357248
    358 void ?{}( Clock & clk ) {
     249static inline void ?{}( Clock & clk ) {
    359250        resetClock( clk );
    360251} // Clock
    361252
    362 void ?{}( Clock & clk, Duration adj ) {
     253static inline void ?{}( Clock & clk, Duration adj ) {
    363254        resetClock( clk, adj );
    364255} // Clock
    365256
    366 Duration getRes() {
     257static inline Duration getRes() {
    367258        struct timespec res;
    368         clock_getres( CLOCK_REALTIME, &res );
    369         return (Duration){ res };
     259        clock_getres( CLOCK_REALTIME_COARSE, &res );
     260        return ((int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns;
    370261} // getRes
    371262
    372 Time getTime() {
     263static inline Time getTimeNsec() {                                              // with nanoseconds
    373264        timespec curr;
    374265        clock_gettime( CLOCK_REALTIME_COARSE, &curr );
     
    376267} // getTime
    377268
    378 Time getTime( Clock & clk ) with( clk ) {
     269static 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
     276static inline Time getTime( Clock & clk ) with( clk ) {
    379277        return getTime() + offset;
    380278} // getTime
    381279
    382 Time ?()( Clock & clk ) with( clk ) {                                   // alternative syntax
     280static inline Time ?()( Clock & clk ) with( clk ) {             // alternative syntax
    383281        return getTime() + offset;
    384282} // getTime
    385283
    386 timeval getTime( Clock & clk ) {
     284static inline timeval getTime( Clock & clk ) {
    387285        return (timeval){ clk() };
    388286} // getTime
    389287
    390 tm getTime( Clock & clk ) with( clk ) {
     288static inline tm getTime( Clock & clk ) with( clk ) {
    391289        tm ret;
    392290        localtime_r( getTime( clk ).tv_sec, &ret );
     
    398296// tab-width: 4 //
    399297// End: //
    400 
  • src/tests/concurrent/examples/datingService.c

    r9d1e3f7 rca37445  
    88// Created On       : Mon Oct 30 12:56:20 2017
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Tue Jan  2 12:19:01 2018
    11 // Update Count     : 22
     10// Last Modified On : Wed Mar 14 22:48:40 2018
     11// Update Count     : 23
    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

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

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

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

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

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

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

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

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

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

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

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

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