Changeset b067d9b for libcfa/src


Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
16 added
93 moved

Legend:

Unmodified
Added
Removed
  • libcfa/src/assert.cfa

    r7951100 rb067d9b  
    1717#include <stdarg.h>                                                             // varargs
    1818#include <stdio.h>                                                              // fprintf
    19 #include "bits/debug.h"
     19#include "bits/debug.hfa"
    2020
    2121extern "C" {
  • libcfa/src/bits/algorithm.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // bits/algorithms.h -- Builtins for exception handling.
     7// bits/algorithms.hfa -- Builtins for exception handling.
    88//
    99// Author           : Thierry Delisle
  • libcfa/src/bits/align.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // align.h --
     7// align.hfa --
    88//
    99// Author           : Thierry Delisle
  • libcfa/src/bits/containers.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // bits/containers.h -- Intrusive generic containers.h
     7// bits/containers.hfa -- Intrusive generic containers.hfa
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Oct 31 16:38:50 2017
    11 // Last Modified By : --
    12 // Last Modified On : --
    13 // Update Count     : 0
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun 26 08:52:20 2019
     13// Update Count     : 4
    1414
    1515#pragma once
    1616
    17 #include "bits/align.h"
    18 #include "bits/defs.h"
     17#include "bits/align.hfa"
     18#include "bits/defs.hfa"
    1919
    2020//-----------------------------------------------------------------------------
     
    7878//-----------------------------------------------------------------------------
    7979#ifdef __cforall
    80         forall(dtype TYPE | is_node(TYPE))
     80        forall(dtype TYPE)
    8181        #define T TYPE
    8282#else
     
    9595
    9696#ifdef __cforall
    97         forall(dtype T | is_node(T))
     97        forall(dtype T)
    9898        static inline void ?{}( __stack(T) & this ) {
    9999                (this.top){ NULL };
     
    116116                return top;
    117117        }
     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        }
    118123#endif
    119124
     
    122127//-----------------------------------------------------------------------------
    123128#ifdef __cforall
    124         forall(dtype TYPE | is_node(TYPE))
     129        forall(dtype TYPE)
    125130        #define T TYPE
    126131#else
     
    141146#ifdef __cforall
    142147
    143         forall(dtype T | is_node(T))
     148        forall(dtype T)
    144149        static inline void ?{}( __queue(T) & this ) with( this ) {
    145150                head{ NULL };
     
    186191
    187192        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 ) {
    189194                return this.head != 0;
    190195        }
     
    196201//-----------------------------------------------------------------------------
    197202#ifdef __cforall
    198         forall(dtype TYPE | sized(TYPE))
     203        forall(dtype TYPE)
    199204        #define T TYPE
    200205        #define __getter_t * [T * & next, T * & prev] ( T & )
     
    268273
    269274        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 ) {
    271276                return this.head != 0;
    272277        }
  • libcfa/src/bits/debug.cfa

    r7951100 rb067d9b  
    99// Author           : Thierry Delisle
    1010// Created On       : Thu Mar 30 12:30:01 2017
    11 // Last Modified By :
    12 // Last Modified On :
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Jul 14 22:17:35 2019
     13// Update Count     : 4
    1414//
    1515
     
    2323}
    2424
    25 enum { buffer_size = 512 };
     25enum { buffer_size = 4096 };
    2626static char buffer[ buffer_size ];
    2727
  • libcfa/src/bits/debug.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // debug.h --
     7// debug.hfa --
    88//
    99// Author           : Thierry Delisle
  • libcfa/src/bits/defs.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // defs.h --
     7// defs.hfa --
    88//
    99// Author           : Thierry Delisle
     
    2828
    2929#ifdef __cforall
    30 #define __cfa_anonymous_object
     30#define __cfa_anonymous_object(x) inline struct x
    3131#else
    32 #define __cfa_anonymous_object __cfa_anonymous_object
     32#define __cfa_anonymous_object(x) x __cfa_anonymous_object
    3333#endif
    3434
     
    4141}
    4242#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  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // bits/locks.h -- Fast internal locks.
     7// bits/locks.hfa -- Fast internal locks.
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Oct 31 15:14:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:18:13 2018
    13 // Update Count     : 9
     12// Last Modified On : Sat Aug 11 15:42:24 2018
     13// Update Count     : 10
    1414//
    1515
    1616#pragma once
    1717
    18 #include "bits/debug.h"
    19 #include "bits/defs.h"
     18#include "bits/debug.hfa"
     19#include "bits/defs.hfa"
    2020#include <assert.h>
    2121
     
    3737#endif
    3838
    39 #if defined( __i386 ) || defined( __x86_64 ) || defined( __ARM_ARCH )
    40         // Intel recommendation
    41         #define __ALIGN__ __attribute__(( aligned (128) ))
    42 #elif defined( __sparc )
    43         #define __ALIGN__ CALIGN
    44 #else
    45         #error unsupported architecture
    46 #endif
    47 
    4839struct __spinlock_t {
    4940        // 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;
    5442        #ifdef __CFA_DEBUG__
    5543                // previous function to acquire the lock
     
    5846                void* prev_thrd;
    5947        #endif
    60 } __ALIGN__;
     48};
    6149
    6250#ifdef __cforall
    6351        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
    6660        }
    6761
     
    7266        }
    7367
    74 
    75         #ifdef __CFA_DEBUG__
    76                 void __cfaabi_dbg_record(__spinlock_t & this, const char * prev_name);
    77         #else
    78                 #define __cfaabi_dbg_record(x, y)
    79         #endif
    80 
    8168        // 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);
    8471                if( result ) {
    8572                        disable_interrupts();
     
    126113
    127114        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;
    131118        };
    132119
    133120        static inline void ?{}(__bin_sem_t & this) with( this ) {
    134                 counter = 0;
     121                signaled = false;
    135122                pthread_mutex_init(&lock, NULL);
    136123                pthread_cond_init (&cond, NULL);
     
    145132                verify(__cfaabi_dbg_in_kernel());
    146133                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;
    151138                pthread_mutex_unlock(&lock);
    152139        }
     
    154141        static inline void post(__bin_sem_t & this) with( this ) {
    155142                verify(__cfaabi_dbg_in_kernel());
     143
    156144                pthread_mutex_lock(&lock);
    157                 bool needs_signal = counter == 0;
    158                 counter = 1;
     145                        bool needs_signal = !signaled;
     146                        signaled = true;
    159147                pthread_mutex_unlock(&lock);
    160                 if (!needs_signal)
     148
     149                if (needs_signal)
    161150                        pthread_cond_signal(&cond);
    162                 }
     151        }
    163152#endif
  • libcfa/src/bits/signal.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // bits/signal.h -- Helper functions and defines to use signals
     7// bits/signal.hfa -- Helper functions and defines to use signals
    88//
    99// Author           : Thierry Delisle
     
    1616#pragma once
    1717
    18 #include "bits/debug.h"
    19 #include "bits/defs.h"
     18#include "bits/debug.hfa"
     19#include "bits/defs.hfa"
    2020
    2121extern "C" {
  • libcfa/src/concurrency/CtxSwitch-i386.S

    r7951100 rb067d9b  
    4141#define PC_OFFSET       ( 2 * PTR_BYTE )
    4242
    43 .text
     43        .text
    4444        .align 2
    45 .globl  CtxSwitch
     45        .globl CtxSwitch
     46        .type  CtxSwitch, @function
    4647CtxSwitch:
    4748
     
    5051
    5152        movl 4(%esp),%eax
    52 
    53         // Save floating & SSE control words on the stack.
    54 
    55         sub    $8,%esp
    56         stmxcsr 0(%esp)         // 4 bytes
    57         fnstcw  4(%esp)         // 2 bytes
    5853
    5954        // Save volatile registers on the stack.
     
    6762        movl %esp,SP_OFFSET(%eax)
    6863        movl %ebp,FP_OFFSET(%eax)
    69 //      movl 4(%ebp),%ebx       // save previous eip for debugger
    70 //      movl %ebx,PC_OFFSET(%eax)
    7164
    7265        // Copy the "to" context argument from the stack to register eax
     
    7467        // argument is now at 8 + 12 = 20(%esp)
    7568
    76         movl 28(%esp),%eax
     69        movl 20(%esp),%eax
    7770
    7871        // Load new context from the "to" area.
     
    8780        popl %ebx
    8881
    89         // Load floating & SSE control words from the stack.
    90 
    91         fldcw   4(%esp)
    92         ldmxcsr 0(%esp)
    93         add    $8,%esp
    94 
    9582        // Return to thread.
    9683
    9784        ret
     85        .size  CtxSwitch, .-CtxSwitch
    9886
    9987// Local Variables: //
  • libcfa/src/concurrency/CtxSwitch-x86_64.S

    r7951100 rb067d9b  
    3939#define SP_OFFSET       ( 0 * PTR_BYTE )
    4040#define FP_OFFSET       ( 1 * PTR_BYTE )
    41 #define PC_OFFSET       ( 2 * PTR_BYTE )
    4241
    43 .text
     42//-----------------------------------------------------------------------------
     43// Regular context switch routine which enables switching from one context to anouther
     44        .text
    4445        .align 2
    45 .globl  CtxSwitch
     46        .globl CtxSwitch
     47        .type  CtxSwitch, @function
    4648CtxSwitch:
    47 
    48         // Save floating & SSE control words on the stack.
    49 
    50         subq   $8,%rsp
    51         stmxcsr 0(%rsp)         // 4 bytes
    52         fnstcw  4(%rsp)         // 2 bytes
    5349
    5450        // Save volatile registers on the stack.
     
    7874        popq %r15
    7975
    80         // Load floating & SSE control words from the stack.
    81 
    82         fldcw   4(%rsp)
    83         ldmxcsr 0(%rsp)
    84         addq   $8,%rsp
    85 
    8676        // Return to thread.
    8777
    8878        ret
     79        .size  CtxSwitch, .-CtxSwitch
    8980
    90 .text
     81//-----------------------------------------------------------------------------
     82// Stub used to create new stacks which are ready to be context switched to
     83        .text
    9184        .align 2
    92 .globl  CtxInvokeStub
     85        .globl CtxInvokeStub
     86        .type    CtxInvokeStub, @function
    9387CtxInvokeStub:
    9488        movq %rbx, %rdi
    9589        jmp *%r12
     90        .size  CtxInvokeStub, .-CtxInvokeStub
    9691
    9792// Local Variables: //
  • libcfa/src/concurrency/alarm.cfa

    r7951100 rb067d9b  
    1414//
    1515
     16#define __cforall_thread__
     17
    1618extern "C" {
    1719#include <errno.h>
     
    2224}
    2325
    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"
    2729
    2830//=============================================================================================
  • libcfa/src/concurrency/alarm.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // alarm.h --
     7// alarm.hfa --
    88//
    99// Author           : Thierry Delisle
     
    2121#include <assert.h>
    2222
    23 #include "time"
     23#include "time.hfa"
    2424
    2525struct thread_desc;
  • libcfa/src/concurrency/coroutine.hfa

    r7951100 rb067d9b  
    1010// Created On       : Mon Nov 28 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 30 18:23:45 2018
    13 // Update Count     : 8
     12// Last Modified On : Fri Jun 21 17:49:39 2019
     13// Update Count     : 9
    1414//
    1515
     
    4646//-----------------------------------------------------------------------------
    4747// Public coroutine API
    48 static inline void suspend();
     48static inline void suspend(void);
    4949
    5050forall(dtype T | is_coroutine(T))
    51 static inline void resume(T & cor);
     51static inline T & resume(T & cor);
    5252
    5353forall(dtype T | is_coroutine(T))
    5454void prime(T & cor);
     55
     56static inline struct coroutine_desc * active_coroutine() { return TL_GET( this_thread )->curr_cor; }
    5557
    5658//-----------------------------------------------------------------------------
     
    6466      forall(dtype T | is_coroutine(T))
    6567      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");
    6672}
    6773
    6874// 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
     76static 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
     96extern void __stack_prepare   ( __stack_info_t * this, size_t size /* ignored if storage already allocated */);
    7197
    7298// Suspend implementation inlined for performance
    73 static inline void suspend() {
     99static inline void suspend(void) {
    74100        // optimization : read TLS once and reuse it
    75101        // Safety note: this is preemption safe since if
     
    77103        // will also migrate which means this value will
    78104        // stay in syn with the TLS
    79         coroutine_desc * src = TL_GET( this_coroutine );
     105        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    80106
    81107        assertf( src->last != 0,
     
    93119// Resume implementation inlined for performance
    94120forall(dtype T | is_coroutine(T))
    95 static inline void resume(T & cor) {
     121static inline T & resume(T & cor) {
    96122        // optimization : read TLS once and reuse it
    97123        // Safety note: this is preemption safe since if
     
    99125        // will also migrate which means this value will
    100126        // stay in syn with the TLS
    101         coroutine_desc * src = TL_GET( this_coroutine );
     127        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    102128        coroutine_desc * dst = get_coroutine(cor);
    103129
    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);
    106132                CtxStart(&cor, CtxInvokeCoroutine);
    107133        }
     
    121147        // always done for performance testing
    122148        CoroutineCtxSwitch( src, dst );
     149
     150        return cor;
    123151}
    124152
     
    129157        // will also migrate which means this value will
    130158        // stay in syn with the TLS
    131         coroutine_desc * src = TL_GET( this_coroutine );
     159        coroutine_desc * src = TL_GET( this_thread )->curr_cor;
    132160
    133161        // not resuming self ?
  • libcfa/src/concurrency/invoke.c

    r7951100 rb067d9b  
    1414//
    1515
     16#define __cforall_thread__
     17
    1618#include <stdbool.h>
    1719#include <stdlib.h>
    1820#include <stdio.h>
     21#include <unwind.h>
    1922
    2023#include "invoke.h"
     
    2730
    2831extern void __suspend_internal(void);
    29 extern void __leave_coroutine(void);
    30 extern void __finish_creation(void);
     32extern void __leave_coroutine( struct coroutine_desc * );
     33extern void __finish_creation( struct thread_desc * );
    3134extern void __leave_thread_monitor( struct thread_desc * this );
    32 extern void disable_interrupts();
     35extern void disable_interrupts() OPTIONAL_THREAD;
    3336extern void enable_interrupts( __cfaabi_dbg_ctx_param );
    3437
     
    4649        cor->state = Active;
    4750
    48         enable_interrupts( __cfaabi_dbg_ctx );
    49 
    5051        main( this );
    5152
    52         cor->state = Halted;
     53        //Final suspend, should never return
     54        __leave_coroutine( cor );
     55        __cabi_abort( "Resumed dead coroutine" );
     56}
    5357
    54         //Final suspend, should never return
    55         __leave_coroutine();
    56         __cabi_abort( "Resumed dead coroutine" );
     58static _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
     77void _CtxCoroutine_Unwind(struct _Unwind_Exception * storage, struct coroutine_desc * cor) __attribute__ ((__noreturn__));
     78void _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();
    5782}
    5883
     
    6388        void *this
    6489) {
     90        // Fetch the thread handle from the user defined thread structure
     91        struct thread_desc* thrd = get_thread( this );
     92
    6593        // First suspend, once the thread arrives here,
    6694        // 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 );
    7296
    7397        // Officially start the thread by enabling preemption
     
    95119        void (*invoke)(void *)
    96120) {
    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;
    98123
    99124#if defined( __i386 )
    100125
    101126        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)
    105128            void *rturn;                          // where to go on return from uSwitch
    106             void *dummyReturn;                          // fake return compiler would have pushed on call to uInvoke
    107             void *argument[3];                          // for 16-byte ABI, 16-byte alignment starts here
    108             void *padding;                              // padding to force 16-byte alignment, as "base" is 16-byte aligned
     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
    109132        };
    110133
    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 fp
     134        cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );
     135        cor->context.FP = NULL;         // terminate stack with NULL fp
    113136
    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-520
    118         ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     137        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;
    119142
    120143#elif defined( __x86_64 )
     
    122145        struct FakeStack {
    123146                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)
    126147                void *rturn;                        // where to go on return from uSwitch
    127148                void *dummyReturn;                  // NULL return address to provide proper alignment
    128149        };
    129150
    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 fp
     151        cor->context.SP = (char *)stack->base - sizeof( struct FakeStack );
     152        cor->context.FP = NULL;         // terminate stack with NULL fp
    132153
    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-520
    138         ((struct FakeStack *)(((struct machine_context_t *)stack->context)->SP))->fcw = 0x037F;  //Vol. 1 8-7
     154        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;
    139160
    140161#elif defined( __ARM_ARCH )
     
    146167        };
    147168
    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;
    150171
    151         struct FakeStack *fs = (struct FakeStack *)((struct machine_context_t *)stack->context)->SP;
     172        struct FakeStack *fs = (struct FakeStack *)cor->context.SP;
    152173
    153174        fs->intRegs[8] = CtxInvokeStub;
  • libcfa/src/concurrency/invoke.h

    r7951100 rb067d9b  
    1010// Created On       : Tue Jan 17 12:27:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 19 08:23:21 2018
    13 // Update Count     : 31
    14 //
    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"
    1919
    2020#ifdef __cforall
     
    4646        #ifdef __cforall
    4747        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 
    5148                extern thread_local struct KernelThreadData {
    52                         struct coroutine_desc * volatile this_coroutine;
    5349                        struct thread_desc    * volatile this_thread;
    5450                        struct processor      * volatile this_processor;
     
    5955                                volatile bool in_progress;
    6056                        } preemption_state;
    61                 } kernelTLS;
     57                } kernelTLS __attribute__ ((tls_model ( "initial-exec" )));
    6258        }
    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 ); } // UNSAFE
    6759        #endif
    6860
    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;
    7790        };
    7891
     
    8093
    8194        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
    90119        struct __waitfor_mask_t {
    91120                // the index of the accepted function, -1 if none
     
    93122
    94123                // 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) );
    96125        };
    97126
     
    121150        struct __monitor_group_t {
    122151                // currently held monitors
    123                 __small_array_t(monitor_desc*) __cfa_anonymous_object;
     152                __cfa_anonymous_object( __small_array_t(monitor_desc*) );
    124153
    125154                // last function that acquired monitors
     
    129158        struct thread_desc {
    130159                // 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
    131168                // coroutine body used to store context
    132169                struct coroutine_desc  self_cor;
     
    155192                        struct thread_desc * prev;
    156193                } node;
    157      };
    158 
    159      #ifdef __cforall
    160      extern "Cforall" {
    161                 static inline thread_desc * & get_next( thread_desc & this ) {
     194        };
     195
     196        #ifdef __cforall
     197        extern "Cforall" {
     198                static inline thread_desc *& get_next( thread_desc & this ) {
    162199                        return this.next;
    163200                }
     
    166203                        return this.node.[next, prev];
    167204                }
    168 
    169                 static inline struct __condition_criterion_t * & get_next( struct __condition_criterion_t & this );
    170205
    171206                static inline void ?{}(__monitor_group_t & this) {
     
    216251        // assembler routines that performs the context switch
    217252        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");
    238256
    239257#endif //_INVOKE_PRIVATE_H_
  • libcfa/src/concurrency/kernel.cfa

    r7951100 rb067d9b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Apr  9 16:11:46 2018
    13 // Update Count     : 24
     12// Last Modified On : Thu Jun 20 17:21:23 2019
     13// Update Count     : 25
    1414//
     15
     16#define __cforall_thread__
    1517
    1618//C Includes
     
    2729
    2830//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"
    3335
    3436//Private includes
     
    3638#include "invoke.h"
    3739
     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//-----------------------------------------------------------------------------
    38109//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 ) ));
     110static void kernel_startup(void)  __attribute__(( constructor( STARTUP_PRIORITY_KERNEL ) ));
     111static void kernel_shutdown(void) __attribute__(( destructor ( STARTUP_PRIORITY_KERNEL ) ));
    41112
    42113//-----------------------------------------------------------------------------
    43114// Kernel storage
    44 KERNEL_STORAGE(cluster,           mainCluster);
    45 KERNEL_STORAGE(processor,         mainProcessor);
    46 KERNEL_STORAGE(thread_desc,       mainThread);
    47 KERNEL_STORAGE(machine_context_t, mainThreadCtx);
     115KERNEL_STORAGE(cluster,         mainCluster);
     116KERNEL_STORAGE(processor,       mainProcessor);
     117KERNEL_STORAGE(thread_desc,     mainThread);
     118KERNEL_STORAGE(__stack_t,       mainThreadCtx);
    48119
    49120cluster     * mainCluster;
     
    55126}
    56127
     128size_t __page_size = 0;
     129
    57130//-----------------------------------------------------------------------------
    58131// Global state
    59 thread_local struct KernelThreadData kernelTLS = {
    60         NULL,
     132thread_local struct KernelThreadData kernelTLS __attribute__ ((tls_model ( "initial-exec" ))) = {
    61133        NULL,
    62134        NULL,
     
    67139// Struct to steal stack
    68140struct current_stack_info_t {
    69         machine_context_t ctx;
    70         unsigned int size;              // size of stack
     141        __stack_t * storage;            // pointer to stack object
    71142        void *base;                             // base of stack
    72         void *storage;                  // pointer to stack
    73143        void *limit;                    // stack grows towards stack limit
    74144        void *context;                  // address of cfa_context_t
    75         void *top;                              // address of top of storage
    76145};
    77146
    78147void ?{}( 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;
    82151
    83152        rlimit r;
    84153        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);
    88157        this.context = &storage_mainThreadCtx;
    89         this.top = this.base;
    90158}
    91159
    92160//-----------------------------------------------------------------------------
    93161// 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 }
    103162
    104163void ?{}( 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;
    106171        name = "Main Thread";
    107         errno_ = 0;
    108172        state = Start;
    109173        starter = NULL;
     174        last = NULL;
     175        cancellation = NULL;
    110176}
    111177
    112178void ?{}( thread_desc & this, current_stack_info_t * info) with( this ) {
     179        state = Start;
    113180        self_cor{ info };
    114181        curr_cor = &self_cor;
     
    133200
    134201// Construct the processor context of non-main processors
    135 void ?{}(processorCtx_t & this, processor * proc, current_stack_info_t * info) {
     202static void ?{}(processorCtx_t & this, processor * proc, current_stack_info_t * info) {
    136203        (this.__cor){ info };
    137204        this.proc = proc;
    138205}
    139206
     207static void start(processor * this);
    140208void ?{}(processor & this, const char * name, cluster & cltr) with( this ) {
    141209        this.name = name;
     
    147215        runner.proc = &this;
    148216
    149         sem_init(&idleLock, 0, 0);
     217        idleLock{};
    150218
    151219        start( &this );
     
    155223        if( ! __atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) ) {
    156224                __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
    160229                P( terminated );
    161230                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 );
    166234}
    167235
     
    186254// Kernel Scheduling logic
    187255//=============================================================================================
     256static void runThread(processor * this, thread_desc * dst);
     257static void finishRunning(processor * this);
     258static void halt(processor * this);
     259
    188260//Main of the processor contexts
    189261void main(processorCtx_t & runner) {
     
    236308}
    237309
     310static int * __volatile_errno() __attribute__((noinline));
     311static int * __volatile_errno() { asm(""); return &errno; }
     312
    238313// KERNEL ONLY
    239314// runThread runs a thread by context switching
    240315// from the processor coroutine to the target thread
    241 void runThread(processor * this, thread_desc * dst) {
    242         assert(dst->curr_cor);
     316static void runThread(processor * this, thread_desc * thrd_dst) {
    243317        coroutine_desc * proc_cor = get_coroutine(this->runner);
    244         coroutine_desc * thrd_cor = dst->curr_cor;
    245318
    246319        // Reset the terminating actions here
     
    248321
    249322        // 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;
    255337}
    256338
    257339// KERNEL_ONLY
    258 void returnToKernel() {
     340static void returnToKernel() {
    259341        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;
    262365}
    263366
     
    265368// Once a thread has finished running, some of
    266369// its final actions must be executed from the kernel
    267 void finishRunning(processor * this) with( this->finish ) {
     370static void finishRunning(processor * this) with( this->finish ) {
    268371        verify( ! kernelTLS.preemption_state.enabled );
    269372        choose( action_code ) {
     
    295398}
    296399
    297 // Handles spinning logic
    298 // TODO : find some strategy to put cores to sleep after some time
    299 void spin(processor * this, unsigned int * spin_count) {
    300         // (*spin_count)++;
    301         halt(this);
    302 }
    303 
    304400// KERNEL_ONLY
    305401// Context invoker for processors
    306402// This is the entry point for processors (kernel threads)
    307403// It effectively constructs a coroutine by stealing the pthread stack
    308 void * CtxInvokeProcessor(void * arg) {
     404static void * CtxInvokeProcessor(void * arg) {
    309405        processor * proc = (processor *) arg;
    310406        kernelTLS.this_processor = proc;
    311         kernelTLS.this_coroutine = NULL;
    312407        kernelTLS.this_thread    = NULL;
    313408        kernelTLS.preemption_state.[enabled, disable_count] = [false, 1];
     
    316411        // to waste the perfectly valid stack create by pthread.
    317412        current_stack_info_t info;
    318         machine_context_t ctx;
    319         info.context = &ctx;
     413        __stack_t ctx;
     414        info.storage = &ctx;
    320415        (proc->runner){ proc, &info };
    321416
    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);
    323418
    324419        //Set global state
    325         kernelTLS.this_coroutine = get_coroutine(proc->runner);
    326420        kernelTLS.this_thread    = NULL;
    327421
     
    343437}
    344438
    345 void start(processor * this) {
     439static void start(processor * this) {
    346440        __cfaabi_dbg_print_safe("Kernel : Starting core %p\n", this);
    347441
     
    352446
    353447// KERNEL_ONLY
    354 void kernel_first_resume(processor * this) {
    355         coroutine_desc * src = kernelTLS.this_coroutine;
     448void kernel_first_resume( processor * this ) {
     449        thread_desc * src = mainThread;
    356450        coroutine_desc * dst = get_coroutine(this->runner);
    357451
    358452        verify( ! kernelTLS.preemption_state.enabled );
    359453
    360         create_stack(&dst->stack, dst->stack.size);
     454        __stack_prepare( &dst->stack, 65000 );
    361455        CtxStart(&this->runner, CtxInvokeCoroutine);
    362456
    363457        verify( ! kernelTLS.preemption_state.enabled );
    364458
    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;
    367461
    368462        // set state of current coroutine to inactive
    369463        src->state = src->state == Halted ? Halted : Inactive;
    370464
    371         // set new coroutine that task is executing
    372         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 will
    378         // stay disabled.
    379         disable_interrupts();
    380 
    381465        // 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 );
    384468        // when CtxSwitch returns we are back in the src coroutine
    385469
     
    388472
    389473        verify( ! kernelTLS.preemption_state.enabled );
     474}
     475
     476// KERNEL_ONLY
     477void 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 );
    390487}
    391488
     
    396493void ScheduleThread( thread_desc * thrd ) {
    397494        verify( thrd );
    398         verify( thrd->self_cor.state != Halted );
     495        verify( thrd->state != Halted );
    399496
    400497        verify( ! kernelTLS.preemption_state.enabled );
     
    408505                unlock( ready_queue_lock );
    409506
    410                 if( was_empty ) {
     507                if(was_empty) {
    411508                        lock      (proc_list_lock __cfaabi_dbg_ctx2);
    412509                        if(idles) {
    413                                 wake(idles.head);
     510                                wake_fast(idles.head);
    414511                        }
    415512                        unlock    (proc_list_lock);
    416513                }
     514                else if( struct processor * idle = idles.head ) {
     515                        wake_fast(idle);
     516                }
     517
    417518        }
    418519
     
    545646//-----------------------------------------------------------------------------
    546647// Kernel boot procedures
    547 void kernel_startup(void) {
     648static void kernel_startup(void) {
    548649        verify( ! kernelTLS.preemption_state.enabled );
    549650        __cfaabi_dbg_print_safe("Kernel : Starting\n");
     651
     652        __page_size = sysconf( _SC_PAGESIZE );
    550653
    551654        __cfa_dbg_global_clusters.list{ __get };
     
    563666        mainThread = (thread_desc *)&storage_mainThread;
    564667        current_stack_info_t info;
     668        info.storage = (__stack_t*)&storage_mainThreadCtx;
    565669        (*mainThread){ &info };
    566670
     
    597701        kernelTLS.this_processor = mainProcessor;
    598702        kernelTLS.this_thread    = mainThread;
    599         kernelTLS.this_coroutine = &mainThread->self_cor;
    600703
    601704        // Enable preemption
     
    621724}
    622725
    623 void kernel_shutdown(void) {
     726static void kernel_shutdown(void) {
    624727        __cfaabi_dbg_print_safe("\n--------------------------------------------------\nKernel : Shutting down\n");
    625728
     
    632735        // which is currently here
    633736        __atomic_store_n(&mainProcessor->do_terminate, true, __ATOMIC_RELEASE);
    634         returnToKernel();
     737        kernel_last_resume( kernelTLS.this_processor );
    635738        mainThread->self_cor.state = Halted;
    636739
     
    658761// Kernel Quiescing
    659762//=============================================================================================
    660 
    661 void halt(processor * this) with( *this ) {
    662         verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
     763static void halt(processor * this) with( *this ) {
     764        // verify( ! __atomic_load_n(&do_terminate, __ATOMIC_SEQ_CST) );
    663765
    664766        with( *cltr ) {
     
    671773        __cfaabi_dbg_print_safe("Kernel : Processor %p ready to sleep\n", this);
    672774
    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 );
    684776
    685777        __cfaabi_dbg_print_safe("Kernel : Processor %p woke up and ready to run\n", this);
     
    693785}
    694786
    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         // #endif
    705 
    706         // post( this->idleLock );
    707 }
    708 
    709787//=============================================================================================
    710788// Unexpected Terminating logic
    711789//=============================================================================================
    712 
    713 
    714790static __spinlock_t kernel_abort_lock;
    715791static bool kernel_abort_called = false;
     
    745821                __cfaabi_dbg_bits_write( abort_text, len );
    746822
    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 );
    749825                        __cfaabi_dbg_bits_write( abort_text, len );
    750826                }
     
    833909void doregister( cluster * cltr, thread_desc & thrd ) {
    834910        lock      (cltr->thread_list_lock __cfaabi_dbg_ctx2);
     911        cltr->nthreads += 1;
    835912        push_front(cltr->threads, thrd);
    836913        unlock    (cltr->thread_list_lock);
     
    840917        lock  (cltr->thread_list_lock __cfaabi_dbg_ctx2);
    841918        remove(cltr->threads, thrd );
     919        cltr->nthreads -= 1;
    842920        unlock(cltr->thread_list_lock);
    843921}
     
    845923void doregister( cluster * cltr, processor * proc ) {
    846924        lock      (cltr->proc_list_lock __cfaabi_dbg_ctx2);
     925        cltr->nprocessors += 1;
    847926        push_front(cltr->procs, *proc);
    848927        unlock    (cltr->proc_list_lock);
     
    852931        lock  (cltr->proc_list_lock __cfaabi_dbg_ctx2);
    853932        remove(cltr->procs, *proc );
     933        cltr->nprocessors -= 1;
    854934        unlock(cltr->proc_list_lock);
    855935}
     
    858938// Debug
    859939__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                }
    863945        }
    864946)
     947
     948//-----------------------------------------------------------------------------
     949// Debug
     950bool threading_enabled(void) {
     951        return true;
     952}
    865953// Local Variables: //
    866954// mode: c //
  • libcfa/src/concurrency/kernel.hfa

    r7951100 rb067d9b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 10 14:46:49 2018
    13 // Update Count     : 10
     12// Last Modified On : Sat Jun 22 11:39:17 2019
     13// Update Count     : 16
    1414//
    1515
     
    1919
    2020#include "invoke.h"
    21 #include "time_t.h"
     21#include "time_t.hfa"
    2222
    2323extern "C" {
     
    9191        this.lock = NULL;
    9292}
    93 static inline void ^?{}(FinishAction & this) {}
     93static inline void ^?{}(FinishAction &) {}
    9494
    9595// Processor
     
    113113        pthread_t kernel_thread;
    114114
     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
    115129        // Termination
    116130        // Set to true to notify the processor should terminate
     
    119133        // Termination synchronisation
    120134        semaphore terminated;
    121 
    122         // RunThread data
    123         // Action to do after a thread is ran
    124         struct FinishAction finish;
    125 
    126         // Preemption data
    127         // Node which is added in the discrete event simulaiton
    128         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 possible
    131         bool pending_preemption;
    132 
    133         // Idle lock
    134         sem_t idleLock;
    135         // __bin_sem_t idleLock;
    136135
    137136        // Link lists fields
     
    177176        __dllist_t(struct processor) procs;
    178177        __dllist_t(struct processor) idles;
    179 
    180         // List of processors
     178        unsigned int nprocessors;
     179
     180        // List of threads
    181181        __spinlock_t thread_list_lock;
    182182        __dllist_t(struct thread_desc) threads;
     183        unsigned int nthreads;
    183184
    184185        // Link lists fields
     
    201202}
    202203
     204static inline struct processor * active_processor() { return TL_GET( this_processor ); } // UNSAFE
     205static inline struct cluster   * active_cluster  () { return TL_GET( this_processor )->cltr; }
     206
    203207// Local Variables: //
    204208// mode: c //
  • libcfa/src/concurrency/kernel_private.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // kernel_private.h --
     7// kernel_private.hfa --
    88//
    99// Author           : Thierry Delisle
     
    1616#pragma once
    1717
    18 #include "kernel"
    19 #include "thread"
     18#include "kernel.hfa"
     19#include "thread.hfa"
    2020
    21 #include "alarm.h"
     21#include "alarm.hfa"
    2222
    2323
     
    2626
    2727extern "C" {
    28         void disable_interrupts();
     28        void disable_interrupts() OPTIONAL_THREAD;
    2929        void enable_interrupts_noPoll();
    3030        void enable_interrupts( __cfaabi_dbg_ctx_param );
     
    3434static inline void WakeThread( thread_desc * thrd ) {
    3535        if( !thrd ) return;
     36
     37        verify(thrd->state == Inactive);
    3638
    3739        disable_interrupts();
     
    5456// Processor
    5557void 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
     59static inline void wake_fast(processor * this) {
     60        __cfaabi_dbg_print_safe("Kernel : Waking up processor %p\n", this);
     61        post( this->idleLock );
     62}
     63
     64static inline void wake(processor * this) {
     65        disable_interrupts();
     66        wake_fast(this);
     67        enable_interrupts( __cfaabi_dbg_ctx );
     68}
    6369
    6470struct event_kernel_t {
     
    6975extern event_kernel_t * event_kernel;
    7076
    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 
    7977struct __cfa_kernel_preemption_state_t {
    8078        bool enabled;
     
    8381};
    8482
    85 extern volatile thread_local __cfa_kernel_preemption_state_t preemption_state;
     83extern volatile thread_local __cfa_kernel_preemption_state_t preemption_state __attribute__ ((tls_model ( "initial-exec" )));
    8684
    8785//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/monitor.cfa

    r7951100 rb067d9b  
    1414//
    1515
    16 #include "monitor"
    17 
    18 #include <stdlib>
     16#define __cforall_thread__
     17
     18#include "monitor.hfa"
     19
     20#include <stdlib.hfa>
    1921#include <inttypes.h>
    2022
    21 #include "kernel_private.h"
    22 
    23 #include "bits/algorithms.h"
     23#include "kernel_private.hfa"
     24
     25#include "bits/algorithm.hfa"
    2426
    2527//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/monitor.hfa

    r7951100 rb067d9b  
    2020#include <assert.h>
    2121#include "invoke.h"
    22 #include "stdlib"
     22#include "stdlib.hfa"
    2323
    2424trait is_monitor(dtype T) {
     
    138138
    139139struct __acceptable_t {
    140         __monitor_group_t;
     140        inline struct __monitor_group_t;
    141141        bool is_dtor;
    142142};
  • libcfa/src/concurrency/mutex.cfa

    r7951100 rb067d9b  
    1616//
    1717
    18 #include "mutex"
     18#define __cforall_thread__
    1919
    20 #include "kernel_private.h"
     20#include "mutex.hfa"
     21
     22#include "kernel_private.hfa"
    2123
    2224//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/mutex.hfa

    r7951100 rb067d9b  
    2020#include <stdbool.h>
    2121
    22 #include "bits/algorithms.h"
    23 #include "bits/locks.h"
     22#include "bits/algorithm.hfa"
     23#include "bits/locks.hfa"
    2424
    2525#include "invoke.h"
    26 #include "time_t.h"
     26#include "time_t.hfa"
    2727
    2828//-----------------------------------------------------------------------------
  • libcfa/src/concurrency/preemption.cfa

    r7951100 rb067d9b  
    1414//
    1515
    16 #include "preemption.h"
     16#define __cforall_thread__
     17
     18#include "preemption.hfa"
    1719#include <assert.h>
    1820
     
    2426}
    2527
    26 #include "bits/signal.h"
     28#include "bits/signal.hfa"
    2729
    2830#if !defined(__CFA_DEFAULT_PREEMPTION__)
     
    3941
    4042// 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__ );
     43static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ );
     44static void sigHandler_segv     ( __CFA_SIGPARMS__ );
     45static void sigHandler_ill      ( __CFA_SIGPARMS__ );
     46static void sigHandler_fpe      ( __CFA_SIGPARMS__ );
     47static void sigHandler_abort    ( __CFA_SIGPARMS__ );
    4648
    4749// FwdDeclarations : alarm thread main
    48 void * alarm_loop( __attribute__((unused)) void * args );
     50static void * alarm_loop( __attribute__((unused)) void * args );
    4951
    5052// Machine specific register name
     
    6365static pthread_t alarm_thread;                        // pthread handle to alarm thread
    6466
    65 void ?{}(event_kernel_t & this) with( this ) {
     67static void ?{}(event_kernel_t & this) with( this ) {
    6668        alarms{};
    6769        lock{};
     
    8587
    8688// Tick one frame of the Discrete Event Simulation for alarms
    87 void tick_preemption() {
     89static void tick_preemption() {
    8890        alarm_node_t * node = NULL;                     // Used in the while loop but cannot be declared in the while condition
    8991        alarm_list_t * alarms = &event_kernel->alarms;  // Local copy for ease of reading
     
    263265}
    264266
    265 // kill wrapper : signal a processor
    266 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 
    275267// reserved for future use
    276268static void timeout( thread_desc * this ) {
     
    360352// Context switch signal handler
    361353// Receives SIGUSR1 signal and causes the current thread to yield
    362 void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
     354static void sigHandler_ctxSwitch( __CFA_SIGPARMS__ ) {
    363355        __cfaabi_dbg_debug_do( last_interrupt = (void *)(cxt->uc_mcontext.CFA_REG_IP); )
    364356
     
    403395// Main of the alarm thread
    404396// Waits on SIGALRM and send SIGUSR1 to whom ever needs it
    405 void * alarm_loop( __attribute__((unused)) void * args ) {
     397static void * alarm_loop( __attribute__((unused)) void * args ) {
    406398        // Block sigalrms to control when they arrive
    407399        sigset_t mask;
  • libcfa/src/concurrency/preemption.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // preemption.h --
     7// preemption.hfa --
    88//
    99// Author           : Thierry Delisle
     
    1616#pragma once
    1717
    18 #include "alarm.h"
    19 #include "kernel_private.h"
     18#include "alarm.hfa"
     19#include "kernel_private.hfa"
    2020
    2121void kernel_start_preemption();
    2222void kernel_stop_preemption();
    2323void update_preemption( processor * this, Duration duration );
    24 void tick_preemption();
    2524
    2625struct preemption_scope {
  • libcfa/src/concurrency/thread.cfa

    r7951100 rb067d9b  
    1414//
    1515
    16 #include "thread"
     16#define __cforall_thread__
    1717
    18 #include "kernel_private.h"
     18#include "thread.hfa"
     19
     20#include "kernel_private.hfa"
    1921
    2022#define __CFA_INVOKE_PRIVATE__
     
    3133// Thread ctors and dtors
    3234void ?{}(thread_desc & this, const char * const name, cluster & cl, void * storage, size_t storageSize ) with( this ) {
     35        context{ NULL, NULL };
    3336        self_cor{ name, storage, storageSize };
    34         verify(&self_cor);
     37        state = Start;
    3538        curr_cor = &self_cor;
    3639        self_mon.owner = &this;
     
    7376forall( dtype T | is_thread(T) )
    7477void __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 );
    8080
    8181        disable_interrupts();
    82         create_stack(&thrd_c->stack, thrd_c->stack.size);
    83         kernelTLS.this_coroutine = thrd_c;
    8482        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 );
    8786
    88         ScheduleThread(thrd_h);
     87        ScheduleThread(this_thrd);
    8988        enable_interrupts( __cfaabi_dbg_ctx );
    9089}
     
    9291extern "C" {
    9392        // 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 );
    9799        }
    98100}
     
    112114}
    113115
    114 // KERNEL ONLY
    115 void ThreadCtxSwitch(coroutine_desc* src, coroutine_desc* dst) {
    116         // set state of current coroutine to inactive
    117         src->state = src->state == Halted ? Halted : Inactive;
    118         dst->state = Active;
    119 
    120         // set new coroutine that the processor is executing
    121         // and context switch to it
    122         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 active
    128         dst->state = dst->state == Halted ? Halted : Inactive;
    129         src->state = Active;
    130 }
    131 
    132116// Local Variables: //
    133117// mode: c //
  • libcfa/src/concurrency/thread.hfa

    r7951100 rb067d9b  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 29 14:07:11 2018
    13 // Update Count     : 4
     12// Last Modified On : Fri Jun 21 17:51:33 2019
     13// Update Count     : 5
    1414//
    1515
     
    1919#include "invoke.h"
    2020
    21 #include "coroutine"
    22 #include "kernel"
    23 #include "monitor"
     21#include "coroutine.hfa"
     22#include "kernel.hfa"
     23#include "monitor.hfa"
    2424
    2525//-----------------------------------------------------------------------------
     
    6161void ^?{}(thread_desc & this);
    6262
    63 static inline void ?{}(thread_desc & this)                                                                  { this{ "Anonymous Thread", *mainCluster, NULL, 0 }; }
     63static inline void ?{}(thread_desc & this)                                                                  { this{ "Anonymous Thread", *mainCluster, NULL, 65000 }; }
    6464static inline void ?{}(thread_desc & this, size_t stackSize )                                               { this{ "Anonymous Thread", *mainCluster, NULL, stackSize }; }
    6565static 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 }; }
     66static inline void ?{}(thread_desc & this, struct cluster & cl )                                            { this{ "Anonymous Thread", cl, NULL, 65000 }; }
     67static inline void ?{}(thread_desc & this, struct cluster & cl, size_t stackSize )                          { this{ "Anonymous Thread", cl, NULL, stackSize }; }
    6868static 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 }; }
     69static inline void ?{}(thread_desc & this, const char * const name)                                         { this{ name, *mainCluster, NULL, 65000 }; }
     70static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl )                   { this{ name, cl, NULL, 65000 }; }
    7171static inline void ?{}(thread_desc & this, const char * const name, struct cluster & cl, size_t stackSize ) { this{ name, cl, NULL, stackSize }; }
    7272
     
    9191void yield( unsigned times );
    9292
     93static inline struct thread_desc * active_thread () { return TL_GET( this_thread ); }
     94
    9395// Local Variables: //
    9496// mode: c //
  • libcfa/src/containers/maybe.cfa

    r7951100 rb067d9b  
    1010// Created On       : Wed May 24 15:40:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 20 15:23:50 2017
    13 // Update Count     : 2
     12// Last Modified On : Sun Feb 17 11:22:03 2019
     13// Update Count     : 3
    1414//
    1515
    16 #include <containers/maybe>
     16#include <containers/maybe.hfa>
    1717#include <assert.h>
    1818
     
    3939forall(otype T)
    4040maybe(T) ?=?(maybe(T) & this, maybe(T) that) {
    41         if (this.has_value & that.has_value) {
     41        if (this.has_value && that.has_value) {
    4242                this.value = that.value;
    4343        } else if (this.has_value) {
  • libcfa/src/containers/pair.cfa

    r7951100 rb067d9b  
    1111//
    1212
    13 #include <containers/pair>
     13#include <containers/pair.hfa>
    1414
    15 forall(otype R, otype S 
     15forall(otype R, otype S
    1616        | { int ?==?(R, R); int ?<?(R, R); int ?<?(S, S); })
    1717int ?<?(pair(R, S) p, pair(R, S) q) {
     
    1919}
    2020
    21 forall(otype R, otype S 
     21forall(otype R, otype S
    2222        | { int ?==?(R, R); int ?<?(R, R); int ?<=?(S, S); })
    2323int ?<=?(pair(R, S) p, pair(R, S) q) {
     
    3535}
    3636
    37 forall(otype R, otype S 
     37forall(otype R, otype S
    3838        | { int ?==?(R, R); int ?>?(R, R); int ?>?(S, S); })
    3939int ?>?(pair(R, S) p, pair(R, S) q) {
     
    4141}
    4242
    43 forall(otype R, otype S 
     43forall(otype R, otype S
    4444        | { int ?==?(R, R); int ?>?(R, R); int ?>=?(S, S); })
    4545int ?>=?(pair(R, S) p, pair(R, S) q) {
  • libcfa/src/containers/result.cfa

    r7951100 rb067d9b  
    1010// Created On       : Wed May 24 15:40:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 20 15:23:58 2017
    13 // Update Count     : 2
     12// Last Modified On : Sun Feb 17 11:24:04 2019
     13// Update Count     : 3
    1414//
    1515
    16 #include <containers/result>
     16#include <containers/result.hfa>
    1717#include <assert.h>
    1818
     
    4848forall(otype T, otype E)
    4949result(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) {
    5151                this.value = that.value;
    5252        } else if (this.has_value) {
  • libcfa/src/containers/result.hfa

    r7951100 rb067d9b  
    2828struct result {
    2929        bool has_value;
    30         inner_result(T, E);
     30        inline union inner_result(T, E);
    3131};
    3232
  • libcfa/src/containers/vector.cfa

    r7951100 rb067d9b  
    1414//
    1515
    16 #include <containers/vector>
     16#include <containers/vector.hfa>
    1717
    18 #include <stdlib>
     18#include <stdlib.hfa>
    1919
    2020forall(otype T, otype allocator_t | allocator_c(T, allocator_t))
  • libcfa/src/exception.c

    r7951100 rb067d9b  
    2323#include <stdio.h>
    2424#include <unwind.h>
    25 #include <bits/debug.h>
     25#include <bits/debug.hfa>
    2626
    2727// FIX ME: temporary hack to keep ARM build working
     
    246246}
    247247
     248#if defined(PIC)
     249#warning Exceptions not yet supported when using Position-Independent Code
     250__attribute__((noinline))
     251void __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
    248257// This is our personality routine.  For every stack frame anotated with ".cfi_personality 0x3,__gcfa_personality_v0".
    249258// This function will be called twice when unwinding.  Once in the search phased and once in the cleanup phase.
     
    477486);
    478487#endif // __i386 || __x86_64
     488#endif //PIC
  • libcfa/src/fstream.cfa

    r7951100 rb067d9b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  5 17:02:56 2018
    13 // Update Count     : 281
    14 //
    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"
    1717
    1818#include <stdio.h>                                                                              // vfprintf, vfscanf
     
    2020#include <stdarg.h>                                                                             // varargs
    2121#include <string.h>                                                                             // strlen
    22 #include <stdbool.h>                                                                    // true/false
    2322#include <float.h>                                                                              // DBL_DIG, LDBL_DIG
    2423#include <complex.h>                                                                    // creal, cimag
    2524#include <assert.h>
     25#include <errno.h>                                                                              // errno
     26
     27
     28//*********************************** ofstream ***********************************
     29
    2630
    2731#define IO_MSG "I/O error: "
    2832
    29 void ?{}( ofstream & os, void * file, _Bool sepDefault, _Bool sepOnOff, const char * separator, const char * tupleSeparator ) {
     33void ?{}( ofstream & os, void * file ) {
    3034        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, " " );
    3441        sepSetCur( os, sepGet( os ) );
    35         sepSetTuple( os, tupleSeparator );
    36 }
     42        sepSetTuple( os, ", " );
     43} // ?{}
    3744
    3845// private
    39 _Bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }
     46bool sepPrt( ofstream & os ) { setNL( os, false ); return os.sepOnOff; }
    4047void sepReset( ofstream & os ) { os.sepOnOff = os.sepDefault; }
    41 void sepReset( ofstream & os, _Bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }
     48void sepReset( ofstream & os, bool reset ) { os.sepDefault = reset; os.sepOnOff = os.sepDefault; }
    4249const char * sepGetCur( ofstream & os ) { return os.sepCur; }
    4350void 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; }
     51bool getNL( ofstream & os ) { return os.sawNL; }
     52void setNL( ofstream & os, bool state ) { os.sawNL = state; }
     53bool getANL( ofstream & os ) { return os.nlOnOff; }
     54bool getPrt( ofstream & os ) { return os.prt; }
     55void setPrt( ofstream & os, bool state ) { os.prt = state; }
    4656
    4757// public
     
    5060void ?{}( ofstream & os, const char * name, const char * mode ) {
    5161        open( os, name, mode );
    52 }
     62} // ?{}
     63
    5364void ?{}( ofstream & os, const char * name ) {
    5465        open( os, name, "w" );
    55 }
     66} // ?{}
    5667
    5768void sepOn( ofstream & os ) { os.sepOnOff = ! getNL( os ); }
    5869void sepOff( ofstream & os ) { os.sepOnOff = false; }
    5970
    60 _Bool sepDisable( ofstream & os ) {
    61         _Bool temp = os.sepDefault;
     71bool sepDisable( ofstream & os ) {
     72        bool temp = os.sepDefault;
    6273        os.sepDefault = false;
    6374        sepReset( os );
     
    6576} // sepDisable
    6677
    67 _Bool sepEnable( ofstream & os ) {
    68         _Bool temp = os.sepDefault;
     78bool sepEnable( ofstream & os ) {
     79        bool temp = os.sepDefault;
    6980        os.sepDefault = true;
    7081        if ( os.sepOnOff ) sepReset( os );                                      // start of line ?
    7182        return temp;
    7283} // sepEnable
     84
     85void nlOn( ofstream & os ) { os.nlOnOff = true; }
     86void nlOff( ofstream & os ) { os.nlOnOff = false; }
    7387
    7488const char * sepGet( ofstream & os ) { return os.separator; }
     
    86100} // sepSet
    87101
     102void 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
    88109int fail( ofstream & os ) {
    89110        return os.file == 0 || ferror( (FILE *)(os.file) );
     
    95116
    96117void open( ofstream & os, const char * name, const char * mode ) {
    97         FILE *file = fopen( name, mode );
    98         // if ( file == 0 ) {                                                                   // do not change unless successful
    99         //      fprintf( stderr, IO_MSG "open output file \"%s\", ", name );
    100         //      perror( 0 );
    101         //      exit( EXIT_FAILURE );
    102         // } // if
    103         (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 };
    104125} // open
    105126
     
    112133
    113134        if ( fclose( (FILE *)(os.file) ) == EOF ) {
    114                 perror( IO_MSG "close output" );
     135                abort | IO_MSG "close output" | nl | strerror( errno );
    115136        } // if
    116137} // close
     
    118139ofstream & write( ofstream & os, const char * data, size_t size ) {
    119140        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";
    122142        } // if
    123143
    124144        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 );
    127146        } // if
    128147        return os;
     
    135154        if ( len == EOF ) {
    136155                if ( ferror( (FILE *)(os.file) ) ) {
    137                         fprintf( stderr, "invalid write\n" );
    138                         exit( EXIT_FAILURE );
     156                        abort | IO_MSG "invalid write";
    139157                } // if
    140158        } // if
    141159        va_end( args );
    142160
     161        setPrt( os, true );                                                                     // called in output cascade
    143162        sepReset( os );                                                                         // reset separator
    144163        return len;
    145164} // fmt
    146165
    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 //---------------------------------------
     166static ofstream soutFile = { (FILE *)stdout };
     167ofstream & sout = soutFile, & stdout = soutFile;
     168static ofstream serrFile = { (FILE *)stderr };
     169ofstream & serr = serrFile, & stderr = serrFile;
     170
     171static ofstream exitFile = { (FILE *)stdout };
     172ofstream & exit = exitFile;
     173static ofstream abortFile = { (FILE *)stderr };
     174ofstream & abort = abortFile;
     175
     176
     177//*********************************** ifstream ***********************************
     178
    154179
    155180// private
    156181void ?{}( ifstream & is, void * file ) {
    157182        is.file = file;
    158 }
     183        is.nlOnOff = false;
     184} // ?{}
    159185
    160186// public
     
    163189void ?{}( ifstream & is, const char * name, const char * mode ) {
    164190        open( is, name, mode );
    165 }
     191} // ?{}
     192
    166193void ?{}( ifstream & is, const char * name ) {
    167194        open( is, name, "r" );
    168 }
     195} // ?{}
     196
     197void nlOn( ifstream & os ) { os.nlOnOff = true; }
     198void nlOff( ifstream & os ) { os.nlOnOff = false; }
     199bool getANL( ifstream & os ) { return os.nlOnOff; }
    169200
    170201int fail( ifstream & is ) {
     
    177208
    178209void open( ifstream & is, const char * name, const char * mode ) {
    179         FILE *file = fopen( name, mode );
    180         // if ( file == 0 ) {                                                                   // do not change unless successful
    181         //      fprintf( stderr, IO_MSG "open input file \"%s\", ", name );
    182         //      perror( 0 );
    183         //      exit( EXIT_FAILURE );
    184         // } // if
     210        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__
    185216        is.file = file;
    186217} // open
     
    194225
    195226        if ( fclose( (FILE *)(is.file) ) == EOF ) {
    196                 perror( IO_MSG "close input" );
     227                abort | IO_MSG "close input" | nl | strerror( errno );
    197228        } // if
    198229} // close
     
    200231ifstream & read( ifstream & is, char * data, size_t size ) {
    201232        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";
    204234        } // if
    205235
    206236        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 );
    209238        } // if
    210239        return is;
     
    213242ifstream &ungetc( ifstream & is, char c ) {
    214243        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";
    217245        } // if
    218246
    219247        if ( ungetc( c, (FILE *)(is.file) ) == EOF ) {
    220                 perror( IO_MSG "ungetc" );
    221                 exit( EXIT_FAILURE );
     248                abort | IO_MSG "ungetc" | nl | strerror( errno );
    222249        } // if
    223250        return is;
     
    231258        if ( len == EOF ) {
    232259                if ( ferror( (FILE *)(is.file) ) ) {
    233                         fprintf( stderr, "invalid read\n" );
    234                         exit( EXIT_FAILURE );
     260                        abort | IO_MSG "invalid read";
    235261                } // if
    236262        } // if
     
    239265} // fmt
    240266
    241 
    242 static ifstream sinFile = { (FILE *)(&_IO_2_1_stdin_) };
    243 ifstream & sin = sinFile;
     267static ifstream sinFile = { (FILE *)stdin };
     268ifstream & sin = sinFile, & stdin = sinFile;
    244269
    245270// Local Variables: //
  • libcfa/src/fstream.hfa

    r7951100 rb067d9b  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  5 10:20:25 2018
    13 // Update Count     : 131
     12// Last Modified On : Mon Jul 15 18:10:23 2019
     13// Update Count     : 167
    1414//
    1515
    1616#pragma once
    1717
    18 #include "iostream"
     18#include "iostream.hfa"
     19
     20
     21//*********************************** ofstream ***********************************
     22
    1923
    2024enum { sepSize = 16 };
    2125struct ofstream {
    2226        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;
    2632        const char * sepCur;
    2733        char separator[sepSize];
     
    3036
    3137// private
    32 _Bool sepPrt( ofstream & );
     38bool sepPrt( ofstream & );
    3339void sepReset( ofstream & );
    34 void sepReset( ofstream &, _Bool );
     40void sepReset( ofstream &, bool );
    3541const char * sepGetCur( ofstream & );
    3642void sepSetCur( ofstream &, const char * );
    37 _Bool getNL( ofstream & );
    38 void setNL( ofstream &, _Bool );
     43bool getNL( ofstream & );
     44void setNL( ofstream &, bool );
     45bool getANL( ofstream & );
     46bool getPrt( ofstream & );
     47void setPrt( ofstream &, bool );
    3948
    4049// public
    4150void sepOn( ofstream & );
    4251void sepOff( ofstream & );
    43 _Bool sepDisable( ofstream & );
    44 _Bool sepEnable( ofstream & );
     52bool sepDisable( ofstream & );
     53bool sepEnable( ofstream & );
     54void nlOn( ofstream & );
     55void nlOff( ofstream & );
    4556
    4657const char * sepGet( ofstream & );
     
    4960void sepSetTuple( ofstream &, const char * );
    5061
     62void ends( ofstream & os );
    5163int fail( ofstream & );
    5264int flush( ofstream & );
     
    5567void close( ofstream & );
    5668ofstream & write( ofstream &, const char * data, size_t size );
    57 int fmt( ofstream &, const char fmt[], ... );
     69int fmt( ofstream &, const char format[], ... );
    5870
    5971void ?{}( ofstream & os );
     
    6173void ?{}( ofstream & os, const char * name );
    6274
    63 extern ofstream & sout, & serr;
     75extern ofstream & sout, & stdout, & serr, & stderr;             // aliases
     76extern ofstream & exit, & abort;
     77
     78
     79//*********************************** ifstream ***********************************
    6480
    6581
    6682struct ifstream {
    6783        void * file;
     84        bool nlOnOff;
    6885}; // ifstream
    6986
    7087// public
     88void nlOn( ifstream & );
     89void nlOff( ifstream & );
     90bool getANL( ifstream & );
    7191int fail( ifstream & is );
    7292int eof( ifstream & is );
     
    7696ifstream & read( ifstream & is, char * data, size_t size );
    7797ifstream & ungetc( ifstream & is, char c );
    78 int fmt( ifstream &, const char fmt[], ... );
     98int fmt( ifstream &, const char format[], ... );
    7999
    80100void ?{}( ifstream & is );
     
    82102void ?{}( ifstream & is, const char * name );
    83103
    84 extern ifstream & sin;
     104extern ifstream & sin, & stdin;                                                 // aliases
    85105
    86106// Local Variables: //
  • libcfa/src/interpose.cfa

    r7951100 rb067d9b  
    1010// Created On       : Wed Mar 29 16:10:31 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  5 11:37:35 2018
    13 // Update Count     : 111
     12// Last Modified On : Sun Jul 14 22:57:16 2019
     13// Update Count     : 116
    1414//
    1515
     
    2525}
    2626
    27 #include "bits/debug.h"
    28 #include "bits/defs.h"
    29 #include "bits/signal.h"                                                                // sigHandler_?
    30 #include "startup.h"                                                                    // STARTUP_PRIORITY_CORE
     27#include "bits/debug.hfa"
     28#include "bits/defs.hfa"
     29#include "bits/signal.hfa"                                                              // sigHandler_?
     30#include "startup.hfa"                                                                  // STARTUP_PRIORITY_CORE
    3131
    3232//=============================================================================================
    3333// Interposing helpers
    3434//=============================================================================================
     35
     36void 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}
    3540
    3641typedef void (* generic_fptr_t)(void);
     
    7681//=============================================================================================
    7782
    78 void sigHandler_segv ( __CFA_SIGPARMS__ );
    79 void sigHandler_ill  ( __CFA_SIGPARMS__ );
    80 void sigHandler_fpe  ( __CFA_SIGPARMS__ );
    81 void sigHandler_abort( __CFA_SIGPARMS__ );
    82 void sigHandler_term ( __CFA_SIGPARMS__ );
     83void sigHandler_segv( __CFA_SIGPARMS__ );
     84void sigHandler_ill ( __CFA_SIGPARMS__ );
     85void sigHandler_fpe ( __CFA_SIGPARMS__ );
     86void sigHandler_abrt( __CFA_SIGPARMS__ );
     87void sigHandler_term( __CFA_SIGPARMS__ );
    8388
    8489struct {
     
    9196        void __cfaabi_interpose_startup( void ) {
    9297                const char *version = NULL;
     98
     99                preload_libgcc();
    93100
    94101#pragma GCC diagnostic push
     
    103110                __cfaabi_sigaction( SIGILL , sigHandler_ill  , SA_SIGINFO );
    104111                __cfaabi_sigaction( SIGFPE , sigHandler_fpe  , SA_SIGINFO );
    105                 __cfaabi_sigaction( SIGABRT, sigHandler_abort, SA_SIGINFO | SA_RESETHAND);
     112                __cfaabi_sigaction( SIGABRT, sigHandler_abrt, SA_SIGINFO | SA_RESETHAND);
    106113                __cfaabi_sigaction( SIGTERM, sigHandler_term , SA_SIGINFO );
    107114                __cfaabi_sigaction( SIGINT , sigHandler_term , SA_SIGINFO );
     
    197204                        if ( *p == '(' ) {
    198205                                name = p;
    199                         }
    200                         else if ( *p == '+' ) {
     206                        } else if ( *p == '+' ) {
    201207                                offset_begin = p;
    202                         }
    203                         else if ( *p == ')' ) {
     208                        } else if ( *p == ')' ) {
    204209                                offset_end = p;
    205210                                break;
     
    216221
    217222                        __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
    221224                        __cfaabi_dbg_bits_print_nolock( "(%i) %s\n", frameNo, messages[i] );
    222225                }
     
    251254}
    252255
    253 void sigHandler_abort( __CFA_SIGPARMS__ ) {
     256void sigHandler_abrt( __CFA_SIGPARMS__ ) {
    254257        __cfaabi_backtrace();
    255258
  • libcfa/src/iterator.cfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // iterator.c -- 
     7// iterator.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul  7 08:38:23 2017
    13 // Update Count     : 28
     12// Last Modified On : Fri Nov  2 07:17:37 2018
     13// Update Count     : 29
    1414//
    1515
    16 #include "iterator"
     16#include "iterator.hfa"
    1717
    1818forall( otype iterator_type, otype elt_type | iterator( iterator_type, elt_type ) )
     
    3333// Local Variables: //
    3434// tab-width: 4 //
    35 // compile-command: "cfa iterator.c" //
     35// compile-command: "cfa iterator.cfa" //
    3636// End: //
  • libcfa/src/limits.cfa

    r7951100 rb067d9b  
    1 // 
     1//
    22// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    33//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    6 // 
    7 // limits.c -- 
    8 // 
     6//
     7// limits.c --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed Apr  6 18:06:52 2016
     
    1212// Last Modified On : Thu Mar  1 16:22:51 2018
    1313// Update Count     : 74
    14 // 
     14//
    1515
    1616#include <limits.h>
     
    1919#include <math.h>
    2020#include <complex.h>
    21 #include "limits"
     21#include "limits.hfa"
    2222
    2323// Integral Constants
  • libcfa/src/math.hfa

    r7951100 rb067d9b  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug  7 07:51:15 2017
    13 // Update Count     : 108
     12// Last Modified On : Fri Jul 13 11:02:15 2018
     13// Update Count     : 116
    1414//
    1515
     
    348348static inline long double scalbln( long double x, long int exp ) { return scalblnl( x, exp ); }
    349349
     350//---------------------------------------
     351
     352#include "common.hfa"
     353
     354//---------------------------------------
     355
     356forall( otype T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T );T ?*?( T, T ); } )
     357T lerp( T x, T y, T a ) { return x * ((T){1} - a) + y * a; }
     358
     359forall( otype T | { void ?{}( T &, zero_t ); void ?{}( T &, one_t ); int ?<?( T, T ); } )
     360T step( T edge, T x ) { return x < edge ? (T){0} : (T){1}; }
     361
     362forall( otype T | { void ?{}( T &, int ); T clamp( T, T, T ); T ?-?( T, T ); T ?*?( T, T ); T ?/?( T, T ); } )
     363T 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
    350365// Local Variables: //
    351366// mode: c //
  • libcfa/src/rational.cfa

    r7951100 rb067d9b  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun  2 09:24:33 2018
    13 // Update Count     : 162
    14 //
    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"
    1919
    2020forall( otype RationalImpl | arithmetic( RationalImpl ) ) {
     
    3535        static RationalImpl simplify( RationalImpl & n, RationalImpl & d ) {
    3636                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.";
    3938                } // exit
    4039                if ( d < (RationalImpl){0} ) { d = -d; n = -n; } // move sign to numerator
     
    5453        void ?{}( Rational(RationalImpl) & r, RationalImpl n, RationalImpl d ) {
    5554                RationalImpl t = simplify( n, d );                              // simplify
    56                 r.numerator = n / t;
    57                 r.denominator = d / t;
     55                r.[numerator, denominator] = [n / t, d / t];
    5856        } // rational
    5957
     
    7876                RationalImpl prev = r.numerator;
    7977                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];
    8279                return prev;
    8380        } // numerator
     
    8683                RationalImpl prev = r.denominator;
    8784                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];
    9086                return prev;
    9187        } // denominator
     
    120116
    121117        Rational(RationalImpl) +?( Rational(RationalImpl) r ) {
    122                 Rational(RationalImpl) t = { r.numerator, r.denominator };
    123                 return t;
     118                return (Rational(RationalImpl)){ r.numerator, r.denominator };
    124119        } // +?
    125120
    126121        Rational(RationalImpl) -?( Rational(RationalImpl) r ) {
    127                 Rational(RationalImpl) t = { -r.numerator, r.denominator };
    128                 return t;
     122                return (Rational(RationalImpl)){ -r.numerator, r.denominator };
    129123        } // -?
    130124
    131125        Rational(RationalImpl) ?+?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    132126                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 };
    135128                } 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 };
    138130                } // if
    139131        } // ?+?
     
    141133        Rational(RationalImpl) ?-?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    142134                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 };
    145136                } 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 };
    148138                } // if
    149139        } // ?-?
    150140
    151141        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 };
    154143        } // ?*?
    155144
    156145        Rational(RationalImpl) ?/?( Rational(RationalImpl) l, Rational(RationalImpl) r ) {
    157146                if ( r.numerator < (RationalImpl){0} ) {
    158                         r.numerator = -r.numerator;
    159                         r.denominator = -r.denominator;
     147                        r.[numerator, denominator] = [-r.numerator, -r.denominator];
    160148                } // 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 };
    163150        } // ?/?
    164151
     
    167154        forall( dtype istype | istream( istype ) | { istype & ?|?( istype &, RationalImpl & ); } )
    168155        istype & ?|?( istype & is, Rational(RationalImpl) & r ) {
    169                 RationalImpl t;
    170156                is | r.numerator | r.denominator;
    171                 t = simplify( r.numerator, r.denominator );
     157                RationalImpl t = simplify( r.numerator, r.denominator );
    172158                r.numerator /= t;
    173159                r.denominator /= t;
     
    175161        } // ?|?
    176162
    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
    181172} // distribution
     173
     174forall( otype RationalImpl | arithmetic( RationalImpl ) | { RationalImpl ?\?( RationalImpl, unsigned long ); } )
     175Rational(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}
    182182
    183183// conversion
  • libcfa/src/rational.hfa

    r7951100 rb067d9b  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Sat Jun  2 09:10:01 2018
    15 // Update Count     : 105
     14// Last Modified On : Tue Mar 26 23:16:10 2019
     15// Update Count     : 109
    1616//
    1717
    1818#pragma once
    1919
    20 #include "iostream"
     20#include "iostream.hfa"
    2121
    2222trait scalar( otype T ) {
     
    9292        istype & ?|?( istype &, Rational(RationalImpl) & );
    9393
    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
    9698} // distribution
     99
     100forall( otype RationalImpl | arithmetic( RationalImpl ) |{RationalImpl ?\?( RationalImpl, unsigned long );} )
     101Rational(RationalImpl) ?\?( Rational(RationalImpl) x, long int y );
    97102
    98103// conversion
  • libcfa/src/startup.hfa

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // startup.h --
     7// startup.hfa --
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Wed Mar 29 15:56:41 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 20 21:37:11 2017
    13 // Update Count     : 2
     12// Last Modified On : Tue Jul 24 16:16:37 2018
     13// Update Count     : 4
    1414//
    1515
     
    1919extern "C" {
    2020        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,
    2424                STARTUP_PRIORITY_IOSTREAM   = 104,
     25                STARTUP_PRIORITY_APPREADY   = 105,
    2526        };
    2627}
    2728#else
    28 #define STARTUP_PRIORITY_CORE       101
    29 #define STARTUP_PRIORITY_KERNEL     102
    30 #define STARTUP_PRIORITY_MEMORY     103
     29#define STARTUP_PRIORITY_MEMORY     101
     30#define STARTUP_PRIORITY_CORE       102
     31#define STARTUP_PRIORITY_KERNEL     103
    3132#define STARTUP_PRIORITY_IOSTREAM   104
     33#define STARTUP_PRIORITY_APPREADY   105
    3234#endif
    3335
  • libcfa/src/stdhdr/bfdlink.h

    r7951100 rb067d9b  
    1010// Created On       : Tue Jul 18 07:26:04 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 18 07:46:50 2017
    13 // Update Count     : 3
     12// Last Modified On : Sun Jul 22 13:49:30 2018
     13// Update Count     : 4
    1414//
    1515
     
    2020#endif
    2121
    22 #include_next <bfdlink.h>                                                               // must have internal check for multiple expansion
     22#include_next <bfdlink.h>                                                               // has internal check for multiple expansion
    2323
    2424#if defined( with ) && defined( __CFA_BFDLINK_H__ )             // reset only if set
  • libcfa/src/stdhdr/hwloc.h

    r7951100 rb067d9b  
    1010// Created On       : Tue Jul 18 07:45:00 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 18 07:56:33 2017
    13 // Update Count     : 3
     12// Last Modified On : Sun Jul 22 13:49:58 2018
     13// Update Count     : 4
    1414//
    1515
     
    2020#endif
    2121
    22 #include_next <hwloc.h>                                                                 // must have internal check for multiple expansion
     22#include_next <hwloc.h>                                                                 // has internal check for multiple expansion
    2323
    2424#if defined( thread ) && defined( __CFA_HWLOC_H__ )             // reset only if set
  • libcfa/src/stdhdr/krb5.h

    r7951100 rb067d9b  
    1010// Created On       : Tue Jul 18 07:55:44 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 18 07:58:01 2017
    13 // Update Count     : 3
     12// Last Modified On : Sun Jul 22 13:50:24 2018
     13// Update Count     : 4
    1414//
    1515
     
    2020#endif
    2121
    22 #include_next <krb5.h>                                                                  // must have internal check for multiple expansion
     22#include_next <krb5.h>                                                                  // has internal check for multiple expansion
    2323
    2424#if defined( enable ) && defined( __CFA_KRB5_H__ )              // reset only if set
  • libcfa/src/stdhdr/malloc.h

    r7951100 rb067d9b  
    1010// Created On       : Thu Jul 20 15:58:16 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jul 20 16:00:12 2017
    13 // Update Count     : 4
     12// Last Modified On : Sat Aug 11 09:06:31 2018
     13// Update Count     : 10
    1414//
     15
     16
     17size_t default_mmap_start();                                                    // CFA extras
     18size_t default_heap_expansion();
     19
     20bool traceHeap();
     21bool traceHeapOn();
     22bool traceHeapOff();
     23
     24bool traceHeapTerm();
     25bool traceHeapTermOn();
     26bool traceHeapTermOff();
     27
     28bool checkFree();
     29bool checkFreeOn();
     30bool checkFreeOff();
     31
     32extern "C" {
     33size_t malloc_alignment( void * );
     34bool malloc_zero_fill( void * );
     35int malloc_stats_fd( int fd );
     36void * cmemalign( size_t alignment, size_t noOfElems, size_t elemSize );
     37} // extern "C"
    1538
    1639extern "C" {
  • libcfa/src/stdhdr/stdbool.h

    r7951100 rb067d9b  
    1010// Created On       : Mon Jul  4 23:25:26 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 20:39:51 2016
    13 // Update Count     : 12
     12// Last Modified On : Mon Mar 25 08:00:08 2019
     13// Update Count     : 15
    1414//
    1515
    1616extern "C" {
    1717#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
    1829} // extern "C"
    1930
  • libcfa/src/stdlib.cfa

    r7951100 rb067d9b  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun  2 06:15:05 2018
    13 // Update Count     : 448
    14 //
    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"
    1717
    1818//---------------------------------------
     
    2121#include <string.h>                                                                             // memcpy, memset
    2222#include <malloc.h>                                                                             // malloc_usable_size
    23 #include <math.h>                                                                               // fabsf, fabs, fabsl
     23//#include <math.h>                                                                             // fabsf, fabs, fabsl
    2424#include <complex.h>                                                                    // _Complex_I
    2525#include <assert.h>
     
    2727//---------------------------------------
    2828
    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
     29forall( 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
    3982
    4083// allocation/deallocation and constructor/destructor, non-array types
    4184forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
    4285T * new( Params p ) {
    43         return &(*malloc()){ p };                                                               // run constructor
     86        return &(*malloc()){ p };                                                       // run constructor
    4487} // new
    4588
     
    4790void delete( T * ptr ) {
    4891        if ( ptr ) {                                                                            // ignore null
    49                 ^(*ptr){};                                                                                      // run destructor
     92                ^(*ptr){};                                                                              // run destructor
    5093                free( ptr );
    5194        } // if
     
    5598void delete( T * ptr, Params rest ) {
    5699        if ( ptr ) {                                                                            // ignore null
    57                 ^(*ptr){};                                                                                      // run destructor
     100                ^(*ptr){};                                                                              // run destructor
    58101                free( ptr );
    59102        } // if
     
    65108forall( dtype T | sized(T), ttype Params | { void ?{}( T &, Params ); } )
    66109T * anew( size_t dim, Params p ) {
    67         T *arr = alloc( dim );
     110        T * arr = alloc( dim );
    68111        for ( unsigned int i = 0; i < dim; i += 1 ) {
    69112                (arr[i]){ p };                                                                  // run constructor
     
    241284//---------------------------------------
    242285
    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; }
     286extern "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
    267291float random( void ) { return (float)drand48(); }               // cast otherwise float uses lrand48
    268292double random( void ) { return drand48(); }
     
    271295long double _Complex random( void ) { return (long double)drand48() + (long double _Complex)(drand48() * _Complex_I); }
    272296
     297//---------------------------------------
     298
     299bool threading_enabled(void) __attribute__((weak)) {
     300        return false;
     301}
    273302
    274303// Local Variables: //
  • libcfa/src/time.cfa

    r7951100 rb067d9b  
    1 // 
     1//
    22// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
    33//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    6 // 
    7 // time.c -- 
    8 // 
     6//
     7// time.c --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Tue Mar 27 13:33:14 2018
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May  6 22:26:00 2018
    13 // Update Count     : 37
    14 // 
     12// Last Modified On : Sat Jul 13 08:41:55 2019
     13// Update Count     : 65
     14//
    1515
    16 #include "time"
    17 #include "iostream"
     16#include "time.hfa"
     17#include "fstream.hfa"
    1818#include <stdio.h>                                                                              // snprintf
    1919#include <assert.h>
     
    3131
    3232
    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 } // ?|?
     33forall( 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
    4348
    4449
     
    4752
    4853#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."
     54static 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
    5158#endif // __CFA_DEBUG__
    5259
     
    5865#ifdef __CFA_DEBUG__
    5966        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 );
    6168        } // if
    6269#endif // __CFA_DEBUG__
     
    6471#ifdef __CFA_DEBUG__
    6572        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 );
    6774        } // if
    6875#endif // __CFA_DEBUG__
     
    7481#ifdef __CFA_DEBUG__
    7582        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 );
    7784        } // if
    7885#endif // __CFA_DEBUG__
     
    8087#ifdef __CFA_DEBUG__
    8188        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 );
    8390        } // if
    8491#endif // __CFA_DEBUG__
     
    137144} // strftime
    138145
    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 } // ?|?
     146forall( 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
    157168
    158169// Local Variables: //
  • libcfa/src/time_t.hfa

    r7951100 rb067d9b  
    1 // 
     1//
    22// Cforall Version 1.0.0 Copyright (C) 2018 University of Waterloo
    33//
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    6 // 
    7 // time_t.h --
    8 // 
     6//
     7// time_t.hfa --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Tue Apr 10 14:42:03 2018
     
    1212// Last Modified On : Fri Apr 13 07:51:47 2018
    1313// Update Count     : 6
    14 // 
     14//
    1515
    1616#pragma once
     
    2424
    2525static inline void ?{}( Duration & dur ) with( dur ) { tv = 0; }
    26 static inline void ?{}( Duration & dur, zero_t ) with( dur ) { tv = 0; }
     26static inline void ?{}( Duration & dur, __attribute__((unused)) zero_t ) with( dur ) { tv = 0; }
    2727
    2828
     
    3434
    3535static inline void ?{}( Time & time ) with( time ) { tv = 0; }
    36 static inline void ?{}( Time & time, zero_t ) with( time ) { tv = 0; }
     36static inline void ?{}( Time & time, __attribute__((unused)) zero_t ) with( time ) { tv = 0; }
    3737
    3838// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.