Changeset 447bf833 for src/libcfa/concurrency/monitor.c
- Timestamp:
- May 24, 2017, 4:16:20 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:
- a8e64c4, cf0b892
- Parents:
- 7f623d6f (diff), 8bcaf21 (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor.c
r7f623d6f r447bf833 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 ) {
Note: See TracChangeset
for help on using the changeset viewer.