Changeset ca37445
- Timestamp:
- Apr 10, 2018, 3:31:07 PM (5 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, 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. - Location:
- src
- Files:
-
- 4 added
- 1 deleted
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/lex.ll
r9d1e3f7 rca37445 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu Mar 22 16:47:06201813 * Update Count : 6 6812 * Last Modified On : Fri Apr 6 15:16:15 2018 13 * Update Count : 670 14 14 */ 15 15 … … 198 198 __asm { KEYWORD_RETURN(ASM); } // GCC 199 199 __asm__ { KEYWORD_RETURN(ASM); } // GCC 200 _At { KEYWORD_RETURN(AT); } // CFA201 200 _Atomic { KEYWORD_RETURN(ATOMIC); } // C11 202 201 __attribute { KEYWORD_RETURN(ATTRIBUTE); } // GCC … … 229 228 exception { KEYWORD_RETURN(EXCEPTION); } // CFA 230 229 extern { KEYWORD_RETURN(EXTERN); } 230 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA 231 231 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA 232 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA233 232 finally { KEYWORD_RETURN(FINALLY); } // CFA 234 233 float { KEYWORD_RETURN(FLOAT); } … … 260 259 __builtin_offsetof { KEYWORD_RETURN(OFFSETOF); } // GCC 261 260 one_t { NUMERIC_RETURN(ONE_T); } // CFA 261 or { QKEYWORD_RETURN(WOR); } // CFA 262 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); } // CFA299 298 when { KEYWORD_RETURN(WHEN); } 300 299 while { KEYWORD_RETURN(WHILE); } -
src/Parser/parser.yy
r9d1e3f7 rca37445 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 22 16:56:21201813 // Update Count : 31 2512 // Last Modified On : Wed Mar 28 17:52:24 2018 13 // Update Count : 3130 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; } // FIX ME499 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } 500 500 | type_name '.' '[' push field_list pop ']' // CFA, nested type / tuple field selector 501 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } // FIX ME501 { SemanticError( yylloc, "Qualified names are currently unimplemented." ); $$ = nullptr; } 502 502 | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11 503 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } // FIX ME503 { SemanticError( yylloc, "_Generic is currently unimplemented." ); $$ = nullptr; } 504 504 ; 505 505 … … 687 687 | '(' type_no_function ')' cast_expression 688 688 { $$ = 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; } 689 695 // VIRTUAL cannot be opt because of look ahead issues 690 | '(' VIRTUAL ')' cast_expression 696 | '(' VIRTUAL ')' cast_expression // CFA 691 697 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $4 ), maybeMoveBuildType( nullptr ) ) ); } 692 | '(' VIRTUAL type_no_function ')' cast_expression 698 | '(' VIRTUAL type_no_function ')' cast_expression // CFA 693 699 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); } 694 700 // | '(' type_no_function ')' tuple … … 782 788 | logical_OR_expression '?' comma_expression ':' conditional_expression 783 789 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); } 784 // FIX ME: this hackcomputes $1 twice790 // FIX ME: computes $1 twice 785 791 | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand 786 792 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); } … … 797 803 { $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) ); } 798 804 | unary_expression '=' '{' initializer_list comma_opt '}' 799 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } // FIX ME805 { SemanticError( yylloc, "Initializer assignment is currently unimplemented." ); $$ = nullptr; } 800 806 ; 801 807 … … 867 873 | exception_statement 868 874 | enable_disable_statement 869 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } // FIX ME875 { SemanticError( yylloc, "enable/disable statement is currently unimplemented." ); $$ = nullptr; } 870 876 | asm_statement 871 877 ; … … 1062 1068 { $$ = new StatementNode( build_return( $2 ) ); } 1063 1069 | RETURN '{' initializer_list comma_opt '}' 1064 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } // FIX ME1070 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1065 1071 | THROW assignment_expression_opt ';' // handles rethrow 1066 1072 { $$ = new StatementNode( build_throw( $2 ) ); } … … 1086 1092 mutex_statement: 1087 1093 MUTEX '(' argument_expression_list ')' statement 1088 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } // FIX ME1094 { SemanticError( yylloc, "Mutex statement is currently unimplemented." ); $$ = nullptr; } 1089 1095 ; 1090 1096 -
src/benchmark/bench.h
r9d1e3f7 rca37445 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
r9d1e3f7 rca37445 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Thu Mar 22 17:14:15201814 ## Update Count : 22 413 ## Last Modified On : Sun Apr 8 23:49:34 2018 14 ## Update Count : 227 15 15 ############################################################################### 16 16 … … 46 46 CC = ${abs_top_srcdir}/src/driver/cfa 47 47 48 headers = fstream iostream iterator limits rational stdlib \48 headers = fstream iostream iterator limits rational time stdlib \ 49 49 containers/maybe containers/pair containers/result containers/vector 50 50 … … 99 99 ${stdhdr} \ 100 100 math \ 101 time \102 101 gmp \ 103 102 bits/align.h \ 104 bits/cfatime.h \105 103 bits/containers.h \ 106 104 bits/defs.h \ -
src/libcfa/Makefile.in
r9d1e3f7 rca37445 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 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 \ 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- stdlib.$(OBJEXT) \167 libcfa_d_a-time.$(OBJEXT) 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 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 193 194 @BUILD_CONCURRENCY_TRUE@am__objects_5 = concurrency/libcfa_a-coroutine.$(OBJEXT) \ 194 195 @BUILD_CONCURRENCY_TRUE@ concurrency/libcfa_a-thread.$(OBJEXT) \ … … 197 198 am__objects_6 = libcfa_a-fstream.$(OBJEXT) libcfa_a-iostream.$(OBJEXT) \ 198 199 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) \ 201 202 containers/libcfa_a-pair.$(OBJEXT) \ 202 203 containers/libcfa_a-result.$(OBJEXT) \ … … 260 261 esac 261 262 am__nobase_cfa_include_HEADERS_DIST = fstream iostream iterator limits \ 262 rational stdlib containers/maybe containers/pair \263 rational time stdlib containers/maybe containers/pair \ 263 264 containers/result containers/vector concurrency/coroutine \ 264 265 concurrency/thread concurrency/kernel concurrency/monitor \ 265 ${shell find stdhdr -type f -printf "%p "} math timegmp \266 bits/align.h bits/c fatime.h bits/containers.h bits/defs.h \267 bits/ debug.h bits/locks.h concurrency/invoke.h266 ${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 268 269 HEADERS = $(nobase_cfa_include_HEADERS) 269 270 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) … … 419 420 EXTRA_FLAGS = -g -Wall -Wno-unused-function -imacros libcfa-prelude.c @CFA_FLAGS@ 420 421 AM_CCASFLAGS = @CFA_FLAGS@ 421 headers = fstream iostream iterator limits rational stdlib \422 headers = fstream iostream iterator limits rational time stdlib \ 422 423 containers/maybe containers/pair containers/result \ 423 424 containers/vector $(am__append_3) … … 435 436 ${stdhdr} \ 436 437 math \ 437 time \438 438 gmp \ 439 439 bits/align.h \ 440 bits/cfatime.h \441 440 bits/containers.h \ 442 441 bits/defs.h \ … … 612 611 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@ 613 612 @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@ 625 626 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@ 626 627 @AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@ … … 787 788 @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` 788 789 790 libcfa_d_a-time.o: time.c 791 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-time.o -MD -MP -MF $(DEPDIR)/libcfa_d_a-time.Tpo -c -o libcfa_d_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c 792 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po 793 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_d_a-time.o' libtool=no @AMDEPBACKSLASH@ 794 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 795 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c 796 797 libcfa_d_a-time.obj: time.c 798 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -MT libcfa_d_a-time.obj -MD -MP -MF $(DEPDIR)/libcfa_d_a-time.Tpo -c -o libcfa_d_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi` 799 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po 800 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_d_a-time.obj' libtool=no @AMDEPBACKSLASH@ 801 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 802 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_d_a_CFLAGS) $(CFLAGS) -c -o libcfa_d_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi` 803 789 804 libcfa_d_a-stdlib.o: stdlib.c 790 805 @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 … … 1080 1095 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1081 1096 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-rational.obj `if test -f 'rational.c'; then $(CYGPATH_W) 'rational.c'; else $(CYGPATH_W) '$(srcdir)/rational.c'; fi` 1097 1098 libcfa_a-time.o: time.c 1099 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-time.o -MD -MP -MF $(DEPDIR)/libcfa_a-time.Tpo -c -o libcfa_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c 1100 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po 1101 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_a-time.o' libtool=no @AMDEPBACKSLASH@ 1102 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1103 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-time.o `test -f 'time.c' || echo '$(srcdir)/'`time.c 1104 1105 libcfa_a-time.obj: time.c 1106 @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -MT libcfa_a-time.obj -MD -MP -MF $(DEPDIR)/libcfa_a-time.Tpo -c -o libcfa_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi` 1107 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po 1108 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_a-time.obj' libtool=no @AMDEPBACKSLASH@ 1109 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1110 @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libcfa_a_CFLAGS) $(CFLAGS) -c -o libcfa_a-time.obj `if test -f 'time.c'; then $(CYGPATH_W) 'time.c'; else $(CYGPATH_W) '$(srcdir)/time.c'; fi` 1082 1111 1083 1112 libcfa_a-stdlib.o: stdlib.c -
src/libcfa/bits/locks.h
r9d1e3f7 rca37445 10 10 // Created On : Tue Oct 31 15:14:38 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 8 16:02:22 201713 // Update Count : 112 // Last Modified On : Fri Mar 30 18:18:13 2018 13 // Update Count : 9 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;68 66 69 67 static inline void ?{}( __spinlock_t & this ) { … … 76 74 if( result ) { 77 75 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 // ) 82 80 } 83 81 return result; … … 107 105 } 108 106 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 // ) 113 111 } 114 112 -
src/libcfa/concurrency/alarm.c
r9d1e3f7 rca37445 10 10 // Created On : Fri Jun 2 11:31:25 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:35:18 201713 // Update Count : 112 // Last Modified On : Mon Apr 9 13:36:18 2018 13 // Update Count : 61 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; // seconds31 it_value.tv_usec = max( (alarm->val % (1`cfa_s).val) / (1`cfa_us).val, 1000 ); // microseconds32 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 42 28 //============================================================================================= 43 29 // Clock logic 44 30 //============================================================================================= 45 31 46 __cfa_time_t__kernel_get_time() {32 Time __kernel_get_time() { 47 33 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 }; 50 36 } 51 37 52 void __kernel_set_timer( __cfa_time_t alarm ) { 53 itimerval val = { &alarm }; 54 setitimer( ITIMER_REAL, &val, NULL ); 38 void __kernel_set_timer( Duration alarm ) { 39 setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL ); 55 40 } 56 41 … … 59 44 //============================================================================================= 60 45 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 ) {46 void ?{}( alarm_node_t & this, thread_desc * thrd, Time alarm, Duration period ) with( this ) { 62 47 this.thrd = thrd; 63 48 this.alarm = alarm; … … 68 53 } 69 54 70 void ?{}( alarm_node_t & this, processor * proc, __cfa_time_t alarm = 0`cfa_s, __cfa_time_t period = 0`cfa_s) with( this ) {55 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period ) with( this ) { 71 56 this.proc = proc; 72 57 this.alarm = alarm; -
src/libcfa/concurrency/alarm.h
r9d1e3f7 rca37445 10 10 // Created On : Fri Jun 2 11:31:25 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:27 201713 // Update Count : 312 // Last Modified On : Mon Mar 26 16:25:41 2018 13 // Update Count : 11 14 14 // 15 15 … … 21 21 #include <assert.h> 22 22 23 #include " bits/cfatime.h"23 #include "time" 24 24 25 25 struct thread_desc; … … 30 30 //============================================================================================= 31 31 32 __cfa_time_t__kernel_get_time();33 void __kernel_set_timer( __cfa_time_talarm );32 Time __kernel_get_time(); 33 void __kernel_set_timer( Duration alarm ); 34 34 35 35 //============================================================================================= … … 38 38 39 39 struct alarm_node_t { 40 __cfa_time_t alarm;// time when alarm goes off41 __cfa_time_t period;// if > 0 => period of alarm40 Time alarm; // time when alarm goes off 41 Duration 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, __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);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 ); 57 57 void ^?{}( alarm_node_t & this ); 58 58 -
src/libcfa/concurrency/coroutine
r9d1e3f7 rca37445 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 30 07:58:29 201713 // Update Count : 312 // Last Modified On : Fri Mar 30 18:23:45 2018 13 // Update Count : 8 14 14 // 15 15 … … 60 60 } 61 61 62 // Get current coroutine63 extern thread_local coroutine_desc * volatile this_coroutine;64 65 62 // Private wrappers for context switch and stack creation 66 63 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst); … … 69 66 // Suspend implementation inlined for performance 70 67 static inline void suspend() { 71 coroutine_desc * src = this_coroutine;// optimization68 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 72 69 73 70 assertf( src->last != 0, … … 86 83 forall(dtype T | is_coroutine(T)) 87 84 static inline void resume(T & cor) { 88 coroutine_desc * src = this_coroutine;// optimization85 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 89 86 coroutine_desc * dst = get_coroutine(cor); 90 87 … … 111 108 112 109 static inline void resume(coroutine_desc * dst) { 113 coroutine_desc * src = this_coroutine;// optimization110 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 114 111 115 112 // not resuming self ? -
src/libcfa/concurrency/coroutine.c
r9d1e3f7 rca37445 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 8 16:10:31201813 // Update Count : 412 // Last Modified On : Fri Mar 30 17:20:57 2018 13 // Update Count : 9 14 14 // 15 15 … … 99 99 // Wrapper for co 100 100 void 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 ); 102 102 disable_interrupts(); 103 103 … … 106 106 107 107 // set new coroutine that task is executing 108 this_coroutine = dst;108 TL_SET( this_coroutine, dst ); 109 109 110 110 // context switch to specified coroutine … … 117 117 118 118 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 ); 120 120 } //ctxSwitchDirect 121 121 … … 172 172 173 173 void __leave_coroutine(void) { 174 coroutine_desc * src = this_coroutine;// optimization174 coroutine_desc * src = TL_GET( this_coroutine ); // optimization 175 175 176 176 assertf( src->starter != 0, -
src/libcfa/concurrency/invoke.h
r9d1e3f7 rca37445 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 14:41:55201813 // Update Count : 612 // Last Modified On : Fri Mar 30 22:33:59 2018 13 // Update Count : 30 14 14 // 15 15 … … 17 17 #include "bits/defs.h" 18 18 #include "bits/locks.h" 19 20 #define TL_GET( member ) kernelThreadData.member 21 #define TL_SET( member, value ) kernelThreadData.member = value; 19 22 20 23 #ifdef __cforall … … 30 33 static inline struct thread_desc * & get_next( struct thread_desc & this ); 31 34 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; 32 47 } 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 ); } 33 52 #endif 34 53 35 54 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 56 62 }; 57 63 … … 59 65 60 66 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 78 73 }; 79 74 -
src/libcfa/concurrency/kernel
r9d1e3f7 rca37445 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:58:39 201713 // Update Count : 212 // Last Modified On : Fri Mar 23 17:08:20 2018 13 // Update Count : 3 14 14 // 15 15 … … 19 19 20 20 #include "invoke.h" 21 #include " bits/cfatime.h"21 #include "time" 22 22 23 23 extern "C" { … … 49 49 50 50 // Preemption rate on this cluster 51 __cfa_time_tpreemption_rate;51 Duration preemption_rate; 52 52 }; 53 53 54 extern __cfa_time_tdefault_preemption();54 extern Duration default_preemption(); 55 55 56 56 void ?{} (cluster & this); -
src/libcfa/concurrency/kernel.c
r9d1e3f7 rca37445 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 8 23:52:19201813 // Update Count : 512 // Last Modified On : Fri Mar 30 18:26:11 2018 13 // Update Count : 23 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 58 54 // volatile thread_local bool preemption_in_progress = 0; 59 55 // volatile thread_local bool preemption_enabled = false; 60 56 // volatile thread_local unsigned short disable_preempt_count = 1; 61 57 62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 }; 58 thread_local struct KernelThreadData kernelThreadData = { 59 NULL, 60 NULL, 61 NULL, 62 { 1, false, false } 63 }; 63 64 64 65 //----------------------------------------------------------------------------- … … 172 173 terminate(&this); 173 174 verify(this.do_terminate); 174 verify( this_processor!= &this);175 verify(TL_GET( this_processor ) != &this); 175 176 P( terminated ); 176 verify( this_processor!= &this);177 verify(TL_GET( this_processor ) != &this); 177 178 pthread_join( kernel_thread, NULL ); 178 179 } … … 213 214 if(readyThread) 214 215 { 215 verify( ! preemption_state.enabled );216 verify( ! TL_GET( preemption_state ).enabled ); 216 217 217 218 runThread(this, readyThread); 218 219 219 verify( ! preemption_state.enabled );220 verify( ! TL_GET( preemption_state ).enabled ); 220 221 221 222 //Some actions need to be taken from the kernel … … 249 250 250 251 //Update global state 251 this_thread = dst;252 TL_SET( this_thread, dst ); 252 253 253 254 // Context Switch to the thread … … 257 258 258 259 void 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 ); 261 262 ThreadCtxSwitch(thrd_cor, proc_cor); 262 263 } … … 266 267 void finishRunning(processor * this) with( this->finish ) { 267 268 if( action_code == Release ) { 268 verify( ! preemption_state.enabled );269 verify( ! TL_GET( preemption_state ).enabled ); 269 270 unlock( *lock ); 270 271 } … … 273 274 } 274 275 else if( action_code == Release_Schedule ) { 275 verify( ! preemption_state.enabled );276 verify( ! TL_GET( preemption_state ).enabled ); 276 277 unlock( *lock ); 277 278 ScheduleThread( thrd ); 278 279 } 279 280 else if( action_code == Release_Multi ) { 280 verify( ! preemption_state.enabled );281 verify( ! TL_GET( preemption_state ).enabled ); 281 282 for(int i = 0; i < lock_count; i++) { 282 283 unlock( *locks[i] ); … … 307 308 void * CtxInvokeProcessor(void * arg) { 308 309 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; 314 315 // SKULLDUGGERY: We want to create a context for the processor coroutine 315 316 // which is needed for the 2-step context switch. However, there is no reason … … 323 324 324 325 //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 ); 327 328 328 329 //We now have a proper context from which to schedule threads … … 352 353 353 354 void kernel_first_resume(processor * this) { 354 coroutine_desc * src = this_coroutine;355 coroutine_desc * src = TL_GET( this_coroutine ); 355 356 coroutine_desc * dst = get_coroutine(this->runner); 356 357 357 verify( ! preemption_state.enabled );358 verify( ! TL_GET( preemption_state ).enabled ); 358 359 359 360 create_stack(&dst->stack, dst->stack.size); 360 361 CtxStart(&this->runner, CtxInvokeCoroutine); 361 362 362 verify( ! preemption_state.enabled );363 verify( ! TL_GET( preemption_state ).enabled ); 363 364 364 365 dst->last = src; … … 369 370 370 371 // set new coroutine that task is executing 371 this_coroutine = dst;372 TL_SET( this_coroutine, dst ); 372 373 373 374 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 386 387 src->state = Active; 387 388 388 verify( ! preemption_state.enabled );389 verify( ! TL_GET( preemption_state ).enabled ); 389 390 } 390 391 … … 392 393 // Scheduler routines 393 394 void ScheduleThread( thread_desc * thrd ) { 394 // if( ! thrd ) return;395 // if( ! thrd ) return; 395 396 verify( thrd ); 396 397 verify( thrd->self_cor.state != Halted ); 397 398 398 verify( ! preemption_state.enabled );399 verify( ! TL_GET( preemption_state ).enabled ); 399 400 400 401 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 401 402 402 with( * this_processor->cltr ) {403 with( *TL_GET( this_processor )->cltr ) { 403 404 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 404 405 append( ready_queue, thrd ); … … 406 407 } 407 408 408 verify( ! preemption_state.enabled );409 verify( ! TL_GET( preemption_state ).enabled ); 409 410 } 410 411 411 412 thread_desc * nextThread(cluster * this) with( *this ) { 412 verify( ! preemption_state.enabled );413 verify( ! TL_GET( preemption_state ).enabled ); 413 414 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 414 415 thread_desc * head = pop_head( ready_queue ); 415 416 unlock( ready_queue_lock ); 416 verify( ! preemption_state.enabled );417 verify( ! TL_GET( preemption_state ).enabled ); 417 418 return head; 418 419 } … … 420 421 void BlockInternal() { 421 422 disable_interrupts(); 422 verify( ! preemption_state.enabled );423 verify( ! TL_GET( preemption_state ).enabled ); 423 424 returnToKernel(); 424 verify( ! preemption_state.enabled );425 verify( ! TL_GET( preemption_state ).enabled ); 425 426 enable_interrupts( __cfaabi_dbg_ctx ); 426 427 } … … 428 429 void BlockInternal( __spinlock_t * lock ) { 429 430 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 ); 434 435 returnToKernel(); 435 verify( ! preemption_state.enabled );436 verify( ! TL_GET( preemption_state ).enabled ); 436 437 437 438 enable_interrupts( __cfaabi_dbg_ctx ); … … 440 441 void BlockInternal( thread_desc * thrd ) { 441 442 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 ); 446 447 returnToKernel(); 447 verify( ! preemption_state.enabled );448 verify( ! TL_GET( preemption_state ).enabled ); 448 449 449 450 enable_interrupts( __cfaabi_dbg_ctx ); … … 453 454 assert(thrd); 454 455 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 ); 460 461 returnToKernel(); 461 verify( ! preemption_state.enabled );462 verify( ! TL_GET( preemption_state ).enabled ); 462 463 463 464 enable_interrupts( __cfaabi_dbg_ctx ); … … 466 467 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 467 468 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 ); 473 474 returnToKernel(); 474 verify( ! preemption_state.enabled );475 verify( ! TL_GET( preemption_state ).enabled ); 475 476 476 477 enable_interrupts( __cfaabi_dbg_ctx ); … … 479 480 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 480 481 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 ); 488 489 returnToKernel(); 489 verify( ! preemption_state.enabled );490 verify( ! TL_GET( preemption_state ).enabled ); 490 491 491 492 enable_interrupts( __cfaabi_dbg_ctx ); … … 493 494 494 495 void 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; 499 500 500 501 returnToKernel(); … … 507 508 // Kernel boot procedures 508 509 void kernel_startup(void) { 509 verify( ! preemption_state.enabled );510 verify( ! TL_GET( preemption_state ).enabled ); 510 511 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 511 512 … … 531 532 532 533 //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 ); 536 537 537 538 // Enable preemption … … 545 546 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 546 547 // 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 ) ); 548 549 549 550 … … 552 553 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 553 554 554 verify( ! preemption_state.enabled );555 verify( ! TL_GET( preemption_state ).enabled ); 555 556 enable_interrupts( __cfaabi_dbg_ctx ); 556 verify( preemption_state.enabled );557 verify( TL_GET( preemption_state ).enabled ); 557 558 } 558 559 … … 560 561 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 561 562 562 verify( preemption_state.enabled );563 verify( TL_GET( preemption_state ).enabled ); 563 564 disable_interrupts(); 564 verify( ! preemption_state.enabled );565 verify( ! TL_GET( preemption_state ).enabled ); 565 566 566 567 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 602 603 603 604 // first task to abort ? 604 if ( ! kernel_abort_called ) { // not first task to abort ?605 if ( ! kernel_abort_called ) { // not first task to abort ? 605 606 kernel_abort_called = true; 606 607 unlock( kernel_abort_lock ); … … 617 618 } 618 619 619 return this_thread;620 return TL_GET( this_thread ); 620 621 } 621 622 … … 626 627 __cfaabi_dbg_bits_write( abort_text, len ); 627 628 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 ) ); 630 631 __cfaabi_dbg_bits_write( abort_text, len ); 631 632 } … … 636 637 637 638 int 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; 639 640 } 640 641 … … 666 667 if ( count < 0 ) { 667 668 // queue current task 668 append( waiting, (thread_desc *) this_thread);669 append( waiting, (thread_desc *)TL_GET( this_thread ) ); 669 670 670 671 // atomically release spin lock and block -
src/libcfa/concurrency/kernel_private.h
r9d1e3f7 rca37445 10 10 // Created On : Mon Feb 13 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:58:09 201713 // Update Count : 212 // Last Modified On : Thu Mar 29 14:06:40 2018 13 // Update Count : 3 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
r9d1e3f7 rca37445 10 10 // Created On : Thd Feb 23 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 16 14:49:53201813 // Update Count : 512 // Last Modified On : Fri Mar 30 14:30:26 2018 13 // Update Count : 9 14 14 // 15 15 … … 85 85 // Lock the monitor spinlock 86 86 lock( this->lock __cfaabi_dbg_ctx2 ); 87 thread_desc * thrd = this_thread;87 thread_desc * thrd = TL_GET( 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 = this_thread;136 thread_desc * thrd = TL_GET( 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( this_thread, 0 )170 wait_ctx_primed( TL_GET( 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( this_thread, 0 )181 wait_ctx( TL_GET( 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", 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 ); 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( 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); 231 231 } 232 232 if( this->recursion != 1 ) { … … 297 297 298 298 // Save previous thread context 299 this.prev = this_thread->monitors;299 this.prev = TL_GET( this_thread )->monitors; 300 300 301 301 // Update thread context (needed for conditions) 302 ( this_thread->monitors){m, count, func};302 (TL_GET( 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 this_thread->monitors = this.prev;324 TL_GET( this_thread )->monitors = this.prev; 325 325 } 326 326 … … 332 332 333 333 // Save previous thread context 334 this.prev = this_thread->monitors;334 this.prev = TL_GET( this_thread )->monitors; 335 335 336 336 // Update thread context (needed for conditions) 337 ( this_thread->monitors){m, 1, func};337 (TL_GET( this_thread )->monitors){m, 1, func}; 338 338 339 339 __enter_monitor_dtor( this.m, func ); … … 346 346 347 347 // Restore thread context 348 this_thread->monitors = this.prev;348 TL_GET( this_thread )->monitors = this.prev; 349 349 } 350 350 … … 386 386 387 387 // Create the node specific to this wait operation 388 wait_ctx( this_thread, user_info );388 wait_ctx( TL_GET( 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 = this_thread;427 thread_desc * this_thrd = TL_GET( 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( this_thread, 0 )475 wait_ctx_primed( TL_GET( 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( this_thread, 0 );568 wait_ctx_primed( TL_GET( 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( this_thread, 0 );614 wait_ctx_primed( TL_GET( 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 == this_thread);620 verify( monitors[i]->owner == TL_GET( this_thread ) ); 621 621 } 622 622 … … 812 812 813 813 static inline void brand_condition( condition & this ) { 814 thread_desc * thrd = this_thread;814 thread_desc * thrd = TL_GET( this_thread ); 815 815 if( !this.monitors ) { 816 816 // __cfaabi_dbg_print_safe( "Branding\n" ); -
src/libcfa/concurrency/preemption.c
r9d1e3f7 rca37445 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Feb 9 16:38:13201813 // Update Count : 1412 // Last Modified On : Mon Apr 9 13:52:39 2018 13 // Update Count : 36 14 14 // 15 15 … … 23 23 } 24 24 25 #include "bits/cfatime.h"26 25 #include "bits/signal.h" 27 26 28 27 #if !defined(__CFA_DEFAULT_PREEMPTION__) 29 #define __CFA_DEFAULT_PREEMPTION__ 10` cfa_ms28 #define __CFA_DEFAULT_PREEMPTION__ 10`ms 30 29 #endif 31 30 32 __cfa_time_tdefault_preemption() __attribute__((weak)) {31 Duration default_preemption() __attribute__((weak)) { 33 32 return __CFA_DEFAULT_PREEMPTION__; 34 33 } … … 78 77 79 78 // Get next expired node 80 static inline alarm_node_t * get_expired( alarm_list_t * alarms, __cfa_time_tcurrtime ) {79 static inline alarm_node_t * get_expired( alarm_list_t * alarms, Time currtime ) { 81 80 if( !alarms->head ) return NULL; // If no alarms return null 82 81 if( alarms->head->alarm >= currtime ) return NULL; // If alarms head not expired return null … … 88 87 alarm_node_t * node = NULL; // Used in the while loop but cannot be declared in the while condition 89 88 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" 91 90 92 91 //Loop throught every thing expired … … 102 101 103 102 // Check if this is a periodic alarm 104 __cfa_time_tperiod = node->period;103 Duration period = node->period; 105 104 if( period > 0 ) { 106 105 node->alarm = currtime + period; // Alarm is periodic, add currtime to it (used cached current time) … … 117 116 118 117 // Update the preemption of a processor and notify interested parties 119 void update_preemption( processor * this, __cfa_time_tduration ) {118 void update_preemption( processor * this, Duration duration ) { 120 119 alarm_node_t * alarm = this->preemption_alarm; 121 120 122 121 // Alarms need to be enabled 123 if ( duration > 0 && ! alarm->set ) {122 if ( duration > 0 && ! alarm->set ) { 124 123 alarm->alarm = __kernel_get_time() + duration; 125 124 alarm->period = duration; 126 125 register_self( alarm ); 127 126 } 128 // Zero dura ction but alarm is set127 // Zero duration but alarm is set 129 128 else if ( duration == 0 && alarm->set ) { 130 129 unregister_self( alarm ); … … 150 149 // Disable interrupts by incrementing the counter 151 150 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; 155 154 verify( new_val < 65_000u ); // If this triggers someone is disabling interrupts without enabling them 156 155 } … … 159 158 // If counter reaches 0, execute any pending CtxSwitch 160 159 void enable_interrupts( __cfaabi_dbg_ctx_param ) { 161 processor * proc = this_processor;// Cache the processor now since interrupts can start happening after the atomic add162 thread_desc * thrd = this_thread;// Cache the thread now since interrupts can start happening after the atomic add163 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; 166 165 verify( prev != 0u ); // If this triggers someone is enabled already enabled interruptsverify( prev != 0u ); 167 166 168 167 // Check if we need to prempt the thread because an interrupt was missed 169 168 if( prev == 1 ) { 170 preemption_state.enabled = true;169 TL_GET( preemption_state ).enabled = true; 171 170 if( proc->pending_preemption ) { 172 171 proc->pending_preemption = false; … … 182 181 // Don't execute any pending CtxSwitch even if counter reaches 0 183 182 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; 186 185 verifyf( prev != 0u, "Incremented from %u\n", prev ); // If this triggers someone is enabled already enabled interrupts 187 186 if( prev == 1 ) { 188 preemption_state.enabled = true;187 TL_GET( preemption_state ).enabled = true; 189 188 } 190 189 } … … 236 235 // If false : preemption is unsafe and marked as pending 237 236 static inline bool preemption_ready() { 238 bool ready = preemption_state.enabled && !preemption_state.in_progress; // Check if preemption is safe239 this_processor->pending_preemption = !ready;// Adjust the pending flag accordingly237 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 240 239 return ready; 241 240 } … … 251 250 252 251 // 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; 255 254 256 255 // Initialize the event kernel … … 291 290 // Used by thread to control when they want to receive preemption signals 292 291 void ?{}( preemption_scope & this, processor * proc ) { 293 (this.alarm){ proc, 0`cfa_s, 0`cfa_s };292 (this.alarm){ proc, (Time){ 0 }, 0`s }; 294 293 this.proc = proc; 295 294 this.proc->preemption_alarm = &this.alarm; … … 301 300 disable_interrupts(); 302 301 303 update_preemption( this.proc, 0` cfa_s );302 update_preemption( this.proc, 0`s ); 304 303 } 305 304 … … 317 316 // before the kernel thread has even started running. When that happens an iterrupt 318 317 // we a null 'this_processor' will be caught, just ignore it. 319 if(! this_processor) return;318 if(!TL_GET( this_processor )) return; 320 319 321 320 choose(sfp->si_value.sival_int) { 322 321 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); 324 323 default: 325 324 abort( "internal error, signal value is %d", sfp->si_value.sival_int ); … … 331 330 __cfaabi_dbg_print_buffer_decl( " KERNEL: preempting core %p (%p).\n", this_processor, this_thread); 332 331 333 preemption_state.in_progress = true;// Sync flag : prevent recursive calls to the signal handler332 TL_GET( preemption_state ).in_progress = true; // Sync flag : prevent recursive calls to the signal handler 334 333 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 flag334 TL_GET( preemption_state ).in_progress = false; // Clear the in progress flag 336 335 337 336 // Preemption can occur here 338 337 339 BlockInternal( (thread_desc*) this_thread );// Do the actual CtxSwitch338 BlockInternal( (thread_desc*)TL_GET( this_thread ) ); // Do the actual CtxSwitch 340 339 } 341 340 -
src/libcfa/concurrency/preemption.h
r9d1e3f7 rca37445 10 10 // Created On : Mon Jun 5 14:20:42 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:34:25 201713 // Update Count : 112 // Last Modified On : Fri Mar 23 17:18:53 2018 13 // Update Count : 2 14 14 // 15 15 … … 21 21 void kernel_start_preemption(); 22 22 void kernel_stop_preemption(); 23 void update_preemption( processor * this, __cfa_time_tduration );23 void update_preemption( processor * this, Duration duration ); 24 24 void tick_preemption(); 25 25 -
src/libcfa/concurrency/thread
r9d1e3f7 rca37445 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jul 22 09:59:40 201713 // Update Count : 312 // Last Modified On : Thu Mar 29 14:07:11 2018 13 // Update Count : 4 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
r9d1e3f7 rca37445 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 21 22:34:46 201713 // Update Count : 112 // Last Modified On : Fri Mar 30 17:19:52 2018 13 // Update Count : 8 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 = this_coroutine;77 thrd_c->last = TL_GET( 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 this_coroutine = thrd_c;83 TL_SET( 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 = this_coroutine;94 coroutine_desc* thrd_c = TL_GET( this_coroutine ); 95 95 ThreadCtxSwitch( thrd_c, thrd_c->last ); 96 96 } … … 98 98 99 99 void 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 ); 103 103 } 104 104 … … 116 116 // set new coroutine that the processor is executing 117 117 // and context switch to it 118 this_coroutine = dst;118 TL_SET( this_coroutine, dst ); 119 119 assert( src->stack.context ); 120 120 CtxSwitch( src->stack.context, dst->stack.context ); 121 this_coroutine = src;121 TL_SET( this_coroutine, src ); 122 122 123 123 // set state of new coroutine to active -
src/libcfa/time
r9d1e3f7 rca37445 1 1 // 2 // Cforall Version 1.0.0 Copyright (C) 201 6University of Waterloo2 // Cforall Version 1.0.0 Copyright (C) 2018 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 // calendar--7 // time -- 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 : Thu Mar 22 17:11:19201813 // Update Count : 49512 // Last Modified On : Mon Apr 9 13:10:23 2018 13 // Update Count : 616 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> 21 #include <time.h> // timespec 22 22 extern "C" { 23 #include <sys/time.h> 24 int snprintf( char * buf, size_t size, const char * fmt, ... ); 23 #include <sys/time.h> // timeval 25 24 } 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 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 47 106 static inline void ?{}( timeval & t ) {} 48 static inline void ?{}( timeval & t, time_t sec ) { t.tv_sec = sec; t.tv_usec = 0; }49 107 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 ######################### 50 118 51 119 static inline void ?{}( timespec & t ) {} 52 static inline void ?{}( timespec & t, time_t sec ) { t.tv_sec = sec; t.tv_nsec = 0; }53 120 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, microseconds 135 it_interval{ 0 }; // 0 seconds, 0 microseconds 136 } // itimerval 137 138 static inline void ?{}( itimerval & itv, Duration alarm, Duration interval ) with( itv ) { 139 // itimerval contains durations but but uses time data-structure timeval. 140 it_value{ alarm`s, (alarm % 1`s)`us }; // seconds, microseconds 141 it_interval{ interval`s, interval`us }; // seconds, microseconds 142 } // itimerval 143 144 145 //######################### C time ######################### 54 146 55 147 static inline char * ctime( time_t tp ) { char * buf = ctime( &tp ); buf[24] = '\0'; return buf; } … … 61 153 62 154 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 } // Duration75 76 static inline void ?{}( Duration & dur, timespec t ) with( dur ) {77 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec;78 } // Duration79 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 } // ?=? timespec89 90 static inline void ?{}( timeval & t, Duration dur ) with( dur ) {91 t.tv_sec = tv / TIMEGRAN; // seconds92 t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1000000L ); // microseconds93 } // ?{}94 95 static inline void ?{}( timespec & t, Duration dur ) with( dur ) {96 t.tv_sec = tv / TIMEGRAN; // seconds97 t.tv_nsec = tv % TIMEGRAN; // nanoseconds98 } // Timespec99 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 } // abs132 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 digit140 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 166 155 //######################### Time ######################### 167 156 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 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 }; } 247 166 248 167 static inline void ?{}( Time & time, timeval t ) with( time ) { … … 250 169 } // Time 251 170 171 static 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 252 176 static inline void ?{}( Time & time, timespec t ) with( time ) { 253 177 tv = (int64_t)t.tv_sec * TIMEGRAN + t.tv_nsec; 254 178 } // 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 } // ?=?260 179 261 180 static inline Time ?=?( Time & time, timespec t ) with( time ) { … … 263 182 return time; 264 183 } // ?=? 265 266 static inline void ?{}( timeval & t, Time time ) with( time ) {267 t.tv_sec = tv / TIMEGRAN; // seconds268 t.tv_usec = tv % TIMEGRAN / ( TIMEGRAN / 1_000_000L ); // microseconds269 } // ?{}270 271 static inline void ?{}( timespec & t, Time time ) with( time ) {272 t.tv_sec = tv / TIMEGRAN; // seconds273 t.tv_nsec = tv % TIMEGRAN; // nanoseconds274 } // ?{}275 276 static inline int64_t nsec( Time time ) with( time ) { return tv; }277 184 278 185 static inline Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; } … … 290 197 static inline _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; } 291 198 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 } // ?|? 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 339 232 340 233 //######################### Clock ######################### 341 234 342 343 struct Clock { 235 struct Clock { // private 344 236 Duration offset; // for virtual clock: contains offset from real-time 345 237 int clocktype; // implementation only -1 (virtual), CLOCK_REALTIME 346 238 }; 347 239 348 void resetClock( Clock & clk ) with( clk ) {349 clocktype = CLOCK_REALTIME ;240 static inline void resetClock( Clock & clk ) with( clk ) { 241 clocktype = CLOCK_REALTIME_COARSE; 350 242 } // Clock::resetClock 351 243 352 void resetClock( Clock & clk, Duration adj ) with( clk ) {244 static inline void resetClock( Clock & clk, Duration adj ) with( clk ) { 353 245 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 356 247 } // resetClock 357 248 358 void ?{}( Clock & clk ) {249 static inline void ?{}( Clock & clk ) { 359 250 resetClock( clk ); 360 251 } // Clock 361 252 362 void ?{}( Clock & clk, Duration adj ) {253 static inline void ?{}( Clock & clk, Duration adj ) { 363 254 resetClock( clk, adj ); 364 255 } // Clock 365 256 366 Duration getRes() {257 static inline Duration getRes() { 367 258 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; 370 261 } // getRes 371 262 372 Time getTime() { 263 static inline Time getTimeNsec() { // with nanoseconds 373 264 timespec curr; 374 265 clock_gettime( CLOCK_REALTIME_COARSE, &curr ); … … 376 267 } // getTime 377 268 378 Time getTime( Clock & clk ) with( clk ) { 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 ) { 379 277 return getTime() + offset; 380 278 } // getTime 381 279 382 Time ?()( Clock & clk ) with( clk ) {// alternative syntax280 static inline Time ?()( Clock & clk ) with( clk ) { // alternative syntax 383 281 return getTime() + offset; 384 282 } // getTime 385 283 386 timeval getTime( Clock & clk ) {284 static inline timeval getTime( Clock & clk ) { 387 285 return (timeval){ clk() }; 388 286 } // getTime 389 287 390 tm getTime( Clock & clk ) with( clk ) {288 static inline tm getTime( Clock & clk ) with( clk ) { 391 289 tm ret; 392 290 localtime_r( getTime( clk ).tv_sec, &ret ); … … 398 296 // tab-width: 4 // 399 297 // End: // 400 -
src/tests/concurrent/examples/datingService.c
r9d1e3f7 rca37445 8 8 // Created On : Mon Oct 30 12:56:20 2017 9 9 // Last Modified By : Peter A. Buhr 10 // Last Modified On : Tue Jan 2 12:19:01201811 // Update Count : 2 210 // Last Modified On : Wed Mar 14 22:48:40 2018 11 // Update Count : 23 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
r9d1e3f7 rca37445 3 3 4 4 #ifndef PREEMPTION_RATE 5 #define PREEMPTION_RATE 10 _000ul5 #define PREEMPTION_RATE 10`ms 6 6 #endif 7 7 8 unsigned intdefault_preemption() {8 Duration default_preemption() { 9 9 return PREEMPTION_RATE; 10 10 } -
src/tests/concurrent/signal/barge.c
r9d1e3f7 rca37445 16 16 17 17 #ifndef PREEMPTION_RATE 18 #define PREEMPTION_RATE 10 _000ul18 #define PREEMPTION_RATE 10`ms 19 19 #endif 20 20 21 unsigned intdefault_preemption() {21 Duration default_preemption() { 22 22 return 0; 23 23 } -
src/tests/concurrent/signal/block.c
r9d1e3f7 rca37445 22 22 23 23 #ifndef PREEMPTION_RATE 24 #define PREEMPTION_RATE 10 _000ul24 #define PREEMPTION_RATE 10`ms 25 25 #endif 26 26 27 unsigned intdefault_preemption() {27 Duration 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)this_thread);53 wait( cond, (uintptr_t)active_thread() ); 54 54 55 55 yield( random( 10 ) ); … … 60 60 } 61 61 62 a.last_thread = b.last_thread = this_thread;62 a.last_thread = b.last_thread = active_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] = this_thread;78 [a.last_thread, b.last_thread, a.last_signaller, b.last_signaller] = active_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 = this_thread;108 a.last_thread = active_thread(); 109 109 } 110 110 -
src/tests/concurrent/signal/disjoint.c
r9d1e3f7 rca37445 13 13 14 14 #ifndef PREEMPTION_RATE 15 #define PREEMPTION_RATE 10 _000ul15 #define PREEMPTION_RATE 10`ms 16 16 #endif 17 17 18 unsigned intdefault_preemption() {18 Duration default_preemption() { 19 19 return PREEMPTION_RATE; 20 20 } -
src/tests/concurrent/signal/wait.c
r9d1e3f7 rca37445 20 20 21 21 #ifndef PREEMPTION_RATE 22 #define PREEMPTION_RATE 10 _000ul22 #define PREEMPTION_RATE 10`ms 23 23 #endif 24 24 25 unsigned intdefault_preemption() {25 Duration default_preemption() { 26 26 return PREEMPTION_RATE; 27 27 } -
src/tests/concurrent/waitfor/simple.c
r9d1e3f7 rca37445 10 10 11 11 #ifndef PREEMPTION_RATE 12 #define PREEMPTION_RATE 10 _000ul12 #define PREEMPTION_RATE 10`ms 13 13 #endif 14 14 15 unsigned intdefault_preemption() {15 Duration default_preemption() { 16 16 return PREEMPTION_RATE; 17 17 } -
src/tests/preempt_longrun/create.c
r9d1e3f7 rca37445 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 _000ul7 #define PREEMPTION_RATE 10`ms 8 8 #endif 9 9 10 unsigned intdefault_preemption() {10 Duration default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/enter.c
r9d1e3f7 rca37445 6 6 7 7 #ifndef PREEMPTION_RATE 8 #define PREEMPTION_RATE 10 _000ul8 #define PREEMPTION_RATE 10`ms 9 9 #endif 10 10 11 unsigned intdefault_preemption() {11 Duration default_preemption() { 12 12 return PREEMPTION_RATE; 13 13 } -
src/tests/preempt_longrun/enter3.c
r9d1e3f7 rca37445 6 6 7 7 #ifndef PREEMPTION_RATE 8 #define PREEMPTION_RATE 10 _000ul8 #define PREEMPTION_RATE 10`ms 9 9 #endif 10 10 11 unsigned intdefault_preemption() {11 Duration default_preemption() { 12 12 return PREEMPTION_RATE; 13 13 } -
src/tests/preempt_longrun/processor.c
r9d1e3f7 rca37445 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 _000ul7 #define PREEMPTION_RATE 10`ms 8 8 #endif 9 9 10 unsigned intdefault_preemption() {10 Duration default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/stack.c
r9d1e3f7 rca37445 5 5 6 6 #ifndef PREEMPTION_RATE 7 #define PREEMPTION_RATE 10 _000ul7 #define PREEMPTION_RATE 10`ms 8 8 #endif 9 9 10 unsigned intdefault_preemption() {10 Duration default_preemption() { 11 11 return PREEMPTION_RATE; 12 12 } -
src/tests/preempt_longrun/yield.c
r9d1e3f7 rca37445 9 9 10 10 #ifndef PREEMPTION_RATE 11 #define PREEMPTION_RATE 10 _000ul11 #define PREEMPTION_RATE 10`ms 12 12 #endif 13 13 14 unsigned intdefault_preemption() {14 Duration default_preemption() { 15 15 return PREEMPTION_RATE; 16 16 }
Note: See TracChangeset
for help on using the changeset viewer.