Changeset 78b3f52 for src/libcfa/concurrency/threads.c
- Timestamp:
- Dec 2, 2016, 5:10:22 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:
- d7bcbf5
- Parents:
- 4cb935e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/libcfa/concurrency/threads.c
r4cb935e r78b3f52 1 // 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 3 // 4 // The contents of this file are covered under the licence agreement in the 5 // file "LICENCE" distributed with Cforall. 6 // 7 // threads.c -- 8 // 9 // Author : Thierry Delisle 10 // Created On : Mon Nov 28 12:27:26 2016 11 // Last Modified By : Thierry Delisle 12 // Last Modified On : Mon Nov 28 12:27:26 2016 13 // Update Count : 0 14 // 15 16 extern "C" { 17 #include <stddef.h> 18 #include <malloc.h> 19 #include <errno.h> 20 #include <string.h> 21 #include <unistd.h> 22 #include <sys/mman.h> 23 } 24 1 25 #include "threads" 2 26 #include "assert" 27 #include "libhdr.h" 3 28 4 #include <stddef.h> 29 extern "C" { extern void coInvokeStub( void ); } 5 30 6 #include <fstream> 7 31 // minimum feasible stack size in bytes 32 #define MinStackSize 1000 33 8 34 static coroutine main_coroutine; 9 35 static coroutine* current_coroutine = &main_coroutine; 10 36 11 void ctxSwitchDirect(void* src, void* dst) { 12 current_coroutine = dst; 37 extern "C" { 38 struct machine_context_t { 39 void *SP; 40 void *FP; 41 void *PC; 42 }; 43 } 44 45 extern "C" { void CtxSwitch( void *from, void *to ) asm ("CtxSwitch"); }// assembler routine that performs the context switch 46 47 static size_t pageSize = 0; // architecture pagesize 48 49 void ctxSwitchDirect(coroutine* src, coroutine* dst) { 50 // THREAD_GETMEM( This )->disableInterrupts(); 51 52 // set state of current coroutine to inactive 53 src->state = Inactive; 54 55 // set new coroutine that task is executing 56 current_coroutine = dst; 57 58 // context switch to specified coroutine 59 CtxSwitch( src->stack.context, dst->stack.context ); 60 // when CtxSwitch returns we are back in the src coroutine 61 62 // set state of new coroutine to active 63 src->state = Active; 64 65 // THREAD_GETMEM( This )->enableInterrupts(); 66 } //ctxSwitchDirect 67 68 void invokeCoroutine(coVtable* vtable, void* this); 69 70 forall(dtype T | coroutine_t(T)) 71 void startCoroutine(T* this, void (*invoke)(coVtable*, void*)); 72 73 // used by all constructors 74 void create_stack( coStack_t* this, unsigned int storageSize ) { 75 //TEMP HACK do this on proper kernel startup 76 if(pageSize == 0ul) pageSize = sysconf( _SC_PAGESIZE ); 77 78 size_t cxtSize = libCeiling( sizeof(machine_context_t), 8 ); // minimum alignment 79 80 if ( (intptr_t)this->storage == 0 ) { 81 this->userStack = false; 82 this->size = libCeiling( storageSize, 16 ); 83 // use malloc/memalign because "new" raises an exception for out-of-memory 84 85 // assume malloc has 8 byte alignment so add 8 to allow rounding up to 16 byte alignment 86 LIB_DEBUG_DO( this->storage = memalign( pageSize, cxtSize + this->size + pageSize ) ); 87 LIB_NO_DEBUG_DO( this->storage = malloc( cxtSize + this->size + 8 ) ); 88 89 LIB_DEBUG_DO( 90 if ( mprotect( this->storage, pageSize, PROT_NONE ) == -1 ) { 91 abortf( "(uMachContext &)%p.createContext() : internal error, mprotect failure, error(%d) %s.", this, (int)errno, strerror( (int)errno ) ); 92 } // if 93 ); 94 95 if ( (intptr_t)this->storage == 0 ) { 96 abortf( "Attempt to allocate %d bytes of storage for coroutine or task execution-state but insufficient memory available.", this->size ); 97 } // if 98 99 LIB_DEBUG_DO( this->limit = (char *)this->storage + pageSize ); 100 LIB_NO_DEBUG_DO( this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ) ); // minimum alignment 101 102 } else { 103 assertf( ((size_t)this->storage & (libAlign() - 1)) != 0ul, "Stack storage %p for task/coroutine must be aligned on %d byte boundary.", this->storage, (int)libAlign() ); 104 this->userStack = true; 105 this->size = storageSize - cxtSize; 106 107 if ( this->size % 16 != 0u ) this->size -= 8; 108 109 this->limit = (char *)libCeiling( (unsigned long)this->storage, 16 ); // minimum alignment 110 } // if 111 assertf( this->size >= MinStackSize, "Stack size %d provides less than minimum of %d bytes for a stack.", this->size, MinStackSize ); 112 113 this->base = (char *)this->limit + this->size; 114 this->context = this->base; 115 this->top = (char *)this->context + cxtSize; 13 116 } 14 117 … … 17 120 } 18 121 122 void ?{}(coStack_t* this) { 123 this->size = 10240; // size of stack 124 this->storage = NULL; // pointer to stack 125 this->limit = NULL; // stack grows towards stack limit 126 this->base = NULL; // base of stack 127 this->context = NULL; // address of cfa_context_t 128 this->top = NULL; // address of top of storage 129 this->userStack = false; 130 create_stack(this, this->size); 131 } 132 19 133 void ?{}(coroutine* this) 20 134 { 135 this->name = "Anonymous Coroutine"; 136 this->errno_ = 0; 137 this->state = Start; 138 this->notHalted = true; 139 this->starter = NULL; 21 140 this->last = NULL; 22 this->name = "A Coroutine"; 23 this->notHalted = true; 141 } 142 143 forall(dtype T | coroutine_t(T)) 144 void start(T* this) { 145 startCoroutine(this, invokeCoroutine); 24 146 } 25 147 … … 27 149 coroutine* src = this_coroutine(); // optimization 28 150 29 assertf( src->last == (coroutine*)0,151 assertf( src->last != 0, 30 152 "Attempt to suspend coroutine %.256s (%p) that has never been resumed.\n" 31 153 "Possible cause is a suspend executed in a member called by a coroutine user rather than by the coroutine main.", … … 44 166 coroutine* dst = this_coroutine(cor); 45 167 168 fprintf(stderr, "Resuming %p from %p\n", dst, src); 46 169 if ( src != dst ) { // not resuming self ? 47 170 assertf( dst->notHalted , … … 49 172 "Possible cause is terminated coroutine's main routine has already returned.", 50 173 src->name, src, dst->name, dst ); 174 fprintf(stderr, "Assigning last pointer\n"); 51 175 dst->last = src; // set last resumer 52 176 } // if 53 177 ctxSwitchDirect( src, dst ); // always done for performance testing 54 178 } 179 180 // Local Variables: // 181 // mode: c // 182 // tab-width: 4 // 183 // End: //
Note: See TracChangeset
for help on using the changeset viewer.