Changeset 50f6afb
- Timestamp:
- Apr 24, 2021, 11:32:49 AM (2 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 424dfc4, 986cb99
- Parents:
- fec63b2 (diff), 8edbe40 (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. - Files:
-
- 2 added
- 21 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/io/http/protocol.cfa
rfec63b2 r50f6afb 5 5 #include <fcntl.h> 6 6 } 7 8 #define xstr(s) str(s) 9 #define str(s) #s 7 10 8 11 #include <fstream.hfa> … … 21 24 22 25 #define PLAINTEXT_1WRITE 26 #define PLAINTEXT_MEMCPY 23 27 #define PLAINTEXT_NOCOPY 24 28 … … 85 89 #if defined(PLAINTEXT_NOCOPY) 86 90 int answer_plaintext( int fd ) { 87 return answer(fd, http_msgs[OK200_PlainText]->msg, http_msgs[OK200_PlainText]->len + 1); // +1 cause snprintf doesn't count nullterminator 91 return answer(fd, http_msgs[OK200_PlainText]->msg, http_msgs[OK200_PlainText]->len); // +1 cause snprintf doesn't count nullterminator 92 } 93 #elif defined(PLAINTEXT_MEMCPY) 94 #define TEXTSIZE 15 95 int answer_plaintext( int fd ) { 96 char text[] = "Hello, World!\n\n"; 97 char ts[] = xstr(TEXTSIZE) " \n\n"; 98 _Static_assert(sizeof(text) - 1 == TEXTSIZE); 99 char buffer[512 + TEXTSIZE]; 100 char * it = buffer; 101 memcpy(it, http_msgs[OK200]->msg, http_msgs[OK200]->len); 102 it += http_msgs[OK200]->len; 103 int len = http_msgs[OK200]->len; 104 memcpy(it, ts, sizeof(ts) - 1); 105 it += sizeof(ts) - 1; 106 len += sizeof(ts) - 1; 107 memcpy(it, text, TEXTSIZE); 108 return answer(fd, buffer, len + TEXTSIZE); 88 109 } 89 110 #elif defined(PLAINTEXT_1WRITE) 90 111 int answer_plaintext( int fd ) { 91 char text[] = "Hello, World!\n ";112 char text[] = "Hello, World!\n\n"; 92 113 char buffer[512 + sizeof(text)]; 93 114 char * it = buffer; … … 103 124 #else 104 125 int answer_plaintext( int fd ) { 105 char text[] = "Hello, World!\n ";126 char text[] = "Hello, World!\n\n"; 106 127 int ret = answer_header(fd, sizeof(text)); 107 128 if( ret < 0 ) return ret; … … 194 215 const char * original_http_msgs[] = { 195 216 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: ", 196 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 15\n\nHello, World!\n ",217 "HTTP/1.1 200 OK\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 15\n\nHello, World!\n\n", 197 218 "HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 198 219 "HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", -
benchmark/io/http/worker.cfa
rfec63b2 r50f6afb 18 18 void ?{}( Worker & this ) { 19 19 size_t cli = rand() % options.clopts.cltr_cnt; 20 ((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli] };20 ((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli], 512000 }; 21 21 options.clopts.thrd_cnt[cli]++; 22 22 this.pipe[0] = -1; -
benchmark/readyQ/cycle.cpp
rfec63b2 r50f6afb 3 3 #include <libfibre/fibre.h> 4 4 5 class __attribute__((aligned(128))) bench_sem {6 Fibre * volatile ptr = nullptr;7 public:8 inline bool wait() {9 static Fibre * const ready = reinterpret_cast<Fibre * const>(1ull);10 for(;;) {11 Fibre * expected = this->ptr;12 if(expected == ready) {13 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {14 return false;15 }16 }17 else {18 /* paranoid */ assert( expected == nullptr );19 if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {20 fibre_park();21 return true;22 }23 }24 25 }26 }27 28 inline bool post() {29 static Fibre * const ready = reinterpret_cast<Fibre * const>(1ull);30 for(;;) {31 Fibre * expected = this->ptr;32 if(expected == ready) return false;33 if(expected == nullptr) {34 if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {35 return false;36 }37 }38 else {39 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {40 fibre_unpark( expected );41 return true;42 }43 }44 }45 }46 };47 5 struct Partner { 48 6 unsigned long long count = 0; -
benchmark/readyQ/locality.cpp
rfec63b2 r50f6afb 9 9 uint64_t dmigs = 0; 10 10 uint64_t gmigs = 0; 11 };12 13 class __attribute__((aligned(128))) bench_sem {14 Fibre * volatile ptr = nullptr;15 public:16 inline bool wait() {17 static Fibre * const ready = reinterpret_cast<Fibre * const>(1ull);18 for(;;) {19 Fibre * expected = this->ptr;20 if(expected == ready) {21 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {22 return false;23 }24 }25 else {26 /* paranoid */ assert( expected == nullptr );27 if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {28 fibre_park();29 return true;30 }31 }32 33 }34 }35 36 inline bool post() {37 static Fibre * const ready = reinterpret_cast<Fibre * const>(1ull);38 for(;;) {39 Fibre * expected = this->ptr;40 if(expected == ready) return false;41 if(expected == nullptr) {42 if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {43 return false;44 }45 }46 else {47 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {48 fibre_unpark( expected );49 return true;50 }51 }52 }53 }54 11 }; 55 12 -
benchmark/readyQ/rq_bench.hfa
rfec63b2 r50f6afb 4 4 #include <stdio.h> 5 5 #include <stdlib.hfa> 6 #include <stats.hfa> 6 7 #include <thread.hfa> 7 8 #include <time.hfa> … … 63 64 (*p){ "Benchmark Processor", this.cl }; 64 65 } 66 #if !defined(__CFA_NO_STATISTICS__) 67 print_stats_at_exit( this.cl, CFA_STATS_READY_Q ); 68 #endif 65 69 } 66 70 -
benchmark/readyQ/rq_bench.hpp
rfec63b2 r50f6afb 6 6 #include <time.h> // timespec 7 7 #include <sys/time.h> // timeval 8 9 typedef __uint128_t __lehmer64_state_t; 10 static inline uint64_t __lehmer64( __lehmer64_state_t & state ) { 11 state *= 0xda942042e4dd58b5; 12 return state >> 64; 13 } 8 14 9 15 enum { TIMEGRAN = 1000000000LL }; // nanosecond granularity, except for timeval … … 75 81 } 76 82 83 class Fibre; 84 int fibre_park(); 85 int fibre_unpark( Fibre * ); 86 Fibre * fibre_self(); 87 88 class __attribute__((aligned(128))) bench_sem { 89 Fibre * volatile ptr = nullptr; 90 public: 91 inline bool wait() { 92 static Fibre * const ready = reinterpret_cast<Fibre *>(1ull); 93 for(;;) { 94 Fibre * expected = this->ptr; 95 if(expected == ready) { 96 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 97 return false; 98 } 99 } 100 else { 101 /* paranoid */ assert( expected == nullptr ); 102 if(__atomic_compare_exchange_n(&this->ptr, &expected, fibre_self(), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 103 fibre_park(); 104 return true; 105 } 106 } 107 108 } 109 } 110 111 inline bool post() { 112 static Fibre * const ready = reinterpret_cast<Fibre *>(1ull); 113 for(;;) { 114 Fibre * expected = this->ptr; 115 if(expected == ready) return false; 116 if(expected == nullptr) { 117 if(__atomic_compare_exchange_n(&this->ptr, &expected, ready, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 118 return false; 119 } 120 } 121 else { 122 if(__atomic_compare_exchange_n(&this->ptr, &expected, nullptr, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) { 123 fibre_unpark( expected ); 124 return true; 125 } 126 } 127 } 128 } 129 }; 130 77 131 // ========================================================================================== 78 132 #include <cstdlib> … … 188 242 this->help = help; 189 243 this->variable = reinterpret_cast<void*>(&variable); 190 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse)); 244 #pragma GCC diagnostic push 245 #pragma GCC diagnostic ignored "-Wcast-function-type" 246 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(static_cast<bool (*)(const char *, T & )>(parse)); 247 #pragma GCC diagnostic pop 191 248 } 192 249 … … 197 254 this->help = help; 198 255 this->variable = reinterpret_cast<void*>(&variable); 199 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(parse); 256 #pragma GCC diagnostic push 257 #pragma GCC diagnostic ignored "-Wcast-function-type" 258 this->parse_fun = reinterpret_cast<bool (*)(const char *, void * )>(parse); 259 #pragma GCC diagnostic pop 200 260 } 201 261 }; -
libcfa/src/concurrency/clib/cfathread.cfa
rfec63b2 r50f6afb 50 50 51 51 cfathread_vtable _cfathread_vtable_instance; 52 53 cfathread_vtable & const _default_vtable = _cfathread_vtable_instance; 52 54 53 55 cfathread_vtable const & get_exception_vtable(cfathread_exception *) { -
libcfa/src/concurrency/coroutine.cfa
rfec63b2 r50f6afb 46 46 47 47 //----------------------------------------------------------------------------- 48 EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled);49 50 48 forall(T &) 51 49 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) { … … 62 60 // This code should not be inlined. It is the error path on resume. 63 61 forall(T & | is_coroutine(T)) 64 void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) { 62 void __cfaehm_cancelled_coroutine( 63 T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable ) { 65 64 verify( desc->cancellation ); 66 65 desc->state = Cancelled; … … 68 67 69 68 // TODO: Remove explitate vtable set once trac#186 is fixed. 70 SomeCoroutineCancelledexcept;71 except.virtual_table = & std_coroutine_cancelled;69 CoroutineCancelled(T) except; 70 except.virtual_table = &_default_vtable; 72 71 except.the_coroutine = &cor; 73 72 except.the_exception = except; 74 73 // Why does this need a cast? 75 throwResume ( SomeCoroutineCancelled&)except;74 throwResume (CoroutineCancelled(T) &)except; 76 75 77 76 except->virtual_table->free( except ); … … 146 145 // Part of the Public API 147 146 // Not inline since only ever called once per coroutine 148 forall(T & | is_coroutine(T) )147 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; }) 149 148 void prime(T& cor) { 150 149 $coroutine* this = get_coroutine(cor); -
libcfa/src/concurrency/coroutine.hfa
rfec63b2 r50f6afb 22 22 //----------------------------------------------------------------------------- 23 23 // Exception thrown from resume when a coroutine stack is cancelled. 24 EHM_EXCEPTION(SomeCoroutineCancelled)(25 void * the_coroutine;26 exception_t * the_exception;27 );28 29 EHM_EXTERN_VTABLE(SomeCoroutineCancelled, std_coroutine_cancelled);30 31 24 EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) ( 32 25 coroutine_t * the_coroutine; … … 44 37 // Anything that implements this trait can be resumed. 45 38 // Anything that is resumed is a coroutine. 46 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION( SomeCoroutineCancelled)) {39 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) { 47 40 void main(T & this); 48 41 $coroutine * get_coroutine(T & this); … … 67 60 //----------------------------------------------------------------------------- 68 61 // Public coroutine API 69 forall(T & | is_coroutine(T) )62 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; }) 70 63 void prime(T & cor); 71 64 … … 137 130 138 131 forall(T & | is_coroutine(T)) 139 void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ); 132 void __cfaehm_cancelled_coroutine( 133 T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable ); 140 134 141 135 // Resume implementation inlined for performance 142 forall(T & | is_coroutine(T) )136 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; }) 143 137 static inline T & resume(T & cor) { 144 138 // optimization : read TLS once and reuse it … … 170 164 $ctx_switch( src, dst ); 171 165 if ( unlikely(dst->cancellation) ) { 172 __cfaehm_cancelled_coroutine( cor, dst );166 __cfaehm_cancelled_coroutine( cor, dst, _default_vtable ); 173 167 } 174 168 -
libcfa/src/concurrency/locks.hfa
rfec63b2 r50f6afb 197 197 static inline $thread * unlock( fast_lock & this ) __attribute__((artificial)); 198 198 static inline $thread * unlock( fast_lock & this ) { 199 $thread * thrd = active_thread(); 200 /* paranoid */ verify(thrd == this.owner); 199 /* paranoid */ verify(active_thread() == this.owner); 201 200 202 201 // open 'owner' before unlocking anyone -
libcfa/src/concurrency/ready_queue.cfa
rfec63b2 r50f6afb 413 413 unsigned it2 = proc->rdq.itr + 1; 414 414 unsigned idx1 = proc->rdq.id + (it1 % READYQ_SHARD_FACTOR); 415 unsigned idx2 = proc->rdq.id + (it 1% READYQ_SHARD_FACTOR);415 unsigned idx2 = proc->rdq.id + (it2 % READYQ_SHARD_FACTOR); 416 416 unsigned long long tsc1 = ts(lanes.data[idx1]); 417 417 unsigned long long tsc2 = ts(lanes.data[idx2]); 418 418 proc->rdq.cutoff = min(tsc1, tsc2); 419 } 420 else if(lanes.tscs[proc->rdq.target].tv < proc->rdq.cutoff) { 421 $thread * t = try_pop(cltr, proc->rdq.target __STATS(, __tls_stats()->ready.pop.help)); 419 if(proc->rdq.cutoff == 0) proc->rdq.cutoff = -1ull; 420 } 421 else { 422 unsigned target = proc->rdq.target; 422 423 proc->rdq.target = -1u; 423 if(t) return t; 424 if(lanes.tscs[target].tv < proc->rdq.cutoff) { 425 $thread * t = try_pop(cltr, target __STATS(, __tls_stats()->ready.pop.help)); 426 if(t) return t; 427 } 424 428 } 425 429 -
libcfa/src/concurrency/stats.cfa
rfec63b2 r50f6afb 126 126 double sExt_len = ready.push.extrn.success ? ((double)ready.push.extrn.attempt) / ready.push.extrn.success : 0; 127 127 128 double rLcl_len = ready.pop.local .success ? ((double)ready.pop.local .attempt) / ready.pop.local .success : 0; 129 double rHlp_len = ready.pop.help .success ? ((double)ready.pop.help .attempt) / ready.pop.help .success : 0; 130 double rStl_len = ready.pop.steal .success ? ((double)ready.pop.steal .attempt) / ready.pop.steal .success : 0; 131 double rSch_len = ready.pop.search.success ? ((double)ready.pop.search.attempt) / ready.pop.search.success : 0; 128 uint64_t total = ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success; 129 double rLcl_pc = (100.0 * (double)ready.pop.local .success) / total; 130 double rHlp_pc = (100.0 * (double)ready.pop.help .success) / total; 131 double rStl_pc = (100.0 * (double)ready.pop.steal .success) / total; 132 double rSch_pc = (100.0 * (double)ready.pop.search.success) / total; 132 133 133 134 __cfaabi_bits_print_safe( STDOUT_FILENO, 134 135 "----- %s \"%s\" (%p) - Ready Q Stats -----\n" 135 136 "- totals : %'3" PRIu64 " run, %'3" PRIu64 " schd (%'" PRIu64 "ext, %'" PRIu64 "mig, %'" PRId64 " )\n" 136 "- push avg : %'3. 2lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n"137 "- local : %'3. 2lf(%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"138 "- help : %'3. 2lf(%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"139 "- steal : %'3. 2lf(%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"140 "- search : %'3. 2lf(%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n"137 "- push avg : %'3.0lf (l: %'3.2lf/%'" PRIu64 ", s: %'3.2lf/%'" PRIu64 ", e: %'3.2lf : %'" PRIu64 "e)\n" 138 "- local : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 139 "- help : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 140 "- steal : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 141 "- search : %'3.0lf%%: %'3" PRIu64 " (%'3" PRIu64 " try, %'3" PRIu64 " spc, %'3" PRIu64 " lck, %'3" PRIu64 " ept)\n" 141 142 "- Idle Slp : %'3" PRIu64 "h, %'3" PRIu64 "c, %'3" PRIu64 "w, %'3" PRIu64 "e\n" 142 143 "\n" 143 144 , type, name, id 144 , ready.pop.local.success + ready.pop.help.success + ready.pop.steal.success + ready.pop.search.success145 , total 145 146 , ready.push.local.success + ready.push.share.success + ready.push.extrn.success 146 147 , ready.push.extrn.success, ready.threads.migration, ready.threads.threads 147 148 , push_len, sLcl_len, ready.push.local.attempt, sOth_len, ready.push.share.attempt, sExt_len, ready.push.extrn.attempt 148 , rLcl_ len, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty149 , rHlp_ len, ready.pop.help .attempt, ready.pop.help .espec, ready.pop.help .elock, ready.pop.help .eempty150 , rStl_ len, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty151 , rSch_ len, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty149 , rLcl_pc, ready.pop.local .success, ready.pop.local .attempt, ready.pop.local .espec, ready.pop.local .elock, ready.pop.local .eempty 150 , rHlp_pc, ready.pop.help .success, ready.pop.help .attempt, ready.pop.help .espec, ready.pop.help .elock, ready.pop.help .eempty 151 , rStl_pc, ready.pop.steal .success, ready.pop.steal .attempt, ready.pop.steal .espec, ready.pop.steal .elock, ready.pop.steal .eempty 152 , rSch_pc, ready.pop.search.success, ready.pop.search.attempt, ready.pop.search.espec, ready.pop.search.elock, ready.pop.search.eempty 152 153 , ready.sleep.halts, ready.sleep.cancels, ready.sleep.wakes, ready.sleep.exits 153 154 ); -
libcfa/src/concurrency/thread.cfa
rfec63b2 r50f6afb 61 61 } 62 62 63 EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled);64 65 63 forall(T &) 66 64 void copy(ThreadCancelled(T) * dst, ThreadCancelled(T) * src) { … … 81 79 } 82 80 83 static void default_thread_cancel_handler(SomeThreadCancelled & ) { 84 // Improve this error message, can I do formatting? 85 abort( "Unhandled thread cancellation.\n" ); 86 } 87 88 forall(T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled)) 81 forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) 82 | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; }) 89 83 void ?{}( thread_dtor_guard_t & this, 90 T & thrd, void(*cancelHandler)( SomeThreadCancelled&)) {84 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) { 91 85 $monitor * m = get_monitor(thrd); 92 86 $thread * desc = get_thread(thrd); … … 94 88 // Setup the monitor guard 95 89 void (*dtor)(T& mutex this) = ^?{}; 96 bool join = cancelHandler != (void(*)( SomeThreadCancelled&))0;90 bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0; 97 91 (this.mg){&m, (void(*)())dtor, join}; 98 92 … … 108 102 } 109 103 desc->state = Cancelled; 110 void(*defaultResumptionHandler)( SomeThreadCancelled&) =104 void(*defaultResumptionHandler)(ThreadCancelled(T) &) = 111 105 join ? cancelHandler : default_thread_cancel_handler; 112 106 113 107 // TODO: Remove explitate vtable set once trac#186 is fixed. 114 SomeThreadCancelledexcept;115 except.virtual_table = & std_thread_cancelled;108 ThreadCancelled(T) except; 109 except.virtual_table = &_default_vtable; 116 110 except.the_thread = &thrd; 117 111 except.the_exception = __cfaehm_cancellation_exception( cancellation ); 118 112 // Why is this cast required? 119 throwResume ( SomeThreadCancelled&)except;113 throwResume (ThreadCancelled(T) &)except; 120 114 121 115 except.the_exception->virtual_table->free( except.the_exception ); … … 164 158 165 159 //----------------------------------------------------------------------------- 166 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled)) 160 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) 161 | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; }) 167 162 T & join( T & this ) { 168 163 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; -
libcfa/src/concurrency/thread.hfa
rfec63b2 r50f6afb 31 31 $thread* get_thread(T& this); 32 32 }; 33 34 EHM_EXCEPTION(SomeThreadCancelled) (35 void * the_thread;36 exception_t * the_exception;37 );38 39 EHM_EXTERN_VTABLE(SomeThreadCancelled, std_thread_cancelled);40 33 41 34 EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) ( … … 86 79 }; 87 80 88 forall( T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled) ) 89 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(SomeThreadCancelled &) ); 81 forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) 82 | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } ) 83 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) ); 90 84 void ^?{}( thread_dtor_guard_t & this ); 91 85 … … 132 126 //---------- 133 127 // join 134 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled) ) 128 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) 129 | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } ) 135 130 T & join( T & this ); 136 131 -
libcfa/src/exception.hfa
rfec63b2 r50f6afb 142 142 _EHM_VTABLE_TYPE(exception_name) parameters const &) {} \ 143 143 144 #define _EHM_TRAIT_FUNCTION2(exception_name, forall_clause, parameters) \145 forall_clause _EHM_VTABLE_TYPE(exception_name) parameters const & \146 get_exception_vtable(exception_name parameters const & this)147 148 144 #define __EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \ 149 145 forall_clause inline _EHM_VTABLE_TYPE(exception_name) parameters const & \ -
src/Concurrency/Keywords.cc
rfec63b2 r50f6afb 414 414 if ( type_decl && isDestructorFor( decl, type_decl ) ) 415 415 dtor_decl = decl; 416 else if ( vtable_name.empty() ) 417 ; 418 else if( !decl->has_body() ) 416 else if ( vtable_name.empty() || !decl->has_body() ) 419 417 ; 420 418 else if ( auto param = isMainFor( decl, cast_target ) ) { … … 428 426 std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) }; 429 427 ObjectDecl * vtable_object = Virtual::makeVtableInstance( 428 "_default_vtable_object_declaration", 430 429 vtable_decl->makeInst( poly_args ), struct_type, nullptr ); 431 430 declsToAddAfter.push_back( vtable_object ); 431 declsToAddAfter.push_back( 432 new ObjectDecl( 433 Virtual::concurrentDefaultVTableName(), 434 Type::Const, 435 LinkageSpec::Cforall, 436 /* bitfieldWidth */ nullptr, 437 new ReferenceType( Type::Const, vtable_object->type->clone() ), 438 new SingleInit( new VariableExpr( vtable_object ) ) 439 ) 440 ); 432 441 declsToAddAfter.push_back( Virtual::makeGetExceptionFunction( 433 442 vtable_object, except_decl->makeInst( std::move( poly_args ) ) … … 488 497 except_decl->makeInst( poly_args ) 489 498 ) ); 490 declsToAddBefore.push_back( Virtual::makeVtableForward( 491 vtable_decl->makeInst( move( poly_args ) ) ) ); 499 ObjectDecl * vtable_object = Virtual::makeVtableForward( 500 "_default_vtable_object_declaration", 501 vtable_decl->makeInst( move( poly_args ) ) ); 502 declsToAddBefore.push_back( vtable_object ); 503 declsToAddBefore.push_back( 504 new ObjectDecl( 505 Virtual::concurrentDefaultVTableName(), 506 Type::Const, 507 LinkageSpec::Cforall, 508 /* bitfieldWidth */ nullptr, 509 new ReferenceType( Type::Const, vtable_object->type->clone() ), 510 /* init */ nullptr 511 ) 512 ); 492 513 } 493 514 -
src/Virtual/Tables.cc
rfec63b2 r50f6afb 10 10 // Created On : Mon Aug 31 11:11:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Apr 8 15:51:00 202113 // Update Count : 112 // Last Modified On : Wed Apr 21 15:36:00 2021 13 // Update Count : 2 14 14 // 15 15 … … 50 50 } 51 51 52 std::string concurrentDefaultVTableName() { 53 return "_default_vtable"; 54 } 55 52 56 bool isVTableInstanceName( std::string const & name ) { 53 57 // There are some delicate length calculations here. … … 57 61 58 62 static ObjectDecl * makeVtableDeclaration( 63 std::string const & name, 59 64 StructInstType * type, Initializer * init ) { 60 std::string const & name = instanceName( type->name );61 65 Type::StorageClasses storage = noStorageClasses; 62 66 if ( nullptr == init ) { … … 73 77 } 74 78 75 ObjectDecl * makeVtableForward( StructInstType * type ) {79 ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) { 76 80 assert( type ); 77 return makeVtableDeclaration( type, nullptr );81 return makeVtableDeclaration( name, type, nullptr ); 78 82 } 79 83 80 84 ObjectDecl * makeVtableInstance( 81 StructInstType * vtableType, Type * objectType, Initializer * init ) { 85 std::string const & name, StructInstType * vtableType, 86 Type * objectType, Initializer * init ) { 82 87 assert( vtableType ); 83 88 assert( objectType ); … … 115 120 assert(false); 116 121 } 117 return makeVtableDeclaration( vtableType, init );122 return makeVtableDeclaration( name, vtableType, init ); 118 123 } 119 124 … … 167 172 } 168 173 169 ObjectDecl * makeTypeIdForward() {170 return nullptr;171 }172 173 174 Attribute * linkonce( const std::string & subsection ) { 174 175 const std::string section = ".gnu.linkonce." + subsection; -
src/Virtual/Tables.h
rfec63b2 r50f6afb 10 10 // Created On : Mon Aug 31 11:07:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Apr 8 15:55:00 202113 // Update Count : 112 // Last Modified On : Wed Apr 21 10:30:00 2021 13 // Update Count : 2 14 14 // 15 15 … … 27 27 std::string instanceName( std::string const & vtable_name ); 28 28 std::string vtableInstanceName( std::string const & type_name ); 29 std::string concurrentDefaultVTableName(); 29 30 bool isVTableInstanceName( std::string const & name ); 30 31 31 ObjectDecl * makeVtableForward( StructInstType * vtableType ); 32 ObjectDecl * makeVtableForward( 33 std::string const & name, StructInstType * vtableType ); 32 34 /* Create a forward declaration of a vtable of the given type. 33 35 * vtableType node is consumed. 34 36 */ 35 37 36 ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType, 38 ObjectDecl * makeVtableInstance( 39 std::string const & name, 40 StructInstType * vtableType, Type * objectType, 37 41 Initializer * init = nullptr ); 38 42 /* Create an initialized definition of a vtable. -
tests/concurrent/coroutineYield.cfa
rfec63b2 r50f6afb 38 38 39 39 40 Coroutine c; 40 41 int main(int argc, char* argv[]) { 41 Coroutine c;42 42 for(int i = 0; TEST(i < N); i++) { 43 43 #if !defined(TEST_FOREVER) -
tests/exceptions/cancel/coroutine.cfa
rfec63b2 r50f6afb 25 25 resume(cancel); 26 26 printf("4"); 27 } catchResume ( SomeCoroutineCancelled* error) {27 } catchResume (CoroutineCancelled(WillCancel) * error) { 28 28 printf("2"); 29 29 if ((virtual internal_error *)error->the_exception) { -
tests/exceptions/cancel/thread.cfa
rfec63b2 r50f6afb 26 26 join(cancel); 27 27 printf("4"); 28 } catchResume ( SomeThreadCancelled* error) {28 } catchResume (ThreadCancelled(WillCancel) * error) { 29 29 printf("2"); 30 30 if ((virtual internal_error *)error->the_exception) { … … 43 43 } 44 44 printf("4"); 45 } catchResume ( SomeThreadCancelled* error) {45 } catchResume (ThreadCancelled(WillCancel) * error) { 46 46 printf("2"); 47 47 if ((virtual internal_error *)error->the_exception) {
Note: See TracChangeset
for help on using the changeset viewer.