Changeset b7b3e41 for libcfa


Ignore:
Timestamp:
Jun 19, 2023, 1:57:11 PM (2 years ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
adc73a5
Parents:
fa5e1aa5 (diff), 33d4bc8 (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
Files:
21 edited

Legend:

Unmodified
Added
Removed
  • libcfa/prelude/builtins.c

    rfa5e1aa5 rb7b3e41  
    149149
    150150static inline {
    151         long int ?\?( int x, unsigned int y ) { __CFA_EXP__(); }
     151        int ?\?( int x, unsigned int y ) { __CFA_EXP__(); }
    152152        long int ?\?( long int x, unsigned long int y ) { __CFA_EXP__(); }
    153153        long long int ?\?( long long int x, unsigned long long int y ) { __CFA_EXP__(); }
    154154        // unsigned computation may be faster and larger
    155         unsigned long int ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); }
     155        unsigned int ?\?( unsigned int x, unsigned int y ) { __CFA_EXP__(); }
    156156        unsigned long int ?\?( unsigned long int x, unsigned long int y ) { __CFA_EXP__(); }
    157157        unsigned long long int ?\?( unsigned long long int x, unsigned long long int y ) { __CFA_EXP__(); }
     
    176176
    177177static inline {
    178         long int ?\=?( int & x, unsigned int y ) { x = x \ y; return x; }
     178        int ?\=?( int & x, unsigned int y ) { x = x \ y; return x; }
    179179        long int ?\=?( long int & x, unsigned long int y ) { x = x \ y; return x; }
    180180        long long int ?\=?( long long int & x, unsigned long long int y ) { x = x \ y; return x; }
    181         unsigned long int ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; }
     181        unsigned int ?\=?( unsigned int & x, unsigned int y ) { x = x \ y; return x; }
    182182        unsigned long int ?\=?( unsigned long int & x, unsigned long int y ) { x = x \ y; return x; }
    183183        unsigned long long int ?\=?( unsigned long long int & x, unsigned long long int y ) { x = x \ y; return x; }
  • libcfa/prelude/sync-builtins.cf

    rfa5e1aa5 rb7b3e41  
    206206_Bool __sync_bool_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    207207#endif
     208// for all pointer types
    208209forall(T &) _Bool __sync_bool_compare_and_swap(T * volatile *, T *, T*, ...);
    209210
     
    223224unsigned __int128 __sync_val_compare_and_swap(volatile unsigned __int128 *, unsigned __int128, unsigned __int128,...);
    224225#endif
     226// for all pointer types
    225227forall(T &) T * __sync_val_compare_and_swap(T * volatile *, T *, T*,...);
    226228
     
    326328void __atomic_exchange(volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, int);
    327329#endif
     330// for all pointer types
    328331forall(T &) T * __atomic_exchange_n(T * volatile *, T *, int);
    329332forall(T &) void __atomic_exchange(T * volatile *, T **, T **, int);
     
    359362void __atomic_load(const volatile unsigned __int128 *, unsigned __int128 *, int);
    360363#endif
     364// for all pointer types
    361365forall(T &) T * __atomic_load_n(T * const volatile *, int);
    362366forall(T &) void __atomic_load(T * const volatile *, T **, int);
     
    390394_Bool __atomic_compare_exchange   (volatile unsigned __int128 *, unsigned __int128 *, unsigned __int128 *, _Bool, int, int);
    391395#endif
     396// for all pointer types
    392397forall(T &) _Bool __atomic_compare_exchange_n (T * volatile *, T **, T*, _Bool, int, int);
    393398forall(T &) _Bool __atomic_compare_exchange   (T * volatile *, T **, T**, _Bool, int, int);
     
    423428void __atomic_store(volatile unsigned __int128 *, unsigned __int128 *, int);
    424429#endif
     430// for all pointer types
    425431forall(T &) void __atomic_store_n(T * volatile *, T *, int);
    426432forall(T &) void __atomic_store(T * volatile *, T **, int);
  • libcfa/src/common.hfa

    rfa5e1aa5 rb7b3e41  
    3232} // extern "C"
    3333static inline __attribute__((always_inline)) {
    34         unsigned char abs( signed char v ) { return abs( (int)v ); }
     34        unsigned char abs( signed char v ) { return (int)abs( (int)v ); }
    3535        // use default C routine for int
    3636        unsigned long int abs( long int v ) { return labs( v ); }
     
    7070        unsigned int min( unsigned int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; }
    7171        long int min( long int v1, long int v2 ) { return v1 < v2 ? v1 : v2; }
    72         unsigned long int min( unsigned long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; }
     72        unsigned long int min( unsigned long int v1, unsigned long int v2 ) { return v1 < v2 ? v1 : v2; }
    7373        long long int min( long long int v1, long long int v2 ) { return v1 < v2 ? v1 : v2; }
    74         unsigned long long int min( unsigned long long int v1, unsigned int v2 ) { return v1 < v2 ? v1 : v2; }
     74        unsigned long long int min( unsigned long long int v1, unsigned long long int v2 ) { return v1 < v2 ? v1 : v2; }
    7575        forall( T | { int ?<?( T, T ); } )                                      // generic
    7676        T min( T v1, T v2 ) { return v1 < v2 ? v1 : v2; }
  • libcfa/src/concurrency/actor.hfa

    rfa5e1aa5 rb7b3e41  
    1313#endif // CFA_DEBUG
    1414
     15#define DEBUG_ABORT( cond, string ) CFA_DEBUG( if ( cond ) abort( string ) )
     16
    1517// Define the default number of processors created in the executor. Must be greater than 0.
    1618#define __DEFAULT_EXECUTOR_PROCESSORS__ 2
     
    2830#define __DEFAULT_EXECUTOR_BUFSIZE__ 10
    2931
    30 #define __STEAL 0 // workstealing toggle. Disjoint from toggles above
     32#define __STEAL 1 // workstealing toggle. Disjoint from toggles above
    3133
    3234// workstealing heuristic selection (only set one to be 1)
     
    4244struct executor;
    4345
    44 enum Allocation { Nodelete, Delete, Destroy, Finished }; // allocation status
    45 
    46 typedef Allocation (*__receive_fn)(actor &, message &);
     46enum allocation { Nodelete, Delete, Destroy, Finished }; // allocation status
     47
     48typedef allocation (*__receive_fn)(actor &, message &);
    4749struct request {
     50    actor * base_receiver;
    4851    actor * receiver;
     52    message * base_msg;
    4953    message * msg;
    5054    __receive_fn fn;
    51     bool stop;
    5255};
    5356
    54 static inline void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel
    55 static inline void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) {
     57struct a_msg {
     58    int m;
     59};
     60static inline void ?{}( request & this ) {}
     61static inline void ?{}( request & this, actor * base_receiver, actor * receiver, message * base_msg, message * msg, __receive_fn fn ) {
     62    this.base_receiver = base_receiver;
    5663    this.receiver = receiver;
     64    this.base_msg = base_msg;
    5765    this.msg = msg;
    5866    this.fn = fn;
    59     this.stop = false;
    6067}
    6168static inline void ?{}( request & this, request & copy ) {
     
    6370    this.msg = copy.msg;
    6471    this.fn = copy.fn;
    65     this.stop = copy.stop;
    6672}
    6773
     
    8187    last_size = 0;
    8288}
    83 static inline void ^?{}( copy_queue & this ) with(this) { adelete(buffer); }
     89static inline void ^?{}( copy_queue & this ) with(this) {
     90    DEBUG_ABORT( count != 0, "Actor system terminated with messages sent but not received\n" );
     91    adelete(buffer);
     92}
    8493
    8594static inline void insert( copy_queue & this, request & elem ) with(this) {
     
    115124}
    116125
    117 static inline bool isEmpty( copy_queue & this ) with(this) { return count == 0; }
     126static inline bool is_empty( copy_queue & this ) with(this) { return count == 0; }
    118127
    119128struct work_queue {
     
    176185    volatile unsigned long long stamp;
    177186    #ifdef ACTOR_STATS
    178     size_t stolen_from, try_steal, stolen, failed_swaps, msgs_stolen;
     187    size_t stolen_from, try_steal, stolen, empty_stolen, failed_swaps, msgs_stolen;
    179188    unsigned long long processed;
    180189    size_t gulps;
     
    189198    this.gulps = 0;                                 // number of gulps
    190199    this.failed_swaps = 0;                          // steal swap failures
     200    this.empty_stolen = 0;                          // queues empty after steal
    191201    this.msgs_stolen = 0;                           // number of messages stolen
    192202    #endif
     
    208218#ifdef ACTOR_STATS
    209219// aggregate counters for statistics
    210 size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0,
     220size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0, __total_empty_stolen = 0,
    211221    __total_failed_swaps = 0, __all_processed = 0, __num_actors_stats = 0, __all_msgs_stolen = 0;
    212222#endif
     
    233243        unsigned int nprocessors, nworkers, nrqueues;   // number of processors/threads/request queues
    234244        bool seperate_clus;                                                             // use same or separate cluster for executor
     245    volatile bool is_shutdown;                      // flag to communicate shutdown to worker threads
    235246}; // executor
    236247
     
    246257    __atomic_add_fetch(&__total_stolen, executor_->w_infos[id].stolen, __ATOMIC_SEQ_CST);
    247258    __atomic_add_fetch(&__total_failed_swaps, executor_->w_infos[id].failed_swaps, __ATOMIC_SEQ_CST);
     259    __atomic_add_fetch(&__total_empty_stolen, executor_->w_infos[id].empty_stolen, __ATOMIC_SEQ_CST);
    248260
    249261    // per worker steal stats (uncomment alongside the lock above this routine to print)
     
    272284    this.nrqueues = nrqueues;
    273285    this.seperate_clus = seperate_clus;
     286    this.is_shutdown = false;
    274287
    275288    if ( nworkers == nrqueues )
     
    320333
    321334static inline void ^?{}( executor & this ) with(this) {
    322     #ifdef __STEAL
    323     request sentinels[nrqueues];
    324     for ( unsigned int i = 0; i < nrqueues; i++ ) {
    325         insert( request_queues[i], sentinels[i] );              // force eventually termination
    326     } // for
    327     #else
    328     request sentinels[nworkers];
    329     unsigned int reqPerWorker = nrqueues / nworkers, extras = nrqueues % nworkers;
    330     for ( unsigned int i = 0, step = 0, range; i < nworkers; i += 1, step += range ) {
    331         range = reqPerWorker + ( i < extras ? 1 : 0 );
    332         insert( request_queues[step], sentinels[i] );           // force eventually termination
    333     } // for
    334     #endif
     335    is_shutdown = true;
    335336
    336337    for ( i; nworkers )
     
    363364    size_t avg_gulps = __all_gulps == 0 ? 0 : __all_processed / __all_gulps;
    364365    printf("\tGulps:\t\t\t\t\t%lu\n\tAverage Gulp Size:\t\t\t%lu\n\tMissed gulps:\t\t\t\t%lu\n", __all_gulps, avg_gulps, misses);
    365     printf("\tSteal attempts:\t\t\t\t%lu\n\tSteals:\t\t\t\t\t%lu\n\tSteal failures (no candidates):\t\t%lu\n\tSteal failures (failed swaps):\t\t%lu\n",
    366         __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps);
     366    printf("\tSteal attempts:\t\t\t\t%lu\n\tSteals:\t\t\t\t\t%lu\n\tSteal failures (no candidates):\t\t%lu\n\tSteal failures (failed swaps):\t\t%lu\t Empty steals:\t\t%lu\n",
     367        __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps, __total_empty_stolen);
    367368    size_t avg_steal = __total_stolen == 0 ? 0 : __all_msgs_stolen / __total_stolen;
    368369    printf("\tMessages stolen:\t\t\t%lu\n\tAverage steal size:\t\t\t%lu\n", __all_msgs_stolen, avg_steal);
     
    393394struct actor {
    394395    size_t ticket;                                          // executor-queue handle
    395     Allocation allocation_;                                         // allocation action
     396    allocation allocation_;                                         // allocation action
    396397    inline virtual_dtor;
    397398};
     
    400401    // Once an actor is allocated it must be sent a message or the actor system cannot stop. Hence, its receive
    401402    // member must be called to end it
    402     verifyf( __actor_executor_, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );
     403    DEBUG_ABORT( __actor_executor_ == 0p, "Creating actor before calling start_actor_system() can cause undefined behaviour.\n" );
    403404    allocation_ = Nodelete;
    404405    ticket = __get_next_ticket( *__actor_executor_ );
     
    430431
    431432struct message {
    432     Allocation allocation_;                     // allocation action
     433    allocation allocation_;                     // allocation action
    433434    inline virtual_dtor;
    434435};
     
    437438    this.allocation_ = Nodelete;
    438439}
    439 static inline void ?{}( message & this, Allocation allocation ) {
    440     memcpy( &this.allocation_, &allocation, sizeof(allocation) ); // optimization to elide ctor
    441     verifyf( this.allocation_ != Finished, "The Finished Allocation status is not supported for message types.\n");
     440static inline void ?{}( message & this, allocation alloc ) {
     441    memcpy( &this.allocation_, &alloc, sizeof(allocation) ); // optimization to elide ctor
     442    DEBUG_ABORT( this.allocation_ == Finished, "The Finished allocation status is not supported for message types.\n" );
    442443}
    443444static inline void ^?{}( message & this ) with(this) {
     
    447448static inline void check_message( message & this ) {
    448449    switch ( this.allocation_ ) {                                               // analyze message status
    449         case Nodelete: CFA_DEBUG(this.allocation_ = Finished); break;
     450        case Nodelete: CFA_DEBUG( this.allocation_ = Finished ); break;
    450451        case Delete: delete( &this ); break;
    451         case Destroy: ^?{}(this); break;
     452        case Destroy: ^?{}( this ); break;
    452453        case Finished: break;
    453454    } // switch
    454455}
    455 static inline void set_allocation( message & this, Allocation state ) {
     456static inline void set_allocation( message & this, allocation state ) {
    456457    this.allocation_ = state;
    457458}
    458459
    459460static inline void deliver_request( request & this ) {
    460     this.receiver->allocation_ = this.fn( *this.receiver, *this.msg );
    461     check_message( *this.msg );
    462     check_actor( *this.receiver );
     461    DEBUG_ABORT( this.receiver->ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );
     462    this.base_receiver->allocation_ = this.fn( *this.receiver, *this.msg );
     463    check_message( *this.base_msg );
     464    check_actor( *this.base_receiver );
    463465}
    464466
     
    510512        curr_steal_queue = request_queues[ i + vic_start ];
    511513        // avoid empty queues and queues that are being operated on
    512         if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || isEmpty( *curr_steal_queue->c_queue ) )
     514        if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || is_empty( *curr_steal_queue->c_queue ) )
    513515            continue;
    514516
     
    518520            executor_->w_infos[id].msgs_stolen += curr_steal_queue->c_queue->count;
    519521            executor_->w_infos[id].stolen++;
     522            if ( is_empty( *curr_steal_queue->c_queue ) ) executor_->w_infos[id].empty_stolen++;
    520523            // __atomic_add_fetch(&executor_->w_infos[victim_id].stolen_from, 1, __ATOMIC_RELAXED);
    521524            // replaced_queue[swap_idx]++;
     
    557560}
    558561
     562#define CHECK_TERMINATION if ( unlikely( executor_->is_shutdown ) ) break Exit
    559563void main( worker & this ) with(this) {
    560564    // #ifdef ACTOR_STATS
     
    578582       
    579583        // check if queue is empty before trying to gulp it
    580         if ( isEmpty( *curr_work_queue->c_queue ) ) {
     584        if ( is_empty( *curr_work_queue->c_queue ) ) {
    581585            #ifdef __STEAL
    582586            empty_count++;
     
    591595        #endif // ACTOR_STATS
    592596        #ifdef __STEAL
    593         if ( isEmpty( *current_queue ) ) {
    594             if ( unlikely( no_steal ) ) continue;
     597        if ( is_empty( *current_queue ) ) {
     598            if ( unlikely( no_steal ) ) { CHECK_TERMINATION; continue; }
    595599            empty_count++;
    596600            if ( empty_count < steal_threshold ) continue;
    597601            empty_count = 0;
     602
     603            CHECK_TERMINATION; // check for termination
    598604
    599605            __atomic_store_n( &executor_->w_infos[id].stamp, rdtscl(), __ATOMIC_RELAXED );
     
    607613        }
    608614        #endif // __STEAL
    609         while ( ! isEmpty( *current_queue ) ) {
     615        while ( ! is_empty( *current_queue ) ) {
    610616            #ifdef ACTOR_STATS
    611617            executor_->w_infos[id].processed++;
     
    613619            &req = &remove( *current_queue );
    614620            if ( !&req ) continue;
    615             if ( req.stop ) break Exit;
    616621            deliver_request( req );
    617622        }
     
    631636
    632637static inline void send( actor & this, request & req ) {
    633     verifyf( this.ticket != (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );
     638    DEBUG_ABORT( this.ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );
    634639    send( *__actor_executor_, req, this.ticket );
    635640}
     
    641646    __all_gulps = 0;
    642647    __total_failed_swaps = 0;
     648    __total_empty_stolen = 0;
    643649    __all_processed = 0;
    644650    __num_actors_stats = 0;
     
    654660}
    655661
    656 // TODO: potentially revisit getting number of processors
    657 //  ( currently the value stored in active_cluster()->procs.total is often stale
    658 //  and doesn't reflect how many procs are allocated )
    659 // static inline void start_actor_system() { start_actor_system( active_cluster()->procs.total ); }
    660 static inline void start_actor_system() { start_actor_system( 1 ); }
     662static inline void start_actor_system() { start_actor_system( get_proc_count( *active_cluster() ) ); }
    661663
    662664static inline void start_actor_system( executor & this ) {
     
    668670
    669671static inline void stop_actor_system() {
    670     park( ); // will receive signal when actor system is finished
     672    park( ); // will be unparked when actor system is finished
    671673
    672674    if ( !__actor_executor_passed ) delete( __actor_executor_ );
     
    680682// assigned at creation to __base_msg_finished to avoid unused message warning
    681683message __base_msg_finished @= { .allocation_ : Finished };
    682 struct __DeleteMsg { inline message; } DeleteMsg = __base_msg_finished;
    683 struct __DestroyMsg { inline message; } DestroyMsg = __base_msg_finished;
    684 struct __FinishedMsg { inline message; } FinishedMsg = __base_msg_finished;
    685 
    686 Allocation receive( actor & this, __DeleteMsg & msg ) { return Delete; }
    687 Allocation receive( actor & this, __DestroyMsg & msg ) { return Destroy; }
    688 Allocation receive( actor & this, __FinishedMsg & msg ) { return Finished; }
    689 
     684struct __delete_msg_t { inline message; } delete_msg = __base_msg_finished;
     685struct __destroy_msg_t { inline message; } destroy_msg = __base_msg_finished;
     686struct __finished_msg_t { inline message; } finished_msg = __base_msg_finished;
     687
     688allocation receive( actor & this, __delete_msg_t & msg ) { return Delete; }
     689allocation receive( actor & this, __destroy_msg_t & msg ) { return Destroy; }
     690allocation receive( actor & this, __finished_msg_t & msg ) { return Finished; }
     691
  • libcfa/src/concurrency/atomic.hfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Thu May 25 15:22:46 2023
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu May 25 15:24:45 2023
    13 // Update Count     : 1
     12// Last Modified On : Wed Jun 14 07:48:57 2023
     13// Update Count     : 52
    1414//
    1515
    16 #define LOAD( lock ) (__atomic_load_n( &(lock), __ATOMIC_SEQ_CST ))
    17 #define LOADM( lock, memorder ) (__atomic_load_n( &(lock), memorder ))
    18 #define STORE( lock, assn ) (__atomic_store_n( &(lock), assn, __ATOMIC_SEQ_CST ))
    19 #define STOREM( lock, assn, memorder ) (__atomic_store_n( &(lock), assn, memorder ))
    20 #define CLR( lock ) (__atomic_clear( &(lock), __ATOMIC_RELEASE ))
    21 #define CLRM( lock, memorder ) (__atomic_clear( &(lock), memorder ))
    22 #define TAS( lock ) (__atomic_test_and_set( &(lock), __ATOMIC_ACQUIRE ))
    23 #define TASM( lock, memorder ) (__atomic_test_and_set( &(lock), memorder ))
    24 #define CAS( change, comp, assn ) ({typeof(comp) __temp = (comp); __atomic_compare_exchange_n( &(change), &(__temp), (assn), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); })
    25 #define CASM( change, comp, assn, memorder... ) ({typeof(comp) * __temp = &(comp); __atomic_compare_exchange_n( &(change), &(__temp), (assn), false, memorder, memorder ); })
    26 #define CASV( change, comp, assn ) (__atomic_compare_exchange_n( &(change), &(comp), (assn), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ))
    27 #define CASVM( change, comp, assn, memorder... ) (__atomic_compare_exchange_n( &(change), &(comp), (assn), false, memorder, memorder ))
    28 #define FAS( change, assn ) (__atomic_exchange_n( &(change), (assn), __ATOMIC_SEQ_CST ))
    29 #define FASM( change, assn, memorder ) (__atomic_exchange_n( &(change), (assn), memorder ))
    30 #define FAI( change, Inc ) (__atomic_fetch_add( &(change), (Inc), __ATOMIC_SEQ_CST ))
    31 #define FAIM( change, Inc, memorder ) (__atomic_fetch_add( &(change), (Inc), memorder ))
     16#define LOAD( val ) (LOADM( val, __ATOMIC_SEQ_CST))
     17#define LOADM( val, memorder ) (__atomic_load_n( &(val), memorder))
     18
     19#define STORE( val, assn ) (STOREM( val, assn, __ATOMIC_SEQ_CST))
     20#define STOREM( val, assn, memorder ) (__atomic_store_n( &(val), assn, memorder))
     21
     22#define TAS( lock ) (TASM( lock, __ATOMIC_ACQUIRE))
     23#define TASM( lock, memorder ) (__atomic_test_and_set( &(lock), memorder))
     24
     25#define TASCLR( lock ) (TASCLRM( lock, __ATOMIC_RELEASE))
     26#define TASCLRM( lock, memorder ) (__atomic_clear( &(lock), memorder))
     27
     28#define FAS( assn, replace ) (FASM(assn, replace, __ATOMIC_SEQ_CST))
     29#define FASM( assn, replace, memorder ) (__atomic_exchange_n( &(assn), (replace), memorder))
     30
     31#define FAI( assn, Inc ) (__atomic_fetch_add( &(assn), (Inc), __ATOMIC_SEQ_CST))
     32#define FAIM( assn, Inc, memorder ) (__atomic_fetch_add( &(assn), (Inc), memorder))
     33
     34// Use __sync because __atomic with 128-bit CAA can result in calls to pthread_mutex_lock.
     35
     36// #define CAS( assn, comp, replace ) (CASM( assn, comp, replace, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
     37// #define CASM( assn, comp, replace, memorder... ) ({ typeof(comp) __temp = (comp); __atomic_compare_exchange_n( &(assn), &(__temp), (replace), false, memorder ); })
     38#define CAS( assn, comp, replace ) (__sync_bool_compare_and_swap( &assn, comp, replace))
     39#define CASM( assn, comp, replace, memorder... ) _Static_assert( false, "memory order unsupported for CAS macro" );
     40
     41// #define CASV( assn, comp, replace ) (__atomic_compare_exchange_n( &(assn), &(comp), (replace), false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ))
     42// #define CASVM( assn, comp, replace, memorder... ) (__atomic_compare_exchange_n( &(assn), &(comp), (replace), false, memorder, memorder ))
     43#define CASV( assn, comp, replace ) ({ \
     44        typeof(comp) temp = comp; \
     45        typeof(comp) old = __sync_val_compare_and_swap( &(assn), (comp), (replace) ); \
     46        old == temp ? true : (comp = old, false); \
     47})
     48#define CASVM( assn, comp, replace, memorder... ) _Static_assert( false, "memory order unsupported for CASV macro" );
  • libcfa/src/concurrency/kernel.hfa

    rfa5e1aa5 rb7b3e41  
    195195        // Total number of processors
    196196        unsigned total;
     197
     198    // Number of processors constructed
     199    //  incremented at construction time, total is incremented once the processor asyncronously registers
     200        unsigned constructed;
    197201
    198202        // Total number of idle processors
     
    297301static inline struct cluster   * active_cluster  () { return publicTLS_get( this_processor )->cltr; }
    298302
     303// gets the number of constructed processors on the cluster
     304static inline unsigned get_proc_count( cluster & this ) { return this.procs.constructed; }
     305
    299306// set the number of internal processors
    300307// these processors are in addition to any explicitly declared processors
  • libcfa/src/concurrency/kernel/cluster.hfa

    rfa5e1aa5 rb7b3e41  
    4040
    4141// convert to log2 scale but using double
    42 static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2(intsc); }
     42static inline __readyQ_avg_t __to_readyQ_avg(unsigned long long intsc) { if(unlikely(0 == intsc)) return 0.0; else return log2((__readyQ_avg_t)intsc); }
    4343
    4444#define warn_large_before warnf( !strict || old_avg < 35.0, "Suspiciously large previous average: %'lf, %'" PRId64 "ms \n", old_avg, program()`ms )
  • libcfa/src/concurrency/kernel/startup.cfa

    rfa5e1aa5 rb7b3e41  
    528528        this.name = name;
    529529        this.cltr = &_cltr;
     530    __atomic_add_fetch( &_cltr.procs.constructed, 1u, __ATOMIC_RELAXED );
    530531        this.rdq.its = 0;
    531532        this.rdq.itr = 0;
     
    595596        __cfadbg_print_safe(runtime_core, "Kernel : core %p signaling termination\n", &this);
    596597
     598    __atomic_sub_fetch( &this.cltr->procs.constructed, 1u, __ATOMIC_RELAXED );
     599
    597600        __atomic_store_n(&do_terminate, true, __ATOMIC_RELAXED);
    598601        __disable_interrupts_checked();
     
    615618        this.fdw   = 0p;
    616619        this.idle  = 0;
     620    this.constructed = 0;
    617621        this.total = 0;
    618622}
  • libcfa/src/concurrency/locks.hfa

    rfa5e1aa5 rb7b3e41  
    3232#include "select.hfa"
    3333
    34 #include <fstream.hfa>
    35 
    3634// futex headers
    3735#include <linux/futex.h>      /* Definition of FUTEX_* constants */
  • libcfa/src/containers/lockfree.hfa

    rfa5e1aa5 rb7b3e41  
    199199
    200200forall( T & )
     201struct LinkData {
     202        T * volatile top;                                                               // pointer to stack top
     203        uintptr_t count;                                                                // count each push
     204};
     205
     206forall( T & )
    201207union Link {
    202         struct {                                                                                        // 32/64-bit x 2
    203                 T * volatile top;                                                               // pointer to stack top
    204                 uintptr_t count;                                                                // count each push
    205         };
     208        LinkData(T) data;
    206209        #if __SIZEOF_INT128__ == 16
    207210        __int128                                                                                        // gcc, 128-bit integer
     
    220223                void ?{}( StackLF(T) & this ) with(this) { stack.atom = 0; }
    221224
    222                 T * top( StackLF(T) & this ) with(this) { return stack.top; }
     225                T * top( StackLF(T) & this ) with(this) { return stack.data.top; }
    223226
    224227                void push( StackLF(T) & this, T & n ) with(this) {
    225228                        *( &n )`next = stack;                                           // atomic assignment unnecessary, or use CAA
    226229                        for () {                                                                        // busy wait
    227                           if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ {&n, ( &n )`next->count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
     230                                if ( __atomic_compare_exchange_n( &stack.atom, &( &n )`next->atom, (Link(T))@{ (LinkData(T))@{ &n, ( &n )`next->data.count + 1} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) break; // attempt to update top node
    228231                        } // for
    229232                } // push
     
    232235                        Link(T) t @= stack;                                                     // atomic assignment unnecessary, or use CAA
    233236                        for () {                                                                        // busy wait
    234                           if ( t.top == 0p ) return 0p;                         // empty stack ?
    235                           if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ {( t.top )`next->top, t.count} }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.top; // attempt to update top node
     237                                if ( t.data.top == 0p ) return 0p;                              // empty stack ?
     238                                Link(T) * next = ( t.data.top )`next;
     239                                if ( __atomic_compare_exchange_n( &stack.atom, &t.atom, (Link(T))@{ (LinkData(T))@{ next->data.top, t.data.count } }.atom, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ) ) return t.data.top; // attempt to update top node
    236240                        } // for
    237241                } // pop
     
    239243                bool unsafe_remove( StackLF(T) & this, T * node ) with(this) {
    240244                        Link(T) * link = &stack;
    241                         for() {
    242                                 T * next = link->top;
    243                                 if( next == node ) {
    244                                         link->top = ( node )`next->top;
     245                        for () {
     246                                // TODO: Avoiding some problems with double fields access.
     247                                LinkData(T) * data = &link->data;
     248                                T * next = (T *)&(*data).top;
     249                                if ( next == node ) {
     250                                        data->top = ( node )`next->data.top;
    245251                                        return true;
    246252                                }
    247                                 if( next == 0p ) return false;
     253                                if ( next == 0p ) return false;
    248254                                link = ( next )`next;
    249255                        }
  • libcfa/src/fstream.cfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr  9 14:55:54 2022
    13 // Update Count     : 515
     12// Last Modified On : Sat Jun 17 08:51:12 2023
     13// Update Count     : 528
    1414//
    1515
     
    117117    } // for
    118118        if ( file == 0p ) {
    119                 throw (Open_Failure){ os };
     119                throw (open_failure){ os };
    120120                // abort | IO_MSG "open output file \"" | name | "\"" | nl | strerror( errno );
    121121        } // if
     
    137137    } // for
    138138        if ( ret == EOF ) {
    139                 throw (Close_Failure){ os };
     139                throw (close_failure){ os };
    140140                // abort | IO_MSG "close output" | nl | strerror( errno );
    141141        } // if
     
    145145ofstream & write( ofstream & os, const char data[], size_t size ) {
    146146        if ( fail( os ) ) {
    147                 throw (Write_Failure){ os };
     147                throw (write_failure){ os };
    148148                // abort | IO_MSG "attempt write I/O on failed stream";
    149149        } // if
    150150
    151151        if ( fwrite( data, 1, size, (FILE *)(os.file$) ) != size ) {
    152                 throw (Write_Failure){ os };
     152                throw (write_failure){ os };
    153153                // abort | IO_MSG "write" | nl | strerror( errno );
    154154        } // if
     
    169169          if ( cnt == 9 ) abort( "ofstream fmt EINTR spinning exceeded" );
    170170    } // for
    171         if ( len == EOF ) {
    172                 if ( ferror( (FILE *)(os.file$) ) ) {
    173                         abort | IO_MSG "invalid write";
    174                 } // if
     171        if ( len == EOF ) {                                                                     // error writing ?
     172                abort | IO_MSG "invalid write";
    175173        } // if
    176174        va_end( args );
     
    240238    } // for
    241239        if ( file == 0p ) {
    242                 throw (Open_Failure){ is };
     240                throw (open_failure){ is };
    243241                // abort | IO_MSG "open input file \"" | name | "\"" | nl | strerror( errno );
    244242        } // if
     
    260258    } // for
    261259        if ( ret == EOF ) {
    262                 throw (Close_Failure){ is };
     260                throw (close_failure){ is };
    263261                // abort | IO_MSG "close input" | nl | strerror( errno );
    264262        } // if
     
    268266ifstream & read( ifstream & is, char data[], size_t size ) {
    269267        if ( fail( is ) ) {
    270                 throw (Read_Failure){ is };
     268                throw (read_failure){ is };
    271269                // abort | IO_MSG "attempt read I/O on failed stream";
    272270        } // if
    273271
    274272        if ( fread( data, size, 1, (FILE *)(is.file$) ) == 0 ) {
    275                 throw (Read_Failure){ is };
     273                throw (read_failure){ is };
    276274                // abort | IO_MSG "read" | nl | strerror( errno );
    277275        } // if
     
    302300          if ( len != EOF || errno != EINTR ) break;            // timer interrupt ?
    303301    } // for
    304         if ( len == EOF ) {
    305                 if ( ferror( (FILE *)(is.file$) ) ) {
     302        if ( len == EOF ) {                                                                     // EOF or matching failure ?
     303                if ( ! feof( (FILE *)(is.file$) ) && ferror( (FILE *)(is.file$) ) ) {
    306304                        abort | IO_MSG "invalid read";
    307305                } // if
     
    318316
    319317
    320 static vtable(Open_Failure) Open_Failure_vt;
     318static vtable(open_failure) open_failure_vt;
    321319
    322320// exception I/O constructors
    323 void ?{}( Open_Failure & ex, ofstream & ostream ) with(ex) {
    324         virtual_table = &Open_Failure_vt;
     321void ?{}( open_failure & ex, ofstream & ostream ) with(ex) {
     322        virtual_table = &open_failure_vt;
    325323        ostream = &ostream;
    326324        tag = 1;
    327325} // ?{}
    328326
    329 void ?{}( Open_Failure & ex, ifstream & istream ) with(ex) {
    330         virtual_table = &Open_Failure_vt;
     327void ?{}( open_failure & ex, ifstream & istream ) with(ex) {
     328        virtual_table = &open_failure_vt;
    331329        istream = &istream;
    332330        tag = 0;
     
    334332
    335333
    336 static vtable(Close_Failure) Close_Failure_vt;
     334static vtable(close_failure) close_failure_vt;
    337335
    338336// exception I/O constructors
    339 void ?{}( Close_Failure & ex, ofstream & ostream ) with(ex) {
    340         virtual_table = &Close_Failure_vt;
     337void ?{}( close_failure & ex, ofstream & ostream ) with(ex) {
     338        virtual_table = &close_failure_vt;
    341339        ostream = &ostream;
    342340        tag = 1;
    343341} // ?{}
    344342
    345 void ?{}( Close_Failure & ex, ifstream & istream ) with(ex) {
    346         virtual_table = &Close_Failure_vt;
     343void ?{}( close_failure & ex, ifstream & istream ) with(ex) {
     344        virtual_table = &close_failure_vt;
    347345        istream = &istream;
    348346        tag = 0;
     
    350348
    351349
    352 static vtable(Write_Failure) Write_Failure_vt;
     350static vtable(write_failure) write_failure_vt;
    353351
    354352// exception I/O constructors
    355 void ?{}( Write_Failure & ex, ofstream & ostream ) with(ex) {
    356         virtual_table = &Write_Failure_vt;
     353void ?{}( write_failure & ex, ofstream & ostream ) with(ex) {
     354        virtual_table = &write_failure_vt;
    357355        ostream = &ostream;
    358356        tag = 1;
    359357} // ?{}
    360358
    361 void ?{}( Write_Failure & ex, ifstream & istream ) with(ex) {
    362         virtual_table = &Write_Failure_vt;
     359void ?{}( write_failure & ex, ifstream & istream ) with(ex) {
     360        virtual_table = &write_failure_vt;
    363361        istream = &istream;
    364362        tag = 0;
     
    366364
    367365
    368 static vtable(Read_Failure) Read_Failure_vt;
     366static vtable(read_failure) read_failure_vt;
    369367
    370368// exception I/O constructors
    371 void ?{}( Read_Failure & ex, ofstream & ostream ) with(ex) {
    372         virtual_table = &Read_Failure_vt;
     369void ?{}( read_failure & ex, ofstream & ostream ) with(ex) {
     370        virtual_table = &read_failure_vt;
    373371        ostream = &ostream;
    374372        tag = 1;
    375373} // ?{}
    376374
    377 void ?{}( Read_Failure & ex, ifstream & istream ) with(ex) {
    378         virtual_table = &Read_Failure_vt;
     375void ?{}( read_failure & ex, ifstream & istream ) with(ex) {
     376        virtual_table = &read_failure_vt;
    379377        istream = &istream;
    380378        tag = 0;
    381379} // ?{}
    382380
    383 // void throwOpen_Failure( ofstream & ostream ) {
    384 //      Open_Failure exc = { ostream };
     381// void throwopen_failure( ofstream & ostream ) {
     382//      open_failure exc = { ostream };
    385383// }
    386384
    387 // void throwOpen_Failure( ifstream & istream ) {
    388 //      Open_Failure exc = { istream };
     385// void throwopen_failure( ifstream & istream ) {
     386//      open_failure exc = { istream };
    389387// }
    390388
  • libcfa/src/fstream.hfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Oct 10 09:37:32 2021
    13 // Update Count     : 243
     12// Last Modified On : Mon Jun  5 22:00:20 2023
     13// Update Count     : 246
    1414//
    1515
     
    137137
    138138
    139 exception Open_Failure {
     139exception open_failure {
    140140        union {
    141141                ofstream * ostream;
     
    146146};
    147147
    148 void ?{}( Open_Failure & this, ofstream & );
    149 void ?{}( Open_Failure & this, ifstream & );
     148void ?{}( open_failure & this, ofstream & );
     149void ?{}( open_failure & this, ifstream & );
    150150
    151 exception Close_Failure {
     151exception close_failure {
    152152        union {
    153153                ofstream * ostream;
     
    158158};
    159159
    160 void ?{}( Close_Failure & this, ofstream & );
    161 void ?{}( Close_Failure & this, ifstream & );
     160void ?{}( close_failure & this, ofstream & );
     161void ?{}( close_failure & this, ifstream & );
    162162
    163 exception Write_Failure {
     163exception write_failure {
    164164        union {
    165165                ofstream * ostream;
     
    170170};
    171171
    172 void ?{}( Write_Failure & this, ofstream & );
    173 void ?{}( Write_Failure & this, ifstream & );
     172void ?{}( write_failure & this, ofstream & );
     173void ?{}( write_failure & this, ifstream & );
    174174
    175 exception Read_Failure {
     175exception read_failure {
    176176        union {
    177177                ofstream * ostream;
     
    182182};
    183183
    184 void ?{}( Read_Failure & this, ofstream & );
    185 void ?{}( Read_Failure & this, ifstream & );
     184void ?{}( read_failure & this, ofstream & );
     185void ?{}( read_failure & this, ifstream & );
    186186
    187187// Local Variables: //
  • libcfa/src/iostream.hfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  2 11:25:39 2023
    13 // Update Count     : 410
     12// Last Modified On : Thu Jun 15 22:34:31 2023
     13// Update Count     : 411
    1414//
    1515
     
    5151        int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    5252}; // basic_ostream
    53        
     53
    5454forall( ostype & | basic_ostream( ostype ) )
    5555trait ostream {
     
    6868
    6969forall( T, ostype & | ostream( ostype ) )
    70         trait writeable {
     70trait writeable {
    7171        ostype & ?|?( ostype &, T );
    7272}; // writeable
     
    161161// *********************************** manipulators ***********************************
    162162
     163struct _Ostream_Flags {
     164        unsigned char eng:1;                                                            // engineering notation
     165        unsigned char neg:1;                                                            // val is negative
     166        unsigned char pc:1;                                                                     // precision specified
     167        unsigned char left:1;                                                           // left justify
     168        unsigned char nobsdp:1;                                                         // base prefix / decimal point
     169        unsigned char sign:1;                                                           // plus / minus sign
     170        unsigned char pad0:1;                                                           // zero pad
     171};
     172
    163173forall( T )
    164174struct _Ostream_Manip {
     
    168178        union {
    169179                unsigned char all;
    170                 struct {
    171                         unsigned char eng:1;                                            // engineering notation
    172                         unsigned char neg:1;                                            // val is negative
    173                         unsigned char pc:1;                                                     // precision specified
    174                         unsigned char left:1;                                           // left justify
    175                         unsigned char nobsdp:1;                                         // base prefix / decimal point
    176                         unsigned char sign:1;                                           // plus / minus sign
    177                         unsigned char pad0:1;                                           // zero pad
    178                 } flags;
     180                _Ostream_Flags flags;
    179181        };
    180182}; // _Ostream_Manip
  • libcfa/src/math.hfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Mon Apr 18 23:37:04 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Oct  8 08:40:42 2022
    13 // Update Count     : 136
     12// Last Modified On : Sun Jun 18 08:13:53 2023
     13// Update Count     : 202
    1414//
    1515
     
    236236
    237237        return (i << 32) + (sum);
    238 }
     238} // log2_u32_32
    239239
    240240//---------------------- Trigonometric ----------------------
     
    371371
    372372inline __attribute__((always_inline)) static {
    373         signed char floor( signed char n, signed char align ) { return n / align * align; }
    374         unsigned char floor( unsigned char n, unsigned char align ) { return n / align * align; }
    375         short int floor( short int n, short int align ) { return n / align * align; }
    376         unsigned short int floor( unsigned short int n, unsigned short int align ) { return n / align * align; }
    377         int floor( int n, int align ) { return n / align * align; }
    378         unsigned int floor( unsigned int n, unsigned int align ) { return n / align * align; }
    379         long int floor( long int n, long int align ) { return n / align * align; }
    380         unsigned long int floor( unsigned long int n, unsigned long int align ) { return n / align * align; }
    381         long long int floor( long long int n, long long int align ) { return n / align * align; }
    382         unsigned long long int floor( unsigned long long int n, unsigned long long int align ) { return n / align * align; }
     373        // force divide before multiply
     374        signed char floor( signed char n, signed char align ) { return (n / align) * align; }
     375        unsigned char floor( unsigned char n, unsigned char align ) { return (n / align) * align; }
     376        short int floor( short int n, short int align ) { return (n / align) * align; }
     377        unsigned short int floor( unsigned short int n, unsigned short int align ) { return (n / align) * align; }
     378        int floor( int n, int align ) { return (n / align) * align; }
     379        unsigned int floor( unsigned int n, unsigned int align ) { return (n / align) * align; }
     380        long int floor( long int n, long int align ) { return (n / align) * align; }
     381        unsigned long int floor( unsigned long int n, unsigned long int align ) { return (n / align) * align; }
     382        long long int floor( long long int n, long long int align ) { return (n / align) * align; }
     383        unsigned long long int floor( unsigned long long int n, unsigned long long int align ) { return (n / align) * align; }
    383384
    384385        // forall( T | { T ?/?( T, T ); T ?*?( T, T ); } )
    385         // T floor( T n, T align ) { return n / align * align; }
    386 
    387         signed char ceiling_div( signed char n, char align ) { return (n + (align - 1)) / align; }
    388         unsigned char ceiling_div( unsigned char n, unsigned char align ) { return (n + (align - 1)) / align; }
    389         short int ceiling_div( short int n, short int align ) { return (n + (align - 1)) / align; }
    390         unsigned short int ceiling_div( unsigned short int n, unsigned short int align ) { return (n + (align - 1)) / align; }
    391         int ceiling_div( int n, int align ) { return (n + (align - 1)) / align; }
    392         unsigned int ceiling_div( unsigned int n, unsigned int align ) { return (n + (align - 1)) / align; }
    393         long int ceiling_div( long int n, long int align ) { return (n + (align - 1)) / align; }
    394         unsigned long int ceiling_div( unsigned long int n, unsigned long int align ) { return (n + (align - 1)) / align; }
    395         long long int ceiling_div( long long int n, long long int align ) { return (n + (align - 1)) / align; }
    396         unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1)) / align; }
    397 
    398         // forall( T | { T ?+?( T, T ); T ?-?( T, T ); T ?%?( T, T ); } )
    399         // T ceiling_div( T n, T align ) { verify( is_pow2( align ) );return (n + (align - 1)) / align; }
    400 
    401         // gcc notices the div/mod pair and saves both so only one div.
    402         signed char ceiling( signed char n, signed char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    403         unsigned char ceiling( unsigned char n, unsigned char align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    404         short int ceiling( short int n, short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    405         unsigned short int ceiling( unsigned short int n, unsigned short int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    406         int ceiling( int n, int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    407         unsigned int ceiling( unsigned int n, unsigned int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    408         long int ceiling( long int n, long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    409         unsigned long int ceiling( unsigned long int n, unsigned long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0) , align); }
    410         long long int ceiling( long long int n, long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    411         unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) { return floor( n + (n % align != 0 ? align - 1 : 0), align ); }
    412 
    413         // forall( T | { void ?{}( T &, one_t ); T ?+?( T, T ); T ?-?( T, T ); T ?/?( T, T ); } )
    414         // T ceiling( T n, T align ) { return return floor( n + (n % align != 0 ? align - 1 : 0), align ); *}
     386        // T floor( T n, T align ) { return (n / align) * align; }
     387
     388        signed char ceiling_div( signed char n, char align ) { return (n + (align - 1hh)) / align; }
     389        unsigned char ceiling_div( unsigned char n, unsigned char align ) { return (n + (align - 1hhu)) / align; }
     390        short int ceiling_div( short int n, short int align ) { return (n + (align - 1h)) / align; }
     391        unsigned short int ceiling_div( unsigned short int n, unsigned short int align ) { return (n + (align - 1hu)) / align; }
     392        int ceiling_div( int n, int align ) { return (n + (align - 1n)) / align; }
     393        unsigned int ceiling_div( unsigned int n, unsigned int align ) { return (n + (align - 1nu)) / align; }
     394        long int ceiling_div( long int n, long int align ) { return (n + (align - 1l)) / align; }
     395        unsigned long int ceiling_div( unsigned long int n, unsigned long int align ) { return (n + (align - 1lu)) / align; }
     396        long long int ceiling_div( long long int n, long long int align ) { return (n + (align - 1ll)) / align; }
     397        unsigned long long int ceiling_div( unsigned long long int n, unsigned long long int align ) { return (n + (align - 1llu)) / align; }
     398
     399        signed char ceiling( signed char n, char align ) {
     400                typeof(n) trunc = floor( n, align );
     401                return n < 0 || n == trunc ? trunc : trunc + align;
     402        }
     403        unsigned char ceiling( unsigned char n, unsigned char align ) {
     404                typeof(n) trunc = floor( n, align );
     405                return n == trunc ? trunc : trunc + align;
     406        }
     407        short int ceiling( short int n, short int align ) {
     408                typeof(n) trunc = floor( n, align );
     409                return n < 0 || n == trunc ? trunc : trunc + align;
     410        }
     411        unsigned short int ceiling( unsigned short int n, unsigned short int align ) {
     412                typeof(n) trunc = floor( n, align );
     413                return n == trunc ? trunc : trunc + align;
     414        }
     415        int ceiling( int n, int align ) {
     416                typeof(n) trunc = floor( n, align );
     417                return n < 0 || n == trunc ? trunc : trunc + align;
     418        }
     419        unsigned int ceiling( unsigned int n, unsigned int align ) {
     420                typeof(n) trunc = floor( n, align );
     421                return n == trunc ? trunc : trunc + align;
     422        }
     423        long int ceiling( long int n, long int align ) {
     424                typeof(n) trunc = floor( n, align );
     425                return n < 0 || n == trunc ? trunc : trunc + align;
     426        }
     427        unsigned long int ceiling( unsigned long int n, unsigned long int align ) {
     428                typeof(n) trunc = floor( n, align );
     429                return n == trunc ? trunc : trunc + align;
     430        }
     431        long long int ceiling( long long int n, signed long long int align ) {
     432                typeof(n) trunc = floor( n, align );
     433                return n < 0 || n == trunc ? trunc : trunc + align;
     434        }
     435        unsigned long long int ceiling( unsigned long long int n, unsigned long long int align ) {
     436                typeof(n) trunc = floor( n, align );
     437                return n == trunc ? trunc : trunc + align;
     438        }
    415439
    416440        float floor( float x ) { return floorf( x ); }
  • libcfa/src/math.trait.hfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Fri Jul 16 15:40:52 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  2 11:36:56 2023
    13 // Update Count     : 20
     12// Last Modified On : Tue Jun  6 07:59:17 2023
     13// Update Count     : 24
    1414//
    1515
     
    1717
    1818forall( U )
    19 trait Not {
     19trait not {
    2020        void ?{}( U &, zero_t );
    2121        int !?( U );
    22 }; // Not
     22}; // not
    2323
    24 forall( T | Not( T ) )
    25 trait Equality {
     24forall( T | not( T ) )
     25trait equality {
    2626        int ?==?( T, T );
    2727        int ?!=?( T, T );
    28 }; // Equality
     28}; // equality
    2929
    30 forall( U | Equality( U ) )
    31 trait Relational {
     30forall( U | equality( U ) )
     31trait relational {
    3232        int ?<?( U, U );
    3333        int ?<=?( U, U );
    3434        int ?>?( U, U );
    3535        int ?>=?( U, U );
    36 }; // Relational
     36}; // relational
    3737
    3838forall ( T )
    39 trait Signed {
     39trait Signed {  // must be capitalized, conflict with keyword signed
    4040        T +?( T );
    4141        T -?( T );
     
    4444
    4545forall( U | Signed( U ) )
    46 trait Additive {
     46trait additive {
    4747        U ?+?( U, U );
    4848        U ?-?( U, U );
    4949        U ?+=?( U &, U );
    5050        U ?-=?( U &, U );
    51 }; // Additive
     51}; // additive
    5252
    53 forall( T | Additive( T ) )
    54 trait Incdec {
     53forall( T | additive( T ) )
     54trait inc_dec {
    5555        void ?{}( T &, one_t );
    5656        // T ?++( T & );
     
    5858        // T ?--( T & );
    5959        // T --?( T & );
    60 }; // Incdec
     60}; // inc_dec
    6161
    62 forall( U | Incdec( U ) )
    63 trait Multiplicative {
     62forall( U | inc_dec( U ) )
     63trait multiplicative {
    6464        U ?*?( U, U );
    6565        U ?/?( U, U );
    6666        U ?%?( U, U );
    6767        U ?/=?( U &, U );
    68 }; // Multiplicative
     68}; // multiplicative
    6969
    70 forall( T | Relational( T ) | Multiplicative( T ) )
    71 trait Arithmetic {
    72 }; // Arithmetic
     70forall( T | relational( T ) | multiplicative( T ) )
     71trait arithmetic {
     72}; // arithmetic
    7373
    7474// Local Variables: //
  • libcfa/src/parseconfig.cfa

    rfa5e1aa5 rb7b3e41  
    144144                        in | nl;                                                                // ignore remainder of line
    145145                } // for
    146         } catch( Open_Failure * ex; ex->istream == &in ) {
     146        } catch( open_failure * ex; ex->istream == &in ) {
    147147                delete( kv_pairs );
    148148                throw *ex;
     
    203203
    204204
    205 forall(T | Relational( T ))
     205forall(T | relational( T ))
    206206[ bool ] is_nonnegative( & T value ) {
    207207        T zero_val = 0;
     
    209209}
    210210
    211 forall(T | Relational( T ))
     211forall(T | relational( T ))
    212212[ bool ] is_positive( & T value ) {
    213213        T zero_val = 0;
     
    215215}
    216216
    217 forall(T | Relational( T ))
     217forall(T | relational( T ))
    218218[ bool ] is_nonpositive( & T value ) {
    219219        T zero_val = 0;
     
    221221}
    222222
    223 forall(T | Relational( T ))
     223forall(T | relational( T ))
    224224[ bool ] is_negative( & T value ) {
    225225        T zero_val = 0;
  • libcfa/src/parseconfig.hfa

    rfa5e1aa5 rb7b3e41  
    107107
    108108
    109 forall(T | Relational( T ))
     109forall(T | relational( T ))
    110110[ bool ] is_nonnegative( & T );
    111111
    112 forall(T | Relational( T ))
     112forall(T | relational( T ))
    113113[ bool ] is_positive( & T );
    114114
    115 forall(T | Relational( T ))
     115forall(T | relational( T ))
    116116[ bool ] is_nonpositive( & T );
    117117
    118 forall(T | Relational( T ))
     118forall(T | relational( T ))
    119119[ bool ] is_negative( & T );
    120120
  • libcfa/src/rational.cfa

    rfa5e1aa5 rb7b3e41  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 25 18:09:58 2022
    13 // Update Count     : 194
     12// Last Modified On : Mon Jun  5 22:49:06 2023
     13// Update Count     : 196
    1414//
    1515
     
    2020#pragma GCC visibility push(default)
    2121
    22 forall( T | Arithmetic( T ) ) {
     22forall( T | arithmetic( T ) ) {
    2323        // helper routines
    2424
     
    3939                        abort | "Invalid rational number construction: denominator cannot be equal to 0.";
    4040                } // exit
    41                 if ( d < (T){0} ) { d = -d; n = -n; } // move sign to numerator
     41                if ( d < (T){0} ) { d = -d; n = -n; }                   // move sign to numerator
    4242                return gcd( abs( n ), d );                                              // simplify
    43         } // Rationalnumber::simplify
     43        } // simplify
    4444
    4545        // constructors
    4646
    47         void ?{}( Rational(T) & r, zero_t ) {
     47        void ?{}( rational(T) & r, zero_t ) {
    4848                r{ (T){0}, (T){1} };
    4949        } // rational
    5050
    51         void ?{}( Rational(T) & r, one_t ) {
     51        void ?{}( rational(T) & r, one_t ) {
    5252                r{ (T){1}, (T){1} };
    5353        } // rational
    5454
    55         void ?{}( Rational(T) & r ) {
     55        void ?{}( rational(T) & r ) {
    5656                r{ (T){0}, (T){1} };
    5757        } // rational
    5858
    59         void ?{}( Rational(T) & r, T n ) {
     59        void ?{}( rational(T) & r, T n ) {
    6060                r{ n, (T){1} };
    6161        } // rational
    6262
    63         void ?{}( Rational(T) & r, T n, T d ) {
    64                 T t = simplify( n, d );                         // simplify
     63        void ?{}( rational(T) & r, T n, T d ) {
     64                T t = simplify( n, d );                                                 // simplify
    6565                r.[numerator, denominator] = [n / t, d / t];
    6666        } // rational
     
    6868        // getter for numerator/denominator
    6969
    70         T numerator( Rational(T) r ) {
     70        T numerator( rational(T) r ) {
    7171                return r.numerator;
    7272        } // numerator
    7373
    74         T denominator( Rational(T) r ) {
     74        T denominator( rational(T) r ) {
    7575                return r.denominator;
    7676        } // denominator
    7777
    78         [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src ) {
     78        [ T, T ] ?=?( & [ T, T ] dest, rational(T) src ) {
    7979                return dest = src.[ numerator, denominator ];
    8080        } // ?=?
     
    8282        // setter for numerator/denominator
    8383
    84         T numerator( Rational(T) r, T n ) {
     84        T numerator( rational(T) r, T n ) {
    8585                T prev = r.numerator;
    86                 T t = gcd( abs( n ), r.denominator ); // simplify
     86                T t = gcd( abs( n ), r.denominator );                   // simplify
    8787                r.[numerator, denominator] = [n / t, r.denominator / t];
    8888                return prev;
    8989        } // numerator
    9090
    91         T denominator( Rational(T) r, T d ) {
     91        T denominator( rational(T) r, T d ) {
    9292                T prev = r.denominator;
    93                 T t = simplify( r.numerator, d );       // simplify
     93                T t = simplify( r.numerator, d );                               // simplify
    9494                r.[numerator, denominator] = [r.numerator / t, d / t];
    9595                return prev;
     
    9898        // comparison
    9999
    100         int ?==?( Rational(T) l, Rational(T) r ) {
     100        int ?==?( rational(T) l, rational(T) r ) {
    101101                return l.numerator * r.denominator == l.denominator * r.numerator;
    102102        } // ?==?
    103103
    104         int ?!=?( Rational(T) l, Rational(T) r ) {
     104        int ?!=?( rational(T) l, rational(T) r ) {
    105105                return ! ( l == r );
    106106        } // ?!=?
    107107
    108         int ?!=?( Rational(T) l, zero_t ) {
    109                 return ! ( l == (Rational(T)){ 0 } );
     108        int ?!=?( rational(T) l, zero_t ) {
     109                return ! ( l == (rational(T)){ 0 } );
    110110        } // ?!=?
    111111
    112         int ?<?( Rational(T) l, Rational(T) r ) {
     112        int ?<?( rational(T) l, rational(T) r ) {
    113113                return l.numerator * r.denominator < l.denominator * r.numerator;
    114114        } // ?<?
    115115
    116         int ?<=?( Rational(T) l, Rational(T) r ) {
     116        int ?<=?( rational(T) l, rational(T) r ) {
    117117                return l.numerator * r.denominator <= l.denominator * r.numerator;
    118118        } // ?<=?
    119119
    120         int ?>?( Rational(T) l, Rational(T) r ) {
     120        int ?>?( rational(T) l, rational(T) r ) {
    121121                return ! ( l <= r );
    122122        } // ?>?
    123123
    124         int ?>=?( Rational(T) l, Rational(T) r ) {
     124        int ?>=?( rational(T) l, rational(T) r ) {
    125125                return ! ( l < r );
    126126        } // ?>=?
     
    128128        // arithmetic
    129129
    130         Rational(T) +?( Rational(T) r ) {
    131                 return (Rational(T)){ r.numerator, r.denominator };
     130        rational(T) +?( rational(T) r ) {
     131                return (rational(T)){ r.numerator, r.denominator };
    132132        } // +?
    133133
    134         Rational(T) -?( Rational(T) r ) {
    135                 return (Rational(T)){ -r.numerator, r.denominator };
     134        rational(T) -?( rational(T) r ) {
     135                return (rational(T)){ -r.numerator, r.denominator };
    136136        } // -?
    137137
    138         Rational(T) ?+?( Rational(T) l, Rational(T) r ) {
     138        rational(T) ?+?( rational(T) l, rational(T) r ) {
    139139                if ( l.denominator == r.denominator ) {                 // special case
    140                         return (Rational(T)){ l.numerator + r.numerator, l.denominator };
     140                        return (rational(T)){ l.numerator + r.numerator, l.denominator };
    141141                } else {
    142                         return (Rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
     142                        return (rational(T)){ l.numerator * r.denominator + l.denominator * r.numerator, l.denominator * r.denominator };
    143143                } // if
    144144        } // ?+?
    145145
    146         Rational(T) ?+=?( Rational(T) & l, Rational(T) r ) {
     146        rational(T) ?+=?( rational(T) & l, rational(T) r ) {
    147147                l = l + r;
    148148                return l;
    149149        } // ?+?
    150150
    151         Rational(T) ?+=?( Rational(T) & l, one_t ) {
    152                 l = l + (Rational(T)){ 1 };
     151        rational(T) ?+=?( rational(T) & l, one_t ) {
     152                l = l + (rational(T)){ 1 };
    153153                return l;
    154154        } // ?+?
    155155
    156         Rational(T) ?-?( Rational(T) l, Rational(T) r ) {
     156        rational(T) ?-?( rational(T) l, rational(T) r ) {
    157157                if ( l.denominator == r.denominator ) {                 // special case
    158                         return (Rational(T)){ l.numerator - r.numerator, l.denominator };
     158                        return (rational(T)){ l.numerator - r.numerator, l.denominator };
    159159                } else {
    160                         return (Rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
     160                        return (rational(T)){ l.numerator * r.denominator - l.denominator * r.numerator, l.denominator * r.denominator };
    161161                } // if
    162162        } // ?-?
    163163
    164         Rational(T) ?-=?( Rational(T) & l, Rational(T) r ) {
     164        rational(T) ?-=?( rational(T) & l, rational(T) r ) {
    165165                l = l - r;
    166166                return l;
    167167        } // ?-?
    168168
    169         Rational(T) ?-=?( Rational(T) & l, one_t ) {
    170                 l = l - (Rational(T)){ 1 };
     169        rational(T) ?-=?( rational(T) & l, one_t ) {
     170                l = l - (rational(T)){ 1 };
    171171                return l;
    172172        } // ?-?
    173173
    174         Rational(T) ?*?( Rational(T) l, Rational(T) r ) {
    175                 return (Rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };
     174        rational(T) ?*?( rational(T) l, rational(T) r ) {
     175                return (rational(T)){ l.numerator * r.numerator, l.denominator * r.denominator };
    176176        } // ?*?
    177177
    178         Rational(T) ?*=?( Rational(T) & l, Rational(T) r ) {
     178        rational(T) ?*=?( rational(T) & l, rational(T) r ) {
    179179                return l = l * r;
    180180        } // ?*?
    181181
    182         Rational(T) ?/?( Rational(T) l, Rational(T) r ) {
     182        rational(T) ?/?( rational(T) l, rational(T) r ) {
    183183                if ( r.numerator < (T){0} ) {
    184184                        r.[numerator, denominator] = [-r.numerator, -r.denominator];
    185185                } // if
    186                 return (Rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };
     186                return (rational(T)){ l.numerator * r.denominator, l.denominator * r.numerator };
    187187        } // ?/?
    188188
    189         Rational(T) ?/=?( Rational(T) & l, Rational(T) r ) {
     189        rational(T) ?/=?( rational(T) & l, rational(T) r ) {
    190190                return l = l / r;
    191191        } // ?/?
     
    194194
    195195        forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } )
    196         istype & ?|?( istype & is, Rational(T) & r ) {
     196        istype & ?|?( istype & is, rational(T) & r ) {
    197197                is | r.numerator | r.denominator;
    198198                T t = simplify( r.numerator, r.denominator );
     
    203203
    204204        forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) {
    205                 ostype & ?|?( ostype & os, Rational(T) r ) {
     205                ostype & ?|?( ostype & os, rational(T) r ) {
    206206                        return os | r.numerator | '/' | r.denominator;
    207207                } // ?|?
    208208
    209                 void ?|?( ostype & os, Rational(T) r ) {
     209                void ?|?( ostype & os, rational(T) r ) {
    210210                        (ostype &)(os | r); ends( os );
    211211                } // ?|?
     
    213213} // distribution
    214214
    215 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
    216         Rational(T) ?\?( Rational(T) x, long int y ) {
     215forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
     216        rational(T) ?\?( rational(T) x, long int y ) {
    217217                if ( y < 0 ) {
    218                         return (Rational(T)){ x.denominator \ -y, x.numerator \ -y };
     218                        return (rational(T)){ x.denominator \ -y, x.numerator \ -y };
    219219                } else {
    220                         return (Rational(T)){ x.numerator \ y, x.denominator \ y };
     220                        return (rational(T)){ x.numerator \ y, x.denominator \ y };
    221221                } // if
    222222        } // ?\?
    223223
    224         Rational(T) ?\=?( Rational(T) & x, long int y ) {
     224        rational(T) ?\=?( rational(T) & x, long int y ) {
    225225                return x = x \ y;
    226226        } // ?\?
     
    229229// conversion
    230230
    231 forall( T | Arithmetic( T ) | { double convert( T ); } )
    232 double widen( Rational(T) r ) {
     231forall( T | arithmetic( T ) | { double convert( T ); } )
     232double widen( rational(T) r ) {
    233233        return convert( r.numerator ) / convert( r.denominator );
    234234} // widen
    235235
    236 forall( T | Arithmetic( T ) | { double convert( T ); T convert( double ); } )
    237 Rational(T) narrow( double f, T md ) {
     236forall( T | arithmetic( T ) | { double convert( T ); T convert( double ); } )
     237rational(T) narrow( double f, T md ) {
    238238        // http://www.ics.uci.edu/~eppstein/numth/frap.c
    239         if ( md <= (T){1} ) {                                   // maximum fractional digits too small?
    240                 return (Rational(T)){ convert( f ), (T){1}}; // truncate fraction
     239        if ( md <= (T){1} ) {                                                           // maximum fractional digits too small?
     240                return (rational(T)){ convert( f ), (T){1}};    // truncate fraction
    241241        } // if
    242242
     
    260260          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
    261261        } // for
    262         return (Rational(T)){ m00, m10 };
     262        return (rational(T)){ m00, m10 };
    263263} // narrow
    264264
  • libcfa/src/rational.hfa

    rfa5e1aa5 rb7b3e41  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Tue Jul 20 17:45:29 2021
    15 // Update Count     : 118
     14// Last Modified On : Mon Jun  5 22:49:05 2023
     15// Update Count     : 119
    1616//
    1717
     
    1919
    2020#include "iostream.hfa"
    21 #include "math.trait.hfa"                                                               // Arithmetic
     21#include "math.trait.hfa"                                                               // arithmetic
    2222
    2323// implementation
    2424
    25 forall( T | Arithmetic( T ) ) {
    26         struct Rational {
     25forall( T | arithmetic( T ) ) {
     26        struct rational {
    2727                T numerator, denominator;                                               // invariant: denominator > 0
    28         }; // Rational
     28        }; // rational
    2929
    3030        // constructors
    3131
    32         void ?{}( Rational(T) & r );
    33         void ?{}( Rational(T) & r, zero_t );
    34         void ?{}( Rational(T) & r, one_t );
    35         void ?{}( Rational(T) & r, T n );
    36         void ?{}( Rational(T) & r, T n, T d );
     32        void ?{}( rational(T) & r );
     33        void ?{}( rational(T) & r, zero_t );
     34        void ?{}( rational(T) & r, one_t );
     35        void ?{}( rational(T) & r, T n );
     36        void ?{}( rational(T) & r, T n, T d );
    3737
    3838        // numerator/denominator getter
    3939
    40         T numerator( Rational(T) r );
    41         T denominator( Rational(T) r );
    42         [ T, T ] ?=?( & [ T, T ] dest, Rational(T) src );
     40        T numerator( rational(T) r );
     41        T denominator( rational(T) r );
     42        [ T, T ] ?=?( & [ T, T ] dest, rational(T) src );
    4343
    4444        // numerator/denominator setter
    4545
    46         T numerator( Rational(T) r, T n );
    47         T denominator( Rational(T) r, T d );
     46        T numerator( rational(T) r, T n );
     47        T denominator( rational(T) r, T d );
    4848
    4949        // comparison
    5050
    51         int ?==?( Rational(T) l, Rational(T) r );
    52         int ?!=?( Rational(T) l, Rational(T) r );
    53         int ?!=?( Rational(T) l, zero_t );                                      // => !
    54         int ?<?( Rational(T) l, Rational(T) r );
    55         int ?<=?( Rational(T) l, Rational(T) r );
    56         int ?>?( Rational(T) l, Rational(T) r );
    57         int ?>=?( Rational(T) l, Rational(T) r );
     51        int ?==?( rational(T) l, rational(T) r );
     52        int ?!=?( rational(T) l, rational(T) r );
     53        int ?!=?( rational(T) l, zero_t );                                      // => !
     54        int ?<?( rational(T) l, rational(T) r );
     55        int ?<=?( rational(T) l, rational(T) r );
     56        int ?>?( rational(T) l, rational(T) r );
     57        int ?>=?( rational(T) l, rational(T) r );
    5858
    5959        // arithmetic
    6060
    61         Rational(T) +?( Rational(T) r );
    62         Rational(T) -?( Rational(T) r );
    63         Rational(T) ?+?( Rational(T) l, Rational(T) r );
    64         Rational(T) ?+=?( Rational(T) & l, Rational(T) r );
    65         Rational(T) ?+=?( Rational(T) & l, one_t );                     // => ++?, ?++
    66         Rational(T) ?-?( Rational(T) l, Rational(T) r );
    67         Rational(T) ?-=?( Rational(T) & l, Rational(T) r );
    68         Rational(T) ?-=?( Rational(T) & l, one_t );                     // => --?, ?--
    69         Rational(T) ?*?( Rational(T) l, Rational(T) r );
    70         Rational(T) ?*=?( Rational(T) & l, Rational(T) r );
    71         Rational(T) ?/?( Rational(T) l, Rational(T) r );
    72         Rational(T) ?/=?( Rational(T) & l, Rational(T) r );
     61        rational(T) +?( rational(T) r );
     62        rational(T) -?( rational(T) r );
     63        rational(T) ?+?( rational(T) l, rational(T) r );
     64        rational(T) ?+=?( rational(T) & l, rational(T) r );
     65        rational(T) ?+=?( rational(T) & l, one_t );                     // => ++?, ?++
     66        rational(T) ?-?( rational(T) l, rational(T) r );
     67        rational(T) ?-=?( rational(T) & l, rational(T) r );
     68        rational(T) ?-=?( rational(T) & l, one_t );                     // => --?, ?--
     69        rational(T) ?*?( rational(T) l, rational(T) r );
     70        rational(T) ?*=?( rational(T) & l, rational(T) r );
     71        rational(T) ?/?( rational(T) l, rational(T) r );
     72        rational(T) ?/=?( rational(T) & l, rational(T) r );
    7373
    7474        // I/O
    7575        forall( istype & | istream( istype ) | { istype & ?|?( istype &, T & ); } )
    76         istype & ?|?( istype &, Rational(T) & );
     76        istype & ?|?( istype &, rational(T) & );
    7777
    7878        forall( ostype & | ostream( ostype ) | { ostype & ?|?( ostype &, T ); } ) {
    79                 ostype & ?|?( ostype &, Rational(T) );
    80                 void ?|?( ostype &, Rational(T) );
     79                ostype & ?|?( ostype &, rational(T) );
     80                void ?|?( ostype &, rational(T) );
    8181        } // distribution
    8282} // distribution
    8383
    84 forall( T | Arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
    85         Rational(T) ?\?( Rational(T) x, long int y );
    86         Rational(T) ?\=?( Rational(T) & x, long int y );
     84forall( T | arithmetic( T ) | { T ?\?( T, unsigned long ); } ) {
     85        rational(T) ?\?( rational(T) x, long int y );
     86        rational(T) ?\=?( rational(T) & x, long int y );
    8787} // distribution
    8888
    8989// conversion
    90 forall( T | Arithmetic( T ) | { double convert( T ); } )
    91 double widen( Rational(T) r );
    92 forall( T | Arithmetic( T ) | { double convert( T );  T convert( double );} )
    93 Rational(T) narrow( double f, T md );
     90forall( T | arithmetic( T ) | { double convert( T ); } )
     91double widen( rational(T) r );
     92forall( T | arithmetic( T ) | { double convert( T );  T convert( double );} )
     93rational(T) narrow( double f, T md );
    9494
    9595// Local Variables: //
  • libcfa/src/stdlib.hfa

    rfa5e1aa5 rb7b3e41  
    367367
    368368        char random( void ) { return (unsigned long int)random(); }
    369         char random( char u ) { return random( (unsigned long int)u ); } // [0,u)
     369        char random( char u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u)
    370370        char random( char l, char u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u)
    371371        int random( void ) { return (long int)random(); }
    372         int random( int u ) { return random( (long int)u ); } // [0,u]
     372        int random( int u ) { return (long int)random( (long int)u ); } // [0,u]
    373373        int random( int l, int u ) { return random( (long int)l, (long int)u ); } // [l,u)
    374374        unsigned int random( void ) { return (unsigned long int)random(); }
    375         unsigned int random( unsigned int u ) { return random( (unsigned long int)u ); } // [0,u]
     375        unsigned int random( unsigned int u ) { return (unsigned long int)random( (unsigned long int)u ); } // [0,u]
    376376        unsigned int random( unsigned int l, unsigned int u ) { return random( (unsigned long int)l, (unsigned long int)u ); } // [l,u)
    377377} // distribution
  • libcfa/src/virtual_dtor.hfa

    rfa5e1aa5 rb7b3e41  
    2525    __virtual_obj_start = &this;
    2626}
    27 static inline void __CFA_dtor_shutdown( virtual_dtor & this ) with(this) {
     27static inline bool __CFA_dtor_shutdown( virtual_dtor & this ) with(this) {
     28    if ( __virtual_dtor_ptr == 1p ) return true; // stop base dtors from being called twice
    2829    if ( __virtual_dtor_ptr ) {
    2930        void (*dtor_ptr)(virtual_dtor &) = __virtual_dtor_ptr;
    3031        __virtual_dtor_ptr = 0p;
    31         dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // replace actor with base type
    32         return;
     32        dtor_ptr(*((virtual_dtor *)__virtual_obj_start)); // call most derived dtor
     33        __virtual_dtor_ptr = 1p; // stop base dtors from being called twice
     34        return true;
    3335    }
     36    return false;
    3437}
    3538static inline void __CFA_virt_free( virtual_dtor & this ) { free( this.__virtual_obj_start ); }
Note: See TracChangeset for help on using the changeset viewer.