Changeset b067d9b for libcfa/src
- Timestamp:
- Oct 29, 2019, 4:01:24 PM (6 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 773db65, 9421f3d8
- Parents:
- 7951100 (diff), 8364209 (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. - Location:
- libcfa/src
- Files:
-
- 16 added
- 93 moved
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/assert.cfa
r7951100 rb067d9b 17 17 #include <stdarg.h> // varargs 18 18 #include <stdio.h> // fprintf 19 #include "bits/debug.h "19 #include "bits/debug.hfa" 20 20 21 21 extern "C" { -
libcfa/src/bits/algorithm.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // bits/algorithms.h -- Builtins for exception handling.7 // bits/algorithms.hfa -- Builtins for exception handling. 8 8 // 9 9 // Author : Thierry Delisle -
libcfa/src/bits/align.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // align.h --7 // align.hfa -- 8 8 // 9 9 // Author : Thierry Delisle -
libcfa/src/bits/containers.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // bits/containers.h -- Intrusive generic containers.h7 // bits/containers.hfa -- Intrusive generic containers.hfa 8 8 // 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Oct 31 16:38:50 2017 11 // Last Modified By : --12 // Last Modified On : --13 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 26 08:52:20 2019 13 // Update Count : 4 14 14 15 15 #pragma once 16 16 17 #include "bits/align.h "18 #include "bits/defs.h "17 #include "bits/align.hfa" 18 #include "bits/defs.hfa" 19 19 20 20 //----------------------------------------------------------------------------- … … 78 78 //----------------------------------------------------------------------------- 79 79 #ifdef __cforall 80 forall(dtype TYPE | is_node(TYPE))80 forall(dtype TYPE) 81 81 #define T TYPE 82 82 #else … … 95 95 96 96 #ifdef __cforall 97 forall(dtype T | is_node(T))97 forall(dtype T) 98 98 static inline void ?{}( __stack(T) & this ) { 99 99 (this.top){ NULL }; … … 116 116 return top; 117 117 } 118 119 forall(dtype T | is_node(T)) 120 static inline int ?!=?( const __stack(T) & this, __attribute__((unused)) zero_t zero ) { 121 return this.top != 0; 122 } 118 123 #endif 119 124 … … 122 127 //----------------------------------------------------------------------------- 123 128 #ifdef __cforall 124 forall(dtype TYPE | is_node(TYPE))129 forall(dtype TYPE) 125 130 #define T TYPE 126 131 #else … … 141 146 #ifdef __cforall 142 147 143 forall(dtype T | is_node(T))148 forall(dtype T) 144 149 static inline void ?{}( __queue(T) & this ) with( this ) { 145 150 head{ NULL }; … … 186 191 187 192 forall(dtype T | is_node(T)) 188 static inline bool ?!=?( __queue(T) & this,zero_t zero ) {193 static inline int ?!=?( const __queue(T) & this, __attribute__((unused)) zero_t zero ) { 189 194 return this.head != 0; 190 195 } … … 196 201 //----------------------------------------------------------------------------- 197 202 #ifdef __cforall 198 forall(dtype TYPE | sized(TYPE))203 forall(dtype TYPE) 199 204 #define T TYPE 200 205 #define __getter_t * [T * & next, T * & prev] ( T & ) … … 268 273 269 274 forall(dtype T | sized(T)) 270 static inline bool ?!=?( __dllist(T) & this,zero_t zero ) {275 static inline int ?!=?( const __dllist(T) & this, __attribute__((unused)) zero_t zero ) { 271 276 return this.head != 0; 272 277 } -
libcfa/src/bits/debug.cfa
r7951100 rb067d9b 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu Mar 30 12:30:01 2017 11 // Last Modified By : 12 // Last Modified On : 13 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jul 14 22:17:35 2019 13 // Update Count : 4 14 14 // 15 15 … … 23 23 } 24 24 25 enum { buffer_size = 512};25 enum { buffer_size = 4096 }; 26 26 static char buffer[ buffer_size ]; 27 27 -
libcfa/src/bits/debug.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // debug.h --7 // debug.hfa -- 8 8 // 9 9 // Author : Thierry Delisle -
libcfa/src/bits/defs.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // defs.h --7 // defs.hfa -- 8 8 // 9 9 // Author : Thierry Delisle … … 28 28 29 29 #ifdef __cforall 30 #define __cfa_anonymous_object 30 #define __cfa_anonymous_object(x) inline struct x 31 31 #else 32 #define __cfa_anonymous_object __cfa_anonymous_object32 #define __cfa_anonymous_object(x) x __cfa_anonymous_object 33 33 #endif 34 34 … … 41 41 } 42 42 #endif 43 44 #if defined(__cforall_thread__) 45 #define OPTIONAL_THREAD 46 #else 47 #define OPTIONAL_THREAD __attribute__((weak)) 48 #endif -
libcfa/src/bits/locks.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // bits/locks.h -- Fast internal locks.7 // bits/locks.hfa -- Fast internal locks. 8 8 // 9 9 // Author : Thierry Delisle 10 10 // Created On : Tue Oct 31 15:14:38 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:18:13201813 // Update Count : 912 // Last Modified On : Sat Aug 11 15:42:24 2018 13 // Update Count : 10 14 14 // 15 15 16 16 #pragma once 17 17 18 #include "bits/debug.h "19 #include "bits/defs.h "18 #include "bits/debug.hfa" 19 #include "bits/defs.hfa" 20 20 #include <assert.h> 21 21 … … 37 37 #endif 38 38 39 #if defined( __i386 ) || defined( __x86_64 ) || defined( __ARM_ARCH )40 // Intel recommendation41 #define __ALIGN__ __attribute__(( aligned (128) ))42 #elif defined( __sparc )43 #define __ALIGN__ CALIGN44 #else45 #error unsupported architecture46 #endif47 48 39 struct __spinlock_t { 49 40 // Wrap in struct to prevent false sharing with debug info 50 struct { 51 // Align lock on 128-bit boundary 52 __ALIGN__ volatile _Bool lock; 53 }; 41 volatile bool lock; 54 42 #ifdef __CFA_DEBUG__ 55 43 // previous function to acquire the lock … … 58 46 void* prev_thrd; 59 47 #endif 60 } __ALIGN__;48 }; 61 49 62 50 #ifdef __cforall 63 51 extern "C" { 64 extern void disable_interrupts(); 65 extern void enable_interrupts_noPoll(); 52 extern void disable_interrupts() OPTIONAL_THREAD; 53 extern void enable_interrupts_noPoll() OPTIONAL_THREAD; 54 55 #ifdef __CFA_DEBUG__ 56 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name); 57 #else 58 #define __cfaabi_dbg_record(x, y) 59 #endif 66 60 } 67 61 … … 72 66 } 73 67 74 75 #ifdef __CFA_DEBUG__76 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);77 #else78 #define __cfaabi_dbg_record(x, y)79 #endif80 81 68 // Lock the spinlock, return false if already acquired 82 static inline _Bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) {83 _Bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0);69 static inline bool try_lock ( __spinlock_t & this __cfaabi_dbg_ctx_param2 ) { 70 bool result = (this.lock == 0) && (__atomic_test_and_set( &this.lock, __ATOMIC_ACQUIRE ) == 0); 84 71 if( result ) { 85 72 disable_interrupts(); … … 126 113 127 114 struct __bin_sem_t { 128 int_fast8_t counter;129 pthread_mutex_t lock;130 pthread_cond_t cond;115 bool signaled; 116 pthread_mutex_t lock; 117 pthread_cond_t cond; 131 118 }; 132 119 133 120 static inline void ?{}(__bin_sem_t & this) with( this ) { 134 counter = 0;121 signaled = false; 135 122 pthread_mutex_init(&lock, NULL); 136 123 pthread_cond_init (&cond, NULL); … … 145 132 verify(__cfaabi_dbg_in_kernel()); 146 133 pthread_mutex_lock(&lock); 147 if(counter != 0) { // this must be a loop, not if!148 pthread_cond_wait(&cond, &lock);149 }150 counter = 1;134 if(!signaled) { // this must be a loop, not if! 135 pthread_cond_wait(&cond, &lock); 136 } 137 signaled = false; 151 138 pthread_mutex_unlock(&lock); 152 139 } … … 154 141 static inline void post(__bin_sem_t & this) with( this ) { 155 142 verify(__cfaabi_dbg_in_kernel()); 143 156 144 pthread_mutex_lock(&lock); 157 bool needs_signal = counter == 0;158 counter = 1;145 bool needs_signal = !signaled; 146 signaled = true; 159 147 pthread_mutex_unlock(&lock); 160 if (!needs_signal) 148 149 if (needs_signal) 161 150 pthread_cond_signal(&cond); 162 151 } 163 152 #endif -
libcfa/src/bits/signal.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // bits/signal.h -- Helper functions and defines to use signals7 // bits/signal.hfa -- Helper functions and defines to use signals 8 8 // 9 9 // Author : Thierry Delisle … … 16 16 #pragma once 17 17 18 #include "bits/debug.h "19 #include "bits/defs.h "18 #include "bits/debug.hfa" 19 #include "bits/defs.hfa" 20 20 21 21 extern "C" { -
libcfa/src/concurrency/CtxSwitch-i386.S
r7951100 rb067d9b 41 41 #define PC_OFFSET ( 2 * PTR_BYTE ) 42 42 43 .text43 .text 44 44 .align 2 45 .globl CtxSwitch 45 .globl CtxSwitch 46 .type CtxSwitch, @function 46 47 CtxSwitch: 47 48 … … 50 51 51 52 movl 4(%esp),%eax 52 53 // Save floating & SSE control words on the stack.54 55 sub $8,%esp56 stmxcsr 0(%esp) // 4 bytes57 fnstcw 4(%esp) // 2 bytes58 53 59 54 // Save volatile registers on the stack. … … 67 62 movl %esp,SP_OFFSET(%eax) 68 63 movl %ebp,FP_OFFSET(%eax) 69 // movl 4(%ebp),%ebx // save previous eip for debugger70 // movl %ebx,PC_OFFSET(%eax)71 64 72 65 // Copy the "to" context argument from the stack to register eax … … 74 67 // argument is now at 8 + 12 = 20(%esp) 75 68 76 movl 2 8(%esp),%eax69 movl 20(%esp),%eax 77 70 78 71 // Load new context from the "to" area. … … 87 80 popl %ebx 88 81 89 // Load floating & SSE control words from the stack.90 91 fldcw 4(%esp)92 ldmxcsr 0(%esp)93 add $8,%esp94 95 82 // Return to thread. 96 83 97 84 ret 85 .size CtxSwitch, .-CtxSwitch 98 86 99 87 // Local Variables: // -
libcfa/src/concurrency/CtxSwitch-x86_64.S
r7951100 rb067d9b 39 39 #define SP_OFFSET ( 0 * PTR_BYTE ) 40 40 #define FP_OFFSET ( 1 * PTR_BYTE ) 41 #define PC_OFFSET ( 2 * PTR_BYTE )42 41 43 .text 42 //----------------------------------------------------------------------------- 43 // Regular context switch routine which enables switching from one context to anouther 44 .text 44 45 .align 2 45 .globl CtxSwitch 46 .globl CtxSwitch 47 .type CtxSwitch, @function 46 48 CtxSwitch: 47 48 // Save floating & SSE control words on the stack.49 50 subq $8,%rsp51 stmxcsr 0(%rsp) // 4 bytes52 fnstcw 4(%rsp) // 2 bytes53 49 54 50 // Save volatile registers on the stack. … … 78 74 popq %r15 79 75 80 // Load floating & SSE control words from the stack.81 82 fldcw 4(%rsp)83 ldmxcsr 0(%rsp)84 addq $8,%rsp85 86 76 // Return to thread. 87 77 88 78 ret 79 .size CtxSwitch, .-CtxSwitch 89 80 90 .text 81 //----------------------------------------------------------------------------- 82 // Stub used to create new stacks which are ready to be context switched to 83 .text 91 84 .align 2 92 .globl CtxInvokeStub 85 .globl CtxInvokeStub 86 .type CtxInvokeStub, @function 93 87 CtxInvokeStub: 94 88 movq %rbx, %rdi 95 89 jmp *%r12 90 .size CtxInvokeStub, .-CtxInvokeStub 96 91 97 92 // Local Variables: // -
libcfa/src/concurrency/alarm.cfa
r7951100 rb067d9b 14 14 // 15 15 16 #define __cforall_thread__ 17 16 18 extern "C" { 17 19 #include <errno.h> … … 22 24 } 23 25 24 #include "alarm.h "25 #include "kernel_private.h "26 #include "preemption.h "26 #include "alarm.hfa" 27 #include "kernel_private.hfa" 28 #include "preemption.hfa" 27 29 28 30 //============================================================================================= -
libcfa/src/concurrency/alarm.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // alarm.h --7 // alarm.hfa -- 8 8 // 9 9 // Author : Thierry Delisle … … 21 21 #include <assert.h> 22 22 23 #include "time "23 #include "time.hfa" 24 24 25 25 struct thread_desc; -
libcfa/src/concurrency/coroutine.hfa
r7951100 rb067d9b 10 10 // Created On : Mon Nov 28 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 30 18:23:45 201813 // Update Count : 812 // Last Modified On : Fri Jun 21 17:49:39 2019 13 // Update Count : 9 14 14 // 15 15 … … 46 46 //----------------------------------------------------------------------------- 47 47 // Public coroutine API 48 static inline void suspend( );48 static inline void suspend(void); 49 49 50 50 forall(dtype T | is_coroutine(T)) 51 static inline voidresume(T & cor);51 static inline T & resume(T & cor); 52 52 53 53 forall(dtype T | is_coroutine(T)) 54 54 void prime(T & cor); 55 56 static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; } 55 57 56 58 //----------------------------------------------------------------------------- … … 64 66 forall(dtype T | is_coroutine(T)) 65 67 void CtxStart(T * this, void ( *invoke)(T *)); 68 69 extern void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc *) __attribute__ ((__noreturn__)); 70 71 extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch"); 66 72 } 67 73 68 74 // Private wrappers for context switch and stack creation 69 extern void CoroutineCtxSwitch(coroutine_desc * src, coroutine_desc * dst); 70 extern void create_stack( coStack_t * this, unsigned int storageSize ); 75 // Wrapper for co 76 static inline void CoroutineCtxSwitch(coroutine_desc* src, coroutine_desc* dst) { 77 // set state of current coroutine to inactive 78 src->state = src->state == Halted ? Halted : Inactive; 79 80 // set new coroutine that task is executing 81 TL_GET( this_thread )->curr_cor = dst; 82 83 // context switch to specified coroutine 84 verify( dst->context.SP ); 85 CtxSwitch( &src->context, &dst->context ); 86 // when CtxSwitch returns we are back in the src coroutine 87 88 // set state of new coroutine to active 89 src->state = Active; 90 91 if( unlikely(src->cancellation != NULL) ) { 92 _CtxCoroutine_Unwind(src->cancellation, src); 93 } 94 } 95 96 extern void __stack_prepare ( __stack_info_t * this, size_t size /* ignored if storage already allocated */); 71 97 72 98 // Suspend implementation inlined for performance 73 static inline void suspend( ) {99 static inline void suspend(void) { 74 100 // optimization : read TLS once and reuse it 75 101 // Safety note: this is preemption safe since if … … 77 103 // will also migrate which means this value will 78 104 // stay in syn with the TLS 79 coroutine_desc * src = TL_GET( this_ coroutine );105 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 80 106 81 107 assertf( src->last != 0, … … 93 119 // Resume implementation inlined for performance 94 120 forall(dtype T | is_coroutine(T)) 95 static inline voidresume(T & cor) {121 static inline T & resume(T & cor) { 96 122 // optimization : read TLS once and reuse it 97 123 // Safety note: this is preemption safe since if … … 99 125 // will also migrate which means this value will 100 126 // stay in syn with the TLS 101 coroutine_desc * src = TL_GET( this_ coroutine );127 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 102 128 coroutine_desc * dst = get_coroutine(cor); 103 129 104 if( unlikely( !dst->stack.base) ) {105 create_stack(&dst->stack, dst->stack.size);130 if( unlikely(dst->context.SP == NULL) ) { 131 __stack_prepare(&dst->stack, 65000); 106 132 CtxStart(&cor, CtxInvokeCoroutine); 107 133 } … … 121 147 // always done for performance testing 122 148 CoroutineCtxSwitch( src, dst ); 149 150 return cor; 123 151 } 124 152 … … 129 157 // will also migrate which means this value will 130 158 // stay in syn with the TLS 131 coroutine_desc * src = TL_GET( this_ coroutine );159 coroutine_desc * src = TL_GET( this_thread )->curr_cor; 132 160 133 161 // not resuming self ? -
libcfa/src/concurrency/invoke.c
r7951100 rb067d9b 14 14 // 15 15 16 #define __cforall_thread__ 17 16 18 #include <stdbool.h> 17 19 #include <stdlib.h> 18 20 #include <stdio.h> 21 #include <unwind.h> 19 22 20 23 #include "invoke.h" … … 27 30 28 31 extern void __suspend_internal(void); 29 extern void __leave_coroutine( void);30 extern void __finish_creation( void);32 extern void __leave_coroutine( struct coroutine_desc * ); 33 extern void __finish_creation( struct thread_desc * ); 31 34 extern void __leave_thread_monitor( struct thread_desc * this ); 32 extern void disable_interrupts() ;35 extern void disable_interrupts() OPTIONAL_THREAD; 33 36 extern void enable_interrupts( __cfaabi_dbg_ctx_param ); 34 37 … … 46 49 cor->state = Active; 47 50 48 enable_interrupts( __cfaabi_dbg_ctx );49 50 51 main( this ); 51 52 52 cor->state = Halted; 53 //Final suspend, should never return 54 __leave_coroutine( cor ); 55 __cabi_abort( "Resumed dead coroutine" ); 56 } 53 57 54 //Final suspend, should never return 55 __leave_coroutine(); 56 __cabi_abort( "Resumed dead coroutine" ); 58 static _Unwind_Reason_Code _CtxCoroutine_UnwindStop( 59 __attribute((__unused__)) int version, 60 _Unwind_Action actions, 61 __attribute((__unused__)) _Unwind_Exception_Class exceptionClass, 62 __attribute((__unused__)) struct _Unwind_Exception * unwind_exception, 63 __attribute((__unused__)) struct _Unwind_Context * context, 64 void * param 65 ) { 66 if( actions & _UA_END_OF_STACK ) { 67 // We finished unwinding the coroutine, 68 // leave it 69 __leave_coroutine( param ); 70 __cabi_abort( "Resumed dead coroutine" ); 71 } 72 if( actions & _UA_CLEANUP_PHASE ) return _URC_NO_REASON; 73 74 return _URC_FATAL_PHASE2_ERROR; 75 } 76 77 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__)); 78 void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) { 79 _Unwind_Reason_Code ret = _Unwind_ForcedUnwind( storage, _CtxCoroutine_UnwindStop, cor ); 80 printf("UNWIND ERROR %d after force unwind\n", ret); 81 abort(); 57 82 } 58 83 … … 63 88 void *this 64 89 ) { 90 // Fetch the thread handle from the user defined thread structure 91 struct thread_desc* thrd = get_thread( this ); 92 65 93 // First suspend, once the thread arrives here, 66 94 // the function pointer to main can be invalidated without risk 67 __finish_creation(); 68 69 // Fetch the thread handle from the user defined thread structure 70 struct thread_desc* thrd = get_thread( this ); 71 thrd->self_cor.last = NULL; 95 __finish_creation( thrd ); 72 96 73 97 // Officially start the thread by enabling preemption … … 95 119 void (*invoke)(void *) 96 120 ) { 97 struct coStack_t* stack = &get_coroutine( this )->stack; 121 struct coroutine_desc * cor = get_coroutine( this ); 122 struct __stack_t * stack = cor->stack.storage; 98 123 99 124 #if defined( __i386 ) 100 125 101 126 struct FakeStack { 102 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 103 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls) 104 uint16_t fcw; // X97 FPU control word (preserved across function calls) 127 void *fixedRegisters[3]; // fixed registers ebx, edi, esi (popped on 1st uSwitch, values unimportant) 105 128 void *rturn; // where to go on return from uSwitch 106 void *dummyReturn; 107 void *argument[3]; 108 void *padding; 129 void *dummyReturn; // fake return compiler would have pushed on call to uInvoke 130 void *argument[3]; // for 16-byte ABI, 16-byte alignment starts here 131 void *padding; // padding to force 16-byte alignment, as "base" is 16-byte aligned 109 132 }; 110 133 111 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );112 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp134 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 135 cor->context.FP = NULL; // terminate stack with NULL fp 113 136 114 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;115 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->argument[0] = this; // argument to invoke 116 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = invoke;117 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520118 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7137 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 138 139 fs->dummyReturn = NULL; 140 fs->argument[0] = this; // argument to invoke 141 fs->rturn = invoke; 119 142 120 143 #elif defined( __x86_64 ) … … 122 145 struct FakeStack { 123 146 void *fixedRegisters[5]; // fixed registers rbx, r12, r13, r14, r15 124 uint32_t mxcr; // SSE Status and Control bits (control bits are preserved across function calls)125 uint16_t fcw; // X97 FPU control word (preserved across function calls)126 147 void *rturn; // where to go on return from uSwitch 127 148 void *dummyReturn; // NULL return address to provide proper alignment 128 149 }; 129 150 130 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );131 ((struct machine_context_t *)stack->context)->FP = NULL; // terminate stack with NULL fp151 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 152 cor->context.FP = NULL; // terminate stack with NULL fp 132 153 133 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->dummyReturn = NULL;134 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->rturn = CtxInvokeStub; 135 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[0] = this;136 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fixedRegisters[1] = invoke;137 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->mxcr = 0x1F80; //Vol. 2A 3-520138 ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F; //Vol. 1 8-7154 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 155 156 fs->dummyReturn = NULL; 157 fs->rturn = CtxInvokeStub; 158 fs->fixedRegisters[0] = this; 159 fs->fixedRegisters[1] = invoke; 139 160 140 161 #elif defined( __ARM_ARCH ) … … 146 167 }; 147 168 148 ((struct machine_context_t *)stack->context)->SP = (char *)stack->base - sizeof( struct FakeStack );149 ((struct machine_context_t *)stack->context)->FP = NULL;169 cor->context.SP = (char *)stack->base - sizeof( struct FakeStack ); 170 cor->context.FP = NULL; 150 171 151 struct FakeStack *fs = (struct FakeStack *) ((struct machine_context_t *)stack->context)->SP;172 struct FakeStack *fs = (struct FakeStack *)cor->context.SP; 152 173 153 174 fs->intRegs[8] = CtxInvokeStub; -
libcfa/src/concurrency/invoke.h
r7951100 rb067d9b 10 10 // Created On : Tue Jan 17 12:27:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat May 19 08:23:21 201813 // Update Count : 3114 // 15 16 #include "bits/containers.h "17 #include "bits/defs.h "18 #include "bits/locks.h "12 // Last Modified On : Sat Jun 22 18:19:13 2019 13 // Update Count : 40 14 // 15 16 #include "bits/containers.hfa" 17 #include "bits/defs.hfa" 18 #include "bits/locks.hfa" 19 19 20 20 #ifdef __cforall … … 46 46 #ifdef __cforall 47 47 extern "Cforall" { 48 static inline struct thread_desc * & get_next( struct thread_desc & this );49 static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );50 51 48 extern thread_local struct KernelThreadData { 52 struct coroutine_desc * volatile this_coroutine;53 49 struct thread_desc * volatile this_thread; 54 50 struct processor * volatile this_processor; … … 59 55 volatile bool in_progress; 60 56 } preemption_state; 61 } kernelTLS ;57 } kernelTLS __attribute__ ((tls_model ( "initial-exec" ))); 62 58 } 63 64 static inline struct coroutine_desc * volatile active_coroutine() { return TL_GET( this_coroutine ); }65 static inline struct thread_desc * volatile active_thread () { return TL_GET( this_thread ); }66 static inline struct processor * volatile active_processor() { return TL_GET( this_processor ); } // UNSAFE67 59 #endif 68 60 69 struct coStack_t { 70 size_t size; // size of stack 71 void * storage; // pointer to stack 72 void * limit; // stack grows towards stack limit 73 void * base; // base of stack 74 void * context; // address of cfa_context_t 75 void * top; // address of top of storage 76 bool userStack; // whether or not the user allocated the stack 61 struct __stack_context_t { 62 void * SP; 63 void * FP; 64 }; 65 66 // low adresses : +----------------------+ <- start of allocation 67 // | optional guard page | 68 // +----------------------+ <- __stack_t.limit 69 // | | 70 // | /\ /\ /\ | 71 // | || || || | 72 // | | 73 // | program stack | 74 // | | 75 // __stack_info_t.storage -> +----------------------+ <- __stack_t.base 76 // | __stack_t | 77 // high adresses : +----------------------+ <- end of allocation 78 79 struct __stack_t { 80 // stack grows towards stack limit 81 void * limit; 82 83 // base of stack 84 void * base; 85 }; 86 87 struct __stack_info_t { 88 // pointer to stack 89 struct __stack_t * storage; 77 90 }; 78 91 … … 80 93 81 94 struct coroutine_desc { 82 struct coStack_t stack; // stack information of the coroutine 83 const char * name; // textual name for coroutine/task, initialized by uC++ generated code 84 int errno_; // copy of global UNIX variable errno 85 enum coroutine_state state; // current execution status for coroutine 86 struct coroutine_desc * starter; // first coroutine to resume this one 87 struct coroutine_desc * last; // last coroutine to resume this one 88 }; 89 95 // context that is switch during a CtxSwitch 96 struct __stack_context_t context; 97 98 // stack information of the coroutine 99 struct __stack_info_t stack; 100 101 // textual name for coroutine/task 102 const char * name; 103 104 // current execution status for coroutine 105 enum coroutine_state state; 106 107 // first coroutine to resume this one 108 struct coroutine_desc * starter; 109 110 // last coroutine to resume this one 111 struct coroutine_desc * last; 112 113 // If non-null stack must be unwound with this exception 114 struct _Unwind_Exception * cancellation; 115 116 }; 117 118 // struct which calls the monitor is accepting 90 119 struct __waitfor_mask_t { 91 120 // the index of the accepted function, -1 if none … … 93 122 94 123 // list of acceptable functions, null if any 95 __ small_array_t(struct __acceptable_t) __cfa_anonymous_object;124 __cfa_anonymous_object( __small_array_t(struct __acceptable_t) ); 96 125 }; 97 126 … … 121 150 struct __monitor_group_t { 122 151 // currently held monitors 123 __ small_array_t(monitor_desc*) __cfa_anonymous_object;152 __cfa_anonymous_object( __small_array_t(monitor_desc*) ); 124 153 125 154 // last function that acquired monitors … … 129 158 struct thread_desc { 130 159 // Core threading fields 160 // context that is switch during a CtxSwitch 161 struct __stack_context_t context; 162 163 // current execution status for coroutine 164 enum coroutine_state state; 165 166 //SKULLDUGGERY errno is not save in the thread data structure because returnToKernel appears to be the only function to require saving and restoring it 167 131 168 // coroutine body used to store context 132 169 struct coroutine_desc self_cor; … … 155 192 struct thread_desc * prev; 156 193 } node; 157 158 159 160 161 static inline thread_desc * 194 }; 195 196 #ifdef __cforall 197 extern "Cforall" { 198 static inline thread_desc *& get_next( thread_desc & this ) { 162 199 return this.next; 163 200 } … … 166 203 return this.node.[next, prev]; 167 204 } 168 169 static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );170 205 171 206 static inline void ?{}(__monitor_group_t & this) { … … 216 251 // assembler routines that performs the context switch 217 252 extern void CtxInvokeStub( void ); 218 void CtxSwitch( void * from, void * to ) asm ("CtxSwitch"); 219 220 #if defined( __i386 ) 221 #define CtxGet( ctx ) __asm__ ( \ 222 "movl %%esp,%0\n" \ 223 "movl %%ebp,%1\n" \ 224 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 225 #elif defined( __x86_64 ) 226 #define CtxGet( ctx ) __asm__ ( \ 227 "movq %%rsp,%0\n" \ 228 "movq %%rbp,%1\n" \ 229 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 230 #elif defined( __ARM_ARCH ) 231 #define CtxGet( ctx ) __asm__ ( \ 232 "mov %0,%%sp\n" \ 233 "mov %1,%%r11\n" \ 234 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 235 #else 236 #error unknown hardware architecture 237 #endif 253 extern void CtxSwitch( struct __stack_context_t * from, struct __stack_context_t * to ) asm ("CtxSwitch"); 254 // void CtxStore ( void * this ) asm ("CtxStore"); 255 // void CtxRet ( void * dst ) asm ("CtxRet"); 238 256 239 257 #endif //_INVOKE_PRIVATE_H_ -
libcfa/src/concurrency/kernel.cfa
r7951100 rb067d9b 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 9 16:11:46 201813 // Update Count : 2 412 // Last Modified On : Thu Jun 20 17:21:23 2019 13 // Update Count : 25 14 14 // 15 16 #define __cforall_thread__ 15 17 16 18 //C Includes … … 27 29 28 30 //CFA Includes 29 #include "time "30 #include "kernel_private.h "31 #include "preemption.h "32 #include "startup.h "31 #include "time.hfa" 32 #include "kernel_private.hfa" 33 #include "preemption.hfa" 34 #include "startup.hfa" 33 35 34 36 //Private includes … … 36 38 #include "invoke.h" 37 39 40 //----------------------------------------------------------------------------- 41 // Some assembly required 42 #if defined( __i386 ) 43 #define CtxGet( ctx ) \ 44 __asm__ volatile ( \ 45 "movl %%esp,%0\n"\ 46 "movl %%ebp,%1\n"\ 47 : "=rm" (ctx.SP),\ 48 "=rm" (ctx.FP) \ 49 ) 50 51 // mxcr : SSE Status and Control bits (control bits are preserved across function calls) 52 // fcw : X87 FPU control word (preserved across function calls) 53 #define __x87_store \ 54 uint32_t __mxcr; \ 55 uint16_t __fcw; \ 56 __asm__ volatile ( \ 57 "stmxcsr %0\n" \ 58 "fnstcw %1\n" \ 59 : "=m" (__mxcr),\ 60 "=m" (__fcw) \ 61 ) 62 63 #define __x87_load \ 64 __asm__ volatile ( \ 65 "fldcw %1\n" \ 66 "ldmxcsr %0\n" \ 67 ::"m" (__mxcr),\ 68 "m" (__fcw) \ 69 ) 70 71 #elif defined( __x86_64 ) 72 #define CtxGet( ctx ) \ 73 __asm__ volatile ( \ 74 "movq %%rsp,%0\n"\ 75 "movq %%rbp,%1\n"\ 76 : "=rm" (ctx.SP),\ 77 "=rm" (ctx.FP) \ 78 ) 79 80 #define __x87_store \ 81 uint32_t __mxcr; \ 82 uint16_t __fcw; \ 83 __asm__ volatile ( \ 84 "stmxcsr %0\n" \ 85 "fnstcw %1\n" \ 86 : "=m" (__mxcr),\ 87 "=m" (__fcw) \ 88 ) 89 90 #define __x87_load \ 91 __asm__ volatile ( \ 92 "fldcw %1\n" \ 93 "ldmxcsr %0\n" \ 94 :: "m" (__mxcr),\ 95 "m" (__fcw) \ 96 ) 97 98 99 #elif defined( __ARM_ARCH ) 100 #define CtxGet( ctx ) __asm__ ( \ 101 "mov %0,%%sp\n" \ 102 "mov %1,%%r11\n" \ 103 : "=rm" (ctx.SP), "=rm" (ctx.FP) ) 104 #else 105 #error unknown hardware architecture 106 #endif 107 108 //----------------------------------------------------------------------------- 38 109 //Start and stop routine for the kernel, declared first to make sure they run first 39 void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));40 void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));110 static void kernel_startup(void) __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) )); 111 static void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) )); 41 112 42 113 //----------------------------------------------------------------------------- 43 114 // Kernel storage 44 KERNEL_STORAGE(cluster, 45 KERNEL_STORAGE(processor, 46 KERNEL_STORAGE(thread_desc, 47 KERNEL_STORAGE( machine_context_t,mainThreadCtx);115 KERNEL_STORAGE(cluster, mainCluster); 116 KERNEL_STORAGE(processor, mainProcessor); 117 KERNEL_STORAGE(thread_desc, mainThread); 118 KERNEL_STORAGE(__stack_t, mainThreadCtx); 48 119 49 120 cluster * mainCluster; … … 55 126 } 56 127 128 size_t __page_size = 0; 129 57 130 //----------------------------------------------------------------------------- 58 131 // Global state 59 thread_local struct KernelThreadData kernelTLS = { 60 NULL, 132 thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) = { 61 133 NULL, 62 134 NULL, … … 67 139 // Struct to steal stack 68 140 struct current_stack_info_t { 69 machine_context_t ctx; 70 unsigned int size; // size of stack 141 __stack_t * storage; // pointer to stack object 71 142 void *base; // base of stack 72 void *storage; // pointer to stack73 143 void *limit; // stack grows towards stack limit 74 144 void *context; // address of cfa_context_t 75 void *top; // address of top of storage76 145 }; 77 146 78 147 void ?{}( current_stack_info_t & this ) { 79 CtxGet( this.ctx );80 this.base = this.ctx.FP;81 this. storage = this.ctx.SP;148 __stack_context_t ctx; 149 CtxGet( ctx ); 150 this.base = ctx.FP; 82 151 83 152 rlimit r; 84 153 getrlimit( RLIMIT_STACK, &r); 85 this.size = r.rlim_cur;86 87 this.limit = (void *)(((intptr_t)this.base) - this.size);154 size_t size = r.rlim_cur; 155 156 this.limit = (void *)(((intptr_t)this.base) - size); 88 157 this.context = &storage_mainThreadCtx; 89 this.top = this.base;90 158 } 91 159 92 160 //----------------------------------------------------------------------------- 93 161 // Main thread construction 94 void ?{}( coStack_t & this, current_stack_info_t * info) with( this ) {95 size = info->size;96 storage = info->storage;97 limit = info->limit;98 base = info->base;99 context = info->context;100 top = info->top;101 userStack = true;102 }103 162 104 163 void ?{}( coroutine_desc & this, current_stack_info_t * info) with( this ) { 105 stack{ info }; 164 stack.storage = info->storage; 165 with(*stack.storage) { 166 limit = info->limit; 167 base = info->base; 168 } 169 __attribute__((may_alias)) intptr_t * istorage = (intptr_t*) &stack.storage; 170 *istorage |= 0x1; 106 171 name = "Main Thread"; 107 errno_ = 0;108 172 state = Start; 109 173 starter = NULL; 174 last = NULL; 175 cancellation = NULL; 110 176 } 111 177 112 178 void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) { 179 state = Start; 113 180 self_cor{ info }; 114 181 curr_cor = &self_cor; … … 133 200 134 201 // Construct the processor context of non-main processors 135 void ?{}(processorCtx_t & this, processor * proc, current_stack_info_t * info) {202 static void ?{}(processorCtx_t & this, processor * proc, current_stack_info_t * info) { 136 203 (this.__cor){ info }; 137 204 this.proc = proc; 138 205 } 139 206 207 static void start(processor * this); 140 208 void ?{}(processor & this, const char * name, cluster & cltr) with( this ) { 141 209 this.name = name; … … 147 215 runner.proc = &this; 148 216 149 sem_init(&idleLock, 0, 0);217 idleLock{}; 150 218 151 219 start( &this ); … … 155 223 if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) { 156 224 __cfaabi_dbg_print_safe("Kernel : core %p signaling termination\n", &this); 157 terminate(&this); 158 verify( __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 159 verify( kernelTLS.this_processor != &this); 225 226 __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED); 227 wake( &this ); 228 160 229 P( terminated ); 161 230 verify( kernelTLS.this_processor != &this); 162 pthread_join( kernel_thread, NULL ); 163 } 164 165 sem_destroy(&idleLock); 231 } 232 233 pthread_join( kernel_thread, NULL ); 166 234 } 167 235 … … 186 254 // Kernel Scheduling logic 187 255 //============================================================================================= 256 static void runThread(processor * this, thread_desc * dst); 257 static void finishRunning(processor * this); 258 static void halt(processor * this); 259 188 260 //Main of the processor contexts 189 261 void main(processorCtx_t & runner) { … … 236 308 } 237 309 310 static int * __volatile_errno() __attribute__((noinline)); 311 static int * __volatile_errno() { asm(""); return &errno; } 312 238 313 // KERNEL ONLY 239 314 // runThread runs a thread by context switching 240 315 // from the processor coroutine to the target thread 241 void runThread(processor * this, thread_desc * dst) { 242 assert(dst->curr_cor); 316 static void runThread(processor * this, thread_desc * thrd_dst) { 243 317 coroutine_desc * proc_cor = get_coroutine(this->runner); 244 coroutine_desc * thrd_cor = dst->curr_cor;245 318 246 319 // Reset the terminating actions here … … 248 321 249 322 // Update global state 250 kernelTLS.this_thread = dst; 251 252 // Context Switch to the thread 253 ThreadCtxSwitch(proc_cor, thrd_cor); 254 // when ThreadCtxSwitch returns we are back in the processor coroutine 323 kernelTLS.this_thread = thrd_dst; 324 325 // set state of processor coroutine to inactive and the thread to active 326 proc_cor->state = proc_cor->state == Halted ? Halted : Inactive; 327 thrd_dst->state = Active; 328 329 // set context switch to the thread that the processor is executing 330 verify( thrd_dst->context.SP ); 331 CtxSwitch( &proc_cor->context, &thrd_dst->context ); 332 // when CtxSwitch returns we are back in the processor coroutine 333 334 // set state of processor coroutine to active and the thread to inactive 335 thrd_dst->state = thrd_dst->state == Halted ? Halted : Inactive; 336 proc_cor->state = Active; 255 337 } 256 338 257 339 // KERNEL_ONLY 258 void returnToKernel() {340 static void returnToKernel() { 259 341 coroutine_desc * proc_cor = get_coroutine(kernelTLS.this_processor->runner); 260 coroutine_desc * thrd_cor = kernelTLS.this_thread->curr_cor = kernelTLS.this_coroutine; 261 ThreadCtxSwitch(thrd_cor, proc_cor); 342 thread_desc * thrd_src = kernelTLS.this_thread; 343 344 // set state of current coroutine to inactive 345 thrd_src->state = thrd_src->state == Halted ? Halted : Inactive; 346 proc_cor->state = Active; 347 int local_errno = *__volatile_errno(); 348 #if defined( __i386 ) || defined( __x86_64 ) 349 __x87_store; 350 #endif 351 352 // set new coroutine that the processor is executing 353 // and context switch to it 354 verify( proc_cor->context.SP ); 355 CtxSwitch( &thrd_src->context, &proc_cor->context ); 356 357 // set state of new coroutine to active 358 proc_cor->state = proc_cor->state == Halted ? Halted : Inactive; 359 thrd_src->state = Active; 360 361 #if defined( __i386 ) || defined( __x86_64 ) 362 __x87_load; 363 #endif 364 *__volatile_errno() = local_errno; 262 365 } 263 366 … … 265 368 // Once a thread has finished running, some of 266 369 // its final actions must be executed from the kernel 267 void finishRunning(processor * this) with( this->finish ) {370 static void finishRunning(processor * this) with( this->finish ) { 268 371 verify( ! kernelTLS.preemption_state.enabled ); 269 372 choose( action_code ) { … … 295 398 } 296 399 297 // Handles spinning logic298 // TODO : find some strategy to put cores to sleep after some time299 void spin(processor * this, unsigned int * spin_count) {300 // (*spin_count)++;301 halt(this);302 }303 304 400 // KERNEL_ONLY 305 401 // Context invoker for processors 306 402 // This is the entry point for processors (kernel threads) 307 403 // It effectively constructs a coroutine by stealing the pthread stack 308 void * CtxInvokeProcessor(void * arg) {404 static void * CtxInvokeProcessor(void * arg) { 309 405 processor * proc = (processor *) arg; 310 406 kernelTLS.this_processor = proc; 311 kernelTLS.this_coroutine = NULL;312 407 kernelTLS.this_thread = NULL; 313 408 kernelTLS.preemption_state.[enabled, disable_count] = [false, 1]; … … 316 411 // to waste the perfectly valid stack create by pthread. 317 412 current_stack_info_t info; 318 machine_context_t ctx;319 info. context= &ctx;413 __stack_t ctx; 414 info.storage = &ctx; 320 415 (proc->runner){ proc, &info }; 321 416 322 __cfaabi_dbg_print_safe("Coroutine : created stack %p\n", get_coroutine(proc->runner)->stack. base);417 __cfaabi_dbg_print_safe("Coroutine : created stack %p\n", get_coroutine(proc->runner)->stack.storage); 323 418 324 419 //Set global state 325 kernelTLS.this_coroutine = get_coroutine(proc->runner);326 420 kernelTLS.this_thread = NULL; 327 421 … … 343 437 } 344 438 345 void start(processor * this) {439 static void start(processor * this) { 346 440 __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this); 347 441 … … 352 446 353 447 // KERNEL_ONLY 354 void kernel_first_resume( processor * this) {355 coroutine_desc * src = kernelTLS.this_coroutine;448 void kernel_first_resume( processor * this ) { 449 thread_desc * src = mainThread; 356 450 coroutine_desc * dst = get_coroutine(this->runner); 357 451 358 452 verify( ! kernelTLS.preemption_state.enabled ); 359 453 360 create_stack(&dst->stack, dst->stack.size);454 __stack_prepare( &dst->stack, 65000 ); 361 455 CtxStart(&this->runner, CtxInvokeCoroutine); 362 456 363 457 verify( ! kernelTLS.preemption_state.enabled ); 364 458 365 dst->last = src;366 dst->starter = dst->starter ? dst->starter : src;459 dst->last = &src->self_cor; 460 dst->starter = dst->starter ? dst->starter : &src->self_cor; 367 461 368 462 // set state of current coroutine to inactive 369 463 src->state = src->state == Halted ? Halted : Inactive; 370 464 371 // set new coroutine that task is executing372 kernelTLS.this_coroutine = dst;373 374 // SKULLDUGGERY normally interrupts are enable before leaving a coroutine ctxswitch.375 // Therefore, when first creating a coroutine, interrupts are enable before calling the main.376 // This is consistent with thread creation. However, when creating the main processor coroutine,377 // we wan't interrupts to be disabled. Therefore, we double-disable interrupts here so they will378 // stay disabled.379 disable_interrupts();380 381 465 // context switch to specified coroutine 382 assert( src->stack.context);383 CtxSwitch( src->stack.context, dst->stack.context );466 verify( dst->context.SP ); 467 CtxSwitch( &src->context, &dst->context ); 384 468 // when CtxSwitch returns we are back in the src coroutine 385 469 … … 388 472 389 473 verify( ! kernelTLS.preemption_state.enabled ); 474 } 475 476 // KERNEL_ONLY 477 void kernel_last_resume( processor * this ) { 478 coroutine_desc * src = &mainThread->self_cor; 479 coroutine_desc * dst = get_coroutine(this->runner); 480 481 verify( ! kernelTLS.preemption_state.enabled ); 482 verify( dst->starter == src ); 483 verify( dst->context.SP ); 484 485 // context switch to the processor 486 CtxSwitch( &src->context, &dst->context ); 390 487 } 391 488 … … 396 493 void ScheduleThread( thread_desc * thrd ) { 397 494 verify( thrd ); 398 verify( thrd->s elf_cor.state != Halted );495 verify( thrd->state != Halted ); 399 496 400 497 verify( ! kernelTLS.preemption_state.enabled ); … … 408 505 unlock( ready_queue_lock ); 409 506 410 if( was_empty) {507 if(was_empty) { 411 508 lock (proc_list_lock __cfaabi_dbg_ctx2); 412 509 if(idles) { 413 wake (idles.head);510 wake_fast(idles.head); 414 511 } 415 512 unlock (proc_list_lock); 416 513 } 514 else if( struct processor * idle = idles.head ) { 515 wake_fast(idle); 516 } 517 417 518 } 418 519 … … 545 646 //----------------------------------------------------------------------------- 546 647 // Kernel boot procedures 547 void kernel_startup(void) {648 static void kernel_startup(void) { 548 649 verify( ! kernelTLS.preemption_state.enabled ); 549 650 __cfaabi_dbg_print_safe("Kernel : Starting\n"); 651 652 __page_size = sysconf( _SC_PAGESIZE ); 550 653 551 654 __cfa_dbg_global_clusters.list{ __get }; … … 563 666 mainThread = (thread_desc *)&storage_mainThread; 564 667 current_stack_info_t info; 668 info.storage = (__stack_t*)&storage_mainThreadCtx; 565 669 (*mainThread){ &info }; 566 670 … … 597 701 kernelTLS.this_processor = mainProcessor; 598 702 kernelTLS.this_thread = mainThread; 599 kernelTLS.this_coroutine = &mainThread->self_cor;600 703 601 704 // Enable preemption … … 621 724 } 622 725 623 void kernel_shutdown(void) {726 static void kernel_shutdown(void) { 624 727 __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n"); 625 728 … … 632 735 // which is currently here 633 736 __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE); 634 returnToKernel();737 kernel_last_resume( kernelTLS.this_processor ); 635 738 mainThread->self_cor.state = Halted; 636 739 … … 658 761 // Kernel Quiescing 659 762 //============================================================================================= 660 661 void halt(processor * this) with( *this ) { 662 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 763 static void halt(processor * this) with( *this ) { 764 // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 663 765 664 766 with( *cltr ) { … … 671 773 __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this); 672 774 673 // #ifdef __CFA_WITH_VERIFY__ 674 // int sval = 0; 675 // sem_getvalue(&this->idleLock, &sval); 676 // verifyf(sval < 200, "Binary semaphore reached value %d : \n", sval); 677 // #endif 678 679 verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) ); 680 int __attribute__((unused)) ret = sem_wait(&idleLock); 681 // verifyf(ret >= 0 || errno == EINTR, "Sem_wait returned %d (errno %d : %s\n", ret, errno, strerror(errno)); 682 683 // wait( idleLock ); 775 wait( idleLock ); 684 776 685 777 __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this); … … 693 785 } 694 786 695 void wake(processor * this) {696 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);697 int __attribute__((unused)) ret = sem_post(&this->idleLock);698 // verifyf(ret >= 0 || errno == EINTR, "Sem_post returned %d (errno %d : %s\n", ret, errno, strerror(errno));699 700 // #ifdef __CFA_WITH_VERIFY__701 // int sval = 0;702 // sem_getvalue(&this->idleLock, &sval);703 // verifyf(sval < 200, "Binary semaphore reached value %d\n", sval);704 // #endif705 706 // post( this->idleLock );707 }708 709 787 //============================================================================================= 710 788 // Unexpected Terminating logic 711 789 //============================================================================================= 712 713 714 790 static __spinlock_t kernel_abort_lock; 715 791 static bool kernel_abort_called = false; … … 745 821 __cfaabi_dbg_bits_write( abort_text, len ); 746 822 747 if ( get_coroutine(thrd) != kernelTLS.this_coroutine) {748 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", kernelTLS.this_coroutine->name, kernelTLS.this_coroutine);823 if ( &thrd->self_cor != thrd->curr_cor ) { 824 len = snprintf( abort_text, abort_text_size, " in coroutine %.256s (%p).\n", thrd->curr_cor->name, thrd->curr_cor ); 749 825 __cfaabi_dbg_bits_write( abort_text, len ); 750 826 } … … 833 909 void doregister( cluster * cltr, thread_desc & thrd ) { 834 910 lock (cltr->thread_list_lock __cfaabi_dbg_ctx2); 911 cltr->nthreads += 1; 835 912 push_front(cltr->threads, thrd); 836 913 unlock (cltr->thread_list_lock); … … 840 917 lock (cltr->thread_list_lock __cfaabi_dbg_ctx2); 841 918 remove(cltr->threads, thrd ); 919 cltr->nthreads -= 1; 842 920 unlock(cltr->thread_list_lock); 843 921 } … … 845 923 void doregister( cluster * cltr, processor * proc ) { 846 924 lock (cltr->proc_list_lock __cfaabi_dbg_ctx2); 925 cltr->nprocessors += 1; 847 926 push_front(cltr->procs, *proc); 848 927 unlock (cltr->proc_list_lock); … … 852 931 lock (cltr->proc_list_lock __cfaabi_dbg_ctx2); 853 932 remove(cltr->procs, *proc ); 933 cltr->nprocessors -= 1; 854 934 unlock(cltr->proc_list_lock); 855 935 } … … 858 938 // Debug 859 939 __cfaabi_dbg_debug_do( 860 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) { 861 this.prev_name = prev_name; 862 this.prev_thrd = kernelTLS.this_thread; 940 extern "C" { 941 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name) { 942 this.prev_name = prev_name; 943 this.prev_thrd = kernelTLS.this_thread; 944 } 863 945 } 864 946 ) 947 948 //----------------------------------------------------------------------------- 949 // Debug 950 bool threading_enabled(void) { 951 return true; 952 } 865 953 // Local Variables: // 866 954 // mode: c // -
libcfa/src/concurrency/kernel.hfa
r7951100 rb067d9b 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 10 14:46:49 201813 // Update Count : 1 012 // Last Modified On : Sat Jun 22 11:39:17 2019 13 // Update Count : 16 14 14 // 15 15 … … 19 19 20 20 #include "invoke.h" 21 #include "time_t.h "21 #include "time_t.hfa" 22 22 23 23 extern "C" { … … 91 91 this.lock = NULL; 92 92 } 93 static inline void ^?{}(FinishAction & this) {}93 static inline void ^?{}(FinishAction &) {} 94 94 95 95 // Processor … … 113 113 pthread_t kernel_thread; 114 114 115 // RunThread data 116 // Action to do after a thread is ran 117 struct FinishAction finish; 118 119 // Preemption data 120 // Node which is added in the discrete event simulaiton 121 struct alarm_node_t * preemption_alarm; 122 123 // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible 124 bool pending_preemption; 125 126 // Idle lock 127 __bin_sem_t idleLock; 128 115 129 // Termination 116 130 // Set to true to notify the processor should terminate … … 119 133 // Termination synchronisation 120 134 semaphore terminated; 121 122 // RunThread data123 // Action to do after a thread is ran124 struct FinishAction finish;125 126 // Preemption data127 // Node which is added in the discrete event simulaiton128 struct alarm_node_t * preemption_alarm;129 130 // If true, a preemption was triggered in an unsafe region, the processor must preempt as soon as possible131 bool pending_preemption;132 133 // Idle lock134 sem_t idleLock;135 // __bin_sem_t idleLock;136 135 137 136 // Link lists fields … … 177 176 __dllist_t(struct processor) procs; 178 177 __dllist_t(struct processor) idles; 179 180 // List of processors 178 unsigned int nprocessors; 179 180 // List of threads 181 181 __spinlock_t thread_list_lock; 182 182 __dllist_t(struct thread_desc) threads; 183 unsigned int nthreads; 183 184 184 185 // Link lists fields … … 201 202 } 202 203 204 static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE 205 static inline struct cluster * active_cluster () { return TL_GET( this_processor )->cltr; } 206 203 207 // Local Variables: // 204 208 // mode: c // -
libcfa/src/concurrency/kernel_private.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // kernel_private.h --7 // kernel_private.hfa -- 8 8 // 9 9 // Author : Thierry Delisle … … 16 16 #pragma once 17 17 18 #include "kernel "19 #include "thread "18 #include "kernel.hfa" 19 #include "thread.hfa" 20 20 21 #include "alarm.h "21 #include "alarm.hfa" 22 22 23 23 … … 26 26 27 27 extern "C" { 28 void disable_interrupts() ;28 void disable_interrupts() OPTIONAL_THREAD; 29 29 void enable_interrupts_noPoll(); 30 30 void enable_interrupts( __cfaabi_dbg_ctx_param ); … … 34 34 static inline void WakeThread( thread_desc * thrd ) { 35 35 if( !thrd ) return; 36 37 verify(thrd->state == Inactive); 36 38 37 39 disable_interrupts(); … … 54 56 // Processor 55 57 void main(processorCtx_t *); 56 void start(processor * this); 57 void runThread(processor * this, thread_desc * dst); 58 void finishRunning(processor * this); 59 void halt(processor * this); 60 void wake(processor * this); 61 void terminate(processor * this); 62 void spin(processor * this, unsigned int * spin_count); 58 59 static inline void wake_fast(processor * this) { 60 __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this); 61 post( this->idleLock ); 62 } 63 64 static inline void wake(processor * this) { 65 disable_interrupts(); 66 wake_fast(this); 67 enable_interrupts( __cfaabi_dbg_ctx ); 68 } 63 69 64 70 struct event_kernel_t { … … 69 75 extern event_kernel_t * event_kernel; 70 76 71 //extern thread_local coroutine_desc * volatile this_coroutine;72 //extern thread_local thread_desc * volatile this_thread;73 //extern thread_local processor * volatile this_processor;74 75 // extern volatile thread_local bool preemption_in_progress;76 // extern volatile thread_local bool preemption_enabled;77 // extern volatile thread_local unsigned short disable_preempt_count;78 79 77 struct __cfa_kernel_preemption_state_t { 80 78 bool enabled; … … 83 81 }; 84 82 85 extern volatile thread_local __cfa_kernel_preemption_state_t preemption_state ;83 extern volatile thread_local __cfa_kernel_preemption_state_t preemption_state __attribute__ ((tls_model ( "initial-exec" ))); 86 84 87 85 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/monitor.cfa
r7951100 rb067d9b 14 14 // 15 15 16 #include "monitor" 17 18 #include <stdlib> 16 #define __cforall_thread__ 17 18 #include "monitor.hfa" 19 20 #include <stdlib.hfa> 19 21 #include <inttypes.h> 20 22 21 #include "kernel_private.h "22 23 #include "bits/algorithm s.h"23 #include "kernel_private.hfa" 24 25 #include "bits/algorithm.hfa" 24 26 25 27 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/monitor.hfa
r7951100 rb067d9b 20 20 #include <assert.h> 21 21 #include "invoke.h" 22 #include "stdlib "22 #include "stdlib.hfa" 23 23 24 24 trait is_monitor(dtype T) { … … 138 138 139 139 struct __acceptable_t { 140 __monitor_group_t;140 inline struct __monitor_group_t; 141 141 bool is_dtor; 142 142 }; -
libcfa/src/concurrency/mutex.cfa
r7951100 rb067d9b 16 16 // 17 17 18 # include "mutex"18 #define __cforall_thread__ 19 19 20 #include "kernel_private.h" 20 #include "mutex.hfa" 21 22 #include "kernel_private.hfa" 21 23 22 24 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/mutex.hfa
r7951100 rb067d9b 20 20 #include <stdbool.h> 21 21 22 #include "bits/algorithm s.h"23 #include "bits/locks.h "22 #include "bits/algorithm.hfa" 23 #include "bits/locks.hfa" 24 24 25 25 #include "invoke.h" 26 #include "time_t.h "26 #include "time_t.hfa" 27 27 28 28 //----------------------------------------------------------------------------- -
libcfa/src/concurrency/preemption.cfa
r7951100 rb067d9b 14 14 // 15 15 16 #include "preemption.h" 16 #define __cforall_thread__ 17 18 #include "preemption.hfa" 17 19 #include <assert.h> 18 20 … … 24 26 } 25 27 26 #include "bits/signal.h "28 #include "bits/signal.hfa" 27 29 28 30 #if !defined(__CFA_DEFAULT_PREEMPTION__) … … 39 41 40 42 // FwdDeclarations : Signal handlers 41 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );42 void sigHandler_segv ( __CFA_SIGPARMS__ );43 void sigHandler_ill ( __CFA_SIGPARMS__ );44 void sigHandler_fpe ( __CFA_SIGPARMS__ );45 void sigHandler_abort ( __CFA_SIGPARMS__ );43 static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ); 44 static void sigHandler_segv ( __CFA_SIGPARMS__ ); 45 static void sigHandler_ill ( __CFA_SIGPARMS__ ); 46 static void sigHandler_fpe ( __CFA_SIGPARMS__ ); 47 static void sigHandler_abort ( __CFA_SIGPARMS__ ); 46 48 47 49 // FwdDeclarations : alarm thread main 48 void * alarm_loop( __attribute__((unused)) void * args );50 static void * alarm_loop( __attribute__((unused)) void * args ); 49 51 50 52 // Machine specific register name … … 63 65 static pthread_t alarm_thread; // pthread handle to alarm thread 64 66 65 void ?{}(event_kernel_t & this) with( this ) {67 static void ?{}(event_kernel_t & this) with( this ) { 66 68 alarms{}; 67 69 lock{}; … … 85 87 86 88 // Tick one frame of the Discrete Event Simulation for alarms 87 void tick_preemption() {89 static void tick_preemption() { 88 90 alarm_node_t * node = NULL; // Used in the while loop but cannot be declared in the while condition 89 91 alarm_list_t * alarms = &event_kernel->alarms; // Local copy for ease of reading … … 263 265 } 264 266 265 // kill wrapper : signal a processor266 void terminate(processor * this) {267 disable_interrupts();268 __atomic_store_n(&this->do_terminate, true, __ATOMIC_SEQ_CST);269 wake( this );270 sigval_t value = { PREEMPT_TERMINATE };271 enable_interrupts( __cfaabi_dbg_ctx );272 pthread_sigqueue( this->kernel_thread, SIGUSR1, value );273 }274 275 267 // reserved for future use 276 268 static void timeout( thread_desc * this ) { … … 360 352 // Context switch signal handler 361 353 // Receives SIGUSR1 signal and causes the current thread to yield 362 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {354 static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) { 363 355 __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); ) 364 356 … … 403 395 // Main of the alarm thread 404 396 // Waits on SIGALRM and send SIGUSR1 to whom ever needs it 405 void * alarm_loop( __attribute__((unused)) void * args ) {397 static void * alarm_loop( __attribute__((unused)) void * args ) { 406 398 // Block sigalrms to control when they arrive 407 399 sigset_t mask; -
libcfa/src/concurrency/preemption.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // preemption.h --7 // preemption.hfa -- 8 8 // 9 9 // Author : Thierry Delisle … … 16 16 #pragma once 17 17 18 #include "alarm.h "19 #include "kernel_private.h "18 #include "alarm.hfa" 19 #include "kernel_private.hfa" 20 20 21 21 void kernel_start_preemption(); 22 22 void kernel_stop_preemption(); 23 23 void update_preemption( processor * this, Duration duration ); 24 void tick_preemption();25 24 26 25 struct preemption_scope { -
libcfa/src/concurrency/thread.cfa
r7951100 rb067d9b 14 14 // 15 15 16 # include "thread"16 #define __cforall_thread__ 17 17 18 #include "kernel_private.h" 18 #include "thread.hfa" 19 20 #include "kernel_private.hfa" 19 21 20 22 #define __CFA_INVOKE_PRIVATE__ … … 31 33 // Thread ctors and dtors 32 34 void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) { 35 context{ NULL, NULL }; 33 36 self_cor{ name, storage, storageSize }; 34 verify(&self_cor);37 state = Start; 35 38 curr_cor = &self_cor; 36 39 self_mon.owner = &this; … … 73 76 forall( dtype T | is_thread(T) ) 74 77 void __thrd_start( T& this ) { 75 coroutine_desc* thrd_c = get_coroutine(this); 76 thread_desc * thrd_h = get_thread (this); 77 thrd_c->last = TL_GET( this_coroutine ); 78 79 // __cfaabi_dbg_print_safe("Thread start : %p (t %p, c %p)\n", this, thrd_c, thrd_h); 78 thread_desc * this_thrd = get_thread(this); 79 thread_desc * curr_thrd = TL_GET( this_thread ); 80 80 81 81 disable_interrupts(); 82 create_stack(&thrd_c->stack, thrd_c->stack.size);83 kernelTLS.this_coroutine = thrd_c;84 82 CtxStart(&this, CtxInvokeThread); 85 assert( thrd_c->last->stack.context ); 86 CtxSwitch( thrd_c->last->stack.context, thrd_c->stack.context ); 83 this_thrd->context.[SP, FP] = this_thrd->self_cor.context.[SP, FP]; 84 verify( this_thrd->context.SP ); 85 CtxSwitch( &curr_thrd->context, &this_thrd->context ); 87 86 88 ScheduleThread(th rd_h);87 ScheduleThread(this_thrd); 89 88 enable_interrupts( __cfaabi_dbg_ctx ); 90 89 } … … 92 91 extern "C" { 93 92 // KERNEL ONLY 94 void __finish_creation(void) { 95 coroutine_desc* thrd_c = kernelTLS.this_coroutine; 96 ThreadCtxSwitch( thrd_c, thrd_c->last ); 93 void __finish_creation(thread_desc * this) { 94 // set new coroutine that the processor is executing 95 // and context switch to it 96 verify( kernelTLS.this_thread != this ); 97 verify( kernelTLS.this_thread->context.SP ); 98 CtxSwitch( &this->context, &kernelTLS.this_thread->context ); 97 99 } 98 100 } … … 112 114 } 113 115 114 // KERNEL ONLY115 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {116 // set state of current coroutine to inactive117 src->state = src->state == Halted ? Halted : Inactive;118 dst->state = Active;119 120 // set new coroutine that the processor is executing121 // and context switch to it122 kernelTLS.this_coroutine = dst;123 assert( src->stack.context );124 CtxSwitch( src->stack.context, dst->stack.context );125 kernelTLS.this_coroutine = src;126 127 // set state of new coroutine to active128 dst->state = dst->state == Halted ? Halted : Inactive;129 src->state = Active;130 }131 132 116 // Local Variables: // 133 117 // mode: c // -
libcfa/src/concurrency/thread.hfa
r7951100 rb067d9b 10 10 // Created On : Tue Jan 17 12:27:26 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 29 14:07:11 201813 // Update Count : 412 // Last Modified On : Fri Jun 21 17:51:33 2019 13 // Update Count : 5 14 14 // 15 15 … … 19 19 #include "invoke.h" 20 20 21 #include "coroutine "22 #include "kernel "23 #include "monitor "21 #include "coroutine.hfa" 22 #include "kernel.hfa" 23 #include "monitor.hfa" 24 24 25 25 //----------------------------------------------------------------------------- … … 61 61 void ^?{}(thread_desc & this); 62 62 63 static inline void ?{}(thread_desc & this) { this{ "Anonymous Thread", *mainCluster, NULL, 0 }; }63 static inline void ?{}(thread_desc & this) { this{ "Anonymous Thread", *mainCluster, NULL, 65000 }; } 64 64 static inline void ?{}(thread_desc & this, size_t stackSize ) { this{ "Anonymous Thread", *mainCluster, NULL, stackSize }; } 65 65 static inline void ?{}(thread_desc & this, void * storage, size_t storageSize ) { this{ "Anonymous Thread", *mainCluster, storage, storageSize }; } 66 static inline void ?{}(thread_desc & this, struct cluster & cl ) { this{ "Anonymous Thread", cl, NULL, 0 }; }67 static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize ) { this{ "Anonymous Thread", cl, 0, stackSize }; }66 static inline void ?{}(thread_desc & this, struct cluster & cl ) { this{ "Anonymous Thread", cl, NULL, 65000 }; } 67 static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize ) { this{ "Anonymous Thread", cl, NULL, stackSize }; } 68 68 static inline void ?{}(thread_desc & this, struct cluster & cl, void * storage, size_t storageSize ) { this{ "Anonymous Thread", cl, storage, storageSize }; } 69 static inline void ?{}(thread_desc & this, const char * const name) { this{ name, *mainCluster, NULL, 0 }; }70 static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl ) { this{ name, cl, NULL, 0 }; }69 static inline void ?{}(thread_desc & this, const char * const name) { this{ name, *mainCluster, NULL, 65000 }; } 70 static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl ) { this{ name, cl, NULL, 65000 }; } 71 71 static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, NULL, stackSize }; } 72 72 … … 91 91 void yield( unsigned times ); 92 92 93 static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); } 94 93 95 // Local Variables: // 94 96 // mode: c // -
libcfa/src/containers/maybe.cfa
r7951100 rb067d9b 10 10 // Created On : Wed May 24 15:40:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 20 15:23:50 201713 // Update Count : 212 // Last Modified On : Sun Feb 17 11:22:03 2019 13 // Update Count : 3 14 14 // 15 15 16 #include <containers/maybe >16 #include <containers/maybe.hfa> 17 17 #include <assert.h> 18 18 … … 39 39 forall(otype T) 40 40 maybe(T) ?=?(maybe(T) & this, maybe(T) that) { 41 if (this.has_value & that.has_value) {41 if (this.has_value && that.has_value) { 42 42 this.value = that.value; 43 43 } else if (this.has_value) { -
libcfa/src/containers/pair.cfa
r7951100 rb067d9b 11 11 // 12 12 13 #include <containers/pair >13 #include <containers/pair.hfa> 14 14 15 forall(otype R, otype S 15 forall(otype R, otype S 16 16 | { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); }) 17 17 int ?<?(pair(R, S) p, pair(R, S) q) { … … 19 19 } 20 20 21 forall(otype R, otype S 21 forall(otype R, otype S 22 22 | { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); }) 23 23 int ?<=?(pair(R, S) p, pair(R, S) q) { … … 35 35 } 36 36 37 forall(otype R, otype S 37 forall(otype R, otype S 38 38 | { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); }) 39 39 int ?>?(pair(R, S) p, pair(R, S) q) { … … 41 41 } 42 42 43 forall(otype R, otype S 43 forall(otype R, otype S 44 44 | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); }) 45 45 int ?>=?(pair(R, S) p, pair(R, S) q) { -
libcfa/src/containers/result.cfa
r7951100 rb067d9b 10 10 // Created On : Wed May 24 15:40:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 20 15:23:58 201713 // Update Count : 212 // Last Modified On : Sun Feb 17 11:24:04 2019 13 // Update Count : 3 14 14 // 15 15 16 #include <containers/result >16 #include <containers/result.hfa> 17 17 #include <assert.h> 18 18 … … 48 48 forall(otype T, otype E) 49 49 result(T, E) ?=?(result(T, E) & this, result(T, E) that) { 50 if (this.has_value & that.has_value) {50 if (this.has_value && that.has_value) { 51 51 this.value = that.value; 52 52 } else if (this.has_value) { -
libcfa/src/containers/result.hfa
r7951100 rb067d9b 28 28 struct result { 29 29 bool has_value; 30 in ner_result(T, E);30 inline union inner_result(T, E); 31 31 }; 32 32 -
libcfa/src/containers/vector.cfa
r7951100 rb067d9b 14 14 // 15 15 16 #include <containers/vector >16 #include <containers/vector.hfa> 17 17 18 #include <stdlib >18 #include <stdlib.hfa> 19 19 20 20 forall(otype T, otype allocator_t | allocator_c(T, allocator_t)) -
libcfa/src/exception.c
r7951100 rb067d9b 23 23 #include <stdio.h> 24 24 #include <unwind.h> 25 #include <bits/debug.h >25 #include <bits/debug.hfa> 26 26 27 27 // FIX ME: temporary hack to keep ARM build working … … 246 246 } 247 247 248 #if defined(PIC) 249 #warning Exceptions not yet supported when using Position-Independent Code 250 __attribute__((noinline)) 251 void __cfaabi_ehm__try_terminate(void (*try_block)(), 252 void (*catch_block)(int index, exception_t * except), 253 __attribute__((unused)) int (*match_block)(exception_t * except)) { 254 abort(); 255 } 256 #else 248 257 // This is our personality routine. For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0". 249 258 // This function will be called twice when unwinding. Once in the search phased and once in the cleanup phase. … … 477 486 ); 478 487 #endif // __i386 || __x86_64 488 #endif //PIC -
libcfa/src/fstream.cfa
r7951100 rb067d9b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jun 5 17:02:56 201813 // Update Count : 28114 // 15 16 #include "fstream "12 // Last Modified On : Tue Sep 10 22:19:56 2019 13 // Update Count : 354 14 // 15 16 #include "fstream.hfa" 17 17 18 18 #include <stdio.h> // vfprintf, vfscanf … … 20 20 #include <stdarg.h> // varargs 21 21 #include <string.h> // strlen 22 #include <stdbool.h> // true/false23 22 #include <float.h> // DBL_DIG, LDBL_DIG 24 23 #include <complex.h> // creal, cimag 25 24 #include <assert.h> 25 #include <errno.h> // errno 26 27 28 //*********************************** ofstream *********************************** 29 26 30 27 31 #define IO_MSG "I/O error: " 28 32 29 void ?{}( ofstream & os, void * file , _Bool sepDefault, _Bool sepOnOff, const char * separator, const char * tupleSeparator) {33 void ?{}( ofstream & os, void * file ) { 30 34 os.file = file; 31 os.sepDefault = sepDefault; 32 os.sepOnOff = sepOnOff; 33 sepSet( os, separator ); 35 os.sepDefault = true; 36 os.sepOnOff = false; 37 os.nlOnOff = true; 38 os.prt = false; 39 os.sawNL = false; 40 sepSet( os, " " ); 34 41 sepSetCur( os, sepGet( os ) ); 35 sepSetTuple( os, tupleSeparator);36 } 42 sepSetTuple( os, ", " ); 43 } // ?{} 37 44 38 45 // private 39 _Bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }46 bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; } 40 47 void sepReset( ofstream & os ) { os.sepOnOff = os.sepDefault; } 41 void sepReset( ofstream & os, _Bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }48 void sepReset( ofstream & os, bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; } 42 49 const char * sepGetCur( ofstream & os ) { return os.sepCur; } 43 50 void sepSetCur( ofstream & os, const char * sepCur ) { os.sepCur = sepCur; } 44 _Bool getNL( ofstream & os ) { return os.sawNL; } 45 void setNL( ofstream & os, _Bool state ) { os.sawNL = state; } 51 bool getNL( ofstream & os ) { return os.sawNL; } 52 void setNL( ofstream & os, bool state ) { os.sawNL = state; } 53 bool getANL( ofstream & os ) { return os.nlOnOff; } 54 bool getPrt( ofstream & os ) { return os.prt; } 55 void setPrt( ofstream & os, bool state ) { os.prt = state; } 46 56 47 57 // public … … 50 60 void ?{}( ofstream & os, const char * name, const char * mode ) { 51 61 open( os, name, mode ); 52 } 62 } // ?{} 63 53 64 void ?{}( ofstream & os, const char * name ) { 54 65 open( os, name, "w" ); 55 } 66 } // ?{} 56 67 57 68 void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); } 58 69 void sepOff( ofstream & os ) { os.sepOnOff = false; } 59 70 60 _Bool sepDisable( ofstream & os ) {61 _Bool temp = os.sepDefault;71 bool sepDisable( ofstream & os ) { 72 bool temp = os.sepDefault; 62 73 os.sepDefault = false; 63 74 sepReset( os ); … … 65 76 } // sepDisable 66 77 67 _Bool sepEnable( ofstream & os ) {68 _Bool temp = os.sepDefault;78 bool sepEnable( ofstream & os ) { 79 bool temp = os.sepDefault; 69 80 os.sepDefault = true; 70 81 if ( os.sepOnOff ) sepReset( os ); // start of line ? 71 82 return temp; 72 83 } // sepEnable 84 85 void nlOn( ofstream & os ) { os.nlOnOff = true; } 86 void nlOff( ofstream & os ) { os.nlOnOff = false; } 73 87 74 88 const char * sepGet( ofstream & os ) { return os.separator; } … … 86 100 } // sepSet 87 101 102 void ends( ofstream & os ) { 103 if ( getANL( os ) ) nl( os ); 104 else setPrt( os, false ); // turn off 105 if ( &os == &exit ) exit( EXIT_FAILURE ); 106 if ( &os == &abort ) abort(); 107 } // ends 108 88 109 int fail( ofstream & os ) { 89 110 return os.file == 0 || ferror( (FILE *)(os.file) ); … … 95 116 96 117 void open( ofstream & os, const char * name, const char * mode ) { 97 FILE * file = fopen( name, mode );98 // if ( file == 0 ) { // do not change unless successful99 // fprintf( stderr, IO_MSG "open output file \"%s\", ", name );100 // perror( 0);101 // exit( EXIT_FAILURE );102 // } // if103 (os){ file , true, false, " ", ", "};118 FILE * file = fopen( name, mode ); 119 #ifdef __CFA_DEBUG__ 120 if ( file == 0 ) { 121 abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno ); 122 } // if 123 #endif // __CFA_DEBUG__ 124 (os){ file }; 104 125 } // open 105 126 … … 112 133 113 134 if ( fclose( (FILE *)(os.file) ) == EOF ) { 114 perror( IO_MSG "close output");135 abort | IO_MSG "close output" | nl | strerror( errno ); 115 136 } // if 116 137 } // close … … 118 139 ofstream & write( ofstream & os, const char * data, size_t size ) { 119 140 if ( fail( os ) ) { 120 fprintf( stderr, "attempt write I/O on failed stream\n" ); 121 exit( EXIT_FAILURE ); 141 abort | IO_MSG "attempt write I/O on failed stream"; 122 142 } // if 123 143 124 144 if ( fwrite( data, 1, size, (FILE *)(os.file) ) != size ) { 125 perror( IO_MSG "write" ); 126 exit( EXIT_FAILURE ); 145 abort | IO_MSG "write" | nl | strerror( errno ); 127 146 } // if 128 147 return os; … … 135 154 if ( len == EOF ) { 136 155 if ( ferror( (FILE *)(os.file) ) ) { 137 fprintf( stderr, "invalid write\n" ); 138 exit( EXIT_FAILURE ); 156 abort | IO_MSG "invalid write"; 139 157 } // if 140 158 } // if 141 159 va_end( args ); 142 160 161 setPrt( os, true ); // called in output cascade 143 162 sepReset( os ); // reset separator 144 163 return len; 145 164 } // fmt 146 165 147 static ofstream soutFile = { (FILE *)(&_IO_2_1_stdout_), true, false, " ", ", " }; 148 ofstream & sout = soutFile; 149 static ofstream serrFile = { (FILE *)(&_IO_2_1_stderr_), true, false, " ", ", " }; 150 ofstream & serr = serrFile; 151 152 153 //--------------------------------------- 166 static ofstream soutFile = { (FILE *)stdout }; 167 ofstream & sout = soutFile, & stdout = soutFile; 168 static ofstream serrFile = { (FILE *)stderr }; 169 ofstream & serr = serrFile, & stderr = serrFile; 170 171 static ofstream exitFile = { (FILE *)stdout }; 172 ofstream & exit = exitFile; 173 static ofstream abortFile = { (FILE *)stderr }; 174 ofstream & abort = abortFile; 175 176 177 //*********************************** ifstream *********************************** 178 154 179 155 180 // private 156 181 void ?{}( ifstream & is, void * file ) { 157 182 is.file = file; 158 } 183 is.nlOnOff = false; 184 } // ?{} 159 185 160 186 // public … … 163 189 void ?{}( ifstream & is, const char * name, const char * mode ) { 164 190 open( is, name, mode ); 165 } 191 } // ?{} 192 166 193 void ?{}( ifstream & is, const char * name ) { 167 194 open( is, name, "r" ); 168 } 195 } // ?{} 196 197 void nlOn( ifstream & os ) { os.nlOnOff = true; } 198 void nlOff( ifstream & os ) { os.nlOnOff = false; } 199 bool getANL( ifstream & os ) { return os.nlOnOff; } 169 200 170 201 int fail( ifstream & is ) { … … 177 208 178 209 void open( ifstream & is, const char * name, const char * mode ) { 179 FILE * file = fopen( name, mode );180 // if ( file == 0 ) { // do not change unless successful181 // fprintf( stderr, IO_MSG "open input file \"%s\", ", name );182 // perror( 0);183 // exit( EXIT_FAILURE );184 // } // if210 FILE * file = fopen( name, mode ); 211 #ifdef __CFA_DEBUG__ 212 if ( file == 0 ) { 213 abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno ); 214 } // if 215 #endif // __CFA_DEBUG__ 185 216 is.file = file; 186 217 } // open … … 194 225 195 226 if ( fclose( (FILE *)(is.file) ) == EOF ) { 196 perror( IO_MSG "close input");227 abort | IO_MSG "close input" | nl | strerror( errno ); 197 228 } // if 198 229 } // close … … 200 231 ifstream & read( ifstream & is, char * data, size_t size ) { 201 232 if ( fail( is ) ) { 202 fprintf( stderr, "attempt read I/O on failed stream\n" ); 203 exit( EXIT_FAILURE ); 233 abort | IO_MSG "attempt read I/O on failed stream"; 204 234 } // if 205 235 206 236 if ( fread( data, size, 1, (FILE *)(is.file) ) == 0 ) { 207 perror( IO_MSG "read" ); 208 exit( EXIT_FAILURE ); 237 abort | IO_MSG "read" | nl | strerror( errno ); 209 238 } // if 210 239 return is; … … 213 242 ifstream &ungetc( ifstream & is, char c ) { 214 243 if ( fail( is ) ) { 215 fprintf( stderr, "attempt ungetc I/O on failed stream\n" ); 216 exit( EXIT_FAILURE ); 244 abort | IO_MSG "attempt ungetc I/O on failed stream"; 217 245 } // if 218 246 219 247 if ( ungetc( c, (FILE *)(is.file) ) == EOF ) { 220 perror( IO_MSG "ungetc" ); 221 exit( EXIT_FAILURE ); 248 abort | IO_MSG "ungetc" | nl | strerror( errno ); 222 249 } // if 223 250 return is; … … 231 258 if ( len == EOF ) { 232 259 if ( ferror( (FILE *)(is.file) ) ) { 233 fprintf( stderr, "invalid read\n" ); 234 exit( EXIT_FAILURE ); 260 abort | IO_MSG "invalid read"; 235 261 } // if 236 262 } // if … … 239 265 } // fmt 240 266 241 242 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) }; 243 ifstream & sin = sinFile; 267 static ifstream sinFile = { (FILE *)stdin }; 268 ifstream & sin = sinFile, & stdin = sinFile; 244 269 245 270 // Local Variables: // -
libcfa/src/fstream.hfa
r7951100 rb067d9b 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jun 5 10:20:25 201813 // Update Count : 1 3112 // Last Modified On : Mon Jul 15 18:10:23 2019 13 // Update Count : 167 14 14 // 15 15 16 16 #pragma once 17 17 18 #include "iostream" 18 #include "iostream.hfa" 19 20 21 //*********************************** ofstream *********************************** 22 19 23 20 24 enum { sepSize = 16 }; 21 25 struct ofstream { 22 26 void * file; 23 _Bool sepDefault; 24 _Bool sepOnOff; 25 _Bool sawNL; 27 bool sepDefault; 28 bool sepOnOff; 29 bool nlOnOff; 30 bool prt; // print text 31 bool sawNL; 26 32 const char * sepCur; 27 33 char separator[sepSize]; … … 30 36 31 37 // private 32 _Bool sepPrt( ofstream & );38 bool sepPrt( ofstream & ); 33 39 void sepReset( ofstream & ); 34 void sepReset( ofstream &, _Bool );40 void sepReset( ofstream &, bool ); 35 41 const char * sepGetCur( ofstream & ); 36 42 void sepSetCur( ofstream &, const char * ); 37 _Bool getNL( ofstream & ); 38 void setNL( ofstream &, _Bool ); 43 bool getNL( ofstream & ); 44 void setNL( ofstream &, bool ); 45 bool getANL( ofstream & ); 46 bool getPrt( ofstream & ); 47 void setPrt( ofstream &, bool ); 39 48 40 49 // public 41 50 void sepOn( ofstream & ); 42 51 void sepOff( ofstream & ); 43 _Bool sepDisable( ofstream & ); 44 _Bool sepEnable( ofstream & ); 52 bool sepDisable( ofstream & ); 53 bool sepEnable( ofstream & ); 54 void nlOn( ofstream & ); 55 void nlOff( ofstream & ); 45 56 46 57 const char * sepGet( ofstream & ); … … 49 60 void sepSetTuple( ofstream &, const char * ); 50 61 62 void ends( ofstream & os ); 51 63 int fail( ofstream & ); 52 64 int flush( ofstream & ); … … 55 67 void close( ofstream & ); 56 68 ofstream & write( ofstream &, const char * data, size_t size ); 57 int fmt( ofstream &, const char f mt[], ... );69 int fmt( ofstream &, const char format[], ... ); 58 70 59 71 void ?{}( ofstream & os ); … … 61 73 void ?{}( ofstream & os, const char * name ); 62 74 63 extern ofstream & sout, & serr; 75 extern ofstream & sout, & stdout, & serr, & stderr; // aliases 76 extern ofstream & exit, & abort; 77 78 79 //*********************************** ifstream *********************************** 64 80 65 81 66 82 struct ifstream { 67 83 void * file; 84 bool nlOnOff; 68 85 }; // ifstream 69 86 70 87 // public 88 void nlOn( ifstream & ); 89 void nlOff( ifstream & ); 90 bool getANL( ifstream & ); 71 91 int fail( ifstream & is ); 72 92 int eof( ifstream & is ); … … 76 96 ifstream & read( ifstream & is, char * data, size_t size ); 77 97 ifstream & ungetc( ifstream & is, char c ); 78 int fmt( ifstream &, const char f mt[], ... );98 int fmt( ifstream &, const char format[], ... ); 79 99 80 100 void ?{}( ifstream & is ); … … 82 102 void ?{}( ifstream & is, const char * name ); 83 103 84 extern ifstream & sin ;104 extern ifstream & sin, & stdin; // aliases 85 105 86 106 // Local Variables: // -
libcfa/src/interpose.cfa
r7951100 rb067d9b 10 10 // Created On : Wed Mar 29 16:10:31 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S at May 5 11:37:35 201813 // Update Count : 11 112 // Last Modified On : Sun Jul 14 22:57:16 2019 13 // Update Count : 116 14 14 // 15 15 … … 25 25 } 26 26 27 #include "bits/debug.h "28 #include "bits/defs.h "29 #include "bits/signal.h " // sigHandler_?30 #include "startup.h " // STARTUP_PRIORITY_CORE27 #include "bits/debug.hfa" 28 #include "bits/defs.hfa" 29 #include "bits/signal.hfa" // sigHandler_? 30 #include "startup.hfa" // STARTUP_PRIORITY_CORE 31 31 32 32 //============================================================================================= 33 33 // Interposing helpers 34 34 //============================================================================================= 35 36 void preload_libgcc(void) { 37 dlopen( "libgcc_s.so.1", RTLD_NOW ); 38 if ( const char * error = dlerror() ) abort( "interpose_symbol : internal error pre-loading libgcc, %s\n", error ); 39 } 35 40 36 41 typedef void (* generic_fptr_t)(void); … … 76 81 //============================================================================================= 77 82 78 void sigHandler_segv 79 void sigHandler_ill 80 void sigHandler_fpe 81 void sigHandler_ab ort( __CFA_SIGPARMS__ );82 void sigHandler_term 83 void sigHandler_segv( __CFA_SIGPARMS__ ); 84 void sigHandler_ill ( __CFA_SIGPARMS__ ); 85 void sigHandler_fpe ( __CFA_SIGPARMS__ ); 86 void sigHandler_abrt( __CFA_SIGPARMS__ ); 87 void sigHandler_term( __CFA_SIGPARMS__ ); 83 88 84 89 struct { … … 91 96 void __cfaabi_interpose_startup( void ) { 92 97 const char *version = NULL; 98 99 preload_libgcc(); 93 100 94 101 #pragma GCC diagnostic push … … 103 110 __cfaabi_sigaction( SIGILL , sigHandler_ill , SA_SIGINFO ); 104 111 __cfaabi_sigaction( SIGFPE , sigHandler_fpe , SA_SIGINFO ); 105 __cfaabi_sigaction( SIGABRT, sigHandler_ab ort, SA_SIGINFO | SA_RESETHAND);112 __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND); 106 113 __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO ); 107 114 __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO ); … … 197 204 if ( *p == '(' ) { 198 205 name = p; 199 } 200 else if ( *p == '+' ) { 206 } else if ( *p == '+' ) { 201 207 offset_begin = p; 202 } 203 else if ( *p == ')' ) { 208 } else if ( *p == ')' ) { 204 209 offset_end = p; 205 210 break; … … 216 221 217 222 __cfaabi_dbg_bits_print_nolock( "(%i) %s : %s + %s %s\n", frameNo, messages[i], name, offset_begin, offset_end); 218 } 219 // otherwise, print the whole line 220 else { 223 } else { // otherwise, print the whole line 221 224 __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] ); 222 225 } … … 251 254 } 252 255 253 void sigHandler_ab ort( __CFA_SIGPARMS__ ) {256 void sigHandler_abrt( __CFA_SIGPARMS__ ) { 254 257 __cfaabi_backtrace(); 255 258 -
libcfa/src/iterator.cfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // iterator.c -- 7 // iterator.c -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 7 08:38:23 201713 // Update Count : 2 812 // Last Modified On : Fri Nov 2 07:17:37 2018 13 // Update Count : 29 14 14 // 15 15 16 #include "iterator "16 #include "iterator.hfa" 17 17 18 18 forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) ) … … 33 33 // Local Variables: // 34 34 // tab-width: 4 // 35 // compile-command: "cfa iterator.c " //35 // compile-command: "cfa iterator.cfa" // 36 36 // End: // -
libcfa/src/limits.cfa
r7951100 rb067d9b 1 // 1 // 2 2 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // limits.c -- 8 // 6 // 7 // limits.c -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Wed Apr 6 18:06:52 2016 … … 12 12 // Last Modified On : Thu Mar 1 16:22:51 2018 13 13 // Update Count : 74 14 // 14 // 15 15 16 16 #include <limits.h> … … 19 19 #include <math.h> 20 20 #include <complex.h> 21 #include "limits "21 #include "limits.hfa" 22 22 23 23 // Integral Constants -
libcfa/src/math.hfa
r7951100 rb067d9b 10 10 // Created On : Mon Apr 18 23:37:04 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 7 07:51:15 201713 // Update Count : 1 0812 // Last Modified On : Fri Jul 13 11:02:15 2018 13 // Update Count : 116 14 14 // 15 15 … … 348 348 static inline long double scalbln( long double x, long int exp ) { return scalblnl( x, exp ); } 349 349 350 //--------------------------------------- 351 352 #include "common.hfa" 353 354 //--------------------------------------- 355 356 forall( otype T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T );T ?*?( T, T ); } ) 357 T lerp( T x, T y, T a ) { return x * ((T){1} - a) + y * a; } 358 359 forall( otype T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); int ?<?( T, T ); } ) 360 T step( T edge, T x ) { return x < edge ? (T){0} : (T){1}; } 361 362 forall( otype T | { void ?{}( T &, int ); T clamp( T, T, T ); T ?-?( T, T ); T ?*?( T, T ); T ?/?( T, T ); } ) 363 T smoothstep( T edge0, T edge1, T x ) { T t = clamp( (x - edge0) / (edge1 - edge0), (T){0}, (T){1} ); return t * t * ((T){3} - (T){2} * t); } 364 350 365 // Local Variables: // 351 366 // mode: c // -
libcfa/src/rational.cfa
r7951100 rb067d9b 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jun 2 09:24:33 201813 // Update Count : 1 6214 // 15 16 #include "rational "17 #include "fstream "18 #include "stdlib "12 // Last Modified On : Fri Jul 12 18:12:08 2019 13 // Update Count : 184 14 // 15 16 #include "rational.hfa" 17 #include "fstream.hfa" 18 #include "stdlib.hfa" 19 19 20 20 forall( otype RationalImpl | arithmetic( RationalImpl ) ) { … … 35 35 static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) { 36 36 if ( d == (RationalImpl){0} ) { 37 serr | "Invalid rational number construction: denominator cannot be equal to 0." | endl; 38 exit( EXIT_FAILURE ); 37 abort | "Invalid rational number construction: denominator cannot be equal to 0."; 39 38 } // exit 40 39 if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator … … 54 53 void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) { 55 54 RationalImpl t = simplify( n, d ); // simplify 56 r.numerator = n / t; 57 r.denominator = d / t; 55 r.[numerator, denominator] = [n / t, d / t]; 58 56 } // rational 59 57 … … 78 76 RationalImpl prev = r.numerator; 79 77 RationalImpl t = gcd( abs( n ), r.denominator ); // simplify 80 r.numerator = n / t; 81 r.denominator = r.denominator / t; 78 r.[numerator, denominator] = [n / t, r.denominator / t]; 82 79 return prev; 83 80 } // numerator … … 86 83 RationalImpl prev = r.denominator; 87 84 RationalImpl t = simplify( r.numerator, d ); // simplify 88 r.numerator = r.numerator / t; 89 r.denominator = d / t; 85 r.[numerator, denominator] = [r.numerator / t, d / t]; 90 86 return prev; 91 87 } // denominator … … 120 116 121 117 Rational(RationalImpl) +?( Rational(RationalImpl) r ) { 122 Rational(RationalImpl) t = { r.numerator, r.denominator }; 123 return t; 118 return (Rational(RationalImpl)){ r.numerator, r.denominator }; 124 119 } // +? 125 120 126 121 Rational(RationalImpl) -?( Rational(RationalImpl) r ) { 127 Rational(RationalImpl) t = { -r.numerator, r.denominator }; 128 return t; 122 return (Rational(RationalImpl)){ -r.numerator, r.denominator }; 129 123 } // -? 130 124 131 125 Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 132 126 if ( l.denominator == r.denominator ) { // special case 133 Rational(RationalImpl) t = { l.numerator + r.numerator, l.denominator }; 134 return t; 127 return (Rational(RationalImpl)){ l.numerator + r.numerator, l.denominator }; 135 128 } else { 136 Rational(RationalImpl) t = { l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 137 return t; 129 return (Rational(RationalImpl)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator }; 138 130 } // if 139 131 } // ?+? … … 141 133 Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 142 134 if ( l.denominator == r.denominator ) { // special case 143 Rational(RationalImpl) t = { l.numerator - r.numerator, l.denominator }; 144 return t; 135 return (Rational(RationalImpl)){ l.numerator - r.numerator, l.denominator }; 145 136 } else { 146 Rational(RationalImpl) t = { l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 147 return t; 137 return (Rational(RationalImpl)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator }; 148 138 } // if 149 139 } // ?-? 150 140 151 141 Rational(RationalImpl) ?*?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 152 Rational(RationalImpl) t = { l.numerator * r.numerator, l.denominator * r.denominator }; 153 return t; 142 return (Rational(RationalImpl)){ l.numerator * r.numerator, l.denominator * r.denominator }; 154 143 } // ?*? 155 144 156 145 Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) { 157 146 if ( r.numerator < (RationalImpl){0} ) { 158 r.numerator = -r.numerator; 159 r.denominator = -r.denominator; 147 r.[numerator, denominator] = [-r.numerator, -r.denominator]; 160 148 } // if 161 Rational(RationalImpl) t = { l.numerator * r.denominator, l.denominator * r.numerator }; 162 return t; 149 return (Rational(RationalImpl)){ l.numerator * r.denominator, l.denominator * r.numerator }; 163 150 } // ?/? 164 151 … … 167 154 forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } ) 168 155 istype & ?|?( istype & is, Rational(RationalImpl) & r ) { 169 RationalImpl t;170 156 is | r.numerator | r.denominator; 171 t = simplify( r.numerator, r.denominator );157 RationalImpl t = simplify( r.numerator, r.denominator ); 172 158 r.numerator /= t; 173 159 r.denominator /= t; … … 175 161 } // ?|? 176 162 177 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) 178 ostype & ?|?( ostype & os, Rational(RationalImpl ) r ) { 179 return os | r.numerator | '/' | r.denominator; 180 } // ?|? 163 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) { 164 ostype & ?|?( ostype & os, Rational(RationalImpl) r ) { 165 return os | r.numerator | '/' | r.denominator; 166 } // ?|? 167 168 void ?|?( ostype & os, Rational(RationalImpl) r ) { 169 (ostype &)(os | r); ends( os ); 170 } // ?|? 171 } // distribution 181 172 } // distribution 173 174 forall( otype RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } ) 175 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ) { 176 if ( y < 0 ) { 177 return (Rational(RationalImpl)){ x.denominator \ -y, x.numerator \ -y }; 178 } else { 179 return (Rational(RationalImpl)){ x.numerator \ y, x.denominator \ y }; 180 } // if 181 } 182 182 183 183 // conversion -
libcfa/src/rational.hfa
r7951100 rb067d9b 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Sat Jun 2 09:10:01 201815 // Update Count : 10 514 // Last Modified On : Tue Mar 26 23:16:10 2019 15 // Update Count : 109 16 16 // 17 17 18 18 #pragma once 19 19 20 #include "iostream "20 #include "iostream.hfa" 21 21 22 22 trait scalar( otype T ) { … … 92 92 istype & ?|?( istype &, Rational(RationalImpl) & ); 93 93 94 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) 95 ostype & ?|?( ostype &, Rational(RationalImpl ) ); 94 forall( dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, RationalImpl ); } ) { 95 ostype & ?|?( ostype &, Rational(RationalImpl) ); 96 void ?|?( ostype &, Rational(RationalImpl) ); 97 } // distribution 96 98 } // distribution 99 100 forall( otype RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} ) 101 Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y ); 97 102 98 103 // conversion -
libcfa/src/startup.hfa
r7951100 rb067d9b 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // startup.h --7 // startup.hfa -- 8 8 // 9 9 // Author : Thierry Delisle 10 10 // Created On : Wed Mar 29 15:56:41 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T hu Jul 20 21:37:11 201713 // Update Count : 212 // Last Modified On : Tue Jul 24 16:16:37 2018 13 // Update Count : 4 14 14 // 15 15 … … 19 19 extern "C" { 20 20 enum { 21 STARTUP_PRIORITY_ CORE= 101,22 STARTUP_PRIORITY_ KERNEL= 102,23 STARTUP_PRIORITY_ MEMORY= 103,21 STARTUP_PRIORITY_MEMORY = 101, 22 STARTUP_PRIORITY_CORE = 102, 23 STARTUP_PRIORITY_KERNEL = 103, 24 24 STARTUP_PRIORITY_IOSTREAM = 104, 25 STARTUP_PRIORITY_APPREADY = 105, 25 26 }; 26 27 } 27 28 #else 28 #define STARTUP_PRIORITY_ CORE10129 #define STARTUP_PRIORITY_ KERNEL10230 #define STARTUP_PRIORITY_ MEMORY10329 #define STARTUP_PRIORITY_MEMORY 101 30 #define STARTUP_PRIORITY_CORE 102 31 #define STARTUP_PRIORITY_KERNEL 103 31 32 #define STARTUP_PRIORITY_IOSTREAM 104 33 #define STARTUP_PRIORITY_APPREADY 105 32 34 #endif 33 35 -
libcfa/src/stdhdr/bfdlink.h
r7951100 rb067d9b 10 10 // Created On : Tue Jul 18 07:26:04 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 18 07:46:50 201713 // Update Count : 312 // Last Modified On : Sun Jul 22 13:49:30 2018 13 // Update Count : 4 14 14 // 15 15 … … 20 20 #endif 21 21 22 #include_next <bfdlink.h> // must haveinternal check for multiple expansion22 #include_next <bfdlink.h> // has internal check for multiple expansion 23 23 24 24 #if defined( with ) && defined( __CFA_BFDLINK_H__ ) // reset only if set -
libcfa/src/stdhdr/hwloc.h
r7951100 rb067d9b 10 10 // Created On : Tue Jul 18 07:45:00 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 18 07:56:33 201713 // Update Count : 312 // Last Modified On : Sun Jul 22 13:49:58 2018 13 // Update Count : 4 14 14 // 15 15 … … 20 20 #endif 21 21 22 #include_next <hwloc.h> // must haveinternal check for multiple expansion22 #include_next <hwloc.h> // has internal check for multiple expansion 23 23 24 24 #if defined( thread ) && defined( __CFA_HWLOC_H__ ) // reset only if set -
libcfa/src/stdhdr/krb5.h
r7951100 rb067d9b 10 10 // Created On : Tue Jul 18 07:55:44 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 18 07:58:01 201713 // Update Count : 312 // Last Modified On : Sun Jul 22 13:50:24 2018 13 // Update Count : 4 14 14 // 15 15 … … 20 20 #endif 21 21 22 #include_next <krb5.h> // must haveinternal check for multiple expansion22 #include_next <krb5.h> // has internal check for multiple expansion 23 23 24 24 #if defined( enable ) && defined( __CFA_KRB5_H__ ) // reset only if set -
libcfa/src/stdhdr/malloc.h
r7951100 rb067d9b 10 10 // Created On : Thu Jul 20 15:58:16 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 20 16:00:12 201713 // Update Count : 412 // Last Modified On : Sat Aug 11 09:06:31 2018 13 // Update Count : 10 14 14 // 15 16 17 size_t default_mmap_start(); // CFA extras 18 size_t default_heap_expansion(); 19 20 bool traceHeap(); 21 bool traceHeapOn(); 22 bool traceHeapOff(); 23 24 bool traceHeapTerm(); 25 bool traceHeapTermOn(); 26 bool traceHeapTermOff(); 27 28 bool checkFree(); 29 bool checkFreeOn(); 30 bool checkFreeOff(); 31 32 extern "C" { 33 size_t malloc_alignment( void * ); 34 bool malloc_zero_fill( void * ); 35 int malloc_stats_fd( int fd ); 36 void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize ); 37 } // extern "C" 15 38 16 39 extern "C" { -
libcfa/src/stdhdr/stdbool.h
r7951100 rb067d9b 10 10 // Created On : Mon Jul 4 23:25:26 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jul 5 20:39:51 201613 // Update Count : 1 212 // Last Modified On : Mon Mar 25 08:00:08 2019 13 // Update Count : 15 14 14 // 15 15 16 16 extern "C" { 17 17 #include_next <stdbool.h> // has internal check for multiple expansion 18 19 // allows printing as true/false 20 #if defined( true ) 21 #undef true 22 #define true ((_Bool)1) 23 #endif // true 24 25 #if defined( false ) 26 #undef false 27 #define false ((_Bool)0) 28 #endif // false 18 29 } // extern "C" 19 30 -
libcfa/src/stdlib.cfa
r7951100 rb067d9b 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Jun 2 06:15:05 201813 // Update Count : 4 4814 // 15 16 #include "stdlib "12 // Last Modified On : Tue Oct 22 08:57:52 2019 13 // Update Count : 478 14 // 15 16 #include "stdlib.hfa" 17 17 18 18 //--------------------------------------- … … 21 21 #include <string.h> // memcpy, memset 22 22 #include <malloc.h> // malloc_usable_size 23 #include <math.h> // fabsf, fabs, fabsl23 //#include <math.h> // fabsf, fabs, fabsl 24 24 #include <complex.h> // _Complex_I 25 25 #include <assert.h> … … 27 27 //--------------------------------------- 28 28 29 // resize, non-array types 30 forall( dtype T | sized(T) ) T * alloc( T ptr[], size_t dim, char fill ) { 31 size_t olen = malloc_usable_size( ptr ); // current allocation 32 char * nptr = (void *)realloc( (void *)ptr, dim * (size_t)sizeof(T) ); // C realloc 33 size_t nlen = malloc_usable_size( nptr ); // new allocation 34 if ( nlen > olen ) { // larger ? 35 memset( nptr + olen, (int)fill, nlen - olen ); // initialize added storage 36 } // 37 return (T *)nptr; 38 } // alloc 29 forall( dtype T | sized(T) ) { 30 T * alloc_set( T ptr[], size_t dim, char fill ) { // realloc array with fill 31 size_t olen = malloc_usable_size( ptr ); // current allocation 32 char * nptr = (char *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc 33 size_t nlen = malloc_usable_size( nptr ); // new allocation 34 if ( nlen > olen ) { // larger ? 35 memset( nptr + olen, (int)fill, nlen - olen ); // initialize added storage 36 } // if 37 return (T *)nptr; 38 } // alloc_set 39 40 T * alloc_align( T ptr[], size_t align ) { // aligned realloc array 41 char * nptr; 42 size_t alignment = malloc_alignment( ptr ); 43 if ( align != alignment && (uintptr_t)ptr % align != 0 ) { 44 size_t olen = malloc_usable_size( ptr ); // current allocation 45 nptr = (char *)memalign( align, olen ); 46 size_t nlen = malloc_usable_size( nptr ); // new allocation 47 size_t lnth = olen < nlen ? olen : nlen; // min 48 memcpy( nptr, ptr, lnth ); // initialize storage 49 free( ptr ); 50 } else { 51 nptr = (char *)ptr; 52 } // if 53 return (T *)nptr; 54 } // alloc_align 55 56 T * alloc_align( T ptr[], size_t align, size_t dim ) { // aligned realloc array 57 char * nptr; 58 size_t alignment = malloc_alignment( ptr ); 59 if ( align != alignment ) { 60 size_t olen = malloc_usable_size( ptr ); // current allocation 61 nptr = (char *)memalign( align, dim * sizeof(T) ); 62 size_t nlen = malloc_usable_size( nptr ); // new allocation 63 size_t lnth = olen < nlen ? olen : nlen; // min 64 memcpy( nptr, ptr, lnth ); // initialize storage 65 free( ptr ); 66 } else { 67 nptr = (char *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc 68 } // if 69 return (T *)nptr; 70 } // alloc_align 71 72 T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill 73 size_t olen = malloc_usable_size( ptr ); // current allocation 74 char * nptr = alloc_align( ptr, align ); 75 size_t nlen = malloc_usable_size( nptr ); // new allocation 76 if ( nlen > olen ) { // larger ? 77 memset( nptr + olen, (int)fill, nlen - olen ); // initialize added storage 78 } // if 79 return (T *)nptr; 80 } // alloc_align_set 81 } // distribution 39 82 40 83 // allocation/deallocation and constructor/destructor, non-array types 41 84 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) 42 85 T * new( Params p ) { 43 return &(*malloc()){ p }; 86 return &(*malloc()){ p }; // run constructor 44 87 } // new 45 88 … … 47 90 void delete( T * ptr ) { 48 91 if ( ptr ) { // ignore null 49 ^(*ptr){}; 92 ^(*ptr){}; // run destructor 50 93 free( ptr ); 51 94 } // if … … 55 98 void delete( T * ptr, Params rest ) { 56 99 if ( ptr ) { // ignore null 57 ^(*ptr){}; 100 ^(*ptr){}; // run destructor 58 101 free( ptr ); 59 102 } // if … … 65 108 forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } ) 66 109 T * anew( size_t dim, Params p ) { 67 T * arr = alloc( dim );110 T * arr = alloc( dim ); 68 111 for ( unsigned int i = 0; i < dim; i += 1 ) { 69 112 (arr[i]){ p }; // run constructor … … 241 284 //--------------------------------------- 242 285 243 [ int, int ] div( int num, int denom ) { div_t qr = div( num, denom ); return [ qr.quot, qr.rem ]; } 244 [ long int, long int ] div( long int num, long int denom ) { ldiv_t qr = ldiv( num, denom ); return [ qr.quot, qr.rem ]; } 245 [ long long int, long long int ] div( long long int num, long long int denom ) { lldiv_t qr = lldiv( num, denom ); return [ qr.quot, qr.rem ]; } 246 forall( otype T | { T ?/?( T, T ); T ?%?( T, T ); } ) 247 [ T, T ] div( T num, T denom ) { return [ num / denom, num % denom ]; } 248 249 //--------------------------------------- 250 251 extern "C" { void srandom( unsigned int seed ) { srand48( (long int)seed ); } } // override C version 252 char random( void ) { return (unsigned long int)random(); } 253 char random( char u ) { return random( (unsigned long int)u ); } 254 char random( char l, char u ) { return random( (unsigned long int)l, (unsigned long int)u ); } 255 int random( void ) { return (long int)random(); } 256 int random( int u ) { return random( (long int)u ); } 257 int random( int l, int u ) { return random( (long int)l, (long int)u ); } 258 unsigned int random( void ) { return (unsigned long int)random(); } 259 unsigned int random( unsigned int u ) { return random( (unsigned long int)u ); } 260 unsigned int random( unsigned int l, unsigned int u ) { return random( (unsigned long int)l, (unsigned long int)u ); } 261 extern "C" { long int random( void ) { return mrand48(); } } // override C version 262 long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } 263 long int random( long int l, long int u ) { assert( l < u ); return lrand48() % (u - l) + l; } 264 unsigned long int random( void ) { return lrand48(); } 265 unsigned long int random( unsigned long int u ) { return lrand48() % u; } 266 unsigned long int random( unsigned long int l, unsigned long int u ) { assert( l < u ); return lrand48() % (u - l) + l; } 286 extern "C" { // override C version 287 void srandom( unsigned int seed ) { srand48( (long int)seed ); } 288 long int random( void ) { return mrand48(); } 289 } // extern "C" 290 267 291 float random( void ) { return (float)drand48(); } // cast otherwise float uses lrand48 268 292 double random( void ) { return drand48(); } … … 271 295 long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); } 272 296 297 //--------------------------------------- 298 299 bool threading_enabled(void) __attribute__((weak)) { 300 return false; 301 } 273 302 274 303 // Local Variables: // -
libcfa/src/time.cfa
r7951100 rb067d9b 1 // 1 // 2 2 // Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // time.c -- 8 // 6 // 7 // time.c -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Tue Mar 27 13:33:14 2018 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : S un May 6 22:26:00 201813 // Update Count : 3714 // 12 // Last Modified On : Sat Jul 13 08:41:55 2019 13 // Update Count : 65 14 // 15 15 16 #include "time "17 #include " iostream"16 #include "time.hfa" 17 #include "fstream.hfa" 18 18 #include <stdio.h> // snprintf 19 19 #include <assert.h> … … 31 31 32 32 33 forall( dtype ostype | ostream( ostype ) ) 34 ostype & ?|?( ostype & os, Duration dur ) with( dur ) { 35 os | tv / TIMEGRAN; // print seconds 36 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; // compute nanoseconds 37 if ( ns != 0 ) { // some ? 38 char buf[16]; 39 os | nanomsd( ns, buf ); // print nanoseconds 40 } // if 41 return os; 42 } // ?|? 33 forall( dtype ostype | ostream( ostype ) ) { 34 ostype & ?|?( ostype & os, Duration dur ) with( dur ) { 35 (ostype &)(os | tv / TIMEGRAN); // print seconds 36 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; // compute nanoseconds 37 if ( ns != 0 ) { // some ? 38 char buf[16]; 39 (ostype &)(os | nanomsd( ns, buf )); // print nanoseconds 40 } // if 41 return os; 42 } // ?|? 43 44 void ?|?( ostype & os, Duration dur ) with( dur ) { 45 (ostype &)(os | dur); ends( os ); 46 } // ?|? 47 } // distribution 43 48 44 49 … … 47 52 48 53 #ifdef __CFA_DEBUG__ 49 #define CreateFmt "Attempt to create Time( year=%d (>=1970), month=%d (1-12), day=%d (1-31), hour=%d (0-23), min=%d (0-59), sec=%d (0-60), nsec=%d (0-999_999_999), " \ 50 "which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038." 54 static void tabort( int year, int month, int day, int hour, int min, int sec, int nsec ) { 55 abort | "Attempt to create Time( year=" | year | "(>=1970), month=" | month | "(1-12), day=" | day | "(1-31), hour=" | hour | "(0-23), min=" | min | "(0-59), sec=" | sec 56 | "(0-60), nsec=" | nsec | "(0-999_999_999), which exceeds range 00:00:00 UTC, January 1, 1970 to 03:14:07 UTC, January 19, 2038."; 57 } // tabort 51 58 #endif // __CFA_DEBUG__ 52 59 … … 58 65 #ifdef __CFA_DEBUG__ 59 66 if ( month < 1 || 12 < month ) { 60 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );67 tabort( year, month, day, hour, min, sec, nsec ); 61 68 } // if 62 69 #endif // __CFA_DEBUG__ … … 64 71 #ifdef __CFA_DEBUG__ 65 72 if ( day < 1 || 31 < day ) { 66 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );73 tabort( year, month, day, hour, min, sec, nsec ); 67 74 } // if 68 75 #endif // __CFA_DEBUG__ … … 74 81 #ifdef __CFA_DEBUG__ 75 82 if ( epochsec == (time_t)-1 ) { 76 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );83 tabort( year, month, day, hour, min, sec, nsec ); 77 84 } // if 78 85 #endif // __CFA_DEBUG__ … … 80 87 #ifdef __CFA_DEBUG__ 81 88 if ( tv > 2147483647LL * TIMEGRAN ) { // between 00:00:00 UTC, January 1, 1970 and 03:14:07 UTC, January 19, 2038. 82 abort( CreateFmt, year, month, day, hour, (int)min, sec, nsec );89 tabort( year, month, day, hour, min, sec, nsec ); 83 90 } // if 84 91 #endif // __CFA_DEBUG__ … … 137 144 } // strftime 138 145 139 forall( dtype ostype | ostream( ostype ) ) 140 ostype & ?|?( ostype & os, Time time ) with( time ) { 141 char buf[32]; // at least 26 142 time_t s = tv / TIMEGRAN; 143 ctime_r( &s, (char *)&buf ); // 26 characters: "Wed Jun 30 21:49:08 1993\n" 144 buf[24] = '\0'; // remove trailing '\n' 145 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; // compute nanoseconds 146 if ( ns == 0 ) { // none ? 147 os | buf; // print date/time/year 148 } else { 149 buf[19] = '\0'; // truncate to "Wed Jun 30 21:49:08" 150 os | buf; // print date/time 151 char buf2[16]; 152 nanomsd( ns, buf2 ); // compute nanoseconds 153 os | buf2 | ' ' | &buf[20]; // print nanoseconds and year 154 } // if 155 return os; 156 } // ?|? 146 forall( dtype ostype | ostream( ostype ) ) { 147 ostype & ?|?( ostype & os, Time time ) with( time ) { 148 char buf[32]; // at least 26 149 time_t s = tv / TIMEGRAN; 150 ctime_r( &s, (char *)&buf ); // 26 characters: "Wed Jun 30 21:49:08 1993\n" 151 buf[24] = '\0'; // remove trailing '\n' 152 long int ns = (tv < 0 ? -tv : tv) % TIMEGRAN; // compute nanoseconds 153 if ( ns == 0 ) { // none ? 154 (ostype &)(os | buf); // print date/time/year 155 } else { 156 buf[19] = '\0'; // truncate to "Wed Jun 30 21:49:08" 157 char buf2[16]; 158 nanomsd( ns, buf2 ); // compute nanoseconds 159 (ostype &)(os | buf | buf2 | ' ' | &buf[20]); // print date/time, nanoseconds and year 160 } // if 161 return os; 162 } // ?|? 163 164 void ?|?( ostype & os, Time time ) with( time ) { 165 (ostype &)(os | time); ends( os ); 166 } // ?|? 167 } // distribution 157 168 158 169 // Local Variables: // -
libcfa/src/time_t.hfa
r7951100 rb067d9b 1 // 1 // 2 2 // Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo 3 3 // 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // time_t.h --8 // 6 // 7 // time_t.hfa -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Tue Apr 10 14:42:03 2018 … … 12 12 // Last Modified On : Fri Apr 13 07:51:47 2018 13 13 // Update Count : 6 14 // 14 // 15 15 16 16 #pragma once … … 24 24 25 25 static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; } 26 static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; }26 static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tv = 0; } 27 27 28 28 … … 34 34 35 35 static inline void ?{}( Time & time ) with( time ) { tv = 0; } 36 static inline void ?{}( Time & time, zero_t ) with( time ) { tv = 0; }36 static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tv = 0; } 37 37 38 38 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.