- File:
-
- 1 edited
-
libcfa/src/concurrency/coroutine.cfa (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
rdd92fe9 rac2b598 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Dec 15 12:06:04202013 // Update Count : 2312 // Last Modified On : Tue Feb 4 12:29:25 2020 13 // Update Count : 16 14 14 // 15 15 … … 18 18 #include "coroutine.hfa" 19 19 20 extern "C" { 20 21 #include <stddef.h> 21 22 #include <malloc.h> … … 23 24 #include <string.h> 24 25 #include <unistd.h> 25 #include <sys/mman.h> // mprotect 26 // use this define to make unwind.h play nice, definetely a hack 27 #define HIDE_EXPORTS 26 28 #include <unwind.h> 29 #undef HIDE_EXPORTS 30 #include <sys/mman.h> 31 } 27 32 28 33 #include "kernel_private.hfa" 29 #include "exception.hfa"30 #include "math.hfa"31 32 #define CFA_COROUTINE_USE_MMAP 033 34 34 35 #define __CFA_INVOKE_PRIVATE__ … … 46 47 47 48 //----------------------------------------------------------------------------- 48 FORALL_DATA_INSTANCE(CoroutineCancelled, (dtype coroutine_t), (coroutine_t))49 50 forall(dtype T)51 void mark_exception(CoroutineCancelled(T) *) {}52 53 forall(dtype T)54 void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {55 dst->virtual_table = src->virtual_table;56 dst->the_coroutine = src->the_coroutine;57 dst->the_exception = src->the_exception;58 }59 60 forall(dtype T)61 const char * msg(CoroutineCancelled(T) *) {62 return "CoroutineCancelled(...)";63 }64 65 // This code should not be inlined. It is the error path on resume.66 forall(dtype T | is_coroutine(T))67 void __cfaehm_cancelled_coroutine( T & cor, $coroutine * desc ) {68 verify( desc->cancellation );69 desc->state = Cancelled;70 exception_t * except = __cfaehm_cancellation_exception( desc->cancellation );71 72 // TODO: Remove explitate vtable set once trac#186 is fixed.73 CoroutineCancelled(T) except;74 except.virtual_table = &get_exception_vtable(&except);75 except.the_coroutine = &cor;76 except.the_exception = except;77 throwResume except;78 79 except->virtual_table->free( except );80 free( desc->cancellation );81 desc->cancellation = 0p;82 }83 84 //-----------------------------------------------------------------------------85 49 // Global state variables 86 50 87 51 // minimum feasible stack size in bytes 88 static const size_t MinStackSize = 1000; 52 #define MinStackSize 1000 89 53 extern size_t __page_size; // architecture pagesize HACK, should go in proper runtime singleton 90 extern int __map_prot;91 54 92 55 void __stack_prepare( __stack_info_t * this, size_t create_size ); 93 void __stack_clean ( __stack_info_t * this );94 56 95 57 //----------------------------------------------------------------------------- … … 112 74 bool userStack = ((intptr_t)this.storage & 0x1) != 0; 113 75 if ( ! userStack && this.storage ) { 114 __stack_clean( &this ); 76 __attribute__((may_alias)) intptr_t * istorage = (intptr_t *)&this.storage; 77 *istorage &= (intptr_t)-1; 78 79 void * storage = this.storage->limit; 80 __cfaabi_dbg_debug_do( 81 storage = (char*)(storage) - __page_size; 82 if ( mprotect( storage, __page_size, PROT_READ | PROT_WRITE ) == -1 ) { 83 abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) ); 84 } 85 ); 86 __cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage); 87 free( storage ); 115 88 } 116 89 } … … 128 101 void ^?{}($coroutine& this) { 129 102 if(this.state != Halted && this.state != Start && this.state != Primed) { 130 $coroutine * src = active_coroutine();103 $coroutine * src = TL_GET( this_thread )->curr_cor; 131 104 $coroutine * dst = &this; 132 105 … … 161 134 assert(__page_size != 0l); 162 135 size_t size = libCeiling( storageSize, 16 ) + stack_data_size; 163 size = ceiling(size, __page_size);164 136 165 137 // If we are running debug, we also need to allocate a guardpage to catch stack overflows. 166 138 void * storage; 167 #if CFA_COROUTINE_USE_MMAP 168 storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0); 169 if(storage == ((void*)-1)) { 170 abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) ); 139 __cfaabi_dbg_debug_do( 140 storage = memalign( __page_size, size + __page_size ); 141 ); 142 __cfaabi_dbg_no_debug_do( 143 storage = (void*)malloc(size); 144 ); 145 146 __cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size); 147 __cfaabi_dbg_debug_do( 148 if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) { 149 abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) ); 171 150 } 172 if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {173 abort( "coroutine stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );174 } // if175 151 storage = (void *)(((intptr_t)storage) + __page_size); 176 #else 177 __cfaabi_dbg_debug_do( 178 storage = memalign( __page_size, size + __page_size ); 179 ); 180 __cfaabi_dbg_no_debug_do( 181 storage = (void*)malloc(size); 182 ); 183 184 __cfaabi_dbg_debug_do( 185 if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) { 186 abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) ); 187 } 188 storage = (void *)(((intptr_t)storage) + __page_size); 189 ); 190 #endif 191 __cfaabi_dbg_print_safe("Kernel : Created stack %p of size %zu\n", storage, size); 152 ); 192 153 193 154 verify( ((intptr_t)storage & (libAlign() - 1)) == 0ul ); 194 155 return [storage, size]; 195 }196 197 void __stack_clean ( __stack_info_t * this ) {198 size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);199 void * storage = this->storage->limit;200 201 #if CFA_COROUTINE_USE_MMAP202 storage = (void *)(((intptr_t)storage) - __page_size);203 if(munmap(storage, size + __page_size) == -1) {204 abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );205 }206 #else207 __cfaabi_dbg_debug_do(208 storage = (char*)(storage) - __page_size;209 if ( mprotect( storage, __page_size, __map_prot ) == -1 ) {210 abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );211 }212 );213 214 free( storage );215 #endif216 __cfaabi_dbg_print_safe("Kernel : Deleting stack %p\n", storage);217 156 } 218 157 … … 236 175 size = libFloor(create_size - stack_data_size - diff, libAlign()); 237 176 } // if 238 assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of % zd bytes for a stack.", size, MinStackSize );239 240 this->storage = (__stack_t *)((intptr_t)storage + size - sizeof(__stack_t));177 assertf( size >= MinStackSize, "Stack size %zd provides less than minimum of %d bytes for a stack.", size, MinStackSize ); 178 179 this->storage = (__stack_t *)((intptr_t)storage + size); 241 180 this->storage->limit = storage; 242 this->storage->base = (void*)((intptr_t)storage + size - sizeof(__stack_t)); 243 this->storage->exception_context.top_resume = 0p; 244 this->storage->exception_context.current_exception = 0p; 181 this->storage->base = (void*)((intptr_t)storage + size); 245 182 __attribute__((may_alias)) intptr_t * istorage = (intptr_t*)&this->storage; 246 183 *istorage |= userStack ? 0x1 : 0x0; … … 268 205 269 206 struct $coroutine * __cfactx_cor_finish(void) { 270 struct $coroutine * cor = active_coroutine();207 struct $coroutine * cor = kernelTLS.this_thread->curr_cor; 271 208 272 209 if(cor->state == Primed) { 273 __cfactx_suspend();210 suspend(); 274 211 } 275 212
Note:
See TracChangeset
for help on using the changeset viewer.