Changes in / [e50e9ff:b3d413b]
- Location:
- src
- Files:
-
- 1 deleted
- 8 edited
-
Concurrency/Keywords.cc (modified) (7 diffs)
-
libcfa/concurrency/invoke.h (modified) (2 diffs)
-
libcfa/concurrency/kernel.c (modified) (2 diffs)
-
libcfa/concurrency/monitor (modified) (3 diffs)
-
libcfa/concurrency/monitor.c (modified) (19 diffs)
-
tests/preempt_longrun/stack.c (modified) (1 diff)
-
tests/sched-ext.c (deleted)
-
tests/sched-int-disjoint.c (modified) (2 diffs)
-
tests/sched-int-wait.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Concurrency/Keywords.cc
re50e9ff rb3d413b 200 200 std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* ); 201 201 void validate( DeclarationWithType * ); 202 void addStatments( FunctionDecl* func,CompoundStmt *, const std::list<DeclarationWithType * > &);202 void addStatments( CompoundStmt *, const std::list<DeclarationWithType * > &); 203 203 204 204 static void implement( std::list< Declaration * > & translationUnit ) { … … 210 210 StructDecl* monitor_decl = nullptr; 211 211 StructDecl* guard_decl = nullptr; 212 213 static std::unique_ptr< Type > generic_func;214 212 }; 215 216 std::unique_ptr< Type > MutexKeyword::generic_func = std::unique_ptr< Type >(217 new FunctionType(218 noQualifiers,219 true220 )221 );222 213 223 214 //----------------------------------------------------------------------------- … … 403 394 // Mutex keyword implementation 404 395 //============================================================================================= 405 406 396 void MutexKeyword::visit(FunctionDecl* decl) { 407 397 Visitor::visit(decl); … … 420 410 if( !guard_decl ) throw SemanticError( "mutex keyword requires monitors to be in scope, add #include <monitor>", decl ); 421 411 422 addStatments( decl,body, mutexArgs );412 addStatments( body, mutexArgs ); 423 413 } 424 414 … … 466 456 } 467 457 468 void MutexKeyword::addStatments( FunctionDecl* func,CompoundStmt * body, const std::list<DeclarationWithType * > & args ) {458 void MutexKeyword::addStatments( CompoundStmt * body, const std::list<DeclarationWithType * > & args ) { 469 459 ObjectDecl * monitors = new ObjectDecl( 470 460 "__monitors", … … 497 487 ); 498 488 499 assert(generic_func);500 501 489 //in reverse order : 502 // monitor_guard_t __guard = { __monitors, # , func};490 // monitor_guard_t __guard = { __monitors, # }; 503 491 body->push_front( 504 492 new DeclStmt( noLabels, new ObjectDecl( … … 514 502 { 515 503 new SingleInit( new VariableExpr( monitors ) ), 516 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ), 517 new SingleInit( new CastExpr( new VariableExpr( func ), generic_func->clone() ) ) 504 new SingleInit( new ConstantExpr( Constant::from_ulong( args.size() ) ) ) 518 505 }, 519 506 noDesignators, -
src/libcfa/concurrency/invoke.h
re50e9ff rb3d413b 87 87 struct __condition_stack_t signal_stack; // stack of conditions to run next once we exit the monitor 88 88 unsigned int recursion; // monitor routines can be called recursively, we need to keep track of that 89 90 struct __acceptable_t * acceptables; // list of acceptable functions, null if any 91 unsigned short acceptable_count; // number of acceptable functions 92 short accepted_index; // the index of the accepted function, -1 if none 93 void (*pre_accept)(void); // function to run before an accept 94 }; 89 }; 95 90 96 91 struct thread_desc { … … 100 95 struct monitor_desc ** current_monitors; // currently held monitors 101 96 unsigned short current_monitor_count; // number of currently held monitors 102 };97 }; 103 98 104 99 #endif //_INVOKE_H_ -
src/libcfa/concurrency/kernel.c
re50e9ff rb3d413b 366 366 367 367 void BlockInternal( thread_desc * thrd ) { 368 assert(thrd);369 368 disable_interrupts(); 370 369 assert( thrd->cor.state != Halted ); … … 380 379 381 380 void BlockInternal( spinlock * lock, thread_desc * thrd ) { 382 assert(thrd);383 381 disable_interrupts(); 384 382 this_processor->finish.action_code = Release_Schedule; -
src/libcfa/concurrency/monitor
re50e9ff rb3d413b 23 23 24 24 static inline void ?{}(monitor_desc * this) { 25 (&this->lock){};26 25 this->owner = NULL; 27 (&this->entry_queue){};28 (&this->signal_stack){};29 26 this->recursion = 0; 30 this->acceptables = NULL;31 this->acceptable_count = 0;32 this->accepted_index = -1;33 this->pre_accept = 0;34 27 } 35 28 … … 45 38 } 46 39 47 void ?{}( monitor_guard_t * this, monitor_desc ** m, int count , void (*func)());40 void ?{}( monitor_guard_t * this, monitor_desc ** m, int count ); 48 41 void ^?{}( monitor_guard_t * this ); 49 42 … … 96 89 uintptr_t front( condition * this ); 97 90 98 //-----------------------------------------------------------------------------99 // External scheduling100 101 typedef void (*void_fptr_t)(void);102 103 91 struct __acceptable_t { 104 void _fptr_t func;92 void (*func)(void); 105 93 unsigned short count; 106 monitor_desc ** monitors; 107 bool run_preaccept; 94 monitor_desc * monitors[1]; 108 95 }; 109 96 110 int __accept_internal( unsigned short count, __acceptable_t * acceptables);97 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ); 111 98 112 99 // Local Variables: // -
src/libcfa/concurrency/monitor.c
re50e9ff rb3d413b 25 25 static inline void set_owner( monitor_desc * this, thread_desc * owner ); 26 26 static inline thread_desc * next_thread( monitor_desc * this ); 27 static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() );28 27 29 28 static inline void lock_all( spinlock ** locks, unsigned short count ); … … 35 34 static inline void restore_recursion( monitor_desc ** ctx, unsigned int * /*in */ recursions, unsigned short count ); 36 35 37 static inline void init ( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );38 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria );39 40 36 static inline thread_desc * check_condition( __condition_criterion_t * ); 41 37 static inline void brand_condition( condition * ); 42 38 static inline unsigned short insert_unique( thread_desc ** thrds, unsigned short end, thread_desc * val ); 43 39 44 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count );45 46 //-----------------------------------------------------------------------------47 // Useful defines48 #define wait_ctx(thrd, user_info) /* Create the necessary information to use the signaller stack */ \49 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \50 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \51 init( count, monitors, &waiter, criteria ); /* Link everything together */ \52 53 #define wait_ctx_primed(thrd, user_info) /* Create the necessary information to use the signaller stack */ \54 __condition_node_t waiter = { thrd, count, user_info }; /* Create the node specific to this wait operation */ \55 __condition_criterion_t criteria[count]; /* Create the creteria this wait operation needs to wake up */ \56 init_push( count, monitors, &waiter, criteria ); /* Link everything together and push it to the AS-Stack */ \57 58 #define monitor_ctx( mons, cnt ) /* Define that create the necessary struct for internal/external scheduling operations */ \59 monitor_desc ** monitors = mons; /* Save the targeted monitors */ \60 unsigned short count = cnt; /* Save the count to a local variable */ \61 unsigned int recursions[ count ]; /* Save the current recursion levels to restore them later */ \62 spinlock * locks [ count ]; /* We need to pass-in an array of locks to BlockInternal */ \63 64 40 //----------------------------------------------------------------------------- 65 41 // Enter/Leave routines … … 67 43 68 44 extern "C" { 69 // Enter single monitor 70 static void __enter_monitor_desc( monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) { 71 // Lock the monitor spinlock, lock_yield to reduce contention 45 void __enter_monitor_desc( monitor_desc * this ) { 72 46 lock_yield( &this->lock DEBUG_CTX2 ); 73 47 thread_desc * thrd = this_thread; 74 48 75 this->accepted_index = -1; 49 // LIB_DEBUG_PRINT_SAFE("%p Entering %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 50 76 51 if( !this->owner ) { 77 // No one has the monitor, just take it52 //No one has the monitor, just take it 78 53 set_owner( this, thrd ); 79 54 } 80 55 else if( this->owner == thrd) { 81 // We already have the monitor, just not how many times we took it56 //We already have the monitor, just not how many times we took it 82 57 verify( this->recursion > 0 ); 83 58 this->recursion += 1; 84 59 } 85 else if( (this->accepted_index = is_accepted( thrd, this, group, group_cnt, func)) >= 0 ) {86 // Some one was waiting for us, enter87 set_owner( this, thrd );88 }89 60 else { 90 // Some one else has the monitor, wait in line for it61 //Some one else has the monitor, wait in line for it 91 62 append( &this->entry_queue, thrd ); 63 // LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 92 64 BlockInternal( &this->lock ); 93 65 94 // BlockInternal will unlock spinlock, no need to unlock ourselves66 //BlockInternal will unlock spinlock, no need to unlock ourselves 95 67 return; 96 68 } 97 69 98 // Release the lock and leave99 70 unlock( &this->lock ); 100 71 return; 101 72 } 102 73 103 // Leave single monitor 74 // leave pseudo code : 75 // TODO 104 76 void __leave_monitor_desc( monitor_desc * this ) { 105 // Lock the monitor spinlock, lock_yield to reduce contention106 77 lock_yield( &this->lock DEBUG_CTX2 ); 107 78 79 // LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i). ", this_thread, this, this->owner, this->recursion); 108 80 verifyf( this_thread == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread, this->owner, this->recursion ); 109 81 110 // Leaving a recursion level, decrement the counter82 //Leaving a recursion level, decrement the counter 111 83 this->recursion -= 1; 112 84 113 // If we haven't left the last level of recursion114 // it means we don't need to do anything85 //If we haven't left the last level of recursion 86 //it means we don't need to do anything 115 87 if( this->recursion != 0) { 116 88 unlock( &this->lock ); … … 118 90 } 119 91 120 // Get the next thread, will be null on low contention monitor121 92 thread_desc * new_owner = next_thread( this ); 122 93 123 // We can now let other threads in safely94 //We can now let other threads in safely 124 95 unlock( &this->lock ); 96 97 // LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner); 125 98 126 99 //We need to wake-up the thread … … 128 101 } 129 102 130 // Leave the thread monitor131 // last routine called by a thread.132 // Should never return133 103 void __leave_thread_monitor( thread_desc * thrd ) { 134 104 monitor_desc * this = &thrd->mon; 135 136 // Lock the monitor now137 105 lock_yield( &this->lock DEBUG_CTX2 ); 138 106 … … 143 111 verifyf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 144 112 145 // Leaving a recursion level, decrement the counter113 //Leaving a recursion level, decrement the counter 146 114 this->recursion -= 1; 147 115 148 // If we haven't left the last level of recursion 149 // it must mean there is an error 150 if( this->recursion != 0) { abortf("Thread internal monitor has unbalanced recursion"); } 151 152 // Fetch the next thread, can be null 116 //If we haven't left the last level of recursion 117 //it means we don't need to do anything 118 if( this->recursion != 0) { 119 unlock( &this->lock ); 120 return; 121 } 122 153 123 thread_desc * new_owner = next_thread( this ); 154 124 155 // Leave the thread, this will unlock the spinlock156 // Use leave thread instead of BlockInternal which is157 // specialized for this case and supports null new_owner158 125 LeaveThread( &this->lock, new_owner ); 159 160 // Control flow should never reach here! 161 } 162 } 163 164 // Enter multiple monitor 165 // relies on the monitor array being sorted 166 static inline void enter(monitor_desc ** monitors, int count, void (*func)() ) { 126 } 127 } 128 129 static inline void enter(monitor_desc ** monitors, int count) { 167 130 for(int i = 0; i < count; i++) { 168 __enter_monitor_desc( monitors[i], monitors, count, func ); 169 } 170 171 int acc_idx = monitors[0]->accepted_index; 172 if( acc_idx >= 0 && monitors[0]->acceptables[ acc_idx ].run_preaccept ) { 173 assert( monitors[0]->pre_accept ); 174 monitors[0]->pre_accept(); 175 } 176 } 177 178 // Leave multiple monitor 179 // relies on the monitor array being sorted 131 __enter_monitor_desc( monitors[i] ); 132 } 133 } 134 180 135 static inline void leave(monitor_desc ** monitors, int count) { 181 136 for(int i = count - 1; i >= 0; i--) { … … 184 139 } 185 140 186 // Ctor for monitor guard 187 // Sorts monitors before entering 188 void ?{}( monitor_guard_t * this, monitor_desc ** m, int count, void (*func)() ) { 189 // Store current array 141 void ?{}( monitor_guard_t * this, monitor_desc ** m, int count ) { 190 142 this->m = m; 191 143 this->count = count; 192 193 // Sort monitors based on address -> TODO use a sort specialized for small numbers194 144 qsort(this->m, count); 195 196 // Enter the monitors in order 197 enter( this->m, this->count, func ); 198 199 // Save previous thread context 145 enter( this->m, this->count ); 146 200 147 this->prev_mntrs = this_thread->current_monitors; 201 148 this->prev_count = this_thread->current_monitor_count; 202 149 203 // Update thread context (needed for conditions)204 150 this_thread->current_monitors = m; 205 151 this_thread->current_monitor_count = count; 206 152 } 207 153 208 // Dtor for monitor guard209 154 void ^?{}( monitor_guard_t * this ) { 210 // Leave the monitors in order211 155 leave( this->m, this->count ); 212 156 213 // Restore thread context214 157 this_thread->current_monitors = this->prev_mntrs; 215 158 this_thread->current_monitor_count = this->prev_count; 216 159 } 217 218 //-----------------------------------------------------------------------------219 // Internal scheduling types220 160 221 161 void ?{}(__condition_node_t * this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) { … … 243 183 // Internal scheduling 244 184 void wait( condition * this, uintptr_t user_info = 0 ) { 185 // LIB_DEBUG_PRINT_SAFE("Waiting\n"); 186 245 187 brand_condition( this ); 246 188 247 // Check that everything is as expected189 //Check that everything is as expected 248 190 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 249 191 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 250 192 verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count ); 251 193 252 // Create storage for monitor context 253 monitor_ctx( this->monitors, this->monitor_count ); 254 255 // Create the node specific to this wait operation 256 wait_ctx( this_thread, user_info ); 257 258 // Append the current wait operation to the ones already queued on the condition 259 // We don't need locks for that since conditions must always be waited on inside monitor mutual exclusion 194 unsigned short count = this->monitor_count; 195 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 196 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 197 198 // LIB_DEBUG_PRINT_SAFE("count %i\n", count); 199 200 __condition_node_t waiter = { (thread_desc*)this_thread, count, user_info }; 201 202 __condition_criterion_t criteria[count]; 203 for(int i = 0; i < count; i++) { 204 (&criteria[i]){ this->monitors[i], &waiter }; 205 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 206 } 207 208 waiter.criteria = criteria; 260 209 append( &this->blocked, &waiter ); 261 210 262 // Lock all monitors (aggregates the lock them as well) 263 lock_all( monitors, locks, count ); 264 265 // DON'T unlock, ask the kernel to do it 266 267 // Save monitor state 268 save_recursion( monitors, recursions, count ); 269 270 // Find the next thread(s) to run 211 lock_all( this->monitors, locks, count ); 212 save_recursion( this->monitors, recursions, count ); 213 //DON'T unlock, ask the kernel to do it 214 215 //Find the next thread(s) to run 271 216 unsigned short thread_count = 0; 272 217 thread_desc * threads[ count ]; … … 275 220 } 276 221 277 // Remove any duplicate threads278 222 for( int i = 0; i < count; i++) { 279 thread_desc * new_owner = next_thread( monitors[i] );223 thread_desc * new_owner = next_thread( this->monitors[i] ); 280 224 thread_count = insert_unique( threads, thread_count, new_owner ); 281 225 } 226 227 // LIB_DEBUG_PRINT_SAFE("Will unblock: "); 228 for(int i = 0; i < thread_count; i++) { 229 // LIB_DEBUG_PRINT_SAFE("%p ", threads[i]); 230 } 231 // LIB_DEBUG_PRINT_SAFE("\n"); 282 232 283 233 // Everything is ready to go to sleep … … 285 235 286 236 287 // WE WOKE UP288 289 290 // We are back, restore the owners and recursions237 //WE WOKE UP 238 239 240 //We are back, restore the owners and recursions 291 241 lock_all( locks, count ); 292 restore_recursion( monitors, recursions, count );242 restore_recursion( this->monitors, recursions, count ); 293 243 unlock_all( locks, count ); 294 244 } 295 245 296 246 bool signal( condition * this ) { 297 if( is_empty( this ) ) { return false; } 247 if( is_empty( this ) ) { 248 // LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 249 return false; 250 } 298 251 299 252 //Check that everything is as expected 300 253 verify( this->monitors ); 301 254 verify( this->monitor_count != 0 ); 255 256 unsigned short count = this->monitor_count; 302 257 303 258 //Some more checking in debug … … 306 261 if ( this->monitor_count != this_thrd->current_monitor_count ) { 307 262 abortf( "Signal on condition %p made with different number of monitor(s), expected %i got %i", this, this->monitor_count, this_thrd->current_monitor_count ); 308 } 263 } // if 309 264 310 265 for(int i = 0; i < this->monitor_count; i++) { 311 266 if ( this->monitors[i] != this_thrd->current_monitors[i] ) { 312 267 abortf( "Signal on condition %p made with different monitor, expected %p got %i", this, this->monitors[i], this_thrd->current_monitors[i] ); 313 } 268 } // if 314 269 } 315 270 ); 316 271 317 unsigned short count = this->monitor_count; 318 319 // Lock all monitors 272 //Lock all the monitors 320 273 lock_all( this->monitors, NULL, count ); 274 // LIB_DEBUG_PRINT_SAFE("Signalling"); 321 275 322 276 //Pop the head of the waiting queue … … 326 280 for(int i = 0; i < count; i++) { 327 281 __condition_criterion_t * crit = &node->criteria[i]; 282 // LIB_DEBUG_PRINT_SAFE(" %p", crit->target); 328 283 assert( !crit->ready ); 329 284 push( &crit->target->signal_stack, crit ); 330 285 } 331 286 287 // LIB_DEBUG_PRINT_SAFE("\n"); 288 332 289 //Release 333 290 unlock_all( this->monitors, count ); … … 337 294 338 295 bool signal_block( condition * this ) { 339 if( !this->blocked.head ) { return false; } 296 if( !this->blocked.head ) { 297 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 298 return false; 299 } 340 300 341 301 //Check that everything is as expected … … 343 303 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 344 304 345 // Create storage for monitor context 346 monitor_ctx( this->monitors, this->monitor_count ); 347 348 // Lock all monitors (aggregates the locks them as well) 349 lock_all( monitors, locks, count ); 350 351 // Create the node specific to this wait operation 352 wait_ctx_primed( this_thread, 0 ) 305 unsigned short count = this->monitor_count; 306 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 307 spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 308 309 lock_all( this->monitors, locks, count ); 310 311 //create creteria 312 __condition_node_t waiter = { (thread_desc*)this_thread, count, 0 }; 313 314 __condition_criterion_t criteria[count]; 315 for(int i = 0; i < count; i++) { 316 (&criteria[i]){ this->monitors[i], &waiter }; 317 // LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 318 push( &criteria[i].target->signal_stack, &criteria[i] ); 319 } 320 321 waiter.criteria = criteria; 353 322 354 323 //save contexts 355 save_recursion( monitors, recursions, count );324 save_recursion( this->monitors, recursions, count ); 356 325 357 326 //Find the thread to run 358 327 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread; 359 328 for(int i = 0; i < count; i++) { 360 set_owner( monitors[i], signallee ); 361 } 329 set_owner( this->monitors[i], signallee ); 330 } 331 332 LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" ); 362 333 363 334 //Everything is ready to go to sleep … … 365 336 366 337 367 // WE WOKE UP 368 338 339 340 LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" ); 369 341 370 342 //We are back, restore the owners and recursions 371 343 lock_all( locks, count ); 372 restore_recursion( monitors, recursions, count );344 restore_recursion( this->monitors, recursions, count ); 373 345 unlock_all( locks, count ); 374 346 … … 376 348 } 377 349 378 // Access the user_info of the thread waiting at the front of the queue379 350 uintptr_t front( condition * this ) { 380 351 verifyf( !is_empty(this), … … 387 358 //----------------------------------------------------------------------------- 388 359 // Internal scheduling 389 int __accept_internal( unsigned short acc_count, __acceptable_t * acceptables ) { 390 thread_desc * thrd = this_thread; 391 392 // Create storage for monitor context 393 monitor_ctx( acceptables->monitors, acceptables->count ); 394 395 // Lock all monitors (aggregates the lock them as well) 396 lock_all( monitors, locks, count ); 397 398 // Create the node specific to this wait operation 399 wait_ctx_primed( thrd, 0 ); 400 401 // Check if the entry queue 402 thread_desc * next = search_entry_queue( acceptables, acc_count, monitors, count ); 403 404 if( !next ) { 405 // Update acceptables on the current monitors 406 for(int i = 0; i < count; i++) { 407 monitors[i]->acceptables = acceptables; 408 monitors[i]->acceptable_count = acc_count; 409 } 410 } 411 412 save_recursion( monitors, recursions, count ); 413 414 // Everything is ready to go to sleep 415 BlockInternal( locks, count, &next, next ? 1 : 0 ); 416 417 418 //WE WOKE UP 419 420 421 //We are back, restore the owners and recursions 422 lock_all( locks, count ); 423 restore_recursion( monitors, recursions, count ); 424 int acc_idx = monitors[0]->accepted_index; 425 unlock_all( locks, count ); 426 427 return acc_idx; 360 void __accept_internal( unsigned short count, __acceptable_t * acceptables, void (*func)(void) ) { 361 // thread_desc * this = this_thread; 362 363 // unsigned short count = this->current_monitor_count; 364 // unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 365 // spinlock * locks [ count ]; //We need to pass-in an array of locks to BlockInternal 366 367 // lock_all( this->current_monitors, locks, count ); 368 369 370 371 372 373 // // // Everything is ready to go to sleep 374 // // BlockInternal( locks, count, threads, thread_count ); 375 376 377 // //WE WOKE UP 378 379 380 // //We are back, restore the owners and recursions 381 // lock_all( locks, count ); 382 // restore_recursion( this->monitors, recursions, count ); 383 // unlock_all( locks, count ); 428 384 } 429 385 … … 459 415 } 460 416 461 static inline int is_accepted( thread_desc * owner, monitor_desc * this, monitor_desc ** group, int group_cnt, void (*func)() ) {462 __acceptable_t* accs = this->acceptables; // Optim463 int acc_cnt = this->acceptable_count;464 465 // Check if there are any acceptable functions466 if( !accs ) return -1;467 468 // If this isn't the first monitor to test this, there is no reason to repeat the test.469 if( this != group[0] ) return group[0]->accepted_index;470 471 // For all acceptable functions check if this is the current function.472 OUT_LOOP:473 for( int i = 0; i < acc_cnt; i++ ) {474 __acceptable_t * acc = &accs[i];475 476 // if function matches, check the monitors477 if( acc->func == func ) {478 479 // If the group count is different then it can't be a match480 if( acc->count != group_cnt ) return -1;481 482 // Check that all the monitors match483 for( int j = 0; j < group_cnt; j++ ) {484 // If not a match, check next function485 if( acc->monitors[j] != group[j] ) continue OUT_LOOP;486 }487 488 // It's a complete match, accept the call489 return i;490 }491 }492 493 // No function matched494 return -1;495 }496 497 static inline void init( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {498 for(int i = 0; i < count; i++) {499 (&criteria[i]){ monitors[i], waiter };500 }501 502 waiter->criteria = criteria;503 }504 505 static inline void init_push( int count, monitor_desc ** monitors, __condition_node_t * waiter, __condition_criterion_t * criteria ) {506 for(int i = 0; i < count; i++) {507 (&criteria[i]){ monitors[i], waiter };508 push( &criteria[i].target->signal_stack, &criteria[i] );509 }510 511 waiter->criteria = criteria;512 }513 514 417 static inline void lock_all( spinlock ** locks, unsigned short count ) { 515 418 for( int i = 0; i < count; i++ ) { … … 602 505 } 603 506 604 static inline thread_desc * search_entry_queue( __acceptable_t * acceptables, int acc_count, monitor_desc ** monitors, int count ) {605 return NULL;606 }607 608 507 void ?{}( __condition_blocked_queue_t * this ) { 609 508 this->head = NULL; -
src/tests/preempt_longrun/stack.c
re50e9ff rb3d413b 15 15 16 16 void main(worker_t * this) { 17 volatile long longp = 5_021_609ul;18 volatile long longa = 326_417ul;19 volatile long longn = 1l;20 for (volatile long longi = 0; i < p; i++) {17 volatile long p = 5_021_609ul; 18 volatile long a = 326_417ul; 19 volatile long n = 1l; 20 for (volatile long i = 0; i < p; i++) { 21 21 n *= a; 22 22 n %= p; -
src/tests/sched-int-disjoint.c
re50e9ff rb3d413b 3 3 #include <monitor> 4 4 #include <thread> 5 6 #include <time.h>7 5 8 6 static const unsigned long N = 10_000ul; … … 109 107 // Main loop 110 108 int main(int argc, char* argv[]) { 111 rand48seed( time( NULL ) );112 109 all_done = false; 113 110 processor p; -
src/tests/sched-int-wait.c
re50e9ff rb3d413b 5 5 #include <thread> 6 6 7 #include <time.h> 8 9 static const unsigned long N = 2_500ul; 7 static const unsigned long N = 10_000ul; 10 8 11 9 #ifndef PREEMPTION_RATE … … 121 119 // Main 122 120 int main(int argc, char* argv[]) { 123 rand48seed( time( NULL ) );124 121 waiter_left = 4; 125 122 processor p[2];
Note:
See TracChangeset
for help on using the changeset viewer.