Changes in / [7b2a786:a5a67ab8]
- Files:
-
- 2 deleted
- 6 edited
-
Jenkins/Distribute (deleted)
-
Jenkins/tools.groovy (deleted)
-
Jenkinsfile (modified) (17 diffs)
-
libcfa/src/bits/containers.hfa (modified) (7 diffs)
-
libcfa/src/concurrency/alarm.cfa (modified) (1 diff)
-
libcfa/src/concurrency/alarm.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/locks.cfa (modified) (16 diffs)
-
libcfa/src/concurrency/locks.hfa (modified) (7 diffs)
Legend:
- Unmodified
- Added
- Removed
-
Jenkinsfile
r7b2a786 ra5a67ab8 2 2 3 3 import groovy.transform.Field 4 5 // For skipping stages 6 import org.jenkinsci.plugins.pipeline.modeldefinition.Utils 4 7 5 8 //=========================================================================================================== … … 12 15 SrcDir = pwd tmp: false 13 16 Settings = null 14 Tools = null17 StageName = '' 15 18 16 19 // Local variables … … 63 66 64 67 //Store the result of the build log 65 currentBuild.result = "${ tools.StageName} FAILURE".trim()68 currentBuild.result = "${StageName} FAILURE".trim() 66 69 } 67 70 … … 82 85 //=========================================================================================================== 83 86 def clean() { 84 Tools.BuildStage('Cleanup', true) {87 build_stage('Cleanup', true) { 85 88 // clean the build by wipping the build directory 86 89 dir(BuildDir) { … … 92 95 //Compilation script is done here but environnement set-up and error handling is done in main loop 93 96 def checkout() { 94 Tools.BuildStage('Checkout', true) {97 build_stage('Checkout', true) { 95 98 //checkout the source code and clean the repo 96 99 final scmVars = checkout scm … … 105 108 debug = true 106 109 release = Settings.RunAllTests || Settings.RunBenchmark 107 Tools.BuildStage('Build : configure', true) {110 build_stage('Build : configure', true) { 108 111 // Configure must be run inside the tree 109 112 dir (SrcDir) { … … 133 136 } 134 137 135 Tools.BuildStage('Build : cfa-cpp', true) {138 build_stage('Build : cfa-cpp', true) { 136 139 // Build outside of the src tree to ease cleaning 137 140 dir (BuildDir) { … … 144 147 } 145 148 146 Tools.BuildStage('Build : libcfa(debug)', debug) {149 build_stage('Build : libcfa(debug)', debug) { 147 150 // Build outside of the src tree to ease cleaning 148 151 dir (BuildDir) { … … 151 154 } 152 155 153 Tools.BuildStage('Build : libcfa(nodebug)', release) {156 build_stage('Build : libcfa(nodebug)', release) { 154 157 // Build outside of the src tree to ease cleaning 155 158 dir (BuildDir) { … … 158 161 } 159 162 160 Tools.BuildStage('Build : install', true) {163 build_stage('Build : install', true) { 161 164 // Build outside of the src tree to ease cleaning 162 165 dir (BuildDir) { … … 168 171 def test() { 169 172 try { 170 Tools.BuildStage('Test: short', !Settings.RunAllTests) {173 build_stage('Test: short', !Settings.RunAllTests) { 171 174 dir (BuildDir) { 172 175 //Run the tests from the tests directory … … 175 178 } 176 179 177 Tools.BuildStage('Test: full', Settings.RunAllTests) {180 build_stage('Test: full', Settings.RunAllTests) { 178 181 dir (BuildDir) { 179 182 //Run the tests from the tests directory … … 193 196 194 197 def benchmark() { 195 Tools.BuildStage('Benchmark', Settings.RunBenchmark) {198 build_stage('Benchmark', Settings.RunBenchmark) { 196 199 dir (BuildDir) { 197 200 //Append bench results … … 202 205 203 206 def build_doc() { 204 Tools.BuildStage('Documentation', Settings.BuildDocumentation) {207 build_stage('Documentation', Settings.BuildDocumentation) { 205 208 dir ('doc/user') { 206 209 make_doc() … … 214 217 215 218 def publish() { 216 Tools.BuildStage('Publish', true) {219 build_stage('Publish', true) { 217 220 218 221 if( Settings.Publish && !Settings.RunBenchmark ) { echo 'No results to publish!!!' } … … 503 506 ]]) 504 507 505 // It's unfortunate but it looks like we need to checkout the entire repo just to get 506 // - the pretty git printer 507 // - Jenkins.tools 508 // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer 508 509 checkout scm 509 510 Tools = load "Jenkins/tools.groovy"511 510 512 511 final settings = new BuildSettings(params, env.BRANCH_NAME) … … 516 515 517 516 return settings 517 } 518 519 def build_stage(String name, boolean run, Closure block ) { 520 StageName = name 521 echo " -------- ${StageName} -------- " 522 if(run) { 523 stage(name, block) 524 } else { 525 stage(name) { Utils.markStageSkippedForConditional(STAGE_NAME) } 526 } 518 527 } 519 528 -
libcfa/src/bits/containers.hfa
r7b2a786 ra5a67ab8 17 17 #include "bits/align.hfa" 18 18 #include "bits/defs.hfa" 19 #include <stdio.h> 19 20 20 //----------------------------------------------------------------------------- 21 21 // Array … … 146 146 static inline forall( dtype T | is_node(T) ) { 147 147 void ?{}( __queue(T) & this ) with( this ) { 148 (this.head){ 1p };149 (this.tail){ &this.head };150 verify(*t his.tail == 1p);148 head{ 1p }; 149 tail{ &head }; 150 verify(*tail == 1p); 151 151 } 152 152 153 153 void append( __queue(T) & this, T * val ) with( this ) { 154 verify(t his.tail != 0p);155 verify(*t his.tail == 1p);156 *t his.tail = val;157 t his.tail = &get_next( *val );158 *t his.tail = 1p;154 verify(tail != 0p); 155 verify(*tail == 1p); 156 *tail = val; 157 tail = &get_next( *val ); 158 *tail = 1p; 159 159 } 160 160 161 161 T * peek( __queue(T) & this ) { 162 162 verify(*this.tail == 1p); 163 T * front= this.head;164 if( front!= 1p ) {163 T * head = this.head; 164 if( head != 1p ) { 165 165 verify(*this.tail == 1p); 166 return front;166 return head; 167 167 } 168 168 verify(*this.tail == 1p); … … 172 172 T * pop_head( __queue(T) & this ) { 173 173 verify(*this.tail == 1p); 174 T * _head = this.head;175 if( _head != 1p ) {176 this.head = get_next( * _head );177 if( get_next( * _head ) == 1p ) {174 T * head = this.head; 175 if( head != 1p ) { 176 this.head = get_next( *head ); 177 if( get_next( *head ) == 1p ) { 178 178 this.tail = &this.head; 179 179 } 180 get_next( * _head ) = 0p;180 get_next( *head ) = 0p; 181 181 verify(*this.tail == 1p); 182 verify( get_next(* _head) == 0p );183 return _head;182 verify( get_next(*head) == 0p ); 183 return head; 184 184 } 185 185 verify(*this.tail == 1p); … … 193 193 (*it) = get_next( *val ); 194 194 195 if( t his.tail == &get_next( *val ) ) {196 t his.tail = it;195 if( tail == &get_next( *val ) ) { 196 tail = it; 197 197 } 198 198 199 199 get_next( *val ) = 0p; 200 200 201 verify( ( this.head == 1p) == (&this.head == this.tail) );202 verify( *t his.tail == 1p );201 verify( (head == 1p) == (&head == tail) ); 202 verify( *tail == 1p ); 203 203 return val; 204 204 } … … 239 239 forall(dtype T ) 240 240 static inline [void] ?{}( __dllist(T) & this, * [T * & next, T * & prev] ( T & ) __get ) { 241 (this.head){ 0p };241 this.head{ 0p }; 242 242 this.__get = __get; 243 243 } … … 248 248 void push_front( __dllist(T) & this, T & node ) with( this ) { 249 249 verify(__get); 250 if ( this.head ) {251 __get( node ).next = this.head;252 __get( node ).prev = __get( * this.head ).prev;250 if ( head ) { 251 __get( node ).next = head; 252 __get( node ).prev = __get( *head ).prev; 253 253 // inserted node must be consistent before it is seen 254 254 // prevent code movement across barrier 255 255 asm( "" : : : "memory" ); 256 __get( * this.head ).prev = &node;256 __get( *head ).prev = &node; 257 257 T & _prev = *__get( node ).prev; 258 258 __get( _prev ).next = &node; … … 264 264 // prevent code movement across barrier 265 265 asm( "" : : : "memory" ); 266 this.head = &node;266 head = &node; 267 267 } 268 268 269 269 void remove( __dllist(T) & this, T & node ) with( this ) { 270 270 verify(__get); 271 if ( &node == this.head ) {272 if ( __get( * this.head ).next == this.head ) {273 this.head = 0p;271 if ( &node == head ) { 272 if ( __get( *head ).next == head ) { 273 head = 0p; 274 274 } else { 275 this.head = __get( *this.head ).next;275 head = __get( *head ).next; 276 276 } 277 277 } -
libcfa/src/concurrency/alarm.cfa
r7b2a786 ra5a67ab8 60 60 type = Kernel; 61 61 } 62 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period ) with( this ) { 62 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) with( this ) { 63 this.thrd = thrd; 63 64 this.alarm = alarm; 64 65 this.period = period; -
libcfa/src/concurrency/alarm.hfa
r7b2a786 ra5a67ab8 52 52 53 53 union { 54 $thread * thrd; // thrd who created event 55 processor * proc; // proc who created event 56 Alarm_Callback callback; // callback to handle event 54 $thread * thrd; // thrd who created event 55 processor * proc; // proc who created event 57 56 }; 57 58 Alarm_Callback callback; 58 59 59 60 bool set :1; // whether or not the alarm has be registered … … 64 65 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period ); 65 66 void ?{}( alarm_node_t & this, processor * proc, Time alarm, Duration period ); 66 void ?{}( alarm_node_t & this, Alarm_Callback callback, Time alarm, Duration period);67 void ?{}( alarm_node_t & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ); 67 68 void ^?{}( alarm_node_t & this ); 68 69 -
libcfa/src/concurrency/locks.cfa
r7b2a786 ra5a67ab8 11 11 //// info_thread 12 12 /////////////////////////////////////////////////////////////////// 13 14 13 forall(dtype L | is_blocking_lock(L)) { 15 14 void ?{}( info_thread(L) & this, $thread * t ) { 16 ((Seqable &) this){};17 15 this.t = t; 18 16 this.lock = 0p; … … 21 19 22 20 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ) { 23 ((Seqable &) this){};24 21 this.t = t; 25 22 this.info = info; … … 28 25 } 29 26 30 void ^?{}( info_thread(L) & this ){ } 31 } 32 27 void ^?{}( info_thread(L) & this ){ 28 // default 29 } 30 31 info_thread(L) *& get_next( info_thread(L) & this ) { 32 return this.next; 33 } 34 } 33 35 /////////////////////////////////////////////////////////////////// 34 36 //// Blocking Locks … … 45 47 } 46 48 47 void ^?{}( blocking_lock & this ) {} 48 void ?{}( single_acquisition_lock & this ) {((blocking_lock &)this){ false, false };} 49 void ^?{}( single_acquisition_lock & this ) {} 50 void ?{}( owner_lock & this ) {((blocking_lock &)this){ true, true };} 51 void ^?{}( owner_lock & this ) {} 52 void ?{}( multiple_acquisition_lock & this ) {((blocking_lock &)this){ true, false };} 53 void ^?{}( multiple_acquisition_lock & this ) {} 49 void ^?{}( blocking_lock & this ) { 50 // default 51 } 52 53 void ?{}( single_acquisition_lock & this ) { 54 ((blocking_lock &)this){ false, false }; 55 } 56 57 void ^?{}( single_acquisition_lock & this ) { 58 // default 59 } 60 61 void ?{}( owner_lock & this ) { 62 ((blocking_lock &)this){ true, true }; 63 } 64 65 void ^?{}( owner_lock & this ) { 66 // default 67 } 68 69 void ?{}( multiple_acquisition_lock & this ) { 70 ((blocking_lock &)this){ true, false }; 71 } 72 73 void ^?{}( multiple_acquisition_lock & this ) { 74 // default 75 } 54 76 55 77 void lock( blocking_lock & this ) with( this ) { 56 78 lock( lock __cfaabi_dbg_ctx2 ); 57 79 if ( owner == active_thread() && !multi_acquisition) { 58 abort("A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); 80 fprintf(stderr, "A single acquisition lock holder attempted to reacquire the lock resulting in a deadlock."); // Possibly throw instead 81 exit(EXIT_FAILURE); 59 82 } else if ( owner != 0p && owner != active_thread() ) { 60 83 append( blocked_threads, active_thread() ); … … 87 110 } 88 111 89 void unlock_error_check( blocking_lock & this ) with( this ) {90 if ( owner == 0p ){ // no owner implies lock isn't held91 abort( "There was an attempt to release a lock that isn't held" );92 } else if ( strict_owner && owner != active_thread() ) {93 abort( "A thread other than the owner attempted to release an owner lock" );94 }95 }96 97 void pop_and_set_new_owner( blocking_lock & this ) with( this ) {98 $thread * t = pop_head( blocked_threads );99 owner = t;100 recursion_count = ( t ? 1 : 0 );101 wait_count--;102 unpark( t );103 }104 105 112 void unlock( blocking_lock & this ) with( this ) { 106 113 lock( lock __cfaabi_dbg_ctx2 ); 107 unlock_error_check( this ); 114 if ( owner == 0p ){ // no owner implies lock isn't held 115 fprintf( stderr, "There was an attempt to release a lock that isn't held" ); 116 return; 117 } else if ( strict_owner && owner != active_thread() ) { 118 fprintf( stderr, "A thread other than the owner attempted to release an owner lock" ); 119 return; 120 } 108 121 recursion_count--; 109 122 if ( recursion_count == 0 ) { 110 pop_and_set_new_owner( this ); 123 $thread * thrd = pop_head( blocked_threads ); 124 owner = thrd; 125 recursion_count = ( thrd ? 1 : 0 ); 126 wait_count--; 127 unpark( thrd ); 111 128 } 112 129 unlock( lock ); … … 116 133 return wait_count; 117 134 } 135 118 136 119 137 void set_recursion_count( blocking_lock & this, size_t recursion ) with( this ) { … … 134 152 owner = t; 135 153 recursion_count = 1; 154 #if !defined( __CFA_NO_STATISTICS__ ) 155 //kernelTLS.this_stats = t->curr_cluster->stats; 156 #endif 136 157 unpark( t ); 137 158 unlock( lock ); … … 141 162 void remove_( blocking_lock & this ) with( this ) { 142 163 lock( lock __cfaabi_dbg_ctx2 ); 143 unlock_error_check( this ); 144 pop_and_set_new_owner( this ); 164 if ( owner == 0p ){ // no owner implies lock isn't held 165 fprintf( stderr, "A lock that is not held was passed to a synchronization lock" ); 166 } else if ( strict_owner && owner != active_thread() ) { 167 fprintf( stderr, "A thread other than the owner of a lock passed it to a synchronization lock" ); 168 } else { 169 $thread * thrd = pop_head( blocked_threads ); 170 owner = thrd; 171 recursion_count = ( thrd ? 1 : 0 ); 172 wait_count--; 173 unpark( thrd ); 174 } 145 175 unlock( lock ); 146 176 } … … 152 182 // This is temporary until an inheritance bug is fixed 153 183 154 void lock( single_acquisition_lock & this ){ lock( (blocking_lock &)this ); } 155 void unlock( single_acquisition_lock & this ){ unlock( (blocking_lock &)this ); } 156 void add_( single_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); } 157 void remove_( single_acquisition_lock & this ){ remove_( (blocking_lock &)this ); } 158 void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 159 size_t get_recursion_count( single_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 160 161 void lock( owner_lock & this ){ lock( (blocking_lock &)this ); } 162 void unlock( owner_lock & this ){ unlock( (blocking_lock &)this ); } 163 void add_( owner_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); } 164 void remove_( owner_lock & this ){ remove_( (blocking_lock &)this ); } 165 void set_recursion_count( owner_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 166 size_t get_recursion_count( owner_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 167 168 void lock( multiple_acquisition_lock & this ){ lock( (blocking_lock &)this ); } 169 void unlock( multiple_acquisition_lock & this ){ unlock( (blocking_lock &)this ); } 170 void add_( multiple_acquisition_lock & this, struct $thread * t ){ add_( (blocking_lock &)this, t ); } 171 void remove_( multiple_acquisition_lock & this ){ remove_( (blocking_lock &)this ); } 172 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ set_recursion_count( (blocking_lock &)this, recursion ); } 173 size_t get_recursion_count( multiple_acquisition_lock & this ){ return get_recursion_count( (blocking_lock &)this ); } 184 void lock( single_acquisition_lock & this ){ 185 lock( (blocking_lock &)this ); 186 } 187 188 void unlock( single_acquisition_lock & this ){ 189 unlock( (blocking_lock &)this ); 190 } 191 192 void add_( single_acquisition_lock & this, struct $thread * t ){ 193 add_( (blocking_lock &)this, t ); 194 } 195 196 void remove_( single_acquisition_lock & this ){ 197 remove_( (blocking_lock &)this ); 198 } 199 200 void set_recursion_count( single_acquisition_lock & this, size_t recursion ){ 201 set_recursion_count( (blocking_lock &)this, recursion ); 202 } 203 204 size_t get_recursion_count( single_acquisition_lock & this ){ 205 return get_recursion_count( (blocking_lock &)this ); 206 } 207 208 void lock( owner_lock & this ){ 209 lock( (blocking_lock &)this ); 210 } 211 212 void unlock( owner_lock & this ){ 213 unlock( (blocking_lock &)this ); 214 } 215 216 void add_( owner_lock & this, struct $thread * t ){ 217 add_( (blocking_lock &)this, t ); 218 } 219 220 void remove_( owner_lock & this ){ 221 remove_( (blocking_lock &)this ); 222 } 223 224 void set_recursion_count( owner_lock & this, size_t recursion ){ 225 set_recursion_count( (blocking_lock &)this, recursion ); 226 } 227 228 size_t get_recursion_count( owner_lock & this ){ 229 return get_recursion_count( (blocking_lock &)this ); 230 } 231 232 void lock( multiple_acquisition_lock & this ){ 233 lock( (blocking_lock &)this ); 234 } 235 236 void unlock( multiple_acquisition_lock & this ){ 237 unlock( (blocking_lock &)this ); 238 } 239 240 void add_( multiple_acquisition_lock & this, struct $thread * t ){ 241 add_( (blocking_lock &)this, t ); 242 } 243 244 void remove_( multiple_acquisition_lock & this ){ 245 remove_( (blocking_lock &)this ); 246 } 247 248 void set_recursion_count( multiple_acquisition_lock & this, size_t recursion ){ 249 set_recursion_count( (blocking_lock &)this, recursion ); 250 } 251 252 size_t get_recursion_count( multiple_acquisition_lock & this ){ 253 return get_recursion_count( (blocking_lock &)this ); 254 } 174 255 175 256 /////////////////////////////////////////////////////////////////// … … 182 263 // This condition_variable member is called from the kernel, and therefore, cannot block, but it can spin. 183 264 lock( cond->lock __cfaabi_dbg_ctx2 ); 184 185 if ( i->listed ) { // is thread on queue 186 cond->last_thread = i; // REMOVE THIS AFTER DEBUG 187 remove( cond->blocked_threads, *i ); //remove this thread O(1) 265 if ( (*i)->listed ) { // is thread on queue 266 info_thread(L) * copy = *i; 267 remove( cond->blocked_threads, i ); //remove this thread O(1) 188 268 cond->count--; 189 if( !i->lock ) { 190 unpark( i->t ); 269 if( !copy->lock ) { 270 #if !defined( __CFA_NO_STATISTICS__ ) 271 //kernelTLS.this_stats = copy->t->curr_cluster->stats; 272 #endif 273 unpark( copy->t ); 191 274 } else { 192 add_(* i->lock, i->t); // call lock's add_275 add_(*copy->lock, copy->t); // call lock's add_ 193 276 } 194 277 } … … 196 279 } 197 280 198 void alarm_node_wrap_cast( alarm_node_t & a ) { timeout_handler( (alarm_node_wrap(L) &)a ); } 281 void alarm_node_wrap_cast( alarm_node_t & a ) { 282 timeout_handler( (alarm_node_wrap(L) &)a ); 283 } 199 284 200 285 void ?{}( condition_variable(L) & this ){ … … 202 287 this.blocked_threads{}; 203 288 this.count = 0; 204 this.last_thread = 0p; // REMOVE AFTER DEBUG 205 } 206 207 void ^?{}( condition_variable(L) & this ){ } 208 209 void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback ) { 210 this.alarm_node{ callback, alarm, period }; 211 } 212 213 void ^?{}( alarm_node_wrap(L) & this ) { } 214 215 void process_popped( condition_variable(L) & this, info_thread(L) & popped ) with( this ) { 216 if(&popped != 0p) { 217 popped.listed = false; 289 } 290 291 void ^?{}( condition_variable(L) & this ){ 292 // default 293 } 294 295 void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ) { 296 this.alarm_node{ thrd, alarm, period, callback }; 297 } 298 299 void ^?{}( alarm_node_wrap(L) & this ) { 300 // default 301 } 302 303 bool notify_one( condition_variable(L) & this ) with( this ) { 304 lock( lock __cfaabi_dbg_ctx2 ); 305 bool ret = !!blocked_threads; 306 info_thread(L) * popped = pop_head( blocked_threads ); 307 if(popped != 0p) { 308 popped->listed = false; 218 309 count--; 219 if (popped .lock) {220 add_(*popped .lock, popped.t);310 if (popped->lock) { 311 add_(*popped->lock, popped->t); 221 312 } else { 222 unpark(popped .t);313 unpark(popped->t); 223 314 } 224 315 } 225 }226 227 bool notify_one( condition_variable(L) & this ) with( this ) {228 lock( lock __cfaabi_dbg_ctx2 );229 bool ret = !empty(blocked_threads);230 process_popped(this, dropHead( blocked_threads ));231 316 unlock( lock ); 232 317 return ret; … … 235 320 bool notify_all( condition_variable(L) & this ) with(this) { 236 321 lock( lock __cfaabi_dbg_ctx2 ); 237 bool ret = !empty(blocked_threads); 238 while( !empty(blocked_threads) ) { 239 process_popped(this, dropHead( blocked_threads )); 322 bool ret = blocked_threads ? true : false; 323 while( blocked_threads ) { 324 info_thread(L) * popped = pop_head( blocked_threads ); 325 if(popped != 0p){ 326 popped->listed = false; 327 count--; 328 if (popped->lock) { 329 add_(*popped->lock, popped->t); 330 } else { 331 unpark(popped->t); 332 } 333 } 240 334 } 241 335 unlock( lock ); … … 244 338 245 339 uintptr_t front( condition_variable(L) & this ) with(this) { 246 return empty(blocked_threads) ? NULL : head(blocked_threads).info; 247 } 248 249 bool empty( condition_variable(L) & this ) with(this) { return empty(blocked_threads); } 250 251 int counter( condition_variable(L) & this ) with(this) { return count; } 252 253 size_t queue_and_get_recursion( condition_variable(L) & this, info_thread(L) * i ) with(this) { 254 addTail( blocked_threads, *i ); 255 count++; 256 i->listed = true; 257 size_t recursion_count = 0; 258 if (i->lock) { 259 i->t->link.next = 1p; 260 recursion_count = get_recursion_count(*i->lock); 261 remove_( *i->lock ); 262 } 263 return recursion_count; 264 } 265 266 // helper for wait()'s' with no timeout 340 if(!blocked_threads) return NULL; 341 return peek(blocked_threads)->info; 342 } 343 344 bool empty( condition_variable(L) & this ) with(this) { 345 return blocked_threads ? false : true; 346 } 347 348 int counter( condition_variable(L) & this ) with(this) { 349 return count; 350 } 351 352 // helper for wait()'s' without a timeout 267 353 void queue_info_thread( condition_variable(L) & this, info_thread(L) & i ) with(this) { 268 354 lock( lock __cfaabi_dbg_ctx2 ); 269 size_t recursion_count = queue_and_get_recursion(this, &i); 355 append( this.blocked_threads, &i ); 356 count++; 357 i.listed = true; 358 size_t recursion_count; 359 if (i.lock) { 360 recursion_count = get_recursion_count(*i.lock); 361 remove_( *i.lock ); 362 } 363 270 364 unlock( lock ); 271 365 park( ); // blocks here 366 272 367 if (i.lock) set_recursion_count(*i.lock, recursion_count); // resets recursion count here after waking 273 368 } … … 276 371 void queue_info_thread_timeout( condition_variable(L) & this, info_thread(L) & info, Time t ) with(this) { 277 372 lock( lock __cfaabi_dbg_ctx2 ); 278 size_t recursion_count = queue_and_get_recursion(this, &info); 279 alarm_node_wrap(L) node_wrap = { t, 0`s, alarm_node_wrap_cast }; 373 374 info_thread(L) * queue_ptr = &info; 375 376 alarm_node_wrap(L) node_wrap = { info.t, t, 0`s, alarm_node_wrap_cast }; 280 377 node_wrap.cond = &this; 281 node_wrap.i = &info; 378 node_wrap.i = &queue_ptr; 379 282 380 register_self( &node_wrap.alarm_node ); 381 382 append( blocked_threads, queue_ptr ); 383 info.listed = true; 384 count++; 385 386 size_t recursion_count; 387 if (info.lock) { 388 recursion_count = get_recursion_count(*info.lock); 389 remove_( *info.lock ); 390 } 391 283 392 unlock( lock ); 284 393 park(); 285 unregister_self( &node_wrap.alarm_node ); 394 286 395 if (info.lock) set_recursion_count(*info.lock, recursion_count); 287 396 } … … 353 462 } 354 463 } 464 465 // thread T1 {}; 466 // thread T2 {}; 467 468 // multiple_acquisition_lock m; 469 // condition_variable( multiple_acquisition_lock ) c; 470 471 // void main( T1 & this ) { 472 // printf("T1 start\n"); 473 // lock(m); 474 // printf("%d\n", counter(c)); 475 // if(empty(c)) { 476 // printf("T1 wait\n"); 477 // wait(c,m,12); 478 // }else{ 479 // printf("%d\n", front(c)); 480 // notify_one(c); 481 // } 482 // unlock(m); 483 // printf("curr thd in main %p \n", active_thread()); 484 // printf("T1 waits for 2s\n"); 485 // lock(m); 486 // wait( c, m, 2`s ); 487 // unlock(m); 488 // printf("T1 wakes\n"); 489 // printf("T1 done\n"); 490 // } 491 492 // void main( T2 & this ) { 493 // printf("T2 start\n"); 494 // lock(m); 495 // printf("%d\n", counter(c)); 496 // if(empty(c)) { 497 // printf("T2 wait\n"); 498 // wait(c,m,12); 499 // }else{ 500 // printf("%d\n", front(c)); 501 // notify_one(c); 502 // } 503 // unlock(m); 504 // printf("T2 done\n"); 505 // } 506 507 // int main() { 508 // printf("start\n"); 509 // processor p[2]; 510 // { 511 // T1 t1; 512 // T2 t2; 513 // } 514 // printf("done\n"); 515 // } -
libcfa/src/concurrency/locks.hfa
r7b2a786 ra5a67ab8 5 5 #include "bits/algorithm.hfa" 6 6 #include "bits/locks.hfa" 7 #include "bits/sequence.hfa"8 7 #include "bits/containers.hfa" 9 8 … … 32 31 forall(dtype L | is_blocking_lock(L)) { 33 32 struct info_thread { 34 inline Seqable;35 33 struct $thread * t; 36 34 uintptr_t info; 35 info_thread(L) * next; 37 36 L * lock; 38 37 bool listed; // true if info_thread is on queue, false otherwise; … … 43 42 void ?{}( info_thread(L) & this, $thread * t, uintptr_t info ); 44 43 void ^?{}( info_thread(L) & this ); 44 45 info_thread(L) *& get_next( info_thread(L) & this ); 45 46 } 46 47 … … 49 50 /////////////////////////////////////////////////////////////////// 50 51 51 // struct lock_thread {52 // struct $thread * t;53 // lock_thread * next;54 // };55 56 // void ?{}( lock_thread & this, struct $thread * thd );57 // void ^?{}( lock_thread & this );58 59 // lock_thread *& get_next( lock_thread & );60 61 52 struct blocking_lock { 62 53 // Spin lock used for mutual exclusion … … 64 55 65 56 // List of blocked threads 66 __queue_t( $thread ) blocked_threads;57 __queue_t( struct $thread ) blocked_threads; 67 58 68 59 // Count of current blocked threads … … 144 135 __spinlock_t lock; 145 136 146 info_thread(L) * last_thread;147 148 137 // List of blocked threads 149 Sequence( info_thread(L) ) blocked_threads;138 __queue_t( info_thread(L) ) blocked_threads; 150 139 151 140 // Count of current blocked threads … … 161 150 condition_variable(L) * cond; 162 151 163 info_thread(L) * i;152 info_thread(L) ** i; 164 153 }; 165 154 166 void ?{}( alarm_node_wrap(L) & this, Time alarm, Duration period, Alarm_Callback callback );155 void ?{}( alarm_node_wrap(L) & this, $thread * thrd, Time alarm, Duration period, Alarm_Callback callback ); 167 156 void ^?{}( alarm_node_wrap(L) & this ); 168 157
Note:
See TracChangeset
for help on using the changeset viewer.