Changes in / [ec35498:4e6fb8e]
- Files:
-
- 11 edited
-
doc/working/exception/impl/exception.c (modified) (1 diff)
-
doc/working/exception/impl/exception.h (modified) (3 diffs)
-
doc/working/exception/impl/test-main.c (modified) (13 diffs)
-
doc/working/exception/translate.c (modified) (7 diffs)
-
src/libcfa/concurrency/alarm.c (modified) (1 diff)
-
src/libcfa/concurrency/coroutine (modified) (5 diffs)
-
src/libcfa/concurrency/kernel.c (modified) (4 diffs)
-
src/libcfa/concurrency/kernel_private.h (modified) (1 diff)
-
src/libcfa/concurrency/monitor (modified) (2 diffs)
-
src/libcfa/concurrency/monitor.c (modified) (7 diffs)
-
src/libcfa/libhdr/libdebug.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
doc/working/exception/impl/exception.c
rec35498 r4e6fb8e 44 44 __throw_terminate(except); 45 45 // TODO: Default handler for resumption. 46 }47 48 /* QUESTION: Could interupts interact with exception handling?49 Ex. could an context switch stop execution, and we get an exception when we50 come back? Is so resumption has to go:51 + create node (init next and handler)52 + prepare cleanup (add a cleanup hook with the ..._cleaup function)53 also the cleanup has to be the next node, not just a pop from the list.54 + push node on the list (change the existing node)55 Which if an exception can come from anywhere, might just be required to ensure56 the list is valid.57 58 void __try_resume_setup(struct __try_resume_node * node,59 bool (*handler)(exception except) {60 node->next = shared_stack.top_resume;61 node->try_to_handle = handler;62 shared_stack.top_resume = node;63 }*/64 65 // We have a single cleanup function66 void __try_resume_cleanup(struct __try_resume_node * node) {67 shared_stack.top_resume = node->next;68 46 } 69 47 -
doc/working/exception/impl/exception.h
rec35498 r4e6fb8e 6 6 7 7 8 // These might be given simpler names and made public. 8 9 void __throw_terminate(exception except) __attribute__((noreturn)); 9 10 void __rethrow_terminate(void) __attribute__((noreturn)); … … 19 20 }; 20 21 21 void __try_resume_cleanup(struct __try_resume_node * node);22 23 22 struct __cleanup_hook {}; 24 23 … … 28 27 * and threads means that... well I'm going to get it working ignoring those 29 28 * first, then get it working with concurrency. 30 * Eventually there should be some global name that just gets you the right31 * data block.32 29 */ 33 30 struct shared_stack_t { 31 //struct lock lock; 34 32 struct __try_resume_node * top_resume; 35 33 struct __try_resume_node * current_resume; -
doc/working/exception/impl/test-main.c
rec35498 r4e6fb8e 6 6 #include <stdbool.h> 7 7 8 // Helps with manual translation. It may or may not get folded into the 9 // header, that depends on how it interacts with concurancy. 8 // Translation Helpers: 9 #define CLEANUP(function) \ 10 struct __cleanup_hook __hidden_hook __attribute__((cleanup(function))) 11 12 #define SET_UP_RESUME_NODE(handler_function) \ 13 struct __try_resume_node node \ 14 __attribute__((cleanup(__try_resume_node_delete))); \ 15 __try_resume_node_new(&node, handler_function) 16 10 17 void __try_resume_node_new(struct __try_resume_node * node, 11 18 _Bool (*handler)(exception except)) { … … 13 20 shared_stack.top_resume = node; 14 21 node->try_to_handle = handler; 22 } 23 24 void __try_resume_node_delete(struct __try_resume_node * node) { 25 shared_stack.top_resume = node->next; 15 26 } 16 27 … … 111 122 } 112 123 struct __try_resume_node node 113 __attribute__((cleanup(__try_resume_ cleanup)));124 __attribute__((cleanup(__try_resume_node_delete))); 114 125 __try_resume_node_new(&node, beta_handle1); 115 126 { … … 133 144 } 134 145 struct __try_resume_node node 135 __attribute__((cleanup(__try_resume_ cleanup)));146 __attribute__((cleanup(__try_resume_node_delete))); 136 147 __try_resume_node_new(&node, alpha_handle1); 137 148 { … … 142 153 143 154 // Finally Test: 144 void farewell( bool jump) {155 void farewell() { 145 156 { 146 157 void farewell_finally1() { … … 150 161 __attribute__((cleanup(farewell_finally1))); 151 162 { 152 if (jump) { 153 printf("jump out of farewell\n"); 154 goto endoffunction; 155 } else { 156 printf("walk out of farewell\n"); 157 } 158 } 159 } 160 endoffunction: 161 printf("leaving farewell\n"); 163 printf("walk out of farewell\n"); 164 } 165 } 162 166 } 163 167 … … 256 260 } 257 261 struct __try_resume_node node 258 __attribute__((cleanup(__try_resume_ cleanup)));262 __attribute__((cleanup(__try_resume_node_delete))); 259 263 __try_resume_node_new(&node, fn_handle1); 260 264 { … … 275 279 } 276 280 struct __try_resume_node node 277 __attribute__((cleanup(__try_resume_ cleanup)));281 __attribute__((cleanup(__try_resume_node_delete))); 278 282 __try_resume_node_new(&node, fn_handle1); 279 283 { … … 345 349 } 346 350 struct __try_resume_node node 347 __attribute__((cleanup(__try_resume_ cleanup)));351 __attribute__((cleanup(__try_resume_node_delete))); 348 352 __try_resume_node_new(&node, reresume_handle1); 349 353 { … … 357 361 } 358 362 struct __try_resume_node node 359 __attribute__((cleanup(__try_resume_ cleanup)));363 __attribute__((cleanup(__try_resume_node_delete))); 360 364 __try_resume_node_new(&node, reresume_handle2); 361 365 { … … 405 409 } 406 410 struct __try_resume_node node 407 __attribute__((cleanup(__try_resume_ cleanup)));411 __attribute__((cleanup(__try_resume_node_delete))); 408 412 __try_resume_node_new(&node, foe_handle1); 409 413 { … … 452 456 } 453 457 struct __try_resume_node node 454 __attribute__((cleanup(__try_resume_ cleanup)));458 __attribute__((cleanup(__try_resume_node_delete))); 455 459 __try_resume_node_new(&node, fee_handle1); 456 460 { … … 467 471 foo(); printf("\n"); 468 472 alpha(); printf("\n"); 469 farewell(false); printf("\n"); 470 farewell(true); printf("\n"); 473 farewell(); printf("\n"); 471 474 fallback(); printf("\n"); 472 475 terminate_swapped(); printf("\n"); -
doc/working/exception/translate.c
rec35498 r4e6fb8e 17 17 18 18 void __throw_terminate(exception except) __attribute__((noreturn)); 19 void __rethrow_terminate() __attribute__((noreturn));20 19 void __throw_resume(exception except); 21 20 … … 28 27 bool (*try_to_handle)(exception except); 29 28 }; 30 31 void __try_resume_cleanup(struct __try_resume_node * node);32 29 33 30 struct __cleanup_hook {}; … … 150 147 void try_resume() { 151 148 { 152 bool handle1(exception except) {149 bool catch1(exception except) { 153 150 OtherException inner_except; 154 151 if (dynamic_cast__SomeException(except)) { … … 164 161 } 165 162 struct __try_resume_node data = 166 {.next = stack.except.top_resume, .try_to_handle = handle1};163 {.next = stack.except.top_resume, .try_to_handle = catch1}; 167 164 stack.except.top_resume = &data; 168 165 … … 207 204 208 205 209 // Resume + Finally: 210 "Cforall" 211 212 void try_resume_finally() { 213 try { 214 insideTry(); 215 } 216 catch resume (SomeException) { 217 fiddleThing(); 218 } 219 finally { 220 twiddleWidget(); 221 } 222 } 223 224 "C" 225 226 void try_resume_finally() { 227 { 228 void finally1() { 229 twiddleWidget(); 230 } 231 bool handle1(exception except) { 232 if (dynamic_cast__SomeException(except)) { 233 fiddleThing(); 234 return true; 235 } else { 236 return false; 237 } 238 } 239 struct __cleanup_hook generated_name 240 __attribute__((cleanup(finally1))); 241 242 struct __try_resume_node data = 243 {.next = stack.except.top_resume, .try_to_handle = handle1}; 244 stack.except.top_resume = &data; 245 246 struct __cleanup_hook generated_name 247 __attribute__((cleanup(__try_resume_cleanup))); 248 } 249 } 250 251 252 // Terminate + Resume + Finally: 206 // Combining the Above: 253 207 "Cforall" 254 208 … … 272 226 void try_all() { 273 227 { 274 bool handle1() {275 if (dynamic_cast__OtherException(except)) {276 twiddleWidget();277 return true;278 }279 return false;280 }281 228 void try1 () { 282 struct __try_resume_node generated_name =283 {.next = stack.except.top_resume, .try_to_handle = handle1}284 __attribute__((cleanup(__try_resume_cleanup)));285 stack.except.top_resume = &data;286 287 229 insideTry(); 288 230 } … … 302 244 return 0; 303 245 } 246 bool catch2() { 247 if (dynamic_cast__OtherException(except)) { 248 twiddleWidget(); 249 return true; 250 } 251 return false; 252 } 304 253 void finally1() { 254 // Finally, because of timing, also works for resume. 255 // However this might not actually be better in any way. 256 __try_resume_cleanup(); 305 257 306 258 twiddleWidget(); 307 259 } 260 261 struct __try_resume_node generated_name = 262 {.next = stack.except.top_resume, .try_to_handle = catch2}; 263 stack.except.top_resume = &data; 308 264 struct __cleanup_hook generated_name 309 265 __attribute__((cleanup(finally1))); -
src/libcfa/concurrency/alarm.c
rec35498 r4e6fb8e 136 136 137 137 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 138 verify( it );139 verify( (*it) == n );138 assert( it ); 139 assert( (*it) == n ); 140 140 141 141 (*it) = n->next; -
src/libcfa/concurrency/coroutine
rec35498 r4e6fb8e 71 71 // Suspend implementation inlined for performance 72 72 static inline void suspend() { 73 coroutine_desc * src = this_coroutine(); // optimization73 coroutine_desc * src = this_coroutine(); // optimization 74 74 75 75 assertf( src->last != 0, … … 91 91 coroutine_desc * dst = get_coroutine(cor); 92 92 93 if( unlikely(!dst->stack.base) ) {93 if( unlikely(!dst->stack.base) ) { 94 94 create_stack(&dst->stack, dst->stack.size); 95 95 CtxStart(cor, CtxInvokeCoroutine); 96 96 } 97 97 98 // not resuming self ?98 // not resuming self ? 99 99 if ( src != dst ) { 100 100 assertf( dst->state != Halted , … … 103 103 src->name, src, dst->name, dst ); 104 104 105 // set last resumer105 // set last resumer 106 106 dst->last = src; 107 107 } // if 108 108 109 // always done for performance testing109 // always done for performance testing 110 110 CoroutineCtxSwitch( src, dst ); 111 111 } … … 114 114 coroutine_desc * src = this_coroutine(); // optimization 115 115 116 // not resuming self ?116 // not resuming self ? 117 117 if ( src != dst ) { 118 118 assertf( dst->state != Halted , … … 121 121 src->name, src, dst->name, dst ); 122 122 123 // set last resumer123 // set last resumer 124 124 dst->last = src; 125 125 } // if 126 126 127 // always done for performance testing127 // always done for performance testing 128 128 CoroutineCtxSwitch( src, dst ); 129 129 } -
src/libcfa/concurrency/kernel.c
rec35498 r4e6fb8e 322 322 // appropriate stack. 323 323 proc_cor_storage.__cor.state = Active; 324 main( &proc_cor_storage );325 proc_cor_storage.__cor.state = Halted;324 main( &proc_cor_storage ); 325 proc_cor_storage.__cor.state = Halted; 326 326 327 327 // Main routine of the core returned, the core is now fully terminated … … 371 371 if( !thrd ) return; 372 372 373 verifyf( thrd->next == NULL, "Expected null got %p", thrd->next );373 assertf( thrd->next == NULL, "Expected null got %p", thrd->next ); 374 374 375 375 lock( &systemProcessor->proc.cltr->lock ); … … 650 650 651 651 void append( __thread_queue_t * this, thread_desc * t ) { 652 verify(this->tail != NULL);652 assert(this->tail != NULL); 653 653 *this->tail = t; 654 654 this->tail = &t->next; … … 672 672 673 673 void push( __condition_stack_t * this, __condition_criterion_t * t ) { 674 verify( !t->next );674 assert( !t->next ); 675 675 t->next = this->top; 676 676 this->top = t; -
src/libcfa/concurrency/kernel_private.h
rec35498 r4e6fb8e 22 22 23 23 #include "alarm.h" 24 25 #include "libhdr.h"26 24 27 25 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor
rec35498 r4e6fb8e 26 26 static inline void ?{}(monitor_desc * this) { 27 27 this->owner = NULL; 28 this->stack_owner = NULL;28 this->stack_owner = NULL; 29 29 this->recursion = 0; 30 30 } … … 33 33 monitor_desc ** m; 34 34 int count; 35 monitor_desc ** prev_mntrs;36 unsigned short prev_count;35 monitor_desc ** prev_mntrs; 36 unsigned short prev_count; 37 37 }; 38 38 -
src/libcfa/concurrency/monitor.c
rec35498 r4e6fb8e 56 56 else if( this->owner == thrd) { 57 57 //We already have the monitor, just not how many times we took it 58 verify( this->recursion > 0 );58 assert( this->recursion > 0 ); 59 59 this->recursion += 1; 60 60 } … … 78 78 lock( &this->lock ); 79 79 80 thread_desc * thrd = this_thread(); 81 80 82 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 81 verifyf( this_thread() == this->owner, "Expected owner to be %p, got %p (r: %i)", this_thread(), this->owner, this->recursion );83 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, this->owner, this->recursion ); 82 84 83 85 //Leaving a recursion level, decrement the counter … … 165 167 //Check that everything is as expected 166 168 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 167 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );168 verifyf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count );169 assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 170 assertf( this->monitor_count < 32u, "Excessive monitor count (%i)", this->monitor_count ); 169 171 170 172 unsigned short count = this->monitor_count; … … 227 229 228 230 //Check that everything is as expected 229 verify( this->monitors );230 verify( this->monitor_count != 0 );231 assert( this->monitors ); 232 assert( this->monitor_count != 0 ); 231 233 232 234 unsigned short count = this->monitor_count; … … 276 278 277 279 //Check that everything is as expected 278 verifyf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors );279 verifyf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count );280 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 281 assertf( this->monitor_count != 0, "Waiting with 0 monitors (%i)", this->monitor_count ); 280 282 281 283 unsigned short count = this->monitor_count; … … 325 327 326 328 uintptr_t front( condition * this ) { 327 verifyf( !is_empty(this), 328 "Attempt to access user data on an empty condition.\n" 329 "Possible cause is not checking if the condition is empty before reading stored data." 329 LIB_DEBUG_DO( 330 if( is_empty(this) ) { 331 abortf( "Attempt to access user data on an empty condition.\n" 332 "Possible cause is not checking if the condition is empty before reading stored data." ); 333 } 330 334 ); 331 335 return this->blocked.head->user_info; … … 487 491 488 492 void append( __condition_blocked_queue_t * this, __condition_node_t * c ) { 489 verify(this->tail != NULL);493 assert(this->tail != NULL); 490 494 *this->tail = c; 491 495 this->tail = &c->next; -
src/libcfa/libhdr/libdebug.h
rec35498 r4e6fb8e 18 18 19 19 #ifdef __CFA_DEBUG__ 20 #define LIB_DEBUG_DO(x) x21 #define LIB_NO_DEBUG_DO(x)20 #define LIB_DEBUG_DO(x) x 21 #define LIB_NO_DEBUG_DO(x) 22 22 #else 23 #define LIB_DEBUG_DO(x)24 #define LIB_NO_DEBUG_DO(x) x23 #define LIB_DEBUG_DO(x) 24 #define LIB_NO_DEBUG_DO(x) x 25 25 #endif 26 27 #if !defined(NDEBUG) && (defined(__CFA_DEBUG__) || defined(__CFA_VERIFY__))28 #define verify(x) assert(x)29 #define verifyf(x, ...) assertf(x, __VA_ARGS__)30 #else31 #define verify(x)32 #define verifyf(x, ...)33 #endif34 35 26 36 27 #ifdef __cforall
Note:
See TracChangeset
for help on using the changeset viewer.