Changes in / [4e6fb8e:ec35498]
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/working/exception/impl/exception.c
r4e6fb8e rec35498 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 we 50 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 ensure 56 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 function 66 void __try_resume_cleanup(struct __try_resume_node * node) { 67 shared_stack.top_resume = node->next; 46 68 } 47 69 -
doc/working/exception/impl/exception.h
r4e6fb8e rec35498 6 6 7 7 8 // These might be given simpler names and made public.9 8 void __throw_terminate(exception except) __attribute__((noreturn)); 10 9 void __rethrow_terminate(void) __attribute__((noreturn)); … … 20 19 }; 21 20 21 void __try_resume_cleanup(struct __try_resume_node * node); 22 22 23 struct __cleanup_hook {}; 23 24 … … 27 28 * and threads means that... well I'm going to get it working ignoring those 28 29 * first, then get it working with concurrency. 30 * Eventually there should be some global name that just gets you the right 31 * data block. 29 32 */ 30 33 struct shared_stack_t { 31 //struct lock lock;32 34 struct __try_resume_node * top_resume; 33 35 struct __try_resume_node * current_resume; -
doc/working/exception/impl/test-main.c
r4e6fb8e rec35498 6 6 #include <stdbool.h> 7 7 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 8 // Helps with manual translation. It may or may not get folded into the 9 // header, that depends on how it interacts with concurancy. 17 10 void __try_resume_node_new(struct __try_resume_node * node, 18 11 _Bool (*handler)(exception except)) { … … 20 13 shared_stack.top_resume = node; 21 14 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;26 15 } 27 16 … … 122 111 } 123 112 struct __try_resume_node node 124 __attribute__((cleanup(__try_resume_ node_delete)));113 __attribute__((cleanup(__try_resume_cleanup))); 125 114 __try_resume_node_new(&node, beta_handle1); 126 115 { … … 144 133 } 145 134 struct __try_resume_node node 146 __attribute__((cleanup(__try_resume_ node_delete)));135 __attribute__((cleanup(__try_resume_cleanup))); 147 136 __try_resume_node_new(&node, alpha_handle1); 148 137 { … … 153 142 154 143 // Finally Test: 155 void farewell( ) {144 void farewell(bool jump) { 156 145 { 157 146 void farewell_finally1() { … … 161 150 __attribute__((cleanup(farewell_finally1))); 162 151 { 163 printf("walk out of farewell\n"); 164 } 165 } 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"); 166 162 } 167 163 … … 260 256 } 261 257 struct __try_resume_node node 262 __attribute__((cleanup(__try_resume_ node_delete)));258 __attribute__((cleanup(__try_resume_cleanup))); 263 259 __try_resume_node_new(&node, fn_handle1); 264 260 { … … 279 275 } 280 276 struct __try_resume_node node 281 __attribute__((cleanup(__try_resume_ node_delete)));277 __attribute__((cleanup(__try_resume_cleanup))); 282 278 __try_resume_node_new(&node, fn_handle1); 283 279 { … … 349 345 } 350 346 struct __try_resume_node node 351 __attribute__((cleanup(__try_resume_ node_delete)));347 __attribute__((cleanup(__try_resume_cleanup))); 352 348 __try_resume_node_new(&node, reresume_handle1); 353 349 { … … 361 357 } 362 358 struct __try_resume_node node 363 __attribute__((cleanup(__try_resume_ node_delete)));359 __attribute__((cleanup(__try_resume_cleanup))); 364 360 __try_resume_node_new(&node, reresume_handle2); 365 361 { … … 409 405 } 410 406 struct __try_resume_node node 411 __attribute__((cleanup(__try_resume_ node_delete)));407 __attribute__((cleanup(__try_resume_cleanup))); 412 408 __try_resume_node_new(&node, foe_handle1); 413 409 { … … 456 452 } 457 453 struct __try_resume_node node 458 __attribute__((cleanup(__try_resume_ node_delete)));454 __attribute__((cleanup(__try_resume_cleanup))); 459 455 __try_resume_node_new(&node, fee_handle1); 460 456 { … … 471 467 foo(); printf("\n"); 472 468 alpha(); printf("\n"); 473 farewell(); printf("\n"); 469 farewell(false); printf("\n"); 470 farewell(true); printf("\n"); 474 471 fallback(); printf("\n"); 475 472 terminate_swapped(); printf("\n"); -
doc/working/exception/translate.c
r4e6fb8e rec35498 17 17 18 18 void __throw_terminate(exception except) __attribute__((noreturn)); 19 void __rethrow_terminate() __attribute__((noreturn)); 19 20 void __throw_resume(exception except); 20 21 … … 27 28 bool (*try_to_handle)(exception except); 28 29 }; 30 31 void __try_resume_cleanup(struct __try_resume_node * node); 29 32 30 33 struct __cleanup_hook {}; … … 147 150 void try_resume() { 148 151 { 149 bool catch1(exception except) {152 bool handle1(exception except) { 150 153 OtherException inner_except; 151 154 if (dynamic_cast__SomeException(except)) { … … 161 164 } 162 165 struct __try_resume_node data = 163 {.next = stack.except.top_resume, .try_to_handle = catch1};166 {.next = stack.except.top_resume, .try_to_handle = handle1}; 164 167 stack.except.top_resume = &data; 165 168 … … 204 207 205 208 206 // Combining the Above: 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: 207 253 "Cforall" 208 254 … … 226 272 void try_all() { 227 273 { 274 bool handle1() { 275 if (dynamic_cast__OtherException(except)) { 276 twiddleWidget(); 277 return true; 278 } 279 return false; 280 } 228 281 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 229 287 insideTry(); 230 288 } … … 244 302 return 0; 245 303 } 246 bool catch2() {247 if (dynamic_cast__OtherException(except)) {248 twiddleWidget();249 return true;250 }251 return false;252 }253 304 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();257 305 258 306 twiddleWidget(); 259 307 } 260 261 struct __try_resume_node generated_name =262 {.next = stack.except.top_resume, .try_to_handle = catch2};263 stack.except.top_resume = &data;264 308 struct __cleanup_hook generated_name 265 309 __attribute__((cleanup(finally1))); -
src/libcfa/concurrency/alarm.c
r4e6fb8e rec35498 136 136 137 137 static inline void remove_at( alarm_list_t * this, alarm_node_t * n, __alarm_it_t it ) { 138 assert( it );139 assert( (*it) == n );138 verify( it ); 139 verify( (*it) == n ); 140 140 141 141 (*it) = n->next; -
src/libcfa/concurrency/coroutine
r4e6fb8e rec35498 71 71 // Suspend implementation inlined for performance 72 72 static inline void suspend() { 73 73 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 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 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 105 // set last resumer 106 106 dst->last = src; 107 107 } // if 108 108 109 109 // always done for performance testing 110 110 CoroutineCtxSwitch( src, dst ); 111 111 } … … 114 114 coroutine_desc * src = this_coroutine(); // optimization 115 115 116 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 123 // set last resumer 124 124 dst->last = src; 125 125 } // if 126 126 127 127 // always done for performance testing 128 128 CoroutineCtxSwitch( src, dst ); 129 129 } -
src/libcfa/concurrency/kernel.c
r4e6fb8e rec35498 322 322 // appropriate stack. 323 323 proc_cor_storage.__cor.state = Active; 324 325 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 assertf( thrd->next == NULL, "Expected null got %p", thrd->next );373 verifyf( 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 assert(this->tail != NULL);652 verify(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 assert( !t->next );674 verify( !t->next ); 675 675 t->next = this->top; 676 676 this->top = t; -
src/libcfa/concurrency/kernel_private.h
r4e6fb8e rec35498 22 22 23 23 #include "alarm.h" 24 25 #include "libhdr.h" 24 26 25 27 //----------------------------------------------------------------------------- -
src/libcfa/concurrency/monitor
r4e6fb8e rec35498 26 26 static inline void ?{}(monitor_desc * this) { 27 27 this->owner = NULL; 28 28 this->stack_owner = NULL; 29 29 this->recursion = 0; 30 30 } … … 33 33 monitor_desc ** m; 34 34 int count; 35 36 35 monitor_desc ** prev_mntrs; 36 unsigned short prev_count; 37 37 }; 38 38 -
src/libcfa/concurrency/monitor.c
r4e6fb8e rec35498 56 56 else if( this->owner == thrd) { 57 57 //We already have the monitor, just not how many times we took it 58 assert( this->recursion > 0 );58 verify( this->recursion > 0 ); 59 59 this->recursion += 1; 60 60 } … … 78 78 lock( &this->lock ); 79 79 80 thread_desc * thrd = this_thread();81 82 80 LIB_DEBUG_PRINT_SAFE("%p Leaving %p (o: %p, r: %i)\n", thrd, this, this->owner, this->recursion); 83 assertf( thrd == this->owner, "Expected owner to be %p, got %p (r: %i)", thrd, 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 ); 84 82 85 83 //Leaving a recursion level, decrement the counter … … 167 165 //Check that everything is as expected 168 166 assertf( this->monitors != NULL, "Waiting with no monitors (%p)", this->monitors ); 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 );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 ); 171 169 172 170 unsigned short count = this->monitor_count; … … 229 227 230 228 //Check that everything is as expected 231 assert( this->monitors );232 assert( this->monitor_count != 0 );229 verify( this->monitors ); 230 verify( this->monitor_count != 0 ); 233 231 234 232 unsigned short count = this->monitor_count; … … 278 276 279 277 //Check that everything is as expected 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 );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 ); 282 280 283 281 unsigned short count = this->monitor_count; … … 327 325 328 326 uintptr_t front( condition * this ) { 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 } 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." 334 330 ); 335 331 return this->blocked.head->user_info; … … 491 487 492 488 void append( __condition_blocked_queue_t * this, __condition_node_t * c ) { 493 assert(this->tail != NULL);489 verify(this->tail != NULL); 494 490 *this->tail = c; 495 491 this->tail = &c->next; -
src/libcfa/libhdr/libdebug.h
r4e6fb8e rec35498 18 18 19 19 #ifdef __CFA_DEBUG__ 20 21 20 #define LIB_DEBUG_DO(x) x 21 #define LIB_NO_DEBUG_DO(x) 22 22 #else 23 24 23 #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 #else 31 #define verify(x) 32 #define verifyf(x, ...) 33 #endif 34 26 35 27 36 #ifdef __cforall
Note: See TracChangeset
for help on using the changeset viewer.