Changes in / [6c53a93:e2853eb]


Ignore:
Files:
11 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • benchmark/io/http/main.cfa

    r6c53a93 re2853eb  
    150150                        if(errno == EADDRINUSE) {
    151151                                if(waited == 0) {
    152                                         if(!options.interactive) abort | "Port already in use in non-interactive mode. Aborting";
    153152                                        sout | "Waiting for port";
    154153                                } else {
  • benchmark/io/http/protocol.cfa

    r6c53a93 re2853eb  
    332332        wait(this.f);
    333333
     334        // Did something crazy happen?
     335        if(this.f.result > this.len) {
     336                mutex(serr) serr | "SPLICE IN spliced too much!";
     337                return error(this.res, -ERANGE);
     338        }
     339
    334340        // Something failed?
    335341        if(this.f.result < 0) {
     
    345351                        return error(this.res, -ECONNRESET);
    346352                }
    347         }
    348 
    349         // Did something crazy happen?
    350         if(this.f.result > this.len) {
    351                 mutex(serr) serr | "SPLICE IN spliced too much!";
    352                 return error(this.res, -ERANGE);
    353353        }
    354354
     
    401401        wait(this.f);
    402402
     403        // Did something crazy happen?
     404        if(this.f.result > this.len) {
     405                mutex(serr) serr | "SPLICE OUT spliced too much!";
     406                return error(this.res, -ERANGE);
     407        }
     408
    403409        // Something failed?
    404410        if(this.f.result < 0) {
     
    414420                        return error(this, -ECONNRESET);
    415421                }
    416         }
    417 
    418         // Did something crazy happen?
    419         if(this.f.result > this.len) {
    420                 mutex(serr) serr | "SPLICE OUT spliced too much!" | this.f.result | ">" | this.len;
    421                 return error(this.res, -ERANGE);
    422422        }
    423423
     
    544544const char * original_http_msgs[] = {
    545545        "HTTP/1.1 200 OK\nServer: HttpForall\nDate: %s \nContent-Type: text/plain\nContent-Length: ",
    546         "HTTP/1.1 200 OK\r\nServer: HttpForall\r\nConnection: keep-alive\r\nContent-Length: 15\r\nContent-Type: text/html\r\nDate: %s \r\n\r\nHello, World!\r\n",
     546        "HTTP/1.1 200 OK\r\nServer: HttpForall\r\nDate\r\nConnection: keep-alive\r\nContent-Length: 15\r\nContent-Type: text/html: %s \r\n\r\nHello, World!\r\n",
    547547        "HTTP/1.1 400 Bad Request\nServer: HttpForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
    548548        "HTTP/1.1 404 Not Found\nServer: HttpForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n",
  • benchmark/io/http/worker.cfa

    r6c53a93 re2853eb  
    1818void ?{}( Worker & this ) {
    1919        size_t cli = rand() % options.clopts.cltr_cnt;
    20         ((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli], 64000 };
     20        ((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli], 512000 };
    2121        options.clopts.thrd_cnt[cli]++;
    2222        this.pipe[0] = -1;
  • driver/as.cc

    r6c53a93 re2853eb  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // as.c -- map assembler file, scan for debug information, then language code, and skip N lines forward to code. If
    8 //         code is C dialect, possibly expand file by one character, and replace with Cforall language code.
     7// as.c -- map assembler file, scan for debug information. If found, expand file by one character and insert Cforall
     8//         language code on the N line from the start of the debug information.
    99//
    1010// Author           : Peter A. Buhr
    1111// Created On       : Wed Aug  1 10:49:42 2018
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Dec  8 07:56:12 2021
    14 // Update Count     : 136
     13// Last Modified On : Sat Sep  8 08:40:16 2018
     14// Update Count     : 97
    1515//
    1616
     
    1818#include <cstdlib>                                                                              // exit
    1919#include <fcntl.h>                                                                              // open
    20 #include <cstring>                                                                              // strstr, memmove
    21 #include <unistd.h>                                                                             // ftruncate,execvp
    22 #include <sys/stat.h>                                                                   // fstat
     20#include <unistd.h>
     21#include <sys/stat.h>
    2322#include <sys/mman.h>                                                                   // mmap
     23#include <string.h>
    2424
    2525//#define __DEBUG_H__
     26
     27#ifdef __DEBUG_H__
     28#include <iostream>
     29using namespace std;
     30#endif // __DEBUG_H__
    2631
    2732int main( const int argc, const char * argv[] ) {
    2833        #ifdef __DEBUG_H__
    2934        for ( int i = 0; i < argc; i += 1 ) {
    30                 fprintf( stderr, "%s\n", argv[i] );
     35                cerr << argv[i] << endl;
    3136        } // for
    3237        #endif // __DEBUG_H__
     
    4348                if ( start == (void *)-1 ) { perror( "mmap" ); exit( EXIT_FAILURE ); };
    4449
    45                 char * dcursor;
    46                 if ( (dcursor = strstr( start, ".Ldebug_info0:" ) ) ) { // debug information ?
     50                if ( char * cursor = strstr( start, ".Ldebug_info0:" ) ) { // debug information ?
     51                        // Expand file by one byte to hold 2 character Cforall language code.
     52                        if ( ftruncate( fd, size + 1 ) ) { perror( "ftruncate" ); exit( EXIT_FAILURE ); };
    4753
    48                         if ( char * cursor = strstr( dcursor, ".long\t.LASF" ) ) { // language code ?
    49                                 for ( int i = 0; i < 2; i += 1 ) {              // move N (magic) lines forward
    50                                         cursor = strstr( cursor, "\n" ) + 1;
    51                                 } // for
    52                                 cursor -= 2;                                                    // backup over "d\n", where d is a hex digit
    53                                 // From elfcpp/dwarf.h in the binutils source tree.
    54                                 // DW_LANG_C89 = 0x1, DW_LANG_C = 0x2, DW_LANG_C99 = 0xc, DW_LANG_C11 = 0x1d
    55                                 if ( *(cursor - 2) == '0' && *(cursor - 1) == 'x' &&
    56                                          (*cursor == 'c' || *cursor == '1' || *cursor == '2') ) { // C99/C89/C
    57                                         // Expand file by one byte to hold 2 character Cforall language code.
    58                                         if ( ftruncate( fd, size + 1 ) ) { perror( "ftruncate" ); exit( EXIT_FAILURE ); };
    59                                         memmove( cursor + 2, cursor + 1, start + size - cursor - 1 ); // move remaining text 1 character right
    60                                 } else if ( *(cursor - 3) == '0' && *(cursor - 2) == 'x' && *(cursor - 1) == '1' && *cursor == 'd' ) { // C11
    61                                 } else {
    62                                         for ( int i = 0; i < 6; i += 1 ) {      // move N (magic) lines forward
    63                                                 cursor = strstr( cursor, "\n" ) + 1;
    64                                         } // for
    65                                         fprintf( stderr, "*** ERROR *** Invalid C language code found in assembler file: %s\n"
    66                                                          "Assembler debug information:\n%.*s",
    67                                                          argv[argc - 1], (int)(cursor - dcursor), dcursor );
    68                                         exit( EXIT_FAILURE );
    69                                 } // if
     54                        for ( int i = 0; i < 8; i += 1 ) {                      // move N (magic) lines forward
     55                                cursor = strstr( cursor, "\n" ) + 1;
     56                        } // for
    7057
    71                                 *(cursor - 1) = '2';                                    // replace C89/C/C99/C11 language code with CFA code
    72                                 *cursor = '5';
    73                         } // if
     58                        cursor -= 2;                                                            // backup over "c\n" language value
     59                        if ( *(cursor - 1) != 'x' ) { fprintf( stderr, "invalid C language code\n" ); exit( EXIT_FAILURE ); };
     60
     61                        memmove( cursor + 2, cursor + 1, start + size - cursor - 1 ); // move remaining text 1 character right
     62
     63                        *(cursor) = '2';                                                        // replace C language value with CFA
     64                        *(cursor + 1) = '5';
    7465                } // if
    7566
  • libcfa/src/Makefile.am

    r6c53a93 re2853eb  
    8484        time.hfa \
    8585        bits/weakso_locks.hfa \
    86         algorithms/range_iterator.hfa \
    8786        containers/maybe.hfa \
    8887        containers/pair.hfa \
  • libcfa/src/concurrency/io.cfa

    r6c53a93 re2853eb  
    3333                #include <sys/syscall.h>
    3434                #include <sys/eventfd.h>
    35                 #include <sys/uio.h>
    3635
    3736                #include <linux/io_uring.h>
     
    134133        }
    135134
    136         bool __cfa_io_flush( processor * proc, int min_comp ) {
     135        void __cfa_io_flush( processor * proc ) {
    137136                /* paranoid */ verify( ! __preemption_enabled() );
    138137                /* paranoid */ verify( proc );
     
    142141                $io_context & ctx = *proc->io.ctx;
    143142
     143                // for(i; 2) {
     144                //      unsigned idx = proc->rdq.id + i;
     145                //      cltr->ready_queue.lanes.tscs[idx].tv = -1ull;
     146                // }
     147
    144148                __ioarbiter_flush( ctx );
    145149
    146150                __STATS__( true, io.calls.flush++; )
    147                 int ret = syscall( __NR_io_uring_enter, ctx.fd, ctx.sq.to_submit, min_comp, min_comp > 0 ? IORING_ENTER_GETEVENTS : 0, (sigset_t *)0p, _NSIG / 8);
     151                int ret = syscall( __NR_io_uring_enter, ctx.fd, ctx.sq.to_submit, 0, 0, (sigset_t *)0p, _NSIG / 8);
    148152                if( ret < 0 ) {
    149153                        switch((int)errno) {
     
    153157                                // Update statistics
    154158                                __STATS__( false, io.calls.errors.busy ++; )
    155                                 return false;
     159                                // for(i; 2) {
     160                                //      unsigned idx = proc->rdq.id + i;
     161                                //      cltr->ready_queue.lanes.tscs[idx].tv = rdtscl();
     162                                // }
     163                                return;
    156164                        default:
    157165                                abort( "KERNEL ERROR: IO_URING SYSCALL - (%d) %s\n", (int)errno, strerror(errno) );
     
    174182
    175183                ctx.proc->io.pending = false;
    176                 ready_schedule_lock();
    177                 bool ret = __cfa_io_drain( proc );
    178                 ready_schedule_unlock();
    179                 return ret;
     184
     185                __cfa_io_drain( proc );
     186                // for(i; 2) {
     187                //      unsigned idx = proc->rdq.id + i;
     188                //      cltr->ready_queue.lanes.tscs[idx].tv = rdtscl();
     189                // }
    180190        }
    181191
     
    281291        }
    282292
     293
    283294        //=============================================================================================
    284295        // submission
     
    303314                ctx->proc->io.dirty   = true;
    304315                if(sq.to_submit > 30 || !lazy) {
    305                         __cfa_io_flush( ctx->proc, 0 );
     316                        ready_schedule_lock();
     317                        __cfa_io_flush( ctx->proc );
     318                        ready_schedule_unlock();
    306319                }
    307320        }
     
    502515                }
    503516        }
    504 
    505         #if defined(CFA_WITH_IO_URING_IDLE)
    506                 bool __kernel_read(processor * proc, io_future_t & future, iovec & iov, int fd) {
    507                         $io_context * ctx = proc->io.ctx;
    508                         /* paranoid */ verify( ! __preemption_enabled() );
    509                         /* paranoid */ verify( proc == __cfaabi_tls.this_processor );
    510                         /* paranoid */ verify( ctx );
    511 
    512                         __u32 idx;
    513                         struct io_uring_sqe * sqe;
    514 
    515                         // We can proceed to the fast path
    516                         if( !__alloc(ctx, &idx, 1) ) return false;
    517 
    518                         // Allocation was successful
    519                         __fill( &sqe, 1, &idx, ctx );
    520 
    521                         sqe->user_data = (uintptr_t)&future;
    522                         sqe->flags = 0;
    523                         sqe->fd = fd;
    524                         sqe->off = 0;
    525                         sqe->ioprio = 0;
    526                         sqe->fsync_flags = 0;
    527                         sqe->__pad2[0] = 0;
    528                         sqe->__pad2[1] = 0;
    529                         sqe->__pad2[2] = 0;
    530 
    531                         #if defined(CFA_HAVE_IORING_OP_READ)
    532                                 sqe->opcode = IORING_OP_READ;
    533                                 sqe->addr = (uint64_t)iov.iov_base;
    534                                 sqe->len = iov.iov_len;
    535                         #elif defined(CFA_HAVE_READV) && defined(CFA_HAVE_IORING_OP_READV)
    536                                 sqe->opcode = IORING_OP_READV;
    537                                 sqe->addr = (uintptr_t)&iov;
    538                                 sqe->len = 1;
    539                         #else
    540                                 #error CFA_WITH_IO_URING_IDLE but none of CFA_HAVE_READV, CFA_HAVE_IORING_OP_READV or CFA_HAVE_IORING_OP_READ defined
    541                         #endif
    542 
    543                         asm volatile("": : :"memory");
    544 
    545                         /* paranoid */ verify( sqe->user_data == (uintptr_t)&future );
    546                         __submit( ctx, &idx, 1, true );
    547 
    548                         /* paranoid */ verify( proc == __cfaabi_tls.this_processor );
    549                         /* paranoid */ verify( ! __preemption_enabled() );
    550                 }
    551         #endif
    552517#endif
  • libcfa/src/concurrency/io/setup.cfa

    r6c53a93 re2853eb  
    3232
    3333        void __cfa_io_start( processor * proc ) {}
    34         bool __cfa_io_flush( processor * proc, int ) {}
     34        void __cfa_io_flush( processor * proc ) {}
    3535        void __cfa_io_stop ( processor * proc ) {}
    3636
     
    111111                this.ext_sq.empty = true;
    112112                (this.ext_sq.queue){};
    113                 __io_uring_setup( this, cl.io.params, proc->idle_fd );
     113                __io_uring_setup( this, cl.io.params, proc->idle );
    114114                __cfadbg_print_safe(io_core, "Kernel I/O : Created ring for io_context %u (%p)\n", this.fd, &this);
    115115        }
     
    220220                cq.cqes = (struct io_uring_cqe *)(((intptr_t)cq.ring_ptr) + params.cq_off.cqes);
    221221
    222                 #if !defined(CFA_WITH_IO_URING_IDLE)
    223                         // Step 4 : eventfd
    224                         // io_uring_register is so f*cking slow on some machine that it
    225                         // will never succeed if preemption isn't hard blocked
    226                         __cfadbg_print_safe(io_core, "Kernel I/O : registering %d for completion with ring %d\n", procfd, fd);
    227 
    228                         __disable_interrupts_hard();
    229 
    230                         int ret = syscall( __NR_io_uring_register, fd, IORING_REGISTER_EVENTFD, &procfd, 1);
    231                         if (ret < 0) {
    232                                 abort("KERNEL ERROR: IO_URING EVENTFD REGISTER - %s\n", strerror(errno));
    233                         }
    234 
    235                         __enable_interrupts_hard();
    236 
    237                         __cfadbg_print_safe(io_core, "Kernel I/O : registered %d for completion with ring %d\n", procfd, fd);
    238                 #endif
     222                // Step 4 : eventfd
     223                // io_uring_register is so f*cking slow on some machine that it
     224                // will never succeed if preemption isn't hard blocked
     225                __cfadbg_print_safe(io_core, "Kernel I/O : registering %d for completion with ring %d\n", procfd, fd);
     226
     227                __disable_interrupts_hard();
     228
     229                int ret = syscall( __NR_io_uring_register, fd, IORING_REGISTER_EVENTFD, &procfd, 1);
     230                if (ret < 0) {
     231                        abort("KERNEL ERROR: IO_URING EVENTFD REGISTER - %s\n", strerror(errno));
     232                }
     233
     234                __enable_interrupts_hard();
     235
     236                __cfadbg_print_safe(io_core, "Kernel I/O : registered %d for completion with ring %d\n", procfd, fd);
    239237
    240238                // some paranoid checks
  • libcfa/src/concurrency/io/types.hfa

    r6c53a93 re2853eb  
    185185
    186186        // Wait for the future to be fulfilled
    187         bool wait     ( io_future_t & this ) { return wait     (this.self); }
    188         void reset    ( io_future_t & this ) { return reset    (this.self); }
    189         bool available( io_future_t & this ) { return available(this.self); }
     187        bool wait( io_future_t & this ) {
     188                return wait(this.self);
     189        }
     190
     191        void reset( io_future_t & this ) {
     192                return reset(this.self);
     193        }
    190194}
  • libcfa/src/concurrency/kernel.cfa

    r6c53a93 re2853eb  
    2727extern "C" {
    2828        #include <sys/eventfd.h>
    29         #include <sys/uio.h>
    3029}
    3130
     
    3534#include "strstream.hfa"
    3635#include "device/cpu.hfa"
    37 #include "io/types.hfa"
    3836
    3937//Private includes
     
    126124static void __wake_one(cluster * cltr);
    127125
    128 static void idle_sleep(processor * proc, io_future_t & future, iovec & iov);
    129 static bool mark_idle (__cluster_proc_list & idles, processor & proc);
     126static void mark_idle (__cluster_proc_list & idles, processor & proc);
    130127static void mark_awake(__cluster_proc_list & idles, processor & proc);
     128static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list idles );
    131129
    132130extern void __cfa_io_start( processor * );
    133131extern bool __cfa_io_drain( processor * );
    134 extern bool __cfa_io_flush( processor *, int min_comp );
     132extern void __cfa_io_flush( processor * );
    135133extern void __cfa_io_stop ( processor * );
    136134static inline bool __maybe_io_drain( processor * );
    137 
    138 #if defined(CFA_WITH_IO_URING_IDLE)
    139         extern bool __kernel_read(processor * proc, io_future_t & future, iovec &, int fd);
    140 #endif
    141135
    142136extern void __disable_interrupts_hard();
     
    154148        /* paranoid */ verify( __preemption_enabled() );
    155149}
    156 
    157150
    158151//=============================================================================================
     
    170163        verify(this);
    171164
    172         io_future_t future; // used for idle sleep when io_uring is present
    173         future.self.ptr = 1p;  // mark it as already fulfilled so we know if there is a pending request or not
    174         eventfd_t idle_val;
    175         iovec idle_iovec = { &idle_val, sizeof(idle_val) };
    176 
    177165        __cfa_io_start( this );
    178166
     
    208196
    209197                        if( !readyThread ) {
    210                                 __cfa_io_flush( this, 0 );
     198                                ready_schedule_lock();
     199                                __cfa_io_flush( this );
     200                                ready_schedule_unlock();
    211201
    212202                                readyThread = __next_thread_slow( this->cltr );
     
    223213
    224214                                // Push self to idle stack
    225                                 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;
     215                                mark_idle(this->cltr->procs, * this);
    226216
    227217                                // Confirm the ready-queue is empty
     
    239229                                }
    240230
    241                                 idle_sleep( this, future, idle_iovec );
    242 
    243                                 // We were woken up, remove self from idle
    244                                 mark_awake(this->cltr->procs, * this);
    245 
    246                                 // DON'T just proceed, start looking again
    247                                 continue MAIN_LOOP;
    248                         }
    249 
    250                         /* paranoid */ verify( readyThread );
    251 
    252                         // Reset io dirty bit
    253                         this->io.dirty = false;
    254 
    255                         // We found a thread run it
    256                         __run_thread(this, readyThread);
    257 
    258                         // Are we done?
    259                         if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
    260 
    261                         if(this->io.pending && !this->io.dirty) {
    262                                 __cfa_io_flush( this, 0 );
    263                         }
    264 
    265                         #else
    266                                 #warning new kernel loop
    267                         SEARCH: {
    268                                 /* paranoid */ verify( ! __preemption_enabled() );
    269 
    270                                 // First, lock the scheduler since we are searching for a thread
    271                                 ready_schedule_lock();
    272 
    273                                 // Try to get the next thread
    274                                 readyThread = pop_fast( this->cltr );
    275                                 if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    276 
    277                                 // If we can't find a thread, might as well flush any outstanding I/O
    278                                 if(this->io.pending) { __cfa_io_flush( this, 0 ); }
    279 
    280                                 // Spin a little on I/O, just in case
    281                                 for(5) {
    282                                         __maybe_io_drain( this );
    283                                         readyThread = pop_fast( this->cltr );
    284                                         if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    285                                 }
    286 
    287                                 // no luck, try stealing a few times
    288                                 for(5) {
    289                                         if( __maybe_io_drain( this ) ) {
    290                                                 readyThread = pop_fast( this->cltr );
    291                                         } else {
    292                                                 readyThread = pop_slow( this->cltr );
     231                                #if !defined(__CFA_NO_STATISTICS__)
     232                                        if(this->print_halts) {
     233                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    293234                                        }
    294                                         if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    295                                 }
    296 
    297                                 // still no luck, search for a thread
    298                                 readyThread = pop_search( this->cltr );
    299                                 if(readyThread) { ready_schedule_unlock(); break SEARCH; }
    300 
    301                                 // Don't block if we are done
    302                                 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) {
    303                                         ready_schedule_unlock();
    304                                         break MAIN_LOOP;
    305                                 }
    306 
    307                                 __STATS( __tls_stats()->ready.sleep.halts++; )
    308 
    309                                 // Push self to idle stack
    310                                 ready_schedule_unlock();
    311                                 if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
    312                                 ready_schedule_lock();
    313 
    314                                 // Confirm the ready-queue is empty
    315                                 __maybe_io_drain( this );
    316                                 readyThread = pop_search( this->cltr );
    317                                 ready_schedule_unlock();
    318 
    319                                 if( readyThread ) {
    320                                         // A thread was found, cancel the halt
    321                                         mark_awake(this->cltr->procs, * this);
    322 
    323                                         __STATS( __tls_stats()->ready.sleep.cancels++; )
    324 
    325                                         // continue the main loop
    326                                         break SEARCH;
    327                                 }
    328 
    329                                 __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
    330                                 __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
     235                                #endif
     236
     237                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
    331238
    332239                                {
    333240                                        eventfd_t val;
    334                                         ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
     241                                        ssize_t ret = read( this->idle, &val, sizeof(val) );
    335242                                        if(ret < 0) {
    336243                                                switch((int)errno) {
     
    348255                                }
    349256
    350                                         __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
     257                                #if !defined(__CFA_NO_STATISTICS__)
     258                                        if(this->print_halts) {
     259                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
     260                                        }
     261                                #endif
    351262
    352263                                // We were woken up, remove self from idle
     
    357268                        }
    358269
     270                        /* paranoid */ verify( readyThread );
     271
     272                        // Reset io dirty bit
     273                        this->io.dirty = false;
     274
     275                        // We found a thread run it
     276                        __run_thread(this, readyThread);
     277
     278                        // Are we done?
     279                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     280
     281                        if(this->io.pending && !this->io.dirty) {
     282                                ready_schedule_lock();
     283                                __cfa_io_flush( this );
     284                                ready_schedule_unlock();
     285                        }
     286
     287                        #else
     288                                #warning new kernel loop
     289                        SEARCH: {
     290                                /* paranoid */ verify( ! __preemption_enabled() );
     291
     292                                // First, lock the scheduler since we are searching for a thread
     293                                ready_schedule_lock();
     294
     295                                // Try to get the next thread
     296                                readyThread = pop_fast( this->cltr );
     297                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     298
     299                                // If we can't find a thread, might as well flush any outstanding I/O
     300                                if(this->io.pending) { __cfa_io_flush( this ); }
     301
     302                                // Spin a little on I/O, just in case
     303                                for(5) {
     304                                        __maybe_io_drain( this );
     305                                        readyThread = pop_fast( this->cltr );
     306                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     307                                }
     308
     309                                // no luck, try stealing a few times
     310                                for(5) {
     311                                        if( __maybe_io_drain( this ) ) {
     312                                                readyThread = pop_fast( this->cltr );
     313                                        } else {
     314                                                readyThread = pop_slow( this->cltr );
     315                                        }
     316                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     317                                }
     318
     319                                // still no luck, search for a thread
     320                                readyThread = pop_search( this->cltr );
     321                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     322
     323                                // Don't block if we are done
     324                                if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) {
     325                                        ready_schedule_unlock();
     326                                        break MAIN_LOOP;
     327                                }
     328
     329                                __STATS( __tls_stats()->ready.sleep.halts++; )
     330
     331                                // Push self to idle stack
     332                                ready_schedule_unlock();
     333                                mark_idle(this->cltr->procs, * this);
     334                                ready_schedule_lock();
     335
     336                                // Confirm the ready-queue is empty
     337                                __maybe_io_drain( this );
     338                                readyThread = pop_search( this->cltr );
     339                                ready_schedule_unlock();
     340
     341                                if( readyThread ) {
     342                                        // A thread was found, cancel the halt
     343                                        mark_awake(this->cltr->procs, * this);
     344
     345                                        __STATS( __tls_stats()->ready.sleep.cancels++; )
     346
     347                                        // continue the main loop
     348                                        break SEARCH;
     349                                }
     350
     351                                __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
     352                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
     353
     354                                {
     355                                        eventfd_t val;
     356                                        ssize_t ret = read( this->idle, &val, sizeof(val) );
     357                                        if(ret < 0) {
     358                                                switch((int)errno) {
     359                                                case EAGAIN:
     360                                                #if EAGAIN != EWOULDBLOCK
     361                                                        case EWOULDBLOCK:
     362                                                #endif
     363                                                case EINTR:
     364                                                        // No need to do anything special here, just assume it's a legitimate wake-up
     365                                                        break;
     366                                                default:
     367                                                        abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     368                                                }
     369                                        }
     370                                }
     371
     372                                        __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
     373
     374                                // We were woken up, remove self from idle
     375                                mark_awake(this->cltr->procs, * this);
     376
     377                                // DON'T just proceed, start looking again
     378                                continue MAIN_LOOP;
     379                        }
     380
    359381                RUN_THREAD:
    360382                        /* paranoid */ verify( ! __preemption_enabled() );
     
    371393
    372394                        if(this->io.pending && !this->io.dirty) {
    373                                 __cfa_io_flush( this, 0 );
     395                                __cfa_io_flush( this );
    374396                        }
    375397
     
    381403
    382404                __cfadbg_print_safe(runtime_core, "Kernel : core %p stopping\n", this);
    383         }
    384 
    385         for(int i = 0; !available(future); i++) {
    386                 if(i > 1000) __cfaabi_dbg_write( "ERROR: kernel has bin spinning on a flush after exit loop.\n", 60);
    387                 __cfa_io_flush( this, 1 );
    388405        }
    389406
     
    749766
    750767        // Check if there is a sleeping processor
    751         int fd = __atomic_load_n(&this->procs.fd, __ATOMIC_SEQ_CST);
     768        processor * p;
     769        unsigned idle;
     770        unsigned total;
     771        [idle, total, p] = query_idles(this->procs);
    752772
    753773        // If no one is sleeping, we are done
    754         if( fd == 0 ) return;
     774        if( idle == 0 ) return;
    755775
    756776        // We found a processor, wake it up
    757777        eventfd_t val;
    758778        val = 1;
    759         eventfd_write( fd, val );
     779        eventfd_write( p->idle, val );
    760780
    761781        #if !defined(__CFA_NO_STATISTICS__)
     
    782802                eventfd_t val;
    783803                val = 1;
    784                 eventfd_write( this->idle_fd, val );
     804                eventfd_write( this->idle, val );
    785805        __enable_interrupts_checked();
    786806}
    787807
    788 static void idle_sleep(processor * this, io_future_t & future, iovec & iov) {
    789         #if !defined(CFA_WITH_IO_URING_IDLE)
    790                 #if !defined(__CFA_NO_STATISTICS__)
    791                         if(this->print_halts) {
    792                                 __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    793                         }
    794                 #endif
    795 
    796                 __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle_fd);
    797 
    798                 {
    799                         eventfd_t val;
    800                         ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
    801                         if(ret < 0) {
    802                                 switch((int)errno) {
    803                                 case EAGAIN:
    804                                 #if EAGAIN != EWOULDBLOCK
    805                                         case EWOULDBLOCK:
    806                                 #endif
    807                                 case EINTR:
    808                                         // No need to do anything special here, just assume it's a legitimate wake-up
    809                                         break;
    810                                 default:
    811                                         abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
    812                                 }
    813                         }
    814                 }
    815 
    816                 #if !defined(__CFA_NO_STATISTICS__)
    817                         if(this->print_halts) {
    818                                 __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
    819                         }
    820                 #endif
    821         #else
    822                 // Do we already have a pending read
    823                 if(available(future)) {
    824                         // There is no pending read, we need to add one
    825                         reset(future);
    826 
    827                         __kernel_read(this, future, iov, this->idle_fd );
    828                 }
    829 
    830                 __cfa_io_flush( this, 1 );
    831         #endif
    832 }
    833 
    834 static bool mark_idle(__cluster_proc_list & this, processor & proc) {
    835         /* paranoid */ verify( ! __preemption_enabled() );
    836         if(!try_lock( this )) return false;
     808static void mark_idle(__cluster_proc_list & this, processor & proc) {
     809        /* paranoid */ verify( ! __preemption_enabled() );
     810        lock( this );
    837811                this.idle++;
    838812                /* paranoid */ verify( this.idle <= this.total );
    839813                remove(proc);
    840814                insert_first(this.idles, proc);
    841 
    842                 __atomic_store_n(&this.fd, proc.idle_fd, __ATOMIC_SEQ_CST);
    843815        unlock( this );
    844816        /* paranoid */ verify( ! __preemption_enabled() );
    845 
    846         return true;
    847817}
    848818
     
    854824                remove(proc);
    855825                insert_last(this.actives, proc);
    856 
    857                 {
    858                         int fd = 0;
    859                         if(!this.idles`isEmpty) fd = this.idles`first.idle_fd;
    860                         __atomic_store_n(&this.fd, fd, __ATOMIC_SEQ_CST);
    861                 }
    862 
    863826        unlock( this );
     827        /* paranoid */ verify( ! __preemption_enabled() );
     828}
     829
     830static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list this ) {
     831        /* paranoid */ verify( ! __preemption_enabled() );
     832        /* paranoid */ verify( ready_schedule_islocked() );
     833
     834        for() {
     835                uint64_t l = __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST);
     836                if( 1 == (l % 2) ) { Pause(); continue; }
     837                unsigned idle    = this.idle;
     838                unsigned total   = this.total;
     839                processor * proc = &this.idles`first;
     840                // Compiler fence is unnecessary, but gcc-8 and older incorrectly reorder code without it
     841                asm volatile("": : :"memory");
     842                if(l != __atomic_load_n(&this.lock, __ATOMIC_SEQ_CST)) { Pause(); continue; }
     843                return [idle, total, proc];
     844        }
     845
     846        /* paranoid */ verify( ready_schedule_islocked() );
    864847        /* paranoid */ verify( ! __preemption_enabled() );
    865848}
     
    923906                if(head == tail) return false;
    924907                #if OLD_MAIN
    925                         ready_schedule_lock();
    926                         ret = __cfa_io_drain( proc );
    927                         ready_schedule_unlock();
     908                ready_schedule_lock();
     909                ret = __cfa_io_drain( proc );
     910                ready_schedule_unlock();
    928911                #else
    929912                        ret = __cfa_io_drain( proc );
    930                 #endif
     913        #endif
    931914        #endif
    932915        return ret;
  • libcfa/src/concurrency/kernel.hfa

    r6c53a93 re2853eb  
    100100
    101101        // Idle lock (kernel semaphore)
    102         int idle_fd;
     102        int idle;
    103103
    104104        // Termination synchronisation (user semaphore)
     
    195195struct __cluster_proc_list {
    196196        // Spin lock protecting the queue
    197         __spinlock_t lock;
    198 
    199         // FD to use to wake a processor
    200         volatile int fd;
     197        volatile uint64_t lock;
    201198
    202199        // Total number of processors
  • libcfa/src/concurrency/kernel/startup.cfa

    r6c53a93 re2853eb  
    527527        this.local_data = 0p;
    528528
    529         this.idle_fd = eventfd(0, 0);
    530         if (idle_fd < 0) {
     529        this.idle = eventfd(0, 0);
     530        if (idle < 0) {
    531531                abort("KERNEL ERROR: PROCESSOR EVENTFD - %s\n", strerror(errno));
    532532        }
     
    542542// Not a ctor, it just preps the destruction but should not destroy members
    543543static void deinit(processor & this) {
    544         close(this.idle_fd);
     544        close(this.idle);
    545545}
    546546
     
    584584// Cluster
    585585static void ?{}(__cluster_proc_list & this) {
    586         this.fd    = 0;
     586        this.lock  = 0;
    587587        this.idle  = 0;
    588588        this.total = 0;
  • libcfa/src/concurrency/kernel_private.hfa

    r6c53a93 re2853eb  
    3939}
    4040
    41 // Defines whether or not we *want* to use io_uring_enter as the idle_sleep blocking call
    42 #define CFA_WANT_IO_URING_IDLE
    43 
    44 // Defines whether or not we *can* use io_uring_enter as the idle_sleep blocking call
    45 #if defined(CFA_WANT_IO_URING_IDLE) && defined(CFA_HAVE_LINUX_IO_URING_H)
    46         #if defined(CFA_HAVE_IORING_OP_READ) || (defined(CFA_HAVE_READV) && defined(CFA_HAVE_IORING_OP_READV))
    47                 #define CFA_WITH_IO_URING_IDLE
    48         #endif
    49 #endif
    50 
    5141//-----------------------------------------------------------------------------
    5242// Scheduler
     
    159149        __atomic_store_n(ll, (bool)false, __ATOMIC_RELEASE);
    160150}
     151
     152
     153
     154
    161155
    162156//-----------------------------------------------------------------------
     
    274268        ready_schedule_lock();
    275269
    276         lock( this.lock __cfaabi_dbg_ctx2 );
    277 
    278         /* paranoid */ verify( ! __preemption_enabled() );
    279 }
    280 
    281 static inline bool try_lock(__cluster_proc_list & this) {
    282         /* paranoid */ verify( ! __preemption_enabled() );
    283 
    284         // Start by locking the global RWlock so that we know no-one is
    285         // adding/removing processors while we mess with the idle lock
    286         ready_schedule_lock();
    287 
    288         if(try_lock( this.lock __cfaabi_dbg_ctx2 )) {
    289                 // success
    290                 /* paranoid */ verify( ! __preemption_enabled() );
    291                 return true;
    292         }
    293 
    294         // failed to lock
    295         ready_schedule_unlock();
    296 
    297         /* paranoid */ verify( ! __preemption_enabled() );
    298         return false;
     270        // Simple counting lock, acquired, acquired by incrementing the counter
     271        // to an odd number
     272        for() {
     273                uint64_t l = this.lock;
     274                if(
     275                        (0 == (l % 2))
     276                        && __atomic_compare_exchange_n(&this.lock, &l, l + 1, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
     277                ) return;
     278                Pause();
     279        }
     280
     281        /* paranoid */ verify( ! __preemption_enabled() );
    299282}
    300283
     
    302285        /* paranoid */ verify( ! __preemption_enabled() );
    303286
    304         unlock(this.lock);
     287        /* paranoid */ verify( 1 == (this.lock % 2) );
     288        // Simple couting lock, release by incrementing to an even number
     289        __atomic_fetch_add( &this.lock, 1, __ATOMIC_SEQ_CST );
    305290
    306291        // Release the global lock, which we acquired when locking
  • libcfa/src/device/cpu.cfa

    r6c53a93 re2853eb  
    3030        #include <fcntl.h>
    3131}
    32 
    33 #include "algorithms/range_iterator.hfa"
    3432
    3533// search a string for character 'character' but looking atmost at len
     
    137135                count++;
    138136        }
    139         int ret = iterate_dir(path, lambda);
    140         if(ret == ENOTDIR) return 0;
     137        iterate_dir(path, lambda);
    141138
    142139        /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max);
     
    146143
    147144// Count number of cpus in the system
    148 static [int, const char *] count_cpus(void) {
     145static int count_cpus(void) {
    149146        const char * fpath = "/sys/devices/system/cpu/online";
    150147        int fd = open(fpath, 0, O_RDONLY);
     
    162159
    163160        const char * _;
    164         return [read_width(buff, r - 1, &_), strndup(buff, r - 1)];
     161        int cnt = read_width(buff, r - 1, &_);
     162        /* paranoid */ verify(cnt == count_prefix_dirs("/sys/devices/system/cpu", "cpu"));
     163        return cnt;
    165164}
    166165
     
    227226
    228227struct raw_cache_instance {
    229         idx_range_t range;      // A text description of the cpus covered
    230         unsigned width;         // The number of cpus covered
    231         unsigned char level;    // the cache level
     228        idx_range_t range;
     229        unsigned width;
     230        unsigned char level;
    232231        // FIXME add at least size and type
    233232};
     
    236235static void ^?{}(raw_cache_instance & this) { free(this.range);}
    237236
    238 // Returns a 2D array of instances of size [cpu count][cache levels]
    239 // where cache level doesn't include instruction caches
    240 raw_cache_instance ** build_raw_cache_table(unsigned cpus_c, idx_range_t cpus, unsigned idxs, unsigned cache_levels)
     237raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels)
    241238{
    242         raw_cache_instance ** raw = alloc(cpus_c, '\0'`fill);
    243 
    244         RangeIter rc = { cpus };
    245         while(moveNext(rc)) {
    246                 unsigned i = rc.com;
     239        raw_cache_instance ** raw = alloc(cpus);
     240        for(i; cpus) {
    247241                raw[i] = alloc(cache_levels);
    248242                void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) {
     
    269263
    270264// returns an allocate list of all the different distinct last level caches
    271 static [*llc_map_t, size_t cnt] distinct_llcs(idx_range_t cpus, unsigned llc_idx, raw_cache_instance ** raw) {
     265static [*llc_map_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) {
    272266        // Allocate at least one element
    273267        llc_map_t* ranges = alloc();
    274268        size_t range_cnt = 1;
    275269
    276         RangeIter rc = { cpus };
    277         __attribute__((unused)) bool ret =
    278         moveNext(rc);
    279         /* paranoid */ verify( ret );
    280         /* paranoid */ verify( rc.com >= 0 );
    281 
    282270        // Initialize with element 0
    283         ranges->raw = &raw[rc.com][llc_idx];
     271        ranges->raw = &raw[0][llc_idx];
    284272        ranges->count = 0;
    285273        ranges->start = -1u;
    286274
    287275        // Go over all other cpus
    288         CPU_LOOP: while(moveNext(rc)) {
    289                 unsigned i = rc.com;
     276        CPU_LOOP: for(i; 1~cpus) {
    290277                // Check if the range is already there
    291278                raw_cache_instance * candidate = &raw[i][llc_idx];
     
    317304}
    318305
    319 static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus_c, idx_range_t cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) {
    320         cpu_pairing_t * pairings = alloc(cpus_c);
    321 
    322         RangeIter rc = { cpus };
    323         CPU_LOOP: while(moveNext(rc)) {
    324                 unsigned i = rc.com;
     306static [[]cpu_pairing_t] get_cpu_pairings(unsigned cpus, raw_cache_instance ** raw, llc_map_t * maps, size_t map_cnt) {
     307        cpu_pairing_t * pairings = alloc(cpus);
     308
     309        CPU_LOOP: for(i; cpus) {
    325310                pairings[i].cpu = i;
    326311                idx_range_t want = raw[i][0].range;
     
    342327extern "C" {
    343328        void __cfaabi_device_startup( void ) {
    344                 int cpus_c;
    345                 const char * cpus;
    346                 [cpus_c, cpus] = count_cpus();
    347                 #if defined(__CFA_WITH_VERIFY__)
    348                 // Verify that the mapping is self consistant.
    349                 {
    350                         RangeIter rc = { cpus };
    351                         while(moveNext(rc)) {
    352                                 unsigned i = rc.com;
    353                                 verify(cpus_c > i);
    354                         }
    355                 }
    356                 #endif
    357 
     329                int cpus = count_cpus();
    358330                int idxs = count_cache_indexes();
    359331
     
    361333                unsigned cache_levels = 0;
    362334                unsigned llc = 0;
    363                 if (idxs != 0) {
     335                {
    364336                        unsigned char prev = -1u;
    365337                        void first(unsigned idx, unsigned char level, const char * map, size_t len) {
     
    373345
    374346                // Read in raw data
    375                 raw_cache_instance ** raw = build_raw_cache_table(cpus_c, cpus, idxs, cache_levels);
     347                raw_cache_instance ** raw = build_raw_cache_table(cpus, idxs, cache_levels);
    376348
    377349                // Find number of distinct cache instances
     
    390362                                width2 += maps[i].raw->width;
    391363                        }
    392                         verify(width1 == cpus_c);
    393                         verify(width2 == cpus_c);
     364                        verify(width1 == cpus);
     365                        verify(width2 == cpus);
    394366                }
    395367                #endif
    396368
    397369                // Get mappings from cpu to cache instance
    398                 cpu_pairing_t * pairings = get_cpu_pairings(cpus_c, cpus, raw, maps, map_cnt);
     370                cpu_pairing_t * pairings = get_cpu_pairings(cpus, raw, maps, map_cnt);
    399371
    400372                // Sort by cache instance
    401                 qsort(pairings, cpus_c);
     373                qsort(pairings, cpus);
    402374
    403375                {
    404376                        unsigned it = 0;
    405                         RangeIter rc = { cpus };
    406                         while(moveNext(rc)) {
    407                                 unsigned i = rc.com;
     377                        for(i; cpus) {
    408378                                unsigned llc_id = pairings[i].id;
    409379                                if(maps[llc_id].start == -1u) {
     
    414384                                }
    415385                        }
    416                         /* paranoid */ verify(it == cpus_c);
     386                        /* paranoid */ verify(it == cpus);
    417387                }
    418388
    419389                // From the mappings build the actual cpu map we want
    420                 struct cpu_map_entry_t * entries = alloc(cpus_c);
    421                 for(i; cpus_c) { entries[i].count = 0; }
    422 
    423                 RangeIter rc = { cpus };
    424                 while(moveNext(rc)) {
    425                         unsigned i = rc.com;
     390                struct cpu_map_entry_t * entries = alloc(cpus);
     391                for(i; cpus) { entries[i].count = 0; }
     392                for(i; cpus) {
    426393                        /* paranoid */ verify(pairings[i].id < map_cnt);
    427394                        unsigned c = pairings[i].cpu;
     
    439406                free(pairings);
    440407
    441                 for(i; cpus_c) {
    442                         if( raw[i] ) for(j; cache_levels) {
     408                for(i; cpus) {
     409                        for(j; cache_levels) {
    443410                                ^(raw[i][j]){};
    444411                        }
     
    448415
    449416                cpu_info.llc_map = entries;
    450                 cpu_info.hthrd_count = cpus_c;
    451                 cpu_info.llc_count = map_cnt;
     417                cpu_info.hthrd_count = cpus;
    452418        }
    453419
  • libcfa/src/device/cpu.hfa

    r6c53a93 re2853eb  
    2323
    2424struct cpu_info_t {
    25         // Array of size [hthrd_count]
     25         // array of size [hthrd_count]
    2626        const cpu_map_entry_t * llc_map;
    2727
    28         // Number of _hardware_ threads present in the system
     28         // Number of _hardware_ threads present in the system
    2929        size_t hthrd_count;
    30 
    31         // Number of distinct last level caches
    32         size_t llc_count;
    3330};
    3431
  • libcfa/src/heap.cfa

    r6c53a93 re2853eb  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jan  2 23:29:41 2022
    13 // Update Count     : 1058
     12// Last Modified On : Mon Aug  9 19:03:02 2021
     13// Update Count     : 1040
    1414//
    1515
     
    263263#ifdef __STATISTICS__
    264264// Heap statistics counters.
    265 static unsigned int malloc_calls, malloc_0_calls;
    266 static unsigned long long int malloc_storage_request, malloc_storage_alloc;
    267 static unsigned int aalloc_calls, aalloc_0_calls;
    268 static unsigned long long int aalloc_storage_request, aalloc_storage_alloc;
    269 static unsigned int calloc_calls, calloc_0_calls;
    270 static unsigned long long int calloc_storage_request, calloc_storage_alloc;
    271 static unsigned int memalign_calls, memalign_0_calls;
    272 static unsigned long long int memalign_storage_request, memalign_storage_alloc;
    273 static unsigned int amemalign_calls, amemalign_0_calls;
    274 static unsigned long long int amemalign_storage_request, amemalign_storage_alloc;
    275 static unsigned int cmemalign_calls, cmemalign_0_calls;
    276 static unsigned long long int cmemalign_storage_request, cmemalign_storage_alloc;
    277 static unsigned int resize_calls, resize_0_calls;
    278 static unsigned long long int resize_storage_request, resize_storage_alloc;
    279 static unsigned int realloc_calls, realloc_0_calls;
    280 static unsigned long long int realloc_storage_request, realloc_storage_alloc;
    281 static unsigned int free_calls, free_null_calls;
    282 static unsigned long long int free_storage_request, free_storage_alloc;
     265static unsigned int malloc_zero_calls, malloc_calls;
     266static unsigned long long int malloc_storage;
     267static unsigned int aalloc_zero_calls, aalloc_calls;
     268static unsigned long long int aalloc_storage;
     269static unsigned int calloc_zero_calls, calloc_calls;
     270static unsigned long long int calloc_storage;
     271static unsigned int memalign_zero_calls, memalign_calls;
     272static unsigned long long int memalign_storage;
     273static unsigned int amemalign_zero_calls, amemalign_calls;
     274static unsigned long long int amemalign_storage;
     275static unsigned int cmemalign_zero_calls, cmemalign_calls;
     276static unsigned long long int cmemalign_storage;
     277static unsigned int resize_zero_calls, resize_calls;
     278static unsigned long long int resize_storage;
     279static unsigned int realloc_zero_calls, realloc_calls;
     280static unsigned long long int realloc_storage;
     281static unsigned int free_zero_calls, free_calls;
     282static unsigned long long int free_storage;
    283283static unsigned int mmap_calls;
    284 static unsigned long long int mmap_storage_request, mmap_storage_alloc;
     284static unsigned long long int mmap_storage;
    285285static unsigned int munmap_calls;
    286 static unsigned long long int munmap_storage_request, munmap_storage_alloc;
     286static unsigned long long int munmap_storage;
    287287static unsigned int sbrk_calls;
    288288static unsigned long long int sbrk_storage;
     
    294294        char helpText[1024];
    295295        __cfaabi_bits_print_buffer( STDERR_FILENO, helpText, sizeof(helpText),
    296                                                                 "\nHeap statistics: (storage request / allocation + header)\n"
    297                                                                 "  malloc    >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    298                                                                 "  aalloc    >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    299                                                                 "  calloc    >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    300                                                                 "  memalign  >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    301                                                                 "  amemalign >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    302                                                                 "  cmemalign >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    303                                                                 "  resize    >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    304                                                                 "  realloc   >0 calls %'u; 0 calls %'u; storage %'llu / %'llu bytes\n"
    305                                                                 "  free      !null calls %'u; null calls %'u; storage %'llu / %'llu bytes\n"
    306                                                                 "  sbrk      calls %'u; storage %'llu bytes\n"
    307                                                                 "  mmap      calls %'u; storage %'llu / %'llu bytes\n"
    308                                                                 "  munmap    calls %'u; storage %'llu / %'llu bytes\n",
    309                                                                 malloc_calls, malloc_0_calls, malloc_storage_request, malloc_storage_alloc,
    310                                                                 aalloc_calls, aalloc_0_calls, aalloc_storage_request, aalloc_storage_alloc,
    311                                                                 calloc_calls, calloc_0_calls, calloc_storage_request, calloc_storage_alloc,
    312                                                                 memalign_calls, memalign_0_calls, memalign_storage_request, memalign_storage_alloc,
    313                                                                 amemalign_calls, amemalign_0_calls, amemalign_storage_request, amemalign_storage_alloc,
    314                                                                 cmemalign_calls, cmemalign_0_calls, cmemalign_storage_request, cmemalign_storage_alloc,
    315                                                                 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc,
    316                                                                 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc,
    317                                                                 free_calls, free_null_calls, free_storage_request, free_storage_alloc,
    318                                                                 sbrk_calls, sbrk_storage,
    319                                                                 mmap_calls, mmap_storage_request, mmap_storage_alloc,
    320                                                                 munmap_calls, munmap_storage_request, munmap_storage_alloc
     296                                                                "\nHeap statistics:\n"
     297                                                                "  malloc    0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     298                                                                "  aalloc    0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     299                                                                "  calloc    0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     300                                                                "  memalign  0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     301                                                                "  amemalign 0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     302                                                                "  cmemalign 0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     303                                                                "  resize    0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     304                                                                "  realloc   0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     305                                                                "  free      0-calls %'u; >0-calls %'u; storage %'llu bytes\n"
     306                                                                "  mmap      calls %'u; storage %'llu bytes\n"
     307                                                                "  munmap    calls %'u; storage %'llu bytes\n"
     308                                                                "  sbrk      calls %'u; storage %'llu bytes\n",
     309                                                                malloc_zero_calls, malloc_calls, malloc_storage,
     310                                                                aalloc_zero_calls, aalloc_calls, aalloc_storage,
     311                                                                calloc_zero_calls, calloc_calls, calloc_storage,
     312                                                                memalign_zero_calls, memalign_calls, memalign_storage,
     313                                                                amemalign_zero_calls, amemalign_calls, amemalign_storage,
     314                                                                cmemalign_zero_calls, cmemalign_calls, cmemalign_storage,
     315                                                                resize_zero_calls, resize_calls, resize_storage,
     316                                                                realloc_zero_calls, realloc_calls, realloc_storage,
     317                                                                free_zero_calls, free_calls, free_storage,
     318                                                                mmap_calls, mmap_storage,
     319                                                                munmap_calls, munmap_storage,
     320                                                                sbrk_calls, sbrk_storage
    321321                );
    322322} // printStats
     
    329329                                                "<sizes>\n"
    330330                                                "</sizes>\n"
    331                                                 "<total type=\"malloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    332                                                 "<total type=\"aalloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    333                                                 "<total type=\"calloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    334                                                 "<total type=\"memalign\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    335                                                 "<total type=\"amemalign\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    336                                                 "<total type=\"cmemalign\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    337                                                 "<total type=\"resize\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    338                                                 "<total type=\"realloc\" >0 count=\"%'u;\" 0 count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    339                                                 "<total type=\"free\" !null=\"%'u;\" 0 null=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
     331                                                "<total type=\"malloc\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     332                                                "<total type=\"aalloc\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     333                                                "<total type=\"calloc\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     334                                                "<total type=\"memalign\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     335                                                "<total type=\"amemalign\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     336                                                "<total type=\"cmemalign\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     337                                                "<total type=\"resize\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     338                                                "<total type=\"realloc\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     339                                                "<total type=\"free\" 0 count=\"%'u;\" >0 count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     340                                                "<total type=\"mmap\" count=\"%'u;\" size=\"%'llu\"/> bytes\n"
     341                                                "<total type=\"munmap\" count=\"%'u;\" size=\"%'llu\"/> bytes\n"
    340342                                                "<total type=\"sbrk\" count=\"%'u;\" size=\"%'llu\"/> bytes\n"
    341                                                 "<total type=\"mmap\" count=\"%'u;\" size=\"%'llu / %'llu\" / > bytes\n"
    342                                                 "<total type=\"munmap\" count=\"%'u;\" size=\"%'llu / %'llu\"/> bytes\n"
    343343                                                "</malloc>",
    344                                                 malloc_calls, malloc_0_calls, malloc_storage_request, malloc_storage_alloc,
    345                                                 aalloc_calls, aalloc_0_calls, aalloc_storage_request, aalloc_storage_alloc,
    346                                                 calloc_calls, calloc_0_calls, calloc_storage_request, calloc_storage_alloc,
    347                                                 memalign_calls, memalign_0_calls, memalign_storage_request, memalign_storage_alloc,
    348                                                 amemalign_calls, amemalign_0_calls, amemalign_storage_request, amemalign_storage_alloc,
    349                                                 cmemalign_calls, cmemalign_0_calls, cmemalign_storage_request, cmemalign_storage_alloc,
    350                                                 resize_calls, resize_0_calls, resize_storage_request, resize_storage_alloc,
    351                                                 realloc_calls, realloc_0_calls, realloc_storage_request, realloc_storage_alloc,
    352                                                 free_calls, free_null_calls, free_storage_request, free_storage_alloc,
    353                                                 sbrk_calls, sbrk_storage,
    354                                                 mmap_calls, mmap_storage_request, mmap_storage_alloc,
    355                                                 munmap_calls, munmap_storage_request, munmap_storage_alloc
     344                                                malloc_zero_calls, malloc_calls, malloc_storage,
     345                                                aalloc_zero_calls, aalloc_calls, aalloc_storage,
     346                                                calloc_zero_calls, calloc_calls, calloc_storage,
     347                                                memalign_zero_calls, memalign_calls, memalign_storage,
     348                                                amemalign_zero_calls, amemalign_calls, amemalign_storage,
     349                                                cmemalign_zero_calls, cmemalign_calls, cmemalign_storage,
     350                                                resize_zero_calls, resize_calls, resize_storage,
     351                                                realloc_zero_calls, realloc_calls, realloc_storage,
     352                                                free_zero_calls, free_calls, free_storage,
     353                                                mmap_calls, mmap_storage,
     354                                                munmap_calls, munmap_storage,
     355                                                sbrk_calls, sbrk_storage
    356356                );
    357357        __cfaabi_bits_write( fileno( stream ), helpText, len ); // ensures all bytes written or exit
     
    577577                #ifdef __STATISTICS__
    578578                __atomic_add_fetch( &mmap_calls, 1, __ATOMIC_SEQ_CST );
    579                 __atomic_add_fetch( &mmap_storage_request, size, __ATOMIC_SEQ_CST );
    580                 __atomic_add_fetch( &mmap_storage_alloc, tsize, __ATOMIC_SEQ_CST );
     579                __atomic_add_fetch( &mmap_storage, tsize, __ATOMIC_SEQ_CST );
    581580                #endif // __STATISTICS__
    582581
     
    627626                #ifdef __STATISTICS__
    628627                __atomic_add_fetch( &munmap_calls, 1, __ATOMIC_SEQ_CST );
    629                 __atomic_add_fetch( &munmap_storage_request, header->kind.real.size, __ATOMIC_SEQ_CST );
    630                 __atomic_add_fetch( &munmap_storage_alloc, size, __ATOMIC_SEQ_CST );
     628                __atomic_add_fetch( &munmap_storage, size, __ATOMIC_SEQ_CST );
    631629                #endif // __STATISTICS__
    632630                if ( munmap( header, size ) == -1 ) {
     
    644642                #ifdef __STATISTICS__
    645643                __atomic_add_fetch( &free_calls, 1, __ATOMIC_SEQ_CST );
    646                 __atomic_add_fetch( &free_storage_request, header->kind.real.size, __ATOMIC_SEQ_CST );
    647                 __atomic_add_fetch( &free_storage_alloc, size, __ATOMIC_SEQ_CST );
     644                __atomic_add_fetch( &free_storage, size, __ATOMIC_SEQ_CST );
    648645                #endif // __STATISTICS__
    649646
     
    822819                if ( likely( size > 0 ) ) {
    823820                        __atomic_add_fetch( &malloc_calls, 1, __ATOMIC_SEQ_CST );
    824                         __atomic_add_fetch( &malloc_storage_request, size, __ATOMIC_SEQ_CST );
     821                        __atomic_add_fetch( &malloc_storage, size, __ATOMIC_SEQ_CST );
    825822                } else {
    826                         __atomic_add_fetch( &malloc_0_calls, 1, __ATOMIC_SEQ_CST );
     823                        __atomic_add_fetch( &malloc_zero_calls, 1, __ATOMIC_SEQ_CST );
    827824                } // if
    828825                #endif // __STATISTICS__
     
    838835                if ( likely( size > 0 ) ) {
    839836                        __atomic_add_fetch( &aalloc_calls, 1, __ATOMIC_SEQ_CST );
    840                         __atomic_add_fetch( &aalloc_storage_request, size, __ATOMIC_SEQ_CST );
     837                        __atomic_add_fetch( &aalloc_storage, size, __ATOMIC_SEQ_CST );
    841838                } else {
    842                         __atomic_add_fetch( &aalloc_0_calls, 1, __ATOMIC_SEQ_CST );
     839                        __atomic_add_fetch( &aalloc_zero_calls, 1, __ATOMIC_SEQ_CST );
    843840                } // if
    844841                #endif // __STATISTICS__
     
    853850          if ( unlikely( size ) == 0 ) {                        // 0 BYTE ALLOCATION RETURNS NULL POINTER
    854851                        #ifdef __STATISTICS__
    855                         __atomic_add_fetch( &calloc_0_calls, 1, __ATOMIC_SEQ_CST );
     852                        __atomic_add_fetch( &calloc_zero_calls, 1, __ATOMIC_SEQ_CST );
    856853                        #endif // __STATISTICS__
    857854                        return 0p;
     
    859856                #ifdef __STATISTICS__
    860857                __atomic_add_fetch( &calloc_calls, 1, __ATOMIC_SEQ_CST );
    861                 __atomic_add_fetch( &calloc_storage_request, dim * elemSize, __ATOMIC_SEQ_CST );
     858                __atomic_add_fetch( &calloc_storage, dim * elemSize, __ATOMIC_SEQ_CST );
    862859                #endif // __STATISTICS__
    863860
     
    894891          if ( unlikely( size == 0 ) ) {                                        // special cases
    895892                        #ifdef __STATISTICS__
    896                         __atomic_add_fetch( &resize_0_calls, 1, __ATOMIC_SEQ_CST );
     893                        __atomic_add_fetch( &resize_zero_calls, 1, __ATOMIC_SEQ_CST );
    897894                        #endif // __STATISTICS__
    898895                        free( oaddr );
     
    905902          if ( unlikely( oaddr == 0p ) ) {
    906903                        #ifdef __STATISTICS__
    907                         __atomic_add_fetch( &resize_storage_request, size, __ATOMIC_SEQ_CST );
     904                        __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    908905                        #endif // __STATISTICS__
    909906                        return mallocNoStats( size );
     
    924921
    925922                #ifdef __STATISTICS__
    926                 __atomic_add_fetch( &resize_storage_request, size, __ATOMIC_SEQ_CST );
     923                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    927924                #endif // __STATISTICS__
    928925
     
    939936          if ( unlikely( size == 0 ) ) {                                        // special cases
    940937                        #ifdef __STATISTICS__
    941                         __atomic_add_fetch( &realloc_0_calls, 1, __ATOMIC_SEQ_CST );
     938                        __atomic_add_fetch( &realloc_zero_calls, 1, __ATOMIC_SEQ_CST );
    942939                        #endif // __STATISTICS__
    943940                        free( oaddr );
     
    950947          if ( unlikely( oaddr == 0p ) ) {
    951948                        #ifdef __STATISTICS__
    952                         __atomic_add_fetch( &realloc_storage_request, size, __ATOMIC_SEQ_CST );
     949                        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    953950                        #endif // __STATISTICS__
    954951                        return mallocNoStats( size );
     
    972969
    973970                #ifdef __STATISTICS__
    974                 __atomic_add_fetch( &realloc_storage_request, size, __ATOMIC_SEQ_CST );
     971                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    975972                #endif // __STATISTICS__
    976973
     
    10031000                if ( likely( size > 0 ) ) {
    10041001                        __atomic_add_fetch( &memalign_calls, 1, __ATOMIC_SEQ_CST );
    1005                         __atomic_add_fetch( &memalign_storage_request, size, __ATOMIC_SEQ_CST );
     1002                        __atomic_add_fetch( &memalign_storage, size, __ATOMIC_SEQ_CST );
    10061003                } else {
    1007                         __atomic_add_fetch( &memalign_0_calls, 1, __ATOMIC_SEQ_CST );
     1004                        __atomic_add_fetch( &memalign_zero_calls, 1, __ATOMIC_SEQ_CST );
    10081005                } // if
    10091006                #endif // __STATISTICS__
     
    10191016                if ( likely( size > 0 ) ) {
    10201017                        __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    1021                         __atomic_add_fetch( &cmemalign_storage_request, size, __ATOMIC_SEQ_CST );
     1018                        __atomic_add_fetch( &cmemalign_storage, size, __ATOMIC_SEQ_CST );
    10221019                } else {
    1023                         __atomic_add_fetch( &cmemalign_0_calls, 1, __ATOMIC_SEQ_CST );
     1020                        __atomic_add_fetch( &cmemalign_zero_calls, 1, __ATOMIC_SEQ_CST );
    10241021                } // if
    10251022                #endif // __STATISTICS__
     
    10341031          if ( unlikely( size ) == 0 ) {                                        // 0 BYTE ALLOCATION RETURNS NULL POINTER
    10351032                        #ifdef __STATISTICS__
    1036                         __atomic_add_fetch( &cmemalign_0_calls, 1, __ATOMIC_SEQ_CST );
     1033                        __atomic_add_fetch( &cmemalign_zero_calls, 1, __ATOMIC_SEQ_CST );
    10371034                        #endif // __STATISTICS__
    10381035                        return 0p;
     
    10401037                #ifdef __STATISTICS__
    10411038                __atomic_add_fetch( &cmemalign_calls, 1, __ATOMIC_SEQ_CST );
    1042                 __atomic_add_fetch( &cmemalign_storage_request, dim * elemSize, __ATOMIC_SEQ_CST );
     1039                __atomic_add_fetch( &cmemalign_storage, dim * elemSize, __ATOMIC_SEQ_CST );
    10431040                #endif // __STATISTICS__
    10441041
     
    11041101          if ( unlikely( addr == 0p ) ) {                                       // special case
    11051102                        #ifdef __STATISTICS__
    1106                         __atomic_add_fetch( &free_null_calls, 1, __ATOMIC_SEQ_CST );
     1103                        __atomic_add_fetch( &free_zero_calls, 1, __ATOMIC_SEQ_CST );
    11071104                        #endif // __STATISTICS__
    11081105
     
    12831280  if ( unlikely( size == 0 ) ) {                                                // special cases
    12841281                #ifdef __STATISTICS__
    1285                 __atomic_add_fetch( &resize_0_calls, 1, __ATOMIC_SEQ_CST );
     1282                __atomic_add_fetch( &resize_zero_calls, 1, __ATOMIC_SEQ_CST );
    12861283                #endif // __STATISTICS__
    12871284                free( oaddr );
     
    12971294                #ifdef __STATISTICS__
    12981295                __atomic_add_fetch( &resize_calls, 1, __ATOMIC_SEQ_CST );
    1299                 __atomic_add_fetch( &resize_storage_request, size, __ATOMIC_SEQ_CST );
     1296                __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    13001297                #endif // __STATISTICS__
    13011298                return memalignNoStats( nalign, size );
     
    13321329
    13331330        #ifdef __STATISTICS__
    1334         __atomic_add_fetch( &resize_storage_request, size, __ATOMIC_SEQ_CST );
     1331        __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST );
    13351332        #endif // __STATISTICS__
    13361333
     
    13451342  if ( unlikely( size == 0 ) ) {                                                // special cases
    13461343                #ifdef __STATISTICS__
    1347                 __atomic_add_fetch( &realloc_0_calls, 1, __ATOMIC_SEQ_CST );
     1344                __atomic_add_fetch( &realloc_zero_calls, 1, __ATOMIC_SEQ_CST );
    13481345                #endif // __STATISTICS__
    13491346                free( oaddr );
     
    13591356                #ifdef __STATISTICS__
    13601357                __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
    1361                 __atomic_add_fetch( &realloc_storage_request, size, __ATOMIC_SEQ_CST );
     1358                __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    13621359                #endif // __STATISTICS__
    13631360                return memalignNoStats( nalign, size );
     
    13831380        #ifdef __STATISTICS__
    13841381        __atomic_add_fetch( &realloc_calls, 1, __ATOMIC_SEQ_CST );
    1385         __atomic_add_fetch( &realloc_storage_request, size, __ATOMIC_SEQ_CST );
     1382        __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST );
    13861383        #endif // __STATISTICS__
    13871384
  • libcfa/src/stdlib.cfa

    r6c53a93 re2853eb  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan  3 09:36:27 2022
    13 // Update Count     : 519
     12// Last Modified On : Thu Nov 12 07:46:09 2020
     13// Update Count     : 503
    1414//
    1515
     
    221221//---------------------------------------
    222222
    223 static uint32_t seed = 0;                                                               // current seed
    224 static thread_local uint32_t state;                                             // random state
    225 
    226 void set_seed( uint32_t seed_ ) { state = seed = seed_; }
    227 uint32_t get_seed() { return seed; }
    228 
    229 #define GENERATOR LCG
    230 
    231 inline uint32_t MarsagliaXor( uint32_t & state ) {
    232         if ( unlikely( seed == 0 ) ) set_seed( rdtscl() );
    233         else if ( unlikely( state == 0 ) ) state = seed;
    234         state ^= state << 6;
    235         state ^= state >> 21;
    236         state ^= state << 7;
    237         return state;
    238 } // MarsagliaXor
    239 
    240 inline uint32_t LCG( uint32_t & state ) {                               // linear congruential generator
    241         if ( unlikely( seed == 0 ) ) set_seed( rdtscl() );
    242         else if ( unlikely( state == 0 ) ) state = seed;
    243         return state = 36969 * (state & 65535) + (state >> 16); // 36969 is NOT prime!
    244 } // LCG
    245 
    246 uint32_t prng( PRNG & prng ) with( prng ) { callcnt += 1; return GENERATOR( state ); }
    247 
    248 uint32_t prng( void ) { return GENERATOR( state ); }
    249 
    250 //---------------------------------------
    251 
    252 bool threading_enabled( void ) __attribute__(( weak )) { return false; }
     223bool threading_enabled(void) __attribute__((weak)) {
     224        return false;
     225}
    253226
    254227// Local Variables: //
  • libcfa/src/stdlib.hfa

    r6c53a93 re2853eb  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jan  2 22:53:57 2022
    13 // Update Count     : 594
     12// Last Modified On : Tue Apr 20 21:20:03 2021
     13// Update Count     : 575
    1414//
    1515
     
    4343//---------------------------------------
    4444
     45// Macro because of returns
     46#define ARRAY_ALLOC$( allocation, alignment, dim ) \
     47        if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( dim, (size_t)sizeof(T) ); /* C allocation */ \
     48        else return (T *)alignment( _Alignof(T), dim, sizeof(T) )
     49
    4550static inline forall( T & | sized(T) ) {
    4651        // CFA safe equivalents, i.e., implicit size specification
    4752
    4853        T * malloc( void ) {
    49                 if ( _Alignof(T) <= libAlign() ) return (T *)malloc( sizeof(T) ); // C allocation
     54                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation
    5055                else return (T *)memalign( _Alignof(T), sizeof(T) );
    5156        } // malloc
    5257
    5358        T * aalloc( size_t dim ) {
    54                 if ( _Alignof(T) <= libAlign() ) return (T *)aalloc( dim, sizeof(T) ); // C allocation
    55                 else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );
     59                ARRAY_ALLOC$( aalloc, amemalign, dim );
    5660        } // aalloc
    5761
    5862        T * calloc( size_t dim ) {
    59                 if ( _Alignof(T) <= libAlign() ) return (T *)calloc( dim, sizeof(T) ); // C allocation
    60                 else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) );
     63                ARRAY_ALLOC$( calloc, cmemalign, dim );
    6164        } // calloc
    6265
    6366        T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
    64                 if ( _Alignof(T) <= libAlign() ) return (T *)resize( (void *)ptr, size ); // CFA resize
    65                 else return (T *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
     67                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
     68                else return (T *)(void *)resize( (void *)ptr, _Alignof(T), size ); // CFA resize
    6669        } // resize
    6770
    6871        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    69                 if ( _Alignof(T) <= libAlign() ) return (T *)realloc( (void *)ptr, size ); // C realloc
    70                 else return (T *)realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc
     72                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
     73                else return (T *)(void *)realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc
    7174        } // realloc
    7275
     
    166169                return ret;
    167170        }
    168         S_fill(T)               ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved
    169         S_fill(T)               ?`fill ( T * a )                                { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved
    170171        S_fill(T)               ?`fill ( char c )                               { return (S_fill(T)){ 'c', c }; }
     172        S_fill(T)               ?`fill ( T * a )                                { return (S_fill(T)){ 'T', '0', 0, a }; }
    171173        S_fill(T)               ?`fill ( T a[], size_t nmemb )  { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; }
    172174
     
    360362
    361363static inline {
    362         long int random( long int l, long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l + 1) + l; } // [l,u]
    363         long int random( long int u ) { return random( 0, u - 1 ); } // [0,u)
     364        long int random( long int l, long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l) + l; } // [l,u)
     365        long int random( long int u ) { if ( u < 0 ) return random( u, 0 ); else return random( 0, u ); } // [0,u)
    364366        unsigned long int random( void ) { return lrand48(); }
    365367        unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,u)
    366         unsigned long int random( unsigned long int l, unsigned long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l + 1) + l; } // [l,u]
     368        unsigned long int random( unsigned long int l, unsigned long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l) + l; } // [l,u)
    367369
    368370        char random( void ) { return (unsigned long int)random(); }
     
    385387//---------------------------------------
    386388
    387 struct PRNG {
    388         uint32_t callcnt;                                                                       // call count
    389         uint32_t seed;                                                                          // current seed
    390         uint32_t state;                                                                         // random state
    391 }; // PRNG
    392 
    393 extern uint32_t prng( PRNG & prng ) __attribute__(( warn_unused_result )); // [0,UINT_MAX]
    394 static inline {
    395         void set_seed( PRNG & prng, uint32_t seed_ ) with( prng ) { state = seed = seed_; } // set seed
    396         void ?{}( PRNG & prng ) { set_seed( prng, rdtscl() ); } // random seed
    397         void ?{}( PRNG & prng, uint32_t seed ) { set_seed( prng, seed ); } // fixed seed
    398         uint32_t get_seed( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } // get seed
    399         uint32_t prng( PRNG & prng, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng ) % u; } // [0,u)
    400         uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng, u - l + 1 ) + l; } // [l,u]
    401         uint32_t calls( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return callcnt; }
    402 } // distribution
    403 
    404 extern void set_seed( uint32_t seed );                                  // set per thread seed
    405 extern uint32_t get_seed();                                                             // get seed
    406 extern uint32_t prng( void ) __attribute__(( warn_unused_result )); // [0,UINT_MAX]
    407 static inline {
    408         uint32_t prng( uint32_t u ) __attribute__(( warn_unused_result ));
    409         uint32_t prng( uint32_t u ) { return prng() % u; }      // [0,u)
    410         uint32_t prng( uint32_t l, uint32_t u ) __attribute__(( warn_unused_result ));
    411         uint32_t prng( uint32_t l, uint32_t u ) { return prng( u - l + 1 ) + l; } // [l,u]
    412 } // distribution
    413 
    414 //---------------------------------------
    415 
    416389extern bool threading_enabled( void ) OPTIONAL_THREAD;
    417390
  • src/AST/Decl.hpp

    r6c53a93 re2853eb  
    270270        : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
    271271
    272         bool is_coroutine() const { return kind == Coroutine; }
    273         bool is_generator() const { return kind == Generator; }
    274         bool is_monitor  () const { return kind == Monitor  ; }
    275         bool is_thread   () const { return kind == Thread   ; }
     272        bool is_coroutine() { return kind == Coroutine; }
     273        bool is_generator() { return kind == Generator; }
     274        bool is_monitor  () { return kind == Monitor  ; }
     275        bool is_thread   () { return kind == Thread   ; }
    276276
    277277        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Expr.cpp

    r6c53a93 re2853eb  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Created On       : Tue Nov 30 14:23:00 2021
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Created On       : Thr Jun 13 13:38:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    141141        /// The type of the address of a type.
    142142        /// Caller is responsible for managing returned memory
    143         Type * addrType( const ptr<Type> & type ) {
    144                 if ( auto refType = type.as< ReferenceType >() ) {
    145                         return new ReferenceType( addrType( refType->base ), refType->qualifiers );
     143        Type * addrType( const Type * type ) {
     144                if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * >( type ) ) {
     145                        return new ReferenceType{ addrType( refType->base ), refType->qualifiers };
    146146                } else {
    147                         return new PointerType( type );
     147                        return new PointerType{ type };
    148148                }
    149149        }
    150 
    151         /// The type of the address of an expression.
    152         /// Caller is responsible for managing returned memory
    153         Type * addrExprType( const CodeLocation & loc, const Expr * arg ) {
    154                 assert( arg );
    155                 // If the expression's type is unknown, the address type is unknown.
    156                 if ( nullptr == arg->result ) {
    157                         return nullptr;
    158                 // An lvalue is transformed directly.
    159                 } else if ( arg->get_lvalue() ) {
    160                         return addrType( arg->result );
    161                 // Strip a layer of reference to "create" an lvalue expression.
    162                 } else if ( auto refType = arg->result.as< ReferenceType >() ) {
    163                         return addrType( refType->base );
     150}
     151
     152AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) {
     153        if ( arg->result ) {
     154                if ( arg->get_lvalue() ) {
     155                        // lvalue, retains all levels of reference, and gains a pointer inside the references
     156                        Type * res = addrType( arg->result );
     157                        result = res;
    164158                } else {
    165                         SemanticError( loc, arg->result.get(),
    166                                 "Attempt to take address of non-lvalue expression: " );
     159                        // taking address of non-lvalue, must be a reference, loses one layer of reference
     160                        if ( const ReferenceType * refType =
     161                                        dynamic_cast< const ReferenceType * >( arg->result.get() ) ) {
     162                                Type * res = addrType( refType->base );
     163                                result = res;
     164                        } else {
     165                                SemanticError( loc, arg->result.get(),
     166                                        "Attempt to take address of non-lvalue expression: " );
     167                        }
    167168                }
    168169        }
    169170}
    170 
    171 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) :
    172         Expr( loc, addrExprType( loc, a ) ), arg( a )
    173 {}
    174171
    175172// --- LabelAddressExpr
  • src/AST/Print.cpp

    r6c53a93 re2853eb  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Print.cpp -- Print an AST (or sub-tree) to a stream.
     7// Print.cpp --
    88//
    99// Author           : Thierry Delisle
  • src/AST/Print.hpp

    r6c53a93 re2853eb  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Print.hpp -- Print an AST (or sub-tree) to a stream.
     7// Print.hpp --
    88//
    99// Author           : Thierry Delisle
     
    3535template< typename Coll >
    3636void printAll( std::ostream & os, const Coll & c, Indenter indent = {} ) {
    37         for ( const auto & i : c ) {
    38                 if ( ! i ) continue;
    39 
    40                 os << indent;
    41                 print( os, i, indent );
    42                 os << std::endl;
    43         }
     37    for ( const auto & i : c ) {
     38        if ( ! i ) continue;
     39       
     40        os << indent;
     41        print( os, i, indent );
     42        os << std::endl;
     43    }
    4444}
    4545
  • src/Concurrency/Keywords.cc

    r6c53a93 re2853eb  
    979979                        // If this is the destructor for a monitor it must be mutex
    980980                        if(isDtor) {
    981                                 // This reflects MutexKeyword::validate, except does not produce an error.
    982981                                Type* ty = decl->get_functionType()->get_parameters().front()->get_type();
    983982
  • src/Concurrency/Keywords.h

    r6c53a93 re2853eb  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Keywords.h -- Implement concurrency constructs from their keywords.
     7// Keywords.h --
    88//
    99// Author           : Thierry Delisle
     
    1919
    2020class Declaration;
    21 namespace ast {
    22         class TranslationUnit;
    23 }
    2421
    2522namespace Concurrency {
     
    2724        void implementMutexFuncs( std::list< Declaration * > & translationUnit );
    2825        void implementThreadStarter( std::list< Declaration * > & translationUnit );
    29 
    30 /// Implement the sue-like keywords and the suspend keyword.
    31 void implementKeywords( ast::TranslationUnit & translationUnit );
    32 /// Implement the mutex parameters and mutex statement.
    33 void implementMutex( ast::TranslationUnit & translationUnit );
    34 /// Add the thread starter code to constructors.
    35 void implementThreadStarter( ast::TranslationUnit & translationUnit );
    3626};
    3727
  • src/Concurrency/module.mk

    r6c53a93 re2853eb  
    1515###############################################################################
    1616
    17 SRC_CONCURRENCY = \
    18         Concurrency/KeywordsNew.cpp \
    19         Concurrency/Keywords.cc
     17SRC += Concurrency/Keywords.cc Concurrency/Keywords.h Concurrency/Waitfor.cc Concurrency/Waitfor.h
     18SRCDEMANGLE += Concurrency/Keywords.cc
    2019
    21 SRC += $(SRC_CONCURRENCY) \
    22         Concurrency/Keywords.h \
    23         Concurrency/Waitfor.cc \
    24         Concurrency/Waitfor.h
    25 
    26 SRCDEMANGLE += $(SRC_CONCURRENCY)
    27 
  • src/InitTweak/InitTweak.cc

    r6c53a93 re2853eb  
    99// Author           : Rob Schluntz
    1010// Created On       : Fri May 13 11:26:36 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Nov 19 19:22:00 2021
    13 // Update Count     : 19
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jun 16 20:57:22 2021
     13// Update Count     : 18
    1414//
    1515
     
    540540        }
    541541
    542         const ast::Type * getTypeofThis( const ast::FunctionType * ftype ) {
    543                 assertf( ftype, "getTypeofThis: nullptr ftype" );
    544                 const std::vector<ast::ptr<ast::Type>> & params = ftype->params;
    545                 assertf( !params.empty(), "getTypeofThis: ftype with 0 parameters: %s",
    546                                 toString( ftype ).c_str() );
    547                 const ast::ReferenceType * refType =
    548                         params.front().strict_as<ast::ReferenceType>();
    549                 return refType->base;
    550         }
    551 
    552542        ObjectDecl * getParamThis( FunctionType * ftype ) {
    553543                assertf( ftype, "getParamThis: nullptr ftype" );
  • src/InitTweak/InitTweak.h

    r6c53a93 re2853eb  
    1010// Created On       : Fri May 13 11:26:36 2016
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Nov 19 14:18:00 2021
    13 // Update Count     : 7
     12// Last Modified On : Fri Jul 19 14:18:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    3535        /// returns the base type of the first parameter to a constructor/destructor/assignment function
    3636        Type * getTypeofThis( FunctionType * ftype );
    37         const ast::Type * getTypeofThis( const ast::FunctionType * ftype );
    3837
    3938        /// returns the first parameter of a constructor/destructor/assignment function
  • src/Validate/module.mk

    r6c53a93 re2853eb  
    1616
    1717SRC_VALIDATE = \
    18         Validate/CompoundLiteral.cpp \
    19         Validate/CompoundLiteral.hpp \
    2018        Validate/HandleAttributes.cc \
    2119        Validate/HandleAttributes.h \
  • src/main.cc

    r6c53a93 re2853eb  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Nov 30 10:25:00 2021
    13 // Update Count     : 659
     12// Last Modified On : Fri Nov 12 11:06:00 2021
     13// Update Count     : 658
    1414//
    1515
     
    5050#include "Common/UnimplementedError.h"      // for UnimplementedError
    5151#include "Common/utility.h"                 // for deleteAll, filter, printAll
    52 #include "Concurrency/Keywords.h"           // for implementMutex, implement...
    5352#include "Concurrency/Waitfor.h"            // for generateWaitfor
    5453#include "ControlStruct/ExceptDecl.h"       // for translateExcept
     
    7473#include "Tuples/Tuples.h"                  // for expandMemberTuples, expan...
    7574#include "Validate/FindSpecialDecls.h"      // for findGlobalDecls
    76 #include "Validate/CompoundLiteral.hpp"     // for handleCompoundLiterals
    7775#include "Validate/InitializerLength.hpp"   // for setLengthFromInitializer
    7876#include "Validate/LabelAddressFixer.hpp"   // for fixLabelAddresses
     
    327325                PASS( "Validate-C", SymTab::validate_C( translationUnit ) );
    328326                PASS( "Validate-D", SymTab::validate_D( translationUnit ) );
     327                PASS( "Validate-E", SymTab::validate_E( translationUnit ) );
    329328
    330329                CodeTools::fillLocations( translationUnit );
     
    339338                        forceFillCodeLocations( transUnit );
    340339
    341                         PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) );
    342                         PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) );
    343                         PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) );
    344340                        PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) );
    345341                        PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) );
     
    406402                        translationUnit = convert( move( transUnit ) );
    407403                } else {
    408                         PASS( "Validate-E", SymTab::validate_E( translationUnit ) );
    409404                        PASS( "Validate-F", SymTab::validate_F( translationUnit ) );
    410405
  • tests/.expect/random.x64.txt

    r6c53a93 re2853eb  
    11õ
    22=
    3 K
     3V
    44-911259971
    556
    6 11
     6-4
    771232105397
    880
    9 11
     918
    1010-914096085
    11111
    12 20
     1215
    13132077092859
    14141
    15 12
     1511
    16160.677254
    17170.678106775246139
  • tests/.expect/random.x86.txt

    r6c53a93 re2853eb  
    11õ
    22=
    3 K
     3V
    44-911259971
    556
    6 11
     6-4
    771232105397
    880
    9 11
     918
    1010-914096085
    11111
    12 20
     1215
    13132077092859
    14141
    15 12
     1511
    16160.677254
    17170.678106775246139
  • tests/pybin/tools.py

    r6c53a93 re2853eb  
    374374
    375375        if not os.path.isfile(core):
    376                 return 1, "ERR No core dump (limit soft: {} hard: {})".format(*resource.getrlimit(resource.RLIMIT_CORE))
     376                return 1, "ERR No core dump"
    377377
    378378        try:
Note: See TracChangeset for help on using the changeset viewer.