Changeset 44264c5
- Timestamp:
- May 23, 2017, 12:17:07 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, resolv-new, with_gc
- Children:
- 2c9ebab
- Parents:
- 535adab
- Location:
- src/libcfa/concurrency
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor
r535adab r44264c5 87 87 void wait( condition * this ); 88 88 void signal( condition * this ); 89 void signal_block( condition * this ); 89 90 #endif //MONITOR_H -
src/libcfa/concurrency/monitor.c
r535adab r44264c5 62 62 //Some one else has the monitor, wait in line for it 63 63 append( &this->entry_queue, thrd ); 64 LIB_DEBUG_PRINT_SAFE("%p Blocking on entry\n", thrd); 64 65 ScheduleInternal( &this->lock ); 65 66 … … 97 98 unlock( &this->lock ); 98 99 100 LIB_DEBUG_PRINT_SAFE("Next owner is %p\n", new_owner); 101 99 102 //We need to wake-up the thread 100 103 ScheduleThread( new_owner ); … … 149 152 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 150 153 assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 154 assertf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count ); 151 155 152 156 unsigned short count = this->monitor_count; … … 184 188 } 185 189 186 debug_break();187 188 190 for( int i = 0; i < count; i++) { 189 191 thread_desc * new_owner = next_thread( this->monitors[i] ); … … 191 193 } 192 194 193 debug_break();194 195 195 LIB_DEBUG_PRINT_SAFE("Will unblock: "); 196 196 for(int i = 0; i < thread_count; i++) { … … 202 202 ScheduleInternal( locks, count, threads, thread_count ); 203 203 204 204 debug_break(); 205 205 //WE WOKE UP 206 206 … … 224 224 unsigned short count = this->monitor_count; 225 225 226 //Some more checking in debug 226 227 LIB_DEBUG_DO( 227 228 thread_desc * this_thrd = this_thread(); … … 237 238 ); 238 239 240 //Lock all the monitors 239 241 lock_all( this->monitors, NULL, count ); 240 242 LIB_DEBUG_PRINT_SAFE("Signalling"); 241 243 244 //Pop the head of the waiting queue 242 245 __condition_node_t * node = pop_head( &this->blocked ); 246 247 //Add the thread to the proper AS stack 243 248 for(int i = 0; i < count; i++) { 244 249 __condition_criterion_t * crit = &node->criteria[i]; … … 250 255 LIB_DEBUG_PRINT_SAFE("\n"); 251 256 257 //Release 252 258 unlock_all( this->monitors, count ); 259 } 260 261 void signal_block( condition * this ) { 262 if( !this->blocked.head ) { 263 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 264 return; 265 } 266 267 //Check that everything is as expected 268 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 269 assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 270 271 unsigned short count = this->monitor_count; 272 unsigned int recursions[ count ]; //Save the current recursion levels to restore them later 273 spinlock * locks [ count ]; //We need to pass-in an array of locks to ScheduleInternal 274 275 lock_all( this->monitors, locks, count ); 276 277 //create creteria 278 __condition_node_t waiter; 279 waiter.waiting_thread = this_thread(); 280 waiter.count = count; 281 waiter.next = NULL; 282 283 __condition_criterion_t criteria[count]; 284 for(int i = 0; i < count; i++) { 285 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 286 criteria[i].ready = false; 287 criteria[i].owner = &waiter; 288 criteria[i].next = NULL; 289 criteria[i].target = this->monitors[i]; 290 push( &criteria[i].target->signal_stack, &criteria[i] ); 291 } 292 293 waiter.criteria = criteria; 294 295 //save contexts 296 save_recursion( this->monitors, recursions, count ); 297 298 //Find the thread to run 299 thread_desc * signallee = pop_head( &this->blocked )->waiting_thread; 300 for(int i = 0; i < count; i++) { 301 set_owner( this->monitors[i], signallee ); 302 } 303 304 LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" ); 305 debug_break(); 306 307 //Everything is ready to go to sleep 308 ScheduleInternal( locks, count, &signallee, 1 ); 309 310 debug_break(); 311 LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" ); 312 313 //We are back, restore the owners and recursions 314 lock_all( locks, count ); 315 restore_recursion( this->monitors, recursions, count ); 316 unlock_all( locks, count ); 253 317 } 254 318 … … 335 399 336 400 for( int i = 0; i < count; i++ ) { 401 337 402 LIB_DEBUG_PRINT_SAFE( "Checking %p for %p\n", &criteria[i], target ); 338 403 if( &criteria[i] == target ) { -
src/libcfa/concurrency/thread
r535adab r44264c5 82 82 83 83 void yield(); 84 void yield( unsigned times ); 84 85 85 86 #endif //THREADS_H -
src/libcfa/concurrency/thread.c
r535adab r44264c5 87 87 } 88 88 89 void yield( unsigned times ) { 90 for( unsigned i = 0; i < times; i++ ) { 91 yield(); 92 } 93 } 94 89 95 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 90 96 // set state of current coroutine to inactive
Note: See TracChangeset
for help on using the changeset viewer.