Changeset be3d020
- Timestamp:
- May 29, 2017, 11:26:03 AM (7 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:
- ccd349d
- Parents:
- 8c700c1
- Location:
- src/libcfa/concurrency
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/monitor
r8c700c1 rbe3d020 59 59 unsigned short count; //Number of criterions in the criteria 60 60 __condition_node_t * next; //Intrusive linked list Next field 61 uintptr_t user_info; //Custom user info accessible before signalling 61 62 }; 62 63 … … 85 86 } 86 87 87 void wait( condition * this ); 88 void signal( condition * this ); 89 void signal_block( condition * this ); 88 void wait( condition * this, uintptr_t user_info = 0 ); 89 bool signal( condition * this ); 90 bool signal_block( condition * this ); 91 static inline bool is_empty( condition * this ) { return !this->blocked.head; } 92 uintptr_t front( condition * this ); 93 90 94 #endif //MONITOR_H -
src/libcfa/concurrency/monitor.c
r8c700c1 rbe3d020 137 137 } 138 138 139 void debug_break() __attribute__(( noinline )) 140 { 141 139 void ?{}(__condition_node_t * this, thread_desc * waiting_thread, unsigned short count, uintptr_t user_info ) { 140 this->waiting_thread = waiting_thread; 141 this->count = count; 142 this->next = NULL; 143 this->user_info = user_info; 144 } 145 146 void ?{}(__condition_criterion_t * this ) { 147 this->ready = false; 148 this->target = NULL; 149 this->owner = NULL; 150 this->next = NULL; 151 } 152 153 void ?{}(__condition_criterion_t * this, monitor_desc * target, __condition_node_t * owner ) { 154 this->ready = false; 155 this->target = target; 156 this->owner = owner; 157 this->next = NULL; 142 158 } 143 159 144 160 //----------------------------------------------------------------------------- 145 161 // Internal scheduling 146 void wait( condition * this ) {162 void wait( condition * this, uintptr_t user_info = 0 ) { 147 163 LIB_DEBUG_PRINT_SAFE("Waiting\n"); 148 164 … … 160 176 LIB_DEBUG_PRINT_SAFE("count %i\n", count); 161 177 162 __condition_node_t waiter; 163 waiter.waiting_thread = this_thread(); 164 waiter.count = count; 165 waiter.next = NULL; 178 __condition_node_t waiter = { this_thread(), count, user_info }; 166 179 167 180 __condition_criterion_t criteria[count]; 168 181 for(int i = 0; i < count; i++) { 169 criteria[i].ready = false; 170 criteria[i].target = this->monitors[i]; 171 criteria[i].owner = &waiter; 172 criteria[i].next = NULL; 182 (&criteria[i]){ this->monitors[i], &waiter }; 173 183 LIB_DEBUG_PRINT_SAFE( "Criterion %p\n", &criteria[i] ); 174 184 } … … 202 212 ScheduleInternal( locks, count, threads, thread_count ); 203 213 204 debug_break();205 214 //WE WOKE UP 206 215 … … 212 221 } 213 222 214 voidsignal( condition * this ) {215 if( !this->blocked.head) {223 bool signal( condition * this ) { 224 if( is_empty( this ) ) { 216 225 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 217 return ;226 return false; 218 227 } 219 228 … … 257 266 //Release 258 267 unlock_all( this->monitors, count ); 259 } 260 261 void signal_block( condition * this ) { 268 269 return true; 270 } 271 272 bool signal_block( condition * this ) { 262 273 if( !this->blocked.head ) { 263 274 LIB_DEBUG_PRINT_SAFE("Nothing to signal\n"); 264 return ;275 return false; 265 276 } 266 277 … … 276 287 277 288 //create creteria 278 __condition_node_t waiter; 279 waiter.waiting_thread = this_thread(); 280 waiter.count = count; 281 waiter.next = NULL; 289 __condition_node_t waiter = { this_thread(), count, 0 }; 282 290 283 291 __condition_criterion_t criteria[count]; 284 292 for(int i = 0; i < count; i++) { 293 (&criteria[i]){ this->monitors[i], &waiter }; 285 294 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 295 push( &criteria[i].target->signal_stack, &criteria[i] ); 291 296 } … … 303 308 304 309 LIB_DEBUG_PRINT_SAFE( "Waiting on signal block\n" ); 305 debug_break();306 310 307 311 //Everything is ready to go to sleep 308 312 ScheduleInternal( locks, count, &signallee, 1 ); 309 313 310 debug_break();311 314 LIB_DEBUG_PRINT_SAFE( "Back from signal block\n" ); 312 315 … … 315 318 restore_recursion( this->monitors, recursions, count ); 316 319 unlock_all( locks, count ); 320 321 return true; 322 } 323 324 uintptr_t front( condition * this ) { 325 LIB_DEBUG_DO( 326 if( is_empty(this) ) { 327 abortf( "Attempt to access user data on an empty condition.\n" 328 "Possible cause is not checking if the condition is empty before reading stored data." ); 329 } 330 ); 331 return this->blocked.head->user_info; 317 332 } 318 333
Note: See TracChangeset
for help on using the changeset viewer.