Changeset c84dd61 for libcfa


Ignore:
Timestamp:
Jun 21, 2023, 2:38:55 AM (2 years ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
92355883
Parents:
0b0a285 (diff), 2de175ce (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:
14 edited

Legend:

Unmodified
Added
Removed
  • libcfa/prelude/builtins.c

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    3030#define __DEFAULT_EXECUTOR_BUFSIZE__ 10
    3131
    32 #define __STEAL 0 // workstealing toggle. Disjoint from toggles above
     32#define __STEAL 1 // workstealing toggle. Disjoint from toggles above
    3333
    3434// workstealing heuristic selection (only set one to be 1)
     
    4646enum allocation { Nodelete, Delete, Destroy, Finished }; // allocation status
    4747
    48 typedef allocation (*__receive_fn)(actor &, message &);
     48typedef allocation (*__receive_fn)(actor &, message &, actor **, message **);
    4949struct request {
    5050    actor * receiver;
    5151    message * msg;
    5252    __receive_fn fn;
    53     bool stop;
    5453};
    5554
    56 static inline void ?{}( request & this ) { this.stop = true; } // default ctor makes a sentinel
     55struct a_msg {
     56    int m;
     57};
     58static inline void ?{}( request & this ) {}
    5759static inline void ?{}( request & this, actor * receiver, message * msg, __receive_fn fn ) {
    5860    this.receiver = receiver;
    5961    this.msg = msg;
    6062    this.fn = fn;
    61     this.stop = false;
    6263}
    6364static inline void ?{}( request & this, request & copy ) {
     
    6566    this.msg = copy.msg;
    6667    this.fn = copy.fn;
    67     this.stop = copy.stop;
    6868}
    6969
     
    8383    last_size = 0;
    8484}
    85 static inline void ^?{}( copy_queue & this ) with(this) { adelete(buffer); }
     85static inline void ^?{}( copy_queue & this ) with(this) {
     86    DEBUG_ABORT( count != 0, "Actor system terminated with messages sent but not received\n" );
     87    adelete(buffer);
     88}
    8689
    8790static inline void insert( copy_queue & this, request & elem ) with(this) {
     
    117120}
    118121
    119 static inline bool isEmpty( copy_queue & this ) with(this) { return count == 0; }
     122static inline bool is_empty( copy_queue & this ) with(this) { return count == 0; }
    120123
    121124struct work_queue {
     
    178181    volatile unsigned long long stamp;
    179182    #ifdef ACTOR_STATS
    180     size_t stolen_from, try_steal, stolen, failed_swaps, msgs_stolen;
     183    size_t stolen_from, try_steal, stolen, empty_stolen, failed_swaps, msgs_stolen;
    181184    unsigned long long processed;
    182185    size_t gulps;
     
    191194    this.gulps = 0;                                 // number of gulps
    192195    this.failed_swaps = 0;                          // steal swap failures
     196    this.empty_stolen = 0;                          // queues empty after steal
    193197    this.msgs_stolen = 0;                           // number of messages stolen
    194198    #endif
     
    210214#ifdef ACTOR_STATS
    211215// aggregate counters for statistics
    212 size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0,
     216size_t __total_tries = 0, __total_stolen = 0, __total_workers, __all_gulps = 0, __total_empty_stolen = 0,
    213217    __total_failed_swaps = 0, __all_processed = 0, __num_actors_stats = 0, __all_msgs_stolen = 0;
    214218#endif
     
    235239        unsigned int nprocessors, nworkers, nrqueues;   // number of processors/threads/request queues
    236240        bool seperate_clus;                                                             // use same or separate cluster for executor
     241    volatile bool is_shutdown;                      // flag to communicate shutdown to worker threads
    237242}; // executor
    238243
     
    248253    __atomic_add_fetch(&__total_stolen, executor_->w_infos[id].stolen, __ATOMIC_SEQ_CST);
    249254    __atomic_add_fetch(&__total_failed_swaps, executor_->w_infos[id].failed_swaps, __ATOMIC_SEQ_CST);
     255    __atomic_add_fetch(&__total_empty_stolen, executor_->w_infos[id].empty_stolen, __ATOMIC_SEQ_CST);
    250256
    251257    // per worker steal stats (uncomment alongside the lock above this routine to print)
     
    274280    this.nrqueues = nrqueues;
    275281    this.seperate_clus = seperate_clus;
     282    this.is_shutdown = false;
    276283
    277284    if ( nworkers == nrqueues )
     
    322329
    323330static inline void ^?{}( executor & this ) with(this) {
    324     #ifdef __STEAL
    325     request sentinels[nrqueues];
    326     for ( unsigned int i = 0; i < nrqueues; i++ ) {
    327         insert( request_queues[i], sentinels[i] );              // force eventually termination
    328     } // for
    329     #else
    330     request sentinels[nworkers];
    331     unsigned int reqPerWorker = nrqueues / nworkers, extras = nrqueues % nworkers;
    332     for ( unsigned int i = 0, step = 0, range; i < nworkers; i += 1, step += range ) {
    333         range = reqPerWorker + ( i < extras ? 1 : 0 );
    334         insert( request_queues[step], sentinels[i] );           // force eventually termination
    335     } // for
    336     #endif
     331    is_shutdown = true;
    337332
    338333    for ( i; nworkers )
     
    365360    size_t avg_gulps = __all_gulps == 0 ? 0 : __all_processed / __all_gulps;
    366361    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);
    367     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",
    368         __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps);
     362    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",
     363        __total_tries, __total_stolen, __total_tries - __total_stolen - __total_failed_swaps, __total_failed_swaps, __total_empty_stolen);
    369364    size_t avg_steal = __total_stolen == 0 ? 0 : __all_msgs_stolen / __total_stolen;
    370365    printf("\tMessages stolen:\t\t\t%lu\n\tAverage steal size:\t\t\t%lu\n", __all_msgs_stolen, avg_steal);
     
    449444static inline void check_message( message & this ) {
    450445    switch ( this.allocation_ ) {                                               // analyze message status
    451         case Nodelete: CFA_DEBUG(this.allocation_ = Finished); break;
     446        case Nodelete: CFA_DEBUG( this.allocation_ = Finished ); break;
    452447        case Delete: delete( &this ); break;
    453         case Destroy: ^?{}(this); break;
     448        case Destroy: ^?{}( this ); break;
    454449        case Finished: break;
    455450    } // switch
     
    461456static inline void deliver_request( request & this ) {
    462457    DEBUG_ABORT( this.receiver->ticket == (unsigned long int)MAX, "Attempted to send message to deleted/dead actor\n" );
    463     this.receiver->allocation_ = this.fn( *this.receiver, *this.msg );
    464     check_message( *this.msg );
    465     check_actor( *this.receiver );
     458    actor * base_actor;
     459    message * base_msg;
     460    allocation temp = this.fn( *this.receiver, *this.msg, &base_actor, &base_msg );
     461    base_actor->allocation_ = temp;
     462    check_message( *base_msg );
     463    check_actor( *base_actor );
    466464}
    467465
     
    513511        curr_steal_queue = request_queues[ i + vic_start ];
    514512        // avoid empty queues and queues that are being operated on
    515         if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || isEmpty( *curr_steal_queue->c_queue ) )
     513        if ( curr_steal_queue == 0p || curr_steal_queue->being_processed || is_empty( *curr_steal_queue->c_queue ) )
    516514            continue;
    517515
     
    521519            executor_->w_infos[id].msgs_stolen += curr_steal_queue->c_queue->count;
    522520            executor_->w_infos[id].stolen++;
     521            if ( is_empty( *curr_steal_queue->c_queue ) ) executor_->w_infos[id].empty_stolen++;
    523522            // __atomic_add_fetch(&executor_->w_infos[victim_id].stolen_from, 1, __ATOMIC_RELAXED);
    524523            // replaced_queue[swap_idx]++;
     
    560559}
    561560
     561#define CHECK_TERMINATION if ( unlikely( executor_->is_shutdown ) ) break Exit
    562562void main( worker & this ) with(this) {
    563563    // #ifdef ACTOR_STATS
     
    581581       
    582582        // check if queue is empty before trying to gulp it
    583         if ( isEmpty( *curr_work_queue->c_queue ) ) {
     583        if ( is_empty( *curr_work_queue->c_queue ) ) {
    584584            #ifdef __STEAL
    585585            empty_count++;
     
    594594        #endif // ACTOR_STATS
    595595        #ifdef __STEAL
    596         if ( isEmpty( *current_queue ) ) {
    597             if ( unlikely( no_steal ) ) continue;
     596        if ( is_empty( *current_queue ) ) {
     597            if ( unlikely( no_steal ) ) { CHECK_TERMINATION; continue; }
    598598            empty_count++;
    599599            if ( empty_count < steal_threshold ) continue;
    600600            empty_count = 0;
     601
     602            CHECK_TERMINATION; // check for termination
    601603
    602604            __atomic_store_n( &executor_->w_infos[id].stamp, rdtscl(), __ATOMIC_RELAXED );
     
    610612        }
    611613        #endif // __STEAL
    612         while ( ! isEmpty( *current_queue ) ) {
     614        while ( ! is_empty( *current_queue ) ) {
    613615            #ifdef ACTOR_STATS
    614616            executor_->w_infos[id].processed++;
     
    616618            &req = &remove( *current_queue );
    617619            if ( !&req ) continue;
    618             if ( req.stop ) break Exit;
    619620            deliver_request( req );
    620621        }
     
    623624        empty_count = 0; // we found work so reset empty counter
    624625        #endif
     626
     627        CHECK_TERMINATION;
    625628       
    626629        // potentially reclaim some of the current queue's vector space if it is unused
     
    644647    __all_gulps = 0;
    645648    __total_failed_swaps = 0;
     649    __total_empty_stolen = 0;
    646650    __all_processed = 0;
    647651    __num_actors_stats = 0;
     
    657661}
    658662
    659 // TODO: potentially revisit getting number of processors
    660 //  ( currently the value stored in active_cluster()->procs.total is often stale
    661 //  and doesn't reflect how many procs are allocated )
    662 // static inline void start_actor_system() { start_actor_system( active_cluster()->procs.total ); }
    663 static inline void start_actor_system() { start_actor_system( 1 ); }
     663static inline void start_actor_system() { start_actor_system( get_proc_count( *active_cluster() ) ); }
    664664
    665665static inline void start_actor_system( executor & this ) {
     
    671671
    672672static inline void stop_actor_system() {
    673     park( ); // will receive signal when actor system is finished
     673    park( ); // will be unparked when actor system is finished
    674674
    675675    if ( !__actor_executor_passed ) delete( __actor_executor_ );
  • libcfa/src/concurrency/atomic.hfa

    r0b0a285 rc84dd61  
    1010// Created On       : Thu May 25 15:22:46 2023
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun  9 13:36:47 2023
    13 // Update Count     : 46
     12// Last Modified On : Wed Jun 14 07:48:57 2023
     13// Update Count     : 52
    1414//
    1515
     
    3535
    3636// #define CAS( assn, comp, replace ) (CASM( assn, comp, replace, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
    37 // #define CASM( assn, comp, replace, memorder... ) ({ \
    38 //      typeof(comp) __temp = (comp); \
    39 //      __atomic_compare_exchange_n( &(assn), &(__temp), (replace), false, memorder ); \
    40 // })
     37// #define CASM( assn, comp, replace, memorder... ) ({ typeof(comp) __temp = (comp); __atomic_compare_exchange_n( &(assn), &(__temp), (replace), false, memorder ); })
    4138#define CAS( assn, comp, replace ) (__sync_bool_compare_and_swap( &assn, comp, replace))
    4239#define CASM( assn, comp, replace, memorder... ) _Static_assert( false, "memory order unsupported for CAS macro" );
  • libcfa/src/concurrency/kernel.hfa

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    3535#include <linux/futex.h>      /* Definition of FUTEX_* constants */
    3636#include <sys/syscall.h>      /* Definition of SYS_* constants */
    37 #include <unistd.h>
     37#include <unistd.h>           /* Definition of syscall routine */
    3838
    3939typedef void (*__cfa_pre_park)( void * );
  • libcfa/src/fstream.cfa

    r0b0a285 rc84dd61  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  5 22:00:23 2023
    13 // Update Count     : 518
     12// Last Modified On : Sat Jun 17 08:51:12 2023
     13// Update Count     : 528
    1414//
    1515
     
    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 );
     
    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
  • libcfa/src/iostream.hfa

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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/stdlib.hfa

    r0b0a285 rc84dd61  
    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

    r0b0a285 rc84dd61  
    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.