Changes in / [ca37445:9d1e3f7]
- Location:
- src
- Files:
-
- 1 added
- 4 deleted
- 33 edited
-
Parser/lex.ll (modified) (5 diffs)
-
Parser/parser.yy (modified) (8 diffs)
-
benchmark/bench.h (modified) (1 diff)
-
libcfa/Makefile.am (modified) (3 diffs)
-
libcfa/Makefile.in (modified) (11 diffs)
-
libcfa/bits/cfatime.h (added)
-
libcfa/bits/locks.h (modified) (4 diffs)
-
libcfa/concurrency/alarm.c (modified) (4 diffs)
-
libcfa/concurrency/alarm.h (modified) (5 diffs)
-
libcfa/concurrency/coroutine (modified) (5 diffs)
-
libcfa/concurrency/coroutine.c (modified) (5 diffs)
-
libcfa/concurrency/invoke.h (modified) (4 diffs)
-
libcfa/concurrency/kernel (modified) (3 diffs)
-
libcfa/concurrency/kernel.c (modified) (32 diffs)
-
libcfa/concurrency/kernel_private.h (modified) (2 diffs)
-
libcfa/concurrency/monitor.c (modified) (18 diffs)
-
libcfa/concurrency/preemption.c (modified) (15 diffs)
-
libcfa/concurrency/preemption.h (modified) (2 diffs)
-
libcfa/concurrency/thread (modified) (2 diffs)
-
libcfa/concurrency/thread.c (modified) (7 diffs)
-
libcfa/time (modified) (8 diffs)
-
libcfa/time.c (deleted)
-
tests/.expect/time.x64.txt (deleted)
-
tests/.expect/time.x86.txt (deleted)
-
tests/concurrent/examples/datingService.c (modified) (2 diffs)
-
tests/concurrent/preempt.c (modified) (1 diff)
-
tests/concurrent/signal/barge.c (modified) (1 diff)
-
tests/concurrent/signal/block.c (modified) (5 diffs)
-
tests/concurrent/signal/disjoint.c (modified) (1 diff)
-
tests/concurrent/signal/wait.c (modified) (1 diff)
-
tests/concurrent/waitfor/simple.c (modified) (1 diff)
-
tests/preempt_longrun/create.c (modified) (1 diff)
-
tests/preempt_longrun/enter.c (modified) (1 diff)
-
tests/preempt_longrun/enter3.c (modified) (1 diff)
-
tests/preempt_longrun/processor.c (modified) (1 diff)
-
tests/preempt_longrun/stack.c (modified) (1 diff)
-
tests/preempt_longrun/yield.c (modified) (1 diff)
-
tests/time.c (deleted)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/lex.ll
rca37445 r9d1e3f7 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Fri Apr 6 15:16:15201813 * Update Count : 6 7012 * Last Modified On : Thu Mar 22 16:47:06 2018 13 * Update Count : 668 14 14 */ 15 15 … … 198 198 __asm { KEYWORD_RETURN(ASM); } // GCC 199 199 __asm__ { KEYWORD_RETURN(ASM); } // GCC 200 _At { KEYWORD_RETURN(AT); } // CFA 200 201 _Atomic { KEYWORD_RETURN(ATOMIC); } // C11 201 202 __attribute { KEYWORD_RETURN(ATTRIBUTE); } // GCC … … 228 229 exception { KEYWORD_RETURN(EXCEPTION); } // CFA 229 230 extern { KEYWORD_RETURN(EXTERN); } 231 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA 230 232 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA 231 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA232 233 finally { KEYWORD_RETURN(FINALLY); } // CFA 233 234 float { KEYWORD_RETURN(FLOAT); } … … 259 260 __builtin_offsetof { KEYWORD_RETURN(OFFSETOF); } // GCC 260 261 one_t { NUMERIC_RETURN(ONE_T); } // CFA 261 or { QKEYWORD_RETURN(WOR); } // CFA262 262 otype { KEYWORD_RETURN(OTYPE); } // CFA 263 263 register { KEYWORD_RETURN(REGISTER); } … … 296 296 __volatile__ { KEYWORD_RETURN(VOLATILE); } // GCC 297 297 waitfor { KEYWORD_RETURN(WAITFOR); } 298 or { QKEYWORD_RETURN(WOR); } // CFA 298 299 when { KEYWORD_RETURN(WHEN); } 299 300 while { KEYWORD_RETURN(WHILE); } -
src/Parser/parser.yy
rca37445 r9d1e3f7 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 28 17:52:24201813 // Update Count : 31 3012 // Last Modified On : Thu Mar 22 16:56:21 2018 13 // Update Count : 3125 14 14 // 15 15 … … 497 497 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); } 498 498 | type_name '.' no_attr_identifier // CFA, nested type 499 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } 499 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME 500 500 | type_name '.' '[' push field_list pop ']' // CFA, nested type / tuple field selector 501 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } 501 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME 502 502 | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11 503 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } 503 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } // FIX ME 504 504 ; 505 505 … … 687 687 | '(' type_no_function ')' cast_expression 688 688 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 689 | '(' COROUTINE '&' ')' cast_expression // CFA690 { SemanticError( yylloc, "coroutine cast is currently unimplemented." ); $$ = nullptr; }691 | '(' THREAD '&' ')' cast_expression // CFA692 { SemanticError( yylloc, "monitor cast is currently unimplemented." ); $$ = nullptr; }693 | '(' MONITOR '&' ')' cast_expression // CFA694 { SemanticError( yylloc, "thread cast is currently unimplemented." ); $$ = nullptr; }695 689 // VIRTUAL cannot be opt because of look ahead issues 696 | '(' VIRTUAL ')' cast_expression // CFA690 | '(' VIRTUAL ')' cast_expression 697 691 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); } 698 | '(' VIRTUAL type_no_function ')' cast_expression // CFA692 | '(' VIRTUAL type_no_function ')' cast_expression 699 693 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); } 700 694 // | '(' type_no_function ')' tuple … … 788 782 | logical_OR_expression '?' comma_expression ':' conditional_expression 789 783 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 790 // FIX ME: computes $1 twice784 // FIX ME: this hack computes $1 twice 791 785 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 792 786 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } … … 803 797 { $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); } 804 798 | unary_expression '=' '{' initializer_list comma_opt '}' 805 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } 799 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } // FIX ME 806 800 ; 807 801 … … 873 867 | exception_statement 874 868 | enable_disable_statement 875 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } 869 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } // FIX ME 876 870 | asm_statement 877 871 ; … … 1068 1062 { $$ = new StatementNode( build_return( $2 ) ); } 1069 1063 | RETURN '{' initializer_list comma_opt '}' 1070 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1064 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } // FIX ME 1071 1065 | THROW assignment_expression_opt ';' // handles rethrow 1072 1066 { $$ = new StatementNode( build_throw( $2 ) ); } … … 1092 1086 mutex_statement: 1093 1087 MUTEX '(' argument_expression_list ')' statement 1094 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } 1088 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } // FIX ME 1095 1089 ; 1096 1090 -
src/benchmark/bench.h
rca37445 r9d1e3f7 10 10 #if defined(__cforall) 11 11 } 12 //#include <bits/cfatime.h>12 #include <bits/cfatime.h> 13 13 #endif 14 14 -
src/libcfa/Makefile.am
rca37445 r9d1e3f7 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Sun Apr 8 23:49:34201814 ## Update Count : 22 713 ## Last Modified On : Thu Mar 22 17:14:15 2018 14 ## Update Count : 224 15 15 ############################################################################### 16 16 … … 46 46 CC = ${abs_top_srcdir}/src/driver/cfa 47 47 48 headers = fstream iostream iterator limits rational timestdlib \48 headers = fstream iostream iterator limits rational stdlib \ 49 49 containers/maybe containers/pair containers/result containers/vector 50 50 … … 99 99 ${stdhdr} \ 100 100 math \ 101 time \ 101 102 gmp \ 102 103 bits/align.h \ 104 bits/cfatime.h \ 103 105 bits/containers.h \ 104 106 bits/defs.h \ -
src/libcfa/Makefile.in
rca37445 r9d1e3f7 150 150 am__libcfa_d_a_SOURCES_DIST = libcfa-prelude.c interpose.c \ 151 151 bits/debug.c fstream.c iostream.c iterator.c limits.c \ 152 rational.c time.c stdlib.c containers/maybe.c \153 containers/ pair.c containers/result.c containers/vector.c \152 rational.c stdlib.c containers/maybe.c containers/pair.c \ 153 containers/result.c containers/vector.c \ 154 154 concurrency/coroutine.c concurrency/thread.c \ 155 155 concurrency/kernel.c concurrency/monitor.c assert.c \ … … 165 165 libcfa_d_a-iostream.$(OBJEXT) libcfa_d_a-iterator.$(OBJEXT) \ 166 166 libcfa_d_a-limits.$(OBJEXT) libcfa_d_a-rational.$(OBJEXT) \ 167 libcfa_d_a- time.$(OBJEXT) libcfa_d_a-stdlib.$(OBJEXT) \167 libcfa_d_a-stdlib.$(OBJEXT) \ 168 168 containers/libcfa_d_a-maybe.$(OBJEXT) \ 169 169 containers/libcfa_d_a-pair.$(OBJEXT) \ … … 184 184 libcfa_a_LIBADD = 185 185 am__libcfa_a_SOURCES_DIST = libcfa-prelude.c interpose.c bits/debug.c \ 186 fstream.c iostream.c iterator.c limits.c rational.c time.c \ 187 stdlib.c containers/maybe.c containers/pair.c \ 188 containers/result.c containers/vector.c \ 189 concurrency/coroutine.c concurrency/thread.c \ 190 concurrency/kernel.c concurrency/monitor.c assert.c \ 191 exception.c virtual.c concurrency/CtxSwitch-@MACHINE_TYPE@.S \ 192 concurrency/alarm.c concurrency/invoke.c \ 193 concurrency/preemption.c 186 fstream.c iostream.c iterator.c limits.c rational.c stdlib.c \ 187 containers/maybe.c containers/pair.c containers/result.c \ 188 containers/vector.c concurrency/coroutine.c \ 189 concurrency/thread.c concurrency/kernel.c \ 190 concurrency/monitor.c assert.c exception.c virtual.c \ 191 concurrency/CtxSwitch-@MACHINE_TYPE@.S concurrency/alarm.c \ 192 concurrency/invoke.c concurrency/preemption.c 194 193 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \ 195 194 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_a-thread.$(OBJEXT) \ … … 198 197 am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \ 199 198 libcfa_a-iterator.$(OBJEXT) libcfa_a-limits.$(OBJEXT) \ 200 libcfa_a-rational.$(OBJEXT) libcfa_a- time.$(OBJEXT) \201 libcfa_a-stdlib.$(OBJEXT)containers/libcfa_a-maybe.$(OBJEXT) \199 libcfa_a-rational.$(OBJEXT) libcfa_a-stdlib.$(OBJEXT) \ 200 containers/libcfa_a-maybe.$(OBJEXT) \ 202 201 containers/libcfa_a-pair.$(OBJEXT) \ 203 202 containers/libcfa_a-result.$(OBJEXT) \ … … 261 260 esac 262 261 am__nobase_cfa_include_HEADERS_DIST = fstream iostream iterator limits \ 263 rational timestdlib containers/maybe containers/pair \262 rational stdlib containers/maybe containers/pair \ 264 263 containers/result containers/vector concurrency/coroutine \ 265 264 concurrency/thread concurrency/kernel concurrency/monitor \ 266 ${shell find stdhdr -type f -printf "%p "} math gmp \267 bits/align.h bits/c ontainers.h bits/defs.h bits/debug.h \268 bits/ locks.h concurrency/invoke.h265 ${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 269 268 HEADERS = $(nobase_cfa_include_HEADERS) 270 269 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 420 419 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ 421 420 AM_CCASFLAGS = @CFA_FLAGS@ 422 headers = fstream iostream iterator limits rational timestdlib \421 headers = fstream iostream iterator limits rational stdlib \ 423 422 containers/maybe containers/pair containers/result \ 424 423 containers/vector $(am__append_3) … … 436 435 ${stdhdr} \ 437 436 math \ 437 time \ 438 438 gmp \ 439 439 bits/align.h \ 440 bits/cfatime.h \ 440 441 bits/containers.h \ 441 442 bits/defs.h \ … … 611 612 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@ 612 613 @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@614 614 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-virtual.Po@am__quote@ 615 615 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@ … … 623 623 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@ 624 624 @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@626 625 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@ 627 626 @AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@ … … 788 787 @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` 789 788 790 libcfa_d_a-time.o: time.c791 @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.c792 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po793 @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.c796 797 libcfa_d_a-time.obj: time.c798 @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.Po800 @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 804 789 libcfa_d_a-stdlib.o: stdlib.c 805 790 @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 … … 1095 1080 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1096 1081 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-rational.obj `if test -f 'rational.c'; then $(CYGPATH_W) 'rational.c'; else $(CYGPATH_W) '$(srcdir)/rational.c'; fi` 1097 1098 libcfa_a-time.o: time.c1099 @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.c1100 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po1101 @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.c1104 1105 libcfa_a-time.obj: time.c1106 @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.Po1108 @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`1111 1082 1112 1083 libcfa_a-stdlib.o: stdlib.c -
src/libcfa/bits/locks.h
rca37445 r9d1e3f7 10 10 // Created On : Tue Oct 31 15:14:38 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:18:13 201813 // Update Count : 912 // Last Modified On : Fri Dec 8 16:02:22 2017 13 // Update Count : 1 14 14 // 15 15 … … 64 64 65 65 extern void yield( unsigned int ); 66 extern thread_local struct thread_desc * volatile this_thread; 67 extern thread_local struct processor * volatile this_processor; 66 68 67 69 static inline void ?{}( __spinlock_t & this ) { … … 74 76 if( result ) { 75 77 disable_interrupts(); 76 //__cfaabi_dbg_debug_do(77 //this.prev_name = caller;78 // this.prev_thrd = TL_GET( this_thread );79 //)78 __cfaabi_dbg_debug_do( 79 this.prev_name = caller; 80 this.prev_thrd = this_thread; 81 ) 80 82 } 81 83 return result; … … 105 107 } 106 108 disable_interrupts(); 107 //__cfaabi_dbg_debug_do(108 //this.prev_name = caller;109 // this.prev_thrd = TL_GET( this_thread );110 //)109 __cfaabi_dbg_debug_do( 110 this.prev_name = caller; 111 this.prev_thrd = this_thread; 112 ) 111 113 } 112 114 -
src/libcfa/concurrency/alarm.c
rca37445 r9d1e3f7 10 10 // Created On : Fri Jun 2 11:31:25 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 9 13:36:18 201813 // Update Count : 6112 // Last Modified On : Fri Jul 21 22:35:18 2017 13 // Update Count : 1 14 14 // 15 15 … … 26 26 #include "preemption.h" 27 27 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 28 42 //============================================================================================= 29 43 // Clock logic 30 44 //============================================================================================= 31 45 32 Time__kernel_get_time() {46 __cfa_time_t __kernel_get_time() { 33 47 timespec curr; 34 clock_gettime( CLOCK_ MONOTONIC_RAW, &curr ); // CLOCK_REALTIME35 return ( Time){curr };48 clock_gettime( CLOCK_REALTIME, &curr ); 49 return (__cfa_time_t){ &curr }; 36 50 } 37 51 38 void __kernel_set_timer( Duration alarm ) { 39 setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL ); 52 void __kernel_set_timer( __cfa_time_t alarm ) { 53 itimerval val = { &alarm }; 54 setitimer( ITIMER_REAL, &val, NULL ); 40 55 } 41 56 … … 44 59 //============================================================================================= 45 60 46 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period) with( this ) {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 ) { 47 62 this.thrd = thrd; 48 63 this.alarm = alarm; … … 53 68 } 54 69 55 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period) with( this ) {70 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s ) with( this ) { 56 71 this.proc = proc; 57 72 this.alarm = alarm; -
src/libcfa/concurrency/alarm.h
rca37445 r9d1e3f7 10 10 // Created On : Fri Jun 2 11:31:25 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 26 16:25:41 201813 // Update Count : 1112 // Last Modified On : Sat Jul 22 09:59:27 2017 13 // Update Count : 3 14 14 // 15 15 … … 21 21 #include <assert.h> 22 22 23 #include " time"23 #include "bits/cfatime.h" 24 24 25 25 struct thread_desc; … … 30 30 //============================================================================================= 31 31 32 Time__kernel_get_time();33 void __kernel_set_timer( Durationalarm );32 __cfa_time_t __kernel_get_time(); 33 void __kernel_set_timer( __cfa_time_t alarm ); 34 34 35 35 //============================================================================================= … … 38 38 39 39 struct alarm_node_t { 40 Time alarm;// time when alarm goes off41 Duration period;// if > 0 => period of alarm40 __cfa_time_t alarm; // time when alarm goes off 41 __cfa_time_t period; // if > 0 => period of alarm 42 42 alarm_node_t * next; // intrusive link list field 43 43 … … 53 53 typedef alarm_node_t ** __alarm_it_t; 54 54 55 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period);56 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period);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 ); 57 57 void ^?{}( alarm_node_t & this ); 58 58 -
src/libcfa/concurrency/coroutine
rca37445 r9d1e3f7 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:23:45 201813 // Update Count : 812 // Last Modified On : Wed Aug 30 07:58:29 2017 13 // Update Count : 3 14 14 // 15 15 … … 60 60 } 61 61 62 // Get current coroutine 63 extern thread_local coroutine_desc * volatile this_coroutine; 64 62 65 // Private wrappers for context switch and stack creation 63 66 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst); … … 66 69 // Suspend implementation inlined for performance 67 70 static inline void suspend() { 68 coroutine_desc * src = TL_GET( this_coroutine );// optimization71 coroutine_desc * src = this_coroutine; // optimization 69 72 70 73 assertf( src->last != 0, … … 83 86 forall(dtype T | is_coroutine(T)) 84 87 static inline void resume(T & cor) { 85 coroutine_desc * src = TL_GET( this_coroutine );// optimization88 coroutine_desc * src = this_coroutine; // optimization 86 89 coroutine_desc * dst = get_coroutine(cor); 87 90 … … 108 111 109 112 static inline void resume(coroutine_desc * dst) { 110 coroutine_desc * src = TL_GET( this_coroutine );// optimization113 coroutine_desc * src = this_coroutine; // optimization 111 114 112 115 // not resuming self ? -
src/libcfa/concurrency/coroutine.c
rca37445 r9d1e3f7 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 17:20:57201813 // Update Count : 912 // Last Modified On : Thu Feb 8 16:10:31 2018 13 // Update Count : 4 14 14 // 15 15 … … 99 99 // Wrapper for co 100 100 void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 101 verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );101 verify( preemption_state.enabled || this_processor->do_terminate ); 102 102 disable_interrupts(); 103 103 … … 106 106 107 107 // set new coroutine that task is executing 108 TL_SET( this_coroutine, dst );108 this_coroutine = dst; 109 109 110 110 // context switch to specified coroutine … … 117 117 118 118 enable_interrupts( __cfaabi_dbg_ctx ); 119 verify( TL_GET( preemption_state ).enabled || TL_GET( this_processor )->do_terminate );119 verify( preemption_state.enabled || this_processor->do_terminate ); 120 120 } //ctxSwitchDirect 121 121 … … 172 172 173 173 void __leave_coroutine(void) { 174 coroutine_desc * src = TL_GET( this_coroutine );// optimization174 coroutine_desc * src = this_coroutine; // optimization 175 175 176 176 assertf( src->starter != 0, -
src/libcfa/concurrency/invoke.h
rca37445 r9d1e3f7 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 22:33:59201813 // Update Count : 3012 // Last Modified On : Fri Feb 9 14:41:55 2018 13 // Update Count : 6 14 14 // 15 15 … … 17 17 #include "bits/defs.h" 18 18 #include "bits/locks.h" 19 20 #define TL_GET( member ) kernelThreadData.member21 #define TL_SET( member, value ) kernelThreadData.member = value;22 19 23 20 #ifdef __cforall … … 33 30 static inline struct thread_desc * & get_next( struct thread_desc & this ); 34 31 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;47 32 } 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 ); }52 33 #endif 53 34 54 35 struct coStack_t { 55 size_t size; // size of stack 56 void * storage; // pointer to stack 57 void * limit; // stack grows towards stack limit 58 void * base; // base of stack 59 void * context; // address of cfa_context_t 60 void * top; // address of top of storage 61 bool userStack; // whether or not the user allocated the stack 36 // size of stack 37 size_t size; 38 39 // pointer to stack 40 void *storage; 41 42 // stack grows towards stack limit 43 void *limit; 44 45 // base of stack 46 void *base; 47 48 // address of cfa_context_t 49 void *context; 50 51 // address of top of storage 52 void *top; 53 54 // whether or not the user allocated the stack 55 bool userStack; 62 56 }; 63 57 … … 65 59 66 60 struct coroutine_desc { 67 struct coStack_t stack; // stack information of the coroutine 68 const char * name; // textual name for coroutine/task, initialized by uC++ generated code 69 int errno_; // copy of global UNIX variable errno 70 enum coroutine_state state; // current execution status for coroutine 71 struct coroutine_desc * starter; // first coroutine to resume this one 72 struct coroutine_desc * last; // last coroutine to resume this one 61 // stack information of the coroutine 62 struct coStack_t stack; 63 64 // textual name for coroutine/task, initialized by uC++ generated code 65 const char *name; 66 67 // copy of global UNIX variable errno 68 int errno_; 69 70 // current execution status for coroutine 71 enum coroutine_state state; 72 73 // first coroutine to resume this one 74 struct coroutine_desc * starter; 75 76 // last coroutine to resume this one 77 struct coroutine_desc * last; 73 78 }; 74 79 -
src/libcfa/concurrency/kernel
rca37445 r9d1e3f7 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 23 17:08:20 201813 // Update Count : 312 // Last Modified On : Sat Jul 22 09:58:39 2017 13 // Update Count : 2 14 14 // 15 15 … … 19 19 20 20 #include "invoke.h" 21 #include " time"21 #include "bits/cfatime.h" 22 22 23 23 extern "C" { … … 49 49 50 50 // Preemption rate on this cluster 51 Durationpreemption_rate;51 __cfa_time_t preemption_rate; 52 52 }; 53 53 54 extern Durationdefault_preemption();54 extern __cfa_time_t default_preemption(); 55 55 56 56 void ?{} (cluster & this); -
src/libcfa/concurrency/kernel.c
rca37445 r9d1e3f7 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:26:11201813 // Update Count : 2312 // Last Modified On : Thu Feb 8 23:52:19 2018 13 // Update Count : 5 14 14 // 15 15 … … 52 52 // Global state 53 53 54 thread_local coroutine_desc * volatile this_coroutine; 55 thread_local thread_desc * volatile this_thread; 56 thread_local processor * volatile this_processor; 57 54 58 // volatile thread_local bool preemption_in_progress = 0; 55 59 // volatile thread_local bool preemption_enabled = false; 56 60 // volatile thread_local unsigned short disable_preempt_count = 1; 57 61 58 thread_local struct KernelThreadData kernelThreadData = { 59 NULL, 60 NULL, 61 NULL, 62 { 1, false, false } 63 }; 62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 }; 64 63 65 64 //----------------------------------------------------------------------------- … … 173 172 terminate(&this); 174 173 verify(this.do_terminate); 175 verify( TL_GET( this_processor )!= &this);174 verify(this_processor != &this); 176 175 P( terminated ); 177 verify( TL_GET( this_processor )!= &this);176 verify(this_processor != &this); 178 177 pthread_join( kernel_thread, NULL ); 179 178 } … … 214 213 if(readyThread) 215 214 { 216 verify( ! TL_GET( preemption_state ).enabled );215 verify( !preemption_state.enabled ); 217 216 218 217 runThread(this, readyThread); 219 218 220 verify( ! TL_GET( preemption_state ).enabled );219 verify( !preemption_state.enabled ); 221 220 222 221 //Some actions need to be taken from the kernel … … 250 249 251 250 //Update global state 252 TL_SET( this_thread, dst );251 this_thread = dst; 253 252 254 253 // Context Switch to the thread … … 258 257 259 258 void returnToKernel() { 260 coroutine_desc * proc_cor = get_coroutine( TL_GET( this_processor )->runner);261 coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine );259 coroutine_desc * proc_cor = get_coroutine(this_processor->runner); 260 coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine; 262 261 ThreadCtxSwitch(thrd_cor, proc_cor); 263 262 } … … 267 266 void finishRunning(processor * this) with( this->finish ) { 268 267 if( action_code == Release ) { 269 verify( ! TL_GET( preemption_state ).enabled );268 verify( !preemption_state.enabled ); 270 269 unlock( *lock ); 271 270 } … … 274 273 } 275 274 else if( action_code == Release_Schedule ) { 276 verify( ! TL_GET( preemption_state ).enabled );275 verify( !preemption_state.enabled ); 277 276 unlock( *lock ); 278 277 ScheduleThread( thrd ); 279 278 } 280 279 else if( action_code == Release_Multi ) { 281 verify( ! TL_GET( preemption_state ).enabled );280 verify( !preemption_state.enabled ); 282 281 for(int i = 0; i < lock_count; i++) { 283 282 unlock( *locks[i] ); … … 308 307 void * CtxInvokeProcessor(void * arg) { 309 308 processor * proc = (processor *) arg; 310 TL_SET( this_processor, proc );311 TL_SET( this_coroutine, NULL );312 TL_SET( this_thread, NULL );313 TL_GET( preemption_state ).enabled = false;314 TL_GET( preemption_state ).disable_count = 1;309 this_processor = proc; 310 this_coroutine = NULL; 311 this_thread = NULL; 312 preemption_state.enabled = false; 313 preemption_state.disable_count = 1; 315 314 // SKULLDUGGERY: We want to create a context for the processor coroutine 316 315 // which is needed for the 2-step context switch. However, there is no reason … … 324 323 325 324 //Set global state 326 TL_SET( this_coroutine, get_coroutine(proc->runner));327 TL_SET( this_thread, NULL );325 this_coroutine = get_coroutine(proc->runner); 326 this_thread = NULL; 328 327 329 328 //We now have a proper context from which to schedule threads … … 353 352 354 353 void kernel_first_resume(processor * this) { 355 coroutine_desc * src = TL_GET( this_coroutine );354 coroutine_desc * src = this_coroutine; 356 355 coroutine_desc * dst = get_coroutine(this->runner); 357 356 358 verify( ! TL_GET( preemption_state ).enabled );357 verify( !preemption_state.enabled ); 359 358 360 359 create_stack(&dst->stack, dst->stack.size); 361 360 CtxStart(&this->runner, CtxInvokeCoroutine); 362 361 363 verify( ! TL_GET( preemption_state ).enabled );362 verify( !preemption_state.enabled ); 364 363 365 364 dst->last = src; … … 370 369 371 370 // set new coroutine that task is executing 372 TL_SET( this_coroutine, dst );371 this_coroutine = dst; 373 372 374 373 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 387 386 src->state = Active; 388 387 389 verify( ! TL_GET( preemption_state ).enabled );388 verify( !preemption_state.enabled ); 390 389 } 391 390 … … 393 392 // Scheduler routines 394 393 void ScheduleThread( thread_desc * thrd ) { 395 // if( ! thrd ) return;394 // if( !thrd ) return; 396 395 verify( thrd ); 397 396 verify( thrd->self_cor.state != Halted ); 398 397 399 verify( ! TL_GET( preemption_state ).enabled );398 verify( !preemption_state.enabled ); 400 399 401 400 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 402 401 403 with( * TL_GET( this_processor )->cltr ) {402 with( *this_processor->cltr ) { 404 403 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 405 404 append( ready_queue, thrd ); … … 407 406 } 408 407 409 verify( ! TL_GET( preemption_state ).enabled );408 verify( !preemption_state.enabled ); 410 409 } 411 410 412 411 thread_desc * nextThread(cluster * this) with( *this ) { 413 verify( ! TL_GET( preemption_state ).enabled );412 verify( !preemption_state.enabled ); 414 413 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 415 414 thread_desc * head = pop_head( ready_queue ); 416 415 unlock( ready_queue_lock ); 417 verify( ! TL_GET( preemption_state ).enabled );416 verify( !preemption_state.enabled ); 418 417 return head; 419 418 } … … 421 420 void BlockInternal() { 422 421 disable_interrupts(); 423 verify( ! TL_GET( preemption_state ).enabled );422 verify( !preemption_state.enabled ); 424 423 returnToKernel(); 425 verify( ! TL_GET( preemption_state ).enabled );424 verify( !preemption_state.enabled ); 426 425 enable_interrupts( __cfaabi_dbg_ctx ); 427 426 } … … 429 428 void BlockInternal( __spinlock_t * lock ) { 430 429 disable_interrupts(); 431 TL_GET( this_processor )->finish.action_code = Release;432 TL_GET( this_processor )->finish.lock = lock;433 434 verify( ! TL_GET( preemption_state ).enabled );430 this_processor->finish.action_code = Release; 431 this_processor->finish.lock = lock; 432 433 verify( !preemption_state.enabled ); 435 434 returnToKernel(); 436 verify( ! TL_GET( preemption_state ).enabled );435 verify( !preemption_state.enabled ); 437 436 438 437 enable_interrupts( __cfaabi_dbg_ctx ); … … 441 440 void BlockInternal( thread_desc * thrd ) { 442 441 disable_interrupts(); 443 TL_GET( this_processor )->finish.action_code = Schedule;444 TL_GET( this_processor )->finish.thrd = thrd;445 446 verify( ! TL_GET( preemption_state ).enabled );442 this_processor->finish.action_code = Schedule; 443 this_processor->finish.thrd = thrd; 444 445 verify( !preemption_state.enabled ); 447 446 returnToKernel(); 448 verify( ! TL_GET( preemption_state ).enabled );447 verify( !preemption_state.enabled ); 449 448 450 449 enable_interrupts( __cfaabi_dbg_ctx ); … … 454 453 assert(thrd); 455 454 disable_interrupts(); 456 TL_GET( this_processor )->finish.action_code = Release_Schedule;457 TL_GET( this_processor )->finish.lock = lock;458 TL_GET( this_processor )->finish.thrd = thrd;459 460 verify( ! TL_GET( preemption_state ).enabled );455 this_processor->finish.action_code = Release_Schedule; 456 this_processor->finish.lock = lock; 457 this_processor->finish.thrd = thrd; 458 459 verify( !preemption_state.enabled ); 461 460 returnToKernel(); 462 verify( ! TL_GET( preemption_state ).enabled );461 verify( !preemption_state.enabled ); 463 462 464 463 enable_interrupts( __cfaabi_dbg_ctx ); … … 467 466 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 468 467 disable_interrupts(); 469 TL_GET( this_processor )->finish.action_code = Release_Multi;470 TL_GET( this_processor )->finish.locks = locks;471 TL_GET( this_processor )->finish.lock_count = count;472 473 verify( ! TL_GET( preemption_state ).enabled );468 this_processor->finish.action_code = Release_Multi; 469 this_processor->finish.locks = locks; 470 this_processor->finish.lock_count = count; 471 472 verify( !preemption_state.enabled ); 474 473 returnToKernel(); 475 verify( ! TL_GET( preemption_state ).enabled );474 verify( !preemption_state.enabled ); 476 475 477 476 enable_interrupts( __cfaabi_dbg_ctx ); … … 480 479 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 481 480 disable_interrupts(); 482 TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule;483 TL_GET( this_processor )->finish.locks = locks;484 TL_GET( this_processor )->finish.lock_count = lock_count;485 TL_GET( this_processor )->finish.thrds = thrds;486 TL_GET( this_processor )->finish.thrd_count = thrd_count;487 488 verify( ! TL_GET( preemption_state ).enabled );481 this_processor->finish.action_code = Release_Multi_Schedule; 482 this_processor->finish.locks = locks; 483 this_processor->finish.lock_count = lock_count; 484 this_processor->finish.thrds = thrds; 485 this_processor->finish.thrd_count = thrd_count; 486 487 verify( !preemption_state.enabled ); 489 488 returnToKernel(); 490 verify( ! TL_GET( preemption_state ).enabled );489 verify( !preemption_state.enabled ); 491 490 492 491 enable_interrupts( __cfaabi_dbg_ctx ); … … 494 493 495 494 void LeaveThread(__spinlock_t * lock, thread_desc * thrd) { 496 verify( ! TL_GET( preemption_state ).enabled );497 TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release;498 TL_GET( this_processor )->finish.lock = lock;499 TL_GET( this_processor )->finish.thrd = thrd;495 verify( !preemption_state.enabled ); 496 this_processor->finish.action_code = thrd ? Release_Schedule : Release; 497 this_processor->finish.lock = lock; 498 this_processor->finish.thrd = thrd; 500 499 501 500 returnToKernel(); … … 508 507 // Kernel boot procedures 509 508 void kernel_startup(void) { 510 verify( ! TL_GET( preemption_state ).enabled );509 verify( !preemption_state.enabled ); 511 510 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 512 511 … … 532 531 533 532 //initialize the global state variables 534 TL_SET( this_processor, mainProcessor );535 TL_SET( this_thread, mainThread );536 TL_SET( this_coroutine, &mainThread->self_cor );533 this_processor = mainProcessor; 534 this_thread = mainThread; 535 this_coroutine = &mainThread->self_cor; 537 536 538 537 // Enable preemption … … 546 545 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 547 546 // mainThread is on the ready queue when this call is made. 548 kernel_first_resume( TL_GET( this_processor ));547 kernel_first_resume( this_processor ); 549 548 550 549 … … 553 552 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 554 553 555 verify( ! TL_GET( preemption_state ).enabled );554 verify( !preemption_state.enabled ); 556 555 enable_interrupts( __cfaabi_dbg_ctx ); 557 verify( TL_GET( preemption_state ).enabled );556 verify( preemption_state.enabled ); 558 557 } 559 558 … … 561 560 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 562 561 563 verify( TL_GET( preemption_state ).enabled );562 verify( preemption_state.enabled ); 564 563 disable_interrupts(); 565 verify( ! TL_GET( preemption_state ).enabled );564 verify( !preemption_state.enabled ); 566 565 567 566 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 603 602 604 603 // first task to abort ? 605 if ( ! kernel_abort_called ) { // not first task to abort ?604 if ( !kernel_abort_called ) { // not first task to abort ? 606 605 kernel_abort_called = true; 607 606 unlock( kernel_abort_lock ); … … 618 617 } 619 618 620 return TL_GET( this_thread );619 return this_thread; 621 620 } 622 621 … … 627 626 __cfaabi_dbg_bits_write( abort_text, len ); 628 627 629 if ( thrd != TL_GET( this_coroutine )) {630 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ));628 if ( thrd != this_coroutine ) { 629 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine ); 631 630 __cfaabi_dbg_bits_write( abort_text, len ); 632 631 } … … 637 636 638 637 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 639 return get_coroutine( TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2;638 return get_coroutine(this_thread) == get_coroutine(mainThread) ? 4 : 2; 640 639 } 641 640 … … 667 666 if ( count < 0 ) { 668 667 // queue current task 669 append( waiting, (thread_desc *) TL_GET( this_thread ));668 append( waiting, (thread_desc *)this_thread ); 670 669 671 670 // atomically release spin lock and block -
src/libcfa/concurrency/kernel_private.h
rca37445 r9d1e3f7 10 10 // Created On : Mon Feb 13 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 29 14:06:40 201813 // Update Count : 312 // Last Modified On : Sat Jul 22 09:58:09 2017 13 // Update Count : 2 14 14 // 15 15 … … 66 66 extern event_kernel_t * event_kernel; 67 67 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; 71 71 72 72 // extern volatile thread_local bool preemption_in_progress; -
src/libcfa/concurrency/monitor.c
rca37445 r9d1e3f7 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 14:30:26201813 // Update Count : 912 // Last Modified On : Fri Feb 16 14:49:53 2018 13 // Update Count : 5 14 14 // 15 15 … … 85 85 // Lock the monitor spinlock 86 86 lock( this->lock __cfaabi_dbg_ctx2 ); 87 thread_desc * thrd = TL_GET( this_thread );87 thread_desc * thrd = this_thread; 88 88 89 89 __cfaabi_dbg_print_safe( "Kernel : %10p Entering mon %p (%p)\n", thrd, this, this->owner); … … 134 134 // Lock the monitor spinlock 135 135 lock( this->lock __cfaabi_dbg_ctx2 ); 136 thread_desc * thrd = TL_GET( this_thread );136 thread_desc * thrd = this_thread; 137 137 138 138 __cfaabi_dbg_print_safe( "Kernel : %10p Entering dtor for mon %p (%p)\n", thrd, this, this->owner); … … 168 168 169 169 // Create the node specific to this wait operation 170 wait_ctx_primed( TL_GET( this_thread ), 0 )170 wait_ctx_primed( this_thread, 0 ) 171 171 172 172 // Some one else has the monitor, wait for him to finish and then run … … 179 179 __cfaabi_dbg_print_safe( "Kernel : blocking \n" ); 180 180 181 wait_ctx( TL_GET( this_thread ), 0 )181 wait_ctx( this_thread, 0 ) 182 182 this->dtor_node = &waiter; 183 183 … … 199 199 lock( this->lock __cfaabi_dbg_ctx2 ); 200 200 201 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", TL_GET( this_thread ), this, this->owner);202 203 verifyf( TL_GET( this_thread ) == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", TL_GET( this_thread ), this->owner, this->recursion, this );201 __cfaabi_dbg_print_safe( "Kernel : %10p Leaving mon %p (%p)\n", this_thread, this, this->owner); 202 203 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i, m: %p)", this_thread, this->owner, this->recursion, this ); 204 204 205 205 // Leaving a recursion level, decrement the counter … … 227 227 void __leave_dtor_monitor_desc( monitor_desc * this ) { 228 228 __cfaabi_dbg_debug_do( 229 if( TL_GET( this_thread )!= this->owner ) {230 abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, TL_GET( this_thread ), this->owner);229 if( this_thread != this->owner ) { 230 abort( "Destroyed monitor %p has inconsistent owner, expected %p got %p.\n", this, this_thread, this->owner); 231 231 } 232 232 if( this->recursion != 1 ) { … … 297 297 298 298 // Save previous thread context 299 this.prev = TL_GET( this_thread )->monitors;299 this.prev = this_thread->monitors; 300 300 301 301 // Update thread context (needed for conditions) 302 ( TL_GET( this_thread )->monitors){m, count, func};302 (this_thread->monitors){m, count, func}; 303 303 304 304 // __cfaabi_dbg_print_safe( "MGUARD : enter %d\n", count); … … 322 322 323 323 // Restore thread context 324 TL_GET( this_thread )->monitors = this.prev;324 this_thread->monitors = this.prev; 325 325 } 326 326 … … 332 332 333 333 // Save previous thread context 334 this.prev = TL_GET( this_thread )->monitors;334 this.prev = this_thread->monitors; 335 335 336 336 // Update thread context (needed for conditions) 337 ( TL_GET( this_thread )->monitors){m, 1, func};337 (this_thread->monitors){m, 1, func}; 338 338 339 339 __enter_monitor_dtor( this.m, func ); … … 346 346 347 347 // Restore thread context 348 TL_GET( this_thread )->monitors = this.prev;348 this_thread->monitors = this.prev; 349 349 } 350 350 … … 386 386 387 387 // Create the node specific to this wait operation 388 wait_ctx( TL_GET( this_thread ), user_info );388 wait_ctx( this_thread, user_info ); 389 389 390 390 // Append the current wait operation to the ones already queued on the condition … … 425 425 //Some more checking in debug 426 426 __cfaabi_dbg_debug_do( 427 thread_desc * this_thrd = TL_GET( this_thread );427 thread_desc * this_thrd = this_thread; 428 428 if ( this.monitor_count != this_thrd->monitors.size ) { 429 429 abort( "Signal on condition %p made with different number of monitor(s), expected %zi got %zi", &this, this.monitor_count, this_thrd->monitors.size ); … … 473 473 474 474 // Create the node specific to this wait operation 475 wait_ctx_primed( TL_GET( this_thread ), 0 )475 wait_ctx_primed( this_thread, 0 ) 476 476 477 477 //save contexts … … 566 566 567 567 // Create the node specific to this wait operation 568 wait_ctx_primed( TL_GET( this_thread ), 0 );568 wait_ctx_primed( this_thread, 0 ); 569 569 570 570 // Save monitor states … … 612 612 613 613 // Create the node specific to this wait operation 614 wait_ctx_primed( TL_GET( this_thread ), 0 );614 wait_ctx_primed( this_thread, 0 ); 615 615 616 616 monitor_save; … … 618 618 619 619 for( __lock_size_t i = 0; i < count; i++) { 620 verify( monitors[i]->owner == TL_GET( this_thread ));620 verify( monitors[i]->owner == this_thread ); 621 621 } 622 622 … … 812 812 813 813 static inline void brand_condition( condition & this ) { 814 thread_desc * thrd = TL_GET( this_thread );814 thread_desc * thrd = this_thread; 815 815 if( !this.monitors ) { 816 816 // __cfaabi_dbg_print_safe( "Branding\n" ); -
src/libcfa/concurrency/preemption.c
rca37445 r9d1e3f7 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 9 13:52:39201813 // Update Count : 3612 // Last Modified On : Fri Feb 9 16:38:13 2018 13 // Update Count : 14 14 14 // 15 15 … … 23 23 } 24 24 25 #include "bits/cfatime.h" 25 26 #include "bits/signal.h" 26 27 27 28 #if !defined(__CFA_DEFAULT_PREEMPTION__) 28 #define __CFA_DEFAULT_PREEMPTION__ 10` ms29 #define __CFA_DEFAULT_PREEMPTION__ 10`cfa_ms 29 30 #endif 30 31 31 Durationdefault_preemption() __attribute__((weak)) {32 __cfa_time_t default_preemption() __attribute__((weak)) { 32 33 return __CFA_DEFAULT_PREEMPTION__; 33 34 } … … 77 78 78 79 // Get next expired node 79 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Timecurrtime ) {80 static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_t currtime ) { 80 81 if( !alarms->head ) return NULL; // If no alarms return null 81 82 if( alarms->head->alarm >= currtime ) return NULL; // If alarms head not expired return null … … 87 88 alarm_node_t * node = NULL; // Used in the while loop but cannot be declared in the while condition 88 89 alarm_list_t * alarms = &event_kernel->alarms; // Local copy for ease of reading 89 Time currtime = __kernel_get_time();// Check current time once so we everything "happens at once"90 __cfa_time_t currtime = __kernel_get_time(); // Check current time once so we everything "happens at once" 90 91 91 92 //Loop throught every thing expired … … 101 102 102 103 // Check if this is a periodic alarm 103 Durationperiod = node->period;104 __cfa_time_t period = node->period; 104 105 if( period > 0 ) { 105 106 node->alarm = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) … … 116 117 117 118 // Update the preemption of a processor and notify interested parties 118 void update_preemption( processor * this, Durationduration ) {119 void update_preemption( processor * this, __cfa_time_t duration ) { 119 120 alarm_node_t * alarm = this->preemption_alarm; 120 121 121 122 // Alarms need to be enabled 122 if ( duration > 0 && ! alarm->set ) {123 if ( duration > 0 && !alarm->set ) { 123 124 alarm->alarm = __kernel_get_time() + duration; 124 125 alarm->period = duration; 125 126 register_self( alarm ); 126 127 } 127 // Zero dura tion but alarm is set128 // Zero duraction but alarm is set 128 129 else if ( duration == 0 && alarm->set ) { 129 130 unregister_self( alarm ); … … 149 150 // Disable interrupts by incrementing the counter 150 151 void disable_interrupts() { 151 TL_GET( preemption_state ).enabled = false;152 __attribute__((unused)) unsigned short new_val = TL_GET( preemption_state ).disable_count + 1;153 TL_GET( preemption_state ).disable_count = new_val;152 preemption_state.enabled = false; 153 __attribute__((unused)) unsigned short new_val = preemption_state.disable_count + 1; 154 preemption_state.disable_count = new_val; 154 155 verify( new_val < 65_000u ); // If this triggers someone is disabling interrupts without enabling them 155 156 } … … 158 159 // If counter reaches 0, execute any pending CtxSwitch 159 160 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 160 processor * proc = TL_GET( this_processor );// Cache the processor now since interrupts can start happening after the atomic add161 thread_desc * thrd = TL_GET( this_thread );// Cache the thread now since interrupts can start happening after the atomic add162 163 unsigned short prev = TL_GET( preemption_state ).disable_count;164 TL_GET( preemption_state ).disable_count -= 1;161 processor * proc = this_processor; // Cache the processor now since interrupts can start happening after the atomic add 162 thread_desc * thrd = this_thread; // Cache the thread now since interrupts can start happening after the atomic add 163 164 unsigned short prev = preemption_state.disable_count; 165 preemption_state.disable_count -= 1; 165 166 verify( prev != 0u ); // If this triggers someone is enabled already enabled interruptsverify( prev != 0u ); 166 167 167 168 // Check if we need to prempt the thread because an interrupt was missed 168 169 if( prev == 1 ) { 169 TL_GET( preemption_state ).enabled = true;170 preemption_state.enabled = true; 170 171 if( proc->pending_preemption ) { 171 172 proc->pending_preemption = false; … … 181 182 // Don't execute any pending CtxSwitch even if counter reaches 0 182 183 void enable_interrupts_noPoll() { 183 unsigned short prev = TL_GET( preemption_state ).disable_count;184 TL_GET( preemption_state ).disable_count -= 1;184 unsigned short prev = preemption_state.disable_count; 185 preemption_state.disable_count -= 1; 185 186 verifyf( prev != 0u, "Incremented from %u\n", prev ); // If this triggers someone is enabled already enabled interrupts 186 187 if( prev == 1 ) { 187 TL_GET( preemption_state ).enabled = true;188 preemption_state.enabled = true; 188 189 } 189 190 } … … 235 236 // If false : preemption is unsafe and marked as pending 236 237 static inline bool preemption_ready() { 237 bool ready = TL_GET( preemption_state ).enabled && !TL_GET( preemption_state ).in_progress; // Check if preemption is safe238 TL_GET( this_processor )->pending_preemption = !ready;// Adjust the pending flag accordingly238 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 239 240 return ready; 240 241 } … … 250 251 251 252 // Start with preemption disabled until ready 252 TL_GET( preemption_state ).enabled = false;253 TL_GET( preemption_state ).disable_count = 1;253 preemption_state.enabled = false; 254 preemption_state.disable_count = 1; 254 255 255 256 // Initialize the event kernel … … 290 291 // Used by thread to control when they want to receive preemption signals 291 292 void ?{}( preemption_scope & this, processor * proc ) { 292 (this.alarm){ proc, (Time){ 0 }, 0`s };293 (this.alarm){ proc, 0`cfa_s, 0`cfa_s }; 293 294 this.proc = proc; 294 295 this.proc->preemption_alarm = &this.alarm; … … 300 301 disable_interrupts(); 301 302 302 update_preemption( this.proc, 0` s );303 update_preemption( this.proc, 0`cfa_s ); 303 304 } 304 305 … … 316 317 // before the kernel thread has even started running. When that happens an iterrupt 317 318 // we a null 'this_processor' will be caught, just ignore it. 318 if(! TL_GET( this_processor )) return;319 if(!this_processor) return; 319 320 320 321 choose(sfp->si_value.sival_int) { 321 322 case PREEMPT_NORMAL : ;// Normal case, nothing to do here 322 case PREEMPT_TERMINATE: verify( TL_GET( this_processor )->do_terminate);323 case PREEMPT_TERMINATE: verify(this_processor->do_terminate); 323 324 default: 324 325 abort( "internal error, signal value is %d", sfp->si_value.sival_int ); … … 330 331 __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread); 331 332 332 TL_GET( preemption_state ).in_progress = true;// Sync flag : prevent recursive calls to the signal handler333 preemption_state.in_progress = true; // Sync flag : prevent recursive calls to the signal handler 333 334 signal_unblock( SIGUSR1 ); // We are about to CtxSwitch out of the signal handler, let other handlers in 334 TL_GET( preemption_state ).in_progress = false;// Clear the in progress flag335 preemption_state.in_progress = false; // Clear the in progress flag 335 336 336 337 // Preemption can occur here 337 338 338 BlockInternal( (thread_desc*) TL_GET( this_thread ) );// Do the actual CtxSwitch339 BlockInternal( (thread_desc*)this_thread ); // Do the actual CtxSwitch 339 340 } 340 341 -
src/libcfa/concurrency/preemption.h
rca37445 r9d1e3f7 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 23 17:18:53 201813 // Update Count : 212 // Last Modified On : Fri Jul 21 22:34:25 2017 13 // Update Count : 1 14 14 // 15 15 … … 21 21 void kernel_start_preemption(); 22 22 void kernel_stop_preemption(); 23 void update_preemption( processor * this, Durationduration );23 void update_preemption( processor * this, __cfa_time_t duration ); 24 24 void tick_preemption(); 25 25 -
src/libcfa/concurrency/thread
rca37445 r9d1e3f7 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 29 14:07:11 201813 // Update Count : 412 // Last Modified On : Sat Jul 22 09:59:40 2017 13 // Update Count : 3 14 14 // 15 15 … … 52 52 } 53 53 54 //extern thread_local thread_desc * volatile this_thread;54 extern thread_local thread_desc * volatile this_thread; 55 55 56 56 forall( dtype T | is_thread(T) ) -
src/libcfa/concurrency/thread.c
rca37445 r9d1e3f7 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 17:19:52 201813 // Update Count : 812 // Last Modified On : Fri Jul 21 22:34:46 2017 13 // Update Count : 1 14 14 // 15 15 … … 26 26 } 27 27 28 //extern volatile thread_local processor * this_processor;28 extern volatile thread_local processor * this_processor; 29 29 30 30 //----------------------------------------------------------------------------- … … 75 75 coroutine_desc* thrd_c = get_coroutine(this); 76 76 thread_desc * thrd_h = get_thread (this); 77 thrd_c->last = TL_GET( this_coroutine );77 thrd_c->last = this_coroutine; 78 78 79 79 // __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); … … 81 81 disable_interrupts(); 82 82 create_stack(&thrd_c->stack, thrd_c->stack.size); 83 TL_SET( this_coroutine, thrd_c );83 this_coroutine = thrd_c; 84 84 CtxStart(&this, CtxInvokeThread); 85 85 assert( thrd_c->last->stack.context ); … … 92 92 extern "C" { 93 93 void __finish_creation(void) { 94 coroutine_desc* thrd_c = TL_GET( this_coroutine );94 coroutine_desc* thrd_c = this_coroutine; 95 95 ThreadCtxSwitch( thrd_c, thrd_c->last ); 96 96 } … … 98 98 99 99 void yield( void ) { 100 verify( TL_GET( preemption_state ).enabled );101 BlockInternal( TL_GET( this_thread ));102 verify( TL_GET( preemption_state ).enabled );100 verify( preemption_state.enabled ); 101 BlockInternal( this_thread ); 102 verify( preemption_state.enabled ); 103 103 } 104 104 … … 116 116 // set new coroutine that the processor is executing 117 117 // and context switch to it 118 TL_SET( this_coroutine, dst );118 this_coroutine = dst; 119 119 assert( src->stack.context ); 120 120 CtxSwitch( src->stack.context, dst->stack.context ); 121 TL_SET( this_coroutine, src );121 this_coroutine = src; 122 122 123 123 // set state of new coroutine to active -
src/libcfa/time
rca37445 r9d1e3f7 1 1 // 2 // Cforall Version 1.0.0 Copyright (C) 201 8University of Waterloo2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // time--7 // calendar -- 8 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Wed Mar 14 23:18:57 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 9 13:10:23201813 // Update Count : 61612 // Last Modified On : Thu Mar 22 17:11:19 2018 13 // Update Count : 495 14 14 // 15 15 … … 19 19 // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0355r5.html#refcc 20 20 21 #include <time.h> // timespec21 #include <time.h> 22 22 extern "C" { 23 #include <sys/time.h> // timeval 23 #include <sys/time.h> 24 int snprintf( char * buf, size_t size, const char * fmt, ... ); 24 25 } 25 #include <iostream> // istype/ostype 26 27 enum { TIMEGRAN = 1_000_000_000LL }; // nanosecond granularity, except for timeval 28 29 30 //######################### Duration ######################### 31 32 struct Duration { // private 33 int64_t tv; // nanoseconds 34 }; // Duration 35 36 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; } 37 static inline void ?{}( Duration & dur, Duration d ) with( dur ) { tv = d.tv; } 38 39 static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; } 40 static inline Duration ?=?( Duration & dur, zero_t ) { return dur{ 0 }; } 41 42 static inline Duration +?( Duration rhs ) with( rhs ) { return (Duration)@{ +tv }; } 43 static inline Duration ?+?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv + rhs.tv }; } 44 static inline Duration ?+=?( Duration & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; } 45 46 static inline Duration -?( Duration rhs ) with( rhs ) { return (Duration)@{ -tv }; } 47 static inline Duration ?-?( Duration & lhs, Duration rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; } 48 static inline Duration ?-=?( Duration & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; } 49 50 static inline Duration ?*?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv * rhs }; } 51 static inline Duration ?*?( int64_t lhs, Duration rhs ) { return (Duration)@{ lhs * rhs.tv }; } 52 static inline Duration ?*=?( Duration & lhs, int64_t rhs ) { lhs = lhs * rhs; return lhs; } 53 54 static inline int64_t ?/?( Duration lhs, Duration rhs ) { return lhs.tv / rhs.tv; } 55 static inline Duration ?/?( Duration lhs, int64_t rhs ) { return (Duration)@{ lhs.tv / rhs }; } 56 static inline Duration ?/=?( Duration & lhs, int64_t rhs ) { lhs = lhs / rhs; return lhs; } 57 static inline double div( Duration lhs, Duration rhs ) { return (double)lhs.tv / (double)rhs.tv; } 58 59 static inline Duration ?%?( Duration lhs, Duration rhs ) { return (Duration)@{ lhs.tv % rhs.tv }; } 60 static inline Duration ?%=?( Duration & lhs, Duration rhs ) { lhs = lhs % rhs; return lhs; } 61 62 static inline _Bool ?==?( Duration lhs, Duration rhs ) { return lhs.tv == rhs.tv; } 63 static inline _Bool ?!=?( Duration lhs, Duration rhs ) { return lhs.tv != rhs.tv; } 64 static inline _Bool ?<? ( Duration lhs, Duration rhs ) { return lhs.tv < rhs.tv; } 65 static inline _Bool ?<=?( Duration lhs, Duration rhs ) { return lhs.tv <= rhs.tv; } 66 static inline _Bool ?>? ( Duration lhs, Duration rhs ) { return lhs.tv > rhs.tv; } 67 static inline _Bool ?>=?( Duration lhs, Duration rhs ) { return lhs.tv >= rhs.tv; } 68 69 static inline _Bool ?==?( Duration lhs, zero_t ) { return lhs.tv == 0; } 70 static inline _Bool ?!=?( Duration lhs, zero_t ) { return lhs.tv != 0; } 71 static inline _Bool ?<? ( Duration lhs, zero_t ) { return lhs.tv < 0; } 72 static inline _Bool ?<=?( Duration lhs, zero_t ) { return lhs.tv <= 0; } 73 static inline _Bool ?>? ( Duration lhs, zero_t ) { return lhs.tv > 0; } 74 static inline _Bool ?>=?( Duration lhs, zero_t ) { return lhs.tv >= 0; } 75 76 static inline Duration abs( Duration rhs ) { return rhs.tv >= 0 ? rhs : -rhs; } 77 78 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur ); 79 80 static inline Duration ?`ns( int64_t nsec ) { return (Duration)@{ nsec }; } 81 static inline Duration ?`us( int64_t usec ) { return (Duration)@{ usec * (TIMEGRAN / 1_000_000LL) }; } 82 static inline Duration ?`ms( int64_t msec ) { return (Duration)@{ msec * (TIMEGRAN / 1_000LL) }; } 83 static inline Duration ?`s( int64_t sec ) { return (Duration)@{ sec * TIMEGRAN }; } 84 static inline Duration ?`s( double sec ) { return (Duration)@{ sec * TIMEGRAN }; } 85 static inline Duration ?`m( int64_t min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; } 86 static inline Duration ?`m( double min ) { return (Duration)@{ min * (60LL * TIMEGRAN) }; } 87 static inline Duration ?`h( int64_t hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; } 88 static inline Duration ?`h( double hours ) { return (Duration)@{ hours * (60LL * 60LL * TIMEGRAN) }; } 89 static inline Duration ?`d( int64_t days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; } 90 static inline Duration ?`d( double days ) { return (Duration)@{ days * (24LL * 60LL * 60LL * TIMEGRAN) }; } 91 static inline Duration ?`w( int64_t weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; } 92 static inline Duration ?`w( double weeks ) { return (Duration)@{ weeks * (7LL * 24LL * 60LL * 60LL * TIMEGRAN) }; } 93 94 static inline int64_t ?`ns( Duration dur ) { return dur.tv; } 95 static inline int64_t ?`us( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000_000LL); } 96 static inline int64_t ?`ms( Duration dur ) { return dur.tv / (TIMEGRAN / 1_000LL); } 97 static inline int64_t ?`s( Duration dur ) { return dur.tv / TIMEGRAN; } 98 static inline int64_t ?`m( Duration dur ) { return dur.tv / (60LL * TIMEGRAN); } 99 static inline int64_t ?`h( Duration dur ) { return dur.tv / (60LL * 60LL * TIMEGRAN); } 100 static inline int64_t ?`d( Duration dur ) { return dur.tv / (24LL * 60LL * 60LL * TIMEGRAN); } 101 static inline int64_t ?`w( Duration dur ) { return dur.tv / (7LL * 24LL * 60LL * 60LL * TIMEGRAN); } 102 103 104 //######################### C timeval ######################### 105 26 #include <fstream> 27 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 106 47 static inline void ?{}( timeval & t ) {} 48 static inline void ?{}( timeval & t, time_t sec ) { t.tv_sec = sec; t.tv_usec = 0; } 107 49 static inline void ?{}( timeval & t, time_t sec, suseconds_t usec ) { t.tv_sec = sec; t.tv_usec = usec; } 108 static inline void ?{}( timeval & t, time_t sec ) { t{ sec, 0 }; }109 static inline void ?{}( timeval & t, zero_t ) { t{ 0, 0 }; }110 static inline timeval ?=?( timeval & t, zero_t ) { return t{ 0 }; }111 static inline timeval ?+?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_usec + rhs.tv_usec }; }112 static inline timeval ?-?( timeval & lhs, timeval rhs ) { return (timeval)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_usec - rhs.tv_usec }; }113 static inline _Bool ?==?( timeval lhs, timeval rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_usec == rhs.tv_usec; }114 static inline _Bool ?!=?( timeval lhs, timeval rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_usec != rhs.tv_usec; }115 116 117 //######################### C timespec #########################118 50 119 51 static inline void ?{}( timespec & t ) {} 52 static inline void ?{}( timespec & t, time_t sec ) { t.tv_sec = sec; t.tv_nsec = 0; } 120 53 static inline void ?{}( timespec & t, time_t sec, __syscall_slong_t nsec ) { t.tv_sec = sec; t.tv_nsec = nsec; } 121 static inline void ?{}( timespec & t, time_t sec ) { t{ sec, 0}; }122 static inline void ?{}( timespec & t, zero_t ) { t{ 0, 0 }; }123 static inline timespec ?=?( timespec & t, zero_t ) { return t{ 0 }; }124 static inline timespec ?+?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec + rhs.tv_sec, lhs.tv_nsec + rhs.tv_nsec }; }125 static inline timespec ?-?( timespec & lhs, timespec rhs ) { return (timespec)@{ lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec }; }126 static inline _Bool ?==?( timespec lhs, timespec rhs ) { return lhs.tv_sec == rhs.tv_sec && lhs.tv_nsec == rhs.tv_nsec; }127 static inline _Bool ?!=?( timespec lhs, timespec rhs ) { return lhs.tv_sec != rhs.tv_sec || lhs.tv_nsec != rhs.tv_nsec; }128 129 130 //######################### C itimerval #########################131 132 static inline void ?{}( itimerval & itv, Duration alarm ) with( itv ) {133 // itimerval contains durations but but uses time data-structure timeval.134 it_value{ alarm`s, (alarm % 1`s)`us }; // seconds, microseconds135 it_interval{ 0 }; // 0 seconds, 0 microseconds136 } // itimerval137 138 static inline void ?{}( itimerval & itv, Duration alarm, Duration interval ) with( itv ) {139 // itimerval contains durations but but uses time data-structure timeval.140 it_value{ alarm`s, (alarm % 1`s)`us }; // seconds, microseconds141 it_interval{ interval`s, interval`us }; // seconds, microseconds142 } // itimerval143 144 145 //######################### C time #########################146 54 147 55 static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; } … … 153 61 154 62 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 155 166 //######################### Time ######################### 156 167 157 struct Time { // private 158 uint64_t tv; // nanoseconds since UNIX epoch 159 }; // Time 160 161 static inline void ?{}( Time & t ) with( t ) { tv = 0; } // fast 162 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 ); // slow 163 164 static inline void ?{}( Time & t, zero_t ) { t.tv = 0; } 165 static inline Time ?=?( Time & t, zero_t ) { return t{ 0 }; } 168 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 166 247 167 248 static inline void ?{}( Time & time, timeval t ) with( time ) { … … 169 250 } // Time 170 251 252 static inline void ?{}( Time & time, timespec t ) with( time ) { 253 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; 254 } // Time 255 171 256 static inline Time ?=?( Time & time, timeval t ) with( time ) { 172 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * (TIMEGRAN / 1_000_000LL);257 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_usec * 1000; 173 258 return time; 174 259 } // ?=? 175 176 static inline void ?{}( Time & time, timespec t ) with( time ) {177 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;178 } // Time179 260 180 261 static inline Time ?=?( Time & time, timespec t ) with( time ) { … … 182 263 return time; 183 264 } // ?=? 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; } 184 277 185 278 static inline Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; } … … 197 290 static inline _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; } 198 291 199 char * yy_mm_dd( Time time, char * buf ); 200 static inline char * ?`ymd( Time time, char * buf ) { // short form 201 return yy_mm_dd( time, buf ); 202 } // ymd 203 204 char * mm_dd_yy( Time time, char * buf ); 205 static inline char * ?`mdy( Time time, char * buf ) { // short form 206 return mm_dd_yy( time, buf ); 207 } // mdy 208 209 char * dd_mm_yy( Time time, char * buf ); 210 static inline char * ?`dmy( Time time, char * buf ) { // short form 211 return dd_mm_yy( time, buf );; 212 } // dmy 213 214 size_t strftime( char * buf, size_t size, const char * fmt, Time time ); 215 216 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 217 218 //------------------------- timeval (cont) ------------------------- 219 220 static inline void ?{}( timeval & t, Time time ) with( t, time ) { 221 tv_sec = tv / TIMEGRAN; // seconds 222 tv_usec = tv % TIMEGRAN / (TIMEGRAN / 1_000_000LL); // microseconds 223 } // ?{} 224 225 //------------------------- timespec (cont) ------------------------- 226 227 static inline void ?{}( timespec & t, Time time ) with( t, time ) { 228 tv_sec = tv / TIMEGRAN; // seconds 229 tv_nsec = tv % TIMEGRAN; // nanoseconds 230 } // ?{} 231 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 } // ?|? 232 339 233 340 //######################### Clock ######################### 234 341 235 struct Clock { // private 342 343 struct Clock { 236 344 Duration offset; // for virtual clock: contains offset from real-time 237 345 int clocktype; // implementation only -1 (virtual), CLOCK_REALTIME 238 346 }; 239 347 240 static inlinevoid resetClock( Clock & clk ) with( clk ) {241 clocktype = CLOCK_REALTIME _COARSE;348 void resetClock( Clock & clk ) with( clk ) { 349 clocktype = CLOCK_REALTIME; 242 350 } // Clock::resetClock 243 351 244 static inlinevoid resetClock( Clock & clk, Duration adj ) with( clk ) {352 void resetClock( Clock & clk, Duration adj ) with( clk ) { 245 353 clocktype = -1; 246 offset = adj + timezone`s; // timezone (global) is (UTC - local time) in seconds 354 Duration tz = (timeval){ timezone, 0 }; 355 offset = adj + tz; 247 356 } // resetClock 248 357 249 static inlinevoid ?{}( Clock & clk ) {358 void ?{}( Clock & clk ) { 250 359 resetClock( clk ); 251 360 } // Clock 252 361 253 static inlinevoid ?{}( Clock & clk, Duration adj ) {362 void ?{}( Clock & clk, Duration adj ) { 254 363 resetClock( clk, adj ); 255 364 } // Clock 256 365 257 static inlineDuration getRes() {366 Duration getRes() { 258 367 struct timespec res; 259 clock_getres( CLOCK_REALTIME _COARSE, &res );260 return ( (int64_t)res.tv_sec * TIMEGRAN + res.tv_nsec)`ns;368 clock_getres( CLOCK_REALTIME, &res ); 369 return (Duration){ res }; 261 370 } // getRes 262 371 263 static inline Time getTimeNsec() { // with nanoseconds 372 Time getTime() { 264 373 timespec curr; 265 374 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); … … 267 376 } // getTime 268 377 269 static inline Time getTime() { // without nanoseconds 270 timespec curr; 271 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); 272 curr.tv_nsec = 0; 273 return (Time){ curr }; 274 } // getTime 275 276 static inline Time getTime( Clock & clk ) with( clk ) { 378 Time getTime( Clock & clk ) with( clk ) { 277 379 return getTime() + offset; 278 380 } // getTime 279 381 280 static inline Time ?()( Clock & clk ) with( clk ) {// alternative syntax382 Time ?()( Clock & clk ) with( clk ) { // alternative syntax 281 383 return getTime() + offset; 282 384 } // getTime 283 385 284 static inlinetimeval getTime( Clock & clk ) {386 timeval getTime( Clock & clk ) { 285 387 return (timeval){ clk() }; 286 388 } // getTime 287 389 288 static inlinetm getTime( Clock & clk ) with( clk ) {390 tm getTime( Clock & clk ) with( clk ) { 289 391 tm ret; 290 392 localtime_r( getTime( clk ).tv_sec, &ret ); … … 296 398 // tab-width: 4 // 297 399 // End: // 400 -
src/tests/concurrent/examples/datingService.c
rca37445 r9d1e3f7 8 8 // Created On : Mon Oct 30 12:56:20 2017 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Wed Mar 14 22:48:40201811 // Update Count : 2 310 // Last Modified On : Tue Jan 2 12:19:01 2018 11 // Update Count : 22 12 12 // 13 13 … … 88 88 int main() { 89 89 DatingService TheExchange; 90 Girl * girls[NoOfPairs];91 Boy * boys[NoOfPairs];90 Girl *girls[NoOfPairs]; 91 Boy *boys[NoOfPairs]; 92 92 93 93 srandom( /*getpid()*/ 103 ); -
src/tests/concurrent/preempt.c
rca37445 r9d1e3f7 3 3 4 4 #ifndef PREEMPTION_RATE 5 #define PREEMPTION_RATE 10 `ms5 #define PREEMPTION_RATE 10_000ul 6 6 #endif 7 7 8 Durationdefault_preemption() {8 unsigned int default_preemption() { 9 9 return PREEMPTION_RATE; 10 10 } -
src/tests/concurrent/signal/barge.c
rca37445 r9d1e3f7 16 16 17 17 #ifndef PREEMPTION_RATE 18 #define PREEMPTION_RATE 10 `ms18 #define PREEMPTION_RATE 10_000ul 19 19 #endif 20 20 21 Durationdefault_preemption() {21 unsigned int default_preemption() { 22 22 return 0; 23 23 } -
src/tests/concurrent/signal/block.c
rca37445 r9d1e3f7 22 22 23 23 #ifndef PREEMPTION_RATE 24 #define PREEMPTION_RATE 10 `ms24 #define PREEMPTION_RATE 10_000ul 25 25 #endif 26 26 27 Durationdefault_preemption() {27 unsigned int default_preemption() { 28 28 return PREEMPTION_RATE; 29 29 } … … 51 51 //------------------------------------------------------------------------------ 52 52 void wait_op( global_data_t & mutex a, global_data_t & mutex b, unsigned i ) { 53 wait( cond, (uintptr_t)active_thread());53 wait( cond, (uintptr_t)this_thread ); 54 54 55 55 yield( random( 10 ) ); … … 60 60 } 61 61 62 a.last_thread = b.last_thread = active_thread();62 a.last_thread = b.last_thread = this_thread; 63 63 64 64 yield( random( 10 ) ); … … 76 76 yield( random( 10 ) ); 77 77 78 [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = active_thread();78 [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = this_thread; 79 79 80 80 if( !is_empty( cond ) ) { … … 106 106 //------------------------------------------------------------------------------ 107 107 void barge_op( global_data_t & mutex a ) { 108 a.last_thread = active_thread();108 a.last_thread = this_thread; 109 109 } 110 110 -
src/tests/concurrent/signal/disjoint.c
rca37445 r9d1e3f7 13 13 14 14 #ifndef PREEMPTION_RATE 15 #define PREEMPTION_RATE 10 `ms15 #define PREEMPTION_RATE 10_000ul 16 16 #endif 17 17 18 Durationdefault_preemption() {18 unsigned int default_preemption() { 19 19 return PREEMPTION_RATE; 20 20 } -
src/tests/concurrent/signal/wait.c
rca37445 r9d1e3f7 20 20 21 21 #ifndef PREEMPTION_RATE 22 #define PREEMPTION_RATE 10 `ms22 #define PREEMPTION_RATE 10_000ul 23 23 #endif 24 24 25 Durationdefault_preemption() {25 unsigned int default_preemption() { 26 26 return PREEMPTION_RATE; 27 27 } -
src/tests/concurrent/waitfor/simple.c
rca37445 r9d1e3f7 10 10 11 11 #ifndef PREEMPTION_RATE 12 #define PREEMPTION_RATE 10 `ms12 #define PREEMPTION_RATE 10_000ul 13 13 #endif 14 14 15 Durationdefault_preemption() {15 unsigned int default_preemption() { 16 16 return PREEMPTION_RATE; 17 17 } -
src/tests/preempt_longrun/create.c
rca37445 r9d1e3f7 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 `ms7 #define PREEMPTION_RATE 10_000ul 8 8 #endif 9 9 10 Durationdefault_preemption() {10 unsigned int default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/enter.c
rca37445 r9d1e3f7 6 6 7 7 #ifndef PREEMPTION_RATE 8 #define PREEMPTION_RATE 10 `ms8 #define PREEMPTION_RATE 10_000ul 9 9 #endif 10 10 11 Durationdefault_preemption() {11 unsigned int default_preemption() { 12 12 return PREEMPTION_RATE; 13 13 } -
src/tests/preempt_longrun/enter3.c
rca37445 r9d1e3f7 6 6 7 7 #ifndef PREEMPTION_RATE 8 #define PREEMPTION_RATE 10 `ms8 #define PREEMPTION_RATE 10_000ul 9 9 #endif 10 10 11 Durationdefault_preemption() {11 unsigned int default_preemption() { 12 12 return PREEMPTION_RATE; 13 13 } -
src/tests/preempt_longrun/processor.c
rca37445 r9d1e3f7 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 `ms7 #define PREEMPTION_RATE 10_000ul 8 8 #endif 9 9 10 Durationdefault_preemption() {10 unsigned int default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/stack.c
rca37445 r9d1e3f7 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 `ms7 #define PREEMPTION_RATE 10_000ul 8 8 #endif 9 9 10 Durationdefault_preemption() {10 unsigned int default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/yield.c
rca37445 r9d1e3f7 9 9 10 10 #ifndef PREEMPTION_RATE 11 #define PREEMPTION_RATE 10 `ms11 #define PREEMPTION_RATE 10_000ul 12 12 #endif 13 13 14 Durationdefault_preemption() {14 unsigned int default_preemption() { 15 15 return PREEMPTION_RATE; 16 16 }
Note:
See TracChangeset
for help on using the changeset viewer.