Changeset 32cab5b for src/libcfa
- Timestamp:
- Apr 17, 2018, 12:01:09 PM (8 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:
- 3265399
- Parents:
- b2fe1c9 (diff), 81bb114 (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/libcfa
- Files:
-
- 4 added
- 1 deleted
- 18 edited
-
Makefile.am (modified) (3 diffs)
-
Makefile.in (modified) (11 diffs)
-
bits/cfatime.h (deleted)
-
bits/locks.h (modified) (4 diffs)
-
clock (added)
-
concurrency/alarm.c (modified) (4 diffs)
-
concurrency/alarm.h (modified) (5 diffs)
-
concurrency/coroutine (modified) (5 diffs)
-
concurrency/coroutine.c (modified) (5 diffs)
-
concurrency/invoke.h (modified) (4 diffs)
-
concurrency/kernel (modified) (3 diffs)
-
concurrency/kernel.c (modified) (33 diffs)
-
concurrency/kernel_private.h (modified) (2 diffs)
-
concurrency/monitor.c (modified) (18 diffs)
-
concurrency/preemption.c (modified) (15 diffs)
-
concurrency/preemption.h (modified) (2 diffs)
-
concurrency/thread (modified) (2 diffs)
-
concurrency/thread.c (modified) (7 diffs)
-
iostream (modified) (2 diffs)
-
stdlib.c (modified) (3 diffs)
-
time (added)
-
time.c (added)
-
time_t.h (added)
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/Makefile.am
rb2fe1c9 r32cab5b 11 11 ## Created On : Sun May 31 08:54:01 2015 12 12 ## Last Modified By : Peter A. Buhr 13 ## Last Modified On : Fri Feb 9 15:51:24 201814 ## Update Count : 2 2313 ## Last Modified On : Thu Apr 12 14:38:34 2018 14 ## Update Count : 231 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 … … 100 100 math \ 101 101 gmp \ 102 time_t.h \ 103 clock \ 102 104 bits/align.h \ 103 bits/cfatime.h \104 105 bits/containers.h \ 105 106 bits/defs.h \ -
src/libcfa/Makefile.in
rb2fe1c9 r32cab5b 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 gmp \266 bits/align.h bits/cfatime.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 time_t.h \ 267 clock 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) … … 436 437 math \ 437 438 gmp \ 439 time_t.h \ 440 clock \ 438 441 bits/align.h \ 439 bits/cfatime.h \440 442 bits/containers.h \ 441 443 bits/defs.h \ … … 611 613 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-rational.Po@am__quote@ 612 614 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-stdlib.Po@am__quote@ 615 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-time.Po@am__quote@ 613 616 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_a-virtual.Po@am__quote@ 614 617 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-assert.Po@am__quote@ … … 622 625 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-rational.Po@am__quote@ 623 626 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-stdlib.Po@am__quote@ 627 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-time.Po@am__quote@ 624 628 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcfa_d_a-virtual.Po@am__quote@ 625 629 @AMDEP_TRUE@@am__include@ @am__quote@bits/$(DEPDIR)/libcfa_a-debug.Po@am__quote@ … … 786 790 @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` 787 791 792 libcfa_d_a-time.o: time.c 793 @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 794 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po 795 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_d_a-time.o' libtool=no @AMDEPBACKSLASH@ 796 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 797 @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 798 799 libcfa_d_a-time.obj: time.c 800 @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` 801 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_d_a-time.Tpo $(DEPDIR)/libcfa_d_a-time.Po 802 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_d_a-time.obj' libtool=no @AMDEPBACKSLASH@ 803 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 804 @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` 805 788 806 libcfa_d_a-stdlib.o: stdlib.c 789 807 @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 … … 1079 1097 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1080 1098 @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` 1099 1100 libcfa_a-time.o: time.c 1101 @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 1102 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po 1103 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_a-time.o' libtool=no @AMDEPBACKSLASH@ 1104 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1105 @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 1106 1107 libcfa_a-time.obj: time.c 1108 @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` 1109 @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcfa_a-time.Tpo $(DEPDIR)/libcfa_a-time.Po 1110 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='time.c' object='libcfa_a-time.obj' libtool=no @AMDEPBACKSLASH@ 1111 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1112 @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` 1081 1113 1082 1114 libcfa_a-stdlib.o: stdlib.c -
src/libcfa/bits/locks.h
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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 : Tue Apr 10 14:46:49 2018 13 // Update Count : 10 14 14 // 15 15 … … 19 19 20 20 #include "invoke.h" 21 #include " bits/cfatime.h"21 #include "time_t.h" 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
rb2fe1c9 r32cab5b 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 : Mon Apr 9 16:11:46 2018 13 // Update Count : 24 14 14 // 15 15 … … 25 25 26 26 //CFA Includes 27 #include "time" 27 28 #include "kernel_private.h" 28 29 #include "preemption.h" … … 52 53 // Global state 53 54 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 55 // volatile thread_local bool preemption_in_progress = 0; 59 56 // volatile thread_local bool preemption_enabled = false; 60 57 // volatile thread_local unsigned short disable_preempt_count = 1; 61 58 62 volatile thread_local __cfa_kernel_preemption_state_t preemption_state = { false, false, 1 }; 59 thread_local struct KernelThreadData kernelThreadData = { 60 NULL, 61 NULL, 62 NULL, 63 { 1, false, false } 64 }; 63 65 64 66 //----------------------------------------------------------------------------- … … 172 174 terminate(&this); 173 175 verify(this.do_terminate); 174 verify( this_processor!= &this);176 verify(TL_GET( this_processor ) != &this); 175 177 P( terminated ); 176 verify( this_processor!= &this);178 verify(TL_GET( this_processor ) != &this); 177 179 pthread_join( kernel_thread, NULL ); 178 180 } … … 213 215 if(readyThread) 214 216 { 215 verify( ! preemption_state.enabled );217 verify( ! TL_GET( preemption_state ).enabled ); 216 218 217 219 runThread(this, readyThread); 218 220 219 verify( ! preemption_state.enabled );221 verify( ! TL_GET( preemption_state ).enabled ); 220 222 221 223 //Some actions need to be taken from the kernel … … 249 251 250 252 //Update global state 251 this_thread = dst;253 TL_SET( this_thread, dst ); 252 254 253 255 // Context Switch to the thread … … 257 259 258 260 void returnToKernel() { 259 coroutine_desc * proc_cor = get_coroutine( this_processor->runner);260 coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;261 coroutine_desc * proc_cor = get_coroutine(TL_GET( this_processor )->runner); 262 coroutine_desc * thrd_cor = TL_GET( this_thread )->curr_cor = TL_GET( this_coroutine ); 261 263 ThreadCtxSwitch(thrd_cor, proc_cor); 262 264 } … … 266 268 void finishRunning(processor * this) with( this->finish ) { 267 269 if( action_code == Release ) { 268 verify( ! preemption_state.enabled );270 verify( ! TL_GET( preemption_state ).enabled ); 269 271 unlock( *lock ); 270 272 } … … 273 275 } 274 276 else if( action_code == Release_Schedule ) { 275 verify( ! preemption_state.enabled );277 verify( ! TL_GET( preemption_state ).enabled ); 276 278 unlock( *lock ); 277 279 ScheduleThread( thrd ); 278 280 } 279 281 else if( action_code == Release_Multi ) { 280 verify( ! preemption_state.enabled );282 verify( ! TL_GET( preemption_state ).enabled ); 281 283 for(int i = 0; i < lock_count; i++) { 282 284 unlock( *locks[i] ); … … 307 309 void * CtxInvokeProcessor(void * arg) { 308 310 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;311 TL_SET( this_processor, proc ); 312 TL_SET( this_coroutine, NULL ); 313 TL_SET( this_thread, NULL ); 314 TL_GET( preemption_state ).enabled = false; 315 TL_GET( preemption_state ).disable_count = 1; 314 316 // SKULLDUGGERY: We want to create a context for the processor coroutine 315 317 // which is needed for the 2-step context switch. However, there is no reason … … 323 325 324 326 //Set global state 325 this_coroutine = get_coroutine(proc->runner);326 this_thread = NULL;327 TL_SET( this_coroutine, get_coroutine(proc->runner) ); 328 TL_SET( this_thread, NULL ); 327 329 328 330 //We now have a proper context from which to schedule threads … … 352 354 353 355 void kernel_first_resume(processor * this) { 354 coroutine_desc * src = this_coroutine;356 coroutine_desc * src = TL_GET( this_coroutine ); 355 357 coroutine_desc * dst = get_coroutine(this->runner); 356 358 357 verify( ! preemption_state.enabled );359 verify( ! TL_GET( preemption_state ).enabled ); 358 360 359 361 create_stack(&dst->stack, dst->stack.size); 360 362 CtxStart(&this->runner, CtxInvokeCoroutine); 361 363 362 verify( ! preemption_state.enabled );364 verify( ! TL_GET( preemption_state ).enabled ); 363 365 364 366 dst->last = src; … … 369 371 370 372 // set new coroutine that task is executing 371 this_coroutine = dst;373 TL_SET( this_coroutine, dst ); 372 374 373 375 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch. … … 386 388 src->state = Active; 387 389 388 verify( ! preemption_state.enabled );390 verify( ! TL_GET( preemption_state ).enabled ); 389 391 } 390 392 … … 392 394 // Scheduler routines 393 395 void ScheduleThread( thread_desc * thrd ) { 394 // if( ! thrd ) return;396 // if( ! thrd ) return; 395 397 verify( thrd ); 396 398 verify( thrd->self_cor.state != Halted ); 397 399 398 verify( ! preemption_state.enabled );400 verify( ! TL_GET( preemption_state ).enabled ); 399 401 400 402 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next ); 401 403 402 with( * this_processor->cltr ) {404 with( *TL_GET( this_processor )->cltr ) { 403 405 lock ( ready_queue_lock __cfaabi_dbg_ctx2 ); 404 406 append( ready_queue, thrd ); … … 406 408 } 407 409 408 verify( ! preemption_state.enabled );410 verify( ! TL_GET( preemption_state ).enabled ); 409 411 } 410 412 411 413 thread_desc * nextThread(cluster * this) with( *this ) { 412 verify( ! preemption_state.enabled );414 verify( ! TL_GET( preemption_state ).enabled ); 413 415 lock( ready_queue_lock __cfaabi_dbg_ctx2 ); 414 416 thread_desc * head = pop_head( ready_queue ); 415 417 unlock( ready_queue_lock ); 416 verify( ! preemption_state.enabled );418 verify( ! TL_GET( preemption_state ).enabled ); 417 419 return head; 418 420 } … … 420 422 void BlockInternal() { 421 423 disable_interrupts(); 422 verify( ! preemption_state.enabled );424 verify( ! TL_GET( preemption_state ).enabled ); 423 425 returnToKernel(); 424 verify( ! preemption_state.enabled );426 verify( ! TL_GET( preemption_state ).enabled ); 425 427 enable_interrupts( __cfaabi_dbg_ctx ); 426 428 } … … 428 430 void BlockInternal( __spinlock_t * lock ) { 429 431 disable_interrupts(); 430 this_processor->finish.action_code = Release;431 this_processor->finish.lock = lock;432 433 verify( ! preemption_state.enabled );432 TL_GET( this_processor )->finish.action_code = Release; 433 TL_GET( this_processor )->finish.lock = lock; 434 435 verify( ! TL_GET( preemption_state ).enabled ); 434 436 returnToKernel(); 435 verify( ! preemption_state.enabled );437 verify( ! TL_GET( preemption_state ).enabled ); 436 438 437 439 enable_interrupts( __cfaabi_dbg_ctx ); … … 440 442 void BlockInternal( thread_desc * thrd ) { 441 443 disable_interrupts(); 442 this_processor->finish.action_code = Schedule;443 this_processor->finish.thrd = thrd;444 445 verify( ! preemption_state.enabled );444 TL_GET( this_processor )->finish.action_code = Schedule; 445 TL_GET( this_processor )->finish.thrd = thrd; 446 447 verify( ! TL_GET( preemption_state ).enabled ); 446 448 returnToKernel(); 447 verify( ! preemption_state.enabled );449 verify( ! TL_GET( preemption_state ).enabled ); 448 450 449 451 enable_interrupts( __cfaabi_dbg_ctx ); … … 453 455 assert(thrd); 454 456 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 );457 TL_GET( this_processor )->finish.action_code = Release_Schedule; 458 TL_GET( this_processor )->finish.lock = lock; 459 TL_GET( this_processor )->finish.thrd = thrd; 460 461 verify( ! TL_GET( preemption_state ).enabled ); 460 462 returnToKernel(); 461 verify( ! preemption_state.enabled );463 verify( ! TL_GET( preemption_state ).enabled ); 462 464 463 465 enable_interrupts( __cfaabi_dbg_ctx ); … … 466 468 void BlockInternal(__spinlock_t * locks [], unsigned short count) { 467 469 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 );470 TL_GET( this_processor )->finish.action_code = Release_Multi; 471 TL_GET( this_processor )->finish.locks = locks; 472 TL_GET( this_processor )->finish.lock_count = count; 473 474 verify( ! TL_GET( preemption_state ).enabled ); 473 475 returnToKernel(); 474 verify( ! preemption_state.enabled );476 verify( ! TL_GET( preemption_state ).enabled ); 475 477 476 478 enable_interrupts( __cfaabi_dbg_ctx ); … … 479 481 void BlockInternal(__spinlock_t * locks [], unsigned short lock_count, thread_desc * thrds [], unsigned short thrd_count) { 480 482 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 );483 TL_GET( this_processor )->finish.action_code = Release_Multi_Schedule; 484 TL_GET( this_processor )->finish.locks = locks; 485 TL_GET( this_processor )->finish.lock_count = lock_count; 486 TL_GET( this_processor )->finish.thrds = thrds; 487 TL_GET( this_processor )->finish.thrd_count = thrd_count; 488 489 verify( ! TL_GET( preemption_state ).enabled ); 488 490 returnToKernel(); 489 verify( ! preemption_state.enabled );491 verify( ! TL_GET( preemption_state ).enabled ); 490 492 491 493 enable_interrupts( __cfaabi_dbg_ctx ); … … 493 495 494 496 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;497 verify( ! TL_GET( preemption_state ).enabled ); 498 TL_GET( this_processor )->finish.action_code = thrd ? Release_Schedule : Release; 499 TL_GET( this_processor )->finish.lock = lock; 500 TL_GET( this_processor )->finish.thrd = thrd; 499 501 500 502 returnToKernel(); … … 507 509 // Kernel boot procedures 508 510 void kernel_startup(void) { 509 verify( ! preemption_state.enabled );511 verify( ! TL_GET( preemption_state ).enabled ); 510 512 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 511 513 … … 531 533 532 534 //initialize the global state variables 533 this_processor = mainProcessor;534 this_thread = mainThread;535 this_coroutine = &mainThread->self_cor;535 TL_SET( this_processor, mainProcessor ); 536 TL_SET( this_thread, mainThread ); 537 TL_SET( this_coroutine, &mainThread->self_cor ); 536 538 537 539 // Enable preemption … … 545 547 // context. Hence, the main thread does not begin through CtxInvokeThread, like all other threads. The trick here is that 546 548 // mainThread is on the ready queue when this call is made. 547 kernel_first_resume( this_processor);549 kernel_first_resume( TL_GET( this_processor ) ); 548 550 549 551 … … 552 554 __cfaabi_dbg_print_safe("Kernel : Started\n--------------------------------------------------\n\n"); 553 555 554 verify( ! preemption_state.enabled );556 verify( ! TL_GET( preemption_state ).enabled ); 555 557 enable_interrupts( __cfaabi_dbg_ctx ); 556 verify( preemption_state.enabled );558 verify( TL_GET( preemption_state ).enabled ); 557 559 } 558 560 … … 560 562 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 561 563 562 verify( preemption_state.enabled );564 verify( TL_GET( preemption_state ).enabled ); 563 565 disable_interrupts(); 564 verify( ! preemption_state.enabled );566 verify( ! TL_GET( preemption_state ).enabled ); 565 567 566 568 // SKULLDUGGERY: Notify the mainProcessor it needs to terminates. … … 602 604 603 605 // first task to abort ? 604 if ( ! kernel_abort_called ) { // not first task to abort ?606 if ( ! kernel_abort_called ) { // not first task to abort ? 605 607 kernel_abort_called = true; 606 608 unlock( kernel_abort_lock ); … … 617 619 } 618 620 619 return this_thread;621 return TL_GET( this_thread ); 620 622 } 621 623 … … 626 628 __cfaabi_dbg_bits_write( abort_text, len ); 627 629 628 if ( thrd != this_coroutine) {629 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", this_coroutine->name, this_coroutine);630 if ( get_coroutine(thrd) != TL_GET( this_coroutine ) ) { 631 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", TL_GET( this_coroutine )->name, TL_GET( this_coroutine ) ); 630 632 __cfaabi_dbg_bits_write( abort_text, len ); 631 633 } … … 636 638 637 639 int kernel_abort_lastframe( void ) __attribute__ ((__nothrow__)) { 638 return get_coroutine( this_thread) == get_coroutine(mainThread) ? 4 : 2;640 return get_coroutine(TL_GET( this_thread )) == get_coroutine(mainThread) ? 4 : 2; 639 641 } 640 642 … … 666 668 if ( count < 0 ) { 667 669 // queue current task 668 append( waiting, (thread_desc *) this_thread);670 append( waiting, (thread_desc *)TL_GET( this_thread ) ); 669 671 670 672 // atomically release spin lock and block -
src/libcfa/concurrency/kernel_private.h
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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
rb2fe1c9 r32cab5b 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/iostream
rb2fe1c9 r32cab5b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jan 25 13:08:39201813 // Update Count : 1 4912 // Last Modified On : Thu Apr 12 14:34:37 2018 13 // Update Count : 150 14 14 // 15 15 … … 159 159 forall( dtype istype | istream( istype ) ) istype & ?|?( istype &, _Istream_cstrC ); 160 160 161 162 #include <time_t.h> // Duration (constructors) / Time (constructors) 163 164 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur ); 165 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time ); 166 167 161 168 // Local Variables: // 162 169 // mode: c // -
src/libcfa/stdlib.c
rb2fe1c9 r32cab5b 99 99 char * eeptr; 100 100 re = strtof( sptr, &eeptr ); 101 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }101 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; } 102 102 im = strtof( eeptr, &eeptr ); 103 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; }103 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; } 104 104 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0f + 0.0f * _Complex_I; } 105 105 return re + im * _Complex_I; … … 110 110 char * eeptr; 111 111 re = strtod( sptr, &eeptr ); 112 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }112 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; } 113 113 im = strtod( eeptr, &eeptr ); 114 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; }114 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; } 115 115 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0 + 0.0 * _Complex_I; } 116 116 return re + im * _Complex_I; … … 121 121 char * eeptr; 122 122 re = strtold( sptr, &eeptr ); 123 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }123 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; } 124 124 im = strtold( eeptr, &eeptr ); 125 if ( sptr == *eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; }125 if ( sptr == eeptr ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; } 126 126 if ( *eeptr != 'i' ) { if ( eptr != 0 ) *eptr = eeptr; return 0.0L + 0.0L * _Complex_I; } 127 127 return re + im * _Complex_I;
Note:
See TracChangeset
for help on using the changeset viewer.