Changeset 80d9e49 for src/libcfa/concurrency
- Timestamp:
- Dec 7, 2016, 2:47:53 PM (8 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:
- 550a3385
- Parents:
- a68caae
- Location:
- src/libcfa/concurrency
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/invoke.c
ra68caae r80d9e49 13 13 // Called from the kernel when starting a coroutine or task so must switch back to user mode. 14 14 15 void invokeCoroutine(covptr_t* vthis) 16 { 17 LIB_DEBUG_PRINTF("Invoke : Received %p (v %p)\n", vthis, *vthis); 15 extern void __suspend__F___1(void); 18 16 19 struct coroutine* cor = get_coroutine( vthis ); 17 void invokeCoroutine( 18 void (*main)(void *), 19 struct coroutine *(*get_coroutine)(void *), 20 void *this 21 ) { 22 LIB_DEBUG_PRINTF("Invoke : Received %p (main %p, get_c %p)\n", this, main, get_coroutine); 23 24 struct coroutine* cor = get_coroutine( this ); 25 26 if(cor->state == Primed) { 27 __suspend__F___1(); 28 } 20 29 21 30 cor->state = Active; 22 31 23 (*vthis)->main( get_object(vthis));32 main( this ); 24 33 } 25 34 26 35 27 void startCoroutine(covptr_t* vthis, void (*invoke)(covptr_t*)) { 28 LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (v %p) to %p\n", vthis, *vthis, invoke); 36 void startCoroutine( 37 void (*main)(void *), 38 struct coroutine *(*get_coroutine)(void *), 39 void *this, 40 void (*invoke)(void *) 41 ) { 42 LIB_DEBUG_PRINTF("StartCoroutine : Passing in %p (main %p, get_c %p) to %p\n", this, main, get_coroutine, invoke); 29 43 30 struct coroutine* this = get_coroutine( vthis ); 31 struct coStack_t* stack = &this->stack; 44 struct coStack_t* stack = &get_coroutine( this )->stack; 32 45 33 46 #if defined( __i386__ ) … … 37 50 void *rturn; // where to go on return from uSwitch 38 51 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 39 void *argument ; // for 16-byte ABI, 16-byte alignment starts here40 void *padding [3]; // padding to force 16-byte alignment, as "base" is 16-byte aligned52 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 53 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 41 54 }; 42 55 … … 45 58 46 59 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 47 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument = vthis; // argument to invoke60 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 48 61 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke; 49 62 … … 61 74 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL; 62 75 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = coInvokeStub; 63 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = vthis;76 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this; 64 77 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke; 65 78 #else -
src/libcfa/concurrency/invoke.h
ra68caae r80d9e49 10 10 #define _INVOKE_H_ 11 11 12 #define OFFSET_OF(type, field) ((intptr_t)( &((type*)0)->field)) 13 #define VPTR_OFFSET(type, vptr, field) (OFFSET_OF(type, field) - OFFSET_OF(type, vptr)) 14 15 struct coVtable_t { 16 void (*main)(void*); 17 intptr_t offset_coroutine; 18 intptr_t offset_object; 19 }; 20 21 typedef struct coVtable_t* covptr_t; 22 23 static inline struct coroutine* get_coroutine(covptr_t* vthis) { 24 return (struct coroutine*) ( ((intptr_t)vthis) + ((intptr_t)(*vthis)->offset_coroutine) ); 25 } 26 27 static inline void* get_object(covptr_t* vthis) { 28 return (void*) ( ((intptr_t)vthis) + ((intptr_t)(*vthis)->offset_object) ); 29 } 30 31 struct coStack_t { 12 struct coStack_t { 32 13 unsigned int size; // size of stack 33 14 void *storage; // pointer to stack … … 39 20 }; 40 21 41 enum coroutine_state { Start, Inactive, Active, Halt };22 enum coroutine_state { Start, Inactive, Active, Halt, Primed }; 42 23 43 24 struct coroutine { … … 52 33 }; 53 34 54 void invokeCoroutine(covptr_t* this);55 void startCoroutine(covptr_t* this, void (*invoke)(covptr_t*));56 35 #endif //_INVOKE_H_ 57 36 #else //! defined(__CFA_INVOKE_PRIVATE__) -
src/libcfa/concurrency/threads
ra68caae r80d9e49 23 23 24 24 void ?{}(coroutine* this); 25 void ?{}(coroutine* this, covptr_t* object);26 25 27 trait coroutine_t(dtype T) {26 trait is_coroutine(dtype T) { 28 27 void co_main(T* this); 29 co vptr_t* vtable(T* this);28 coroutine* get_coroutine(T* this); 30 29 }; 31 30 32 31 void suspend(void); 33 32 34 forall(dtype T | coroutine_t(T))33 forall(dtype T | is_coroutine(T)) 35 34 void resume(T* cor); 35 36 forall(dtype T | is_coroutine(T)) 37 void prime(T* cor); 36 38 37 39 #endif //__THREADS_H__ -
src/libcfa/concurrency/threads.c
ra68caae r80d9e49 34 34 static size_t pageSize = 0; // architecture pagesize 35 35 36 static coroutine main_coroutine; 36 void ?{}(coStack_t* this, size_t size); 37 void ?{}(coroutine* this, size_t size); 38 39 static coroutine main_coroutine = { 1000 }; 37 40 static coroutine* current_coroutine = &main_coroutine; 38 41 … … 43 46 void ctxSwitchDirect(coroutine* src, coroutine* dst); 44 47 void create_stack( coStack_t* this, unsigned int storageSize ); // used by all constructors 48 49 extern "C" { 50 forall(dtype T | is_coroutine(T)) 51 void invokeCoroutine(T* this); 52 53 forall(dtype T | is_coroutine(T)) 54 void startCoroutine(T* this, void (*invoke)(T*)); 55 } 45 56 46 57 void ?{}(coStack_t* this) { … … 52 63 this->top = NULL; // address of top of storage 53 64 this->userStack = false; 65 } 66 67 void ?{}(coStack_t* this, size_t size) { 68 this{}; 69 this->size = size; 54 70 55 71 create_stack(this, this->size); … … 66 82 } 67 83 68 void ?{}(coroutine* this, covptr_t* object)84 void ?{}(coroutine* this, size_t size) 69 85 { 70 86 this{}; 71 72 startCoroutine(object, invokeCoroutine); 87 (&this->stack){size}; 73 88 } 74 89 … … 88 103 } 89 104 90 forall(dtype T | coroutine_t(T))105 forall(dtype T | is_coroutine(T)) 91 106 void resume(T* cor) { 92 107 coroutine* src = this_coroutine(); // optimization 93 coroutine* dst = get_coroutine(vtable(cor)); 108 coroutine* dst = get_coroutine(cor); 109 110 if( ((intptr_t)dst->stack.base) == 0 ) { 111 create_stack(&dst->stack, dst->stack.size); 112 startCoroutine(cor, invokeCoroutine); 113 } 94 114 95 115 if ( src != dst ) { // not resuming self ? … … 103 123 } 104 124 125 forall(dtype T | is_coroutine(T)) 126 void prime(T* cor) { 127 coroutine* this = get_coroutine(cor); 128 assert(this->state == Start); 129 130 this->state = Primed; 131 resume(cor); 132 } 133 105 134 void ctxSwitchDirect(coroutine* src, coroutine* dst) { 106 135 // THREAD_GETMEM( This )->disableInterrupts();
Note: See TracChangeset
for help on using the changeset viewer.