Changes in / [295dd61:813dfd86]


Ignore:
Files:
11 deleted
22 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/Makefile.am

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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);
    129126static bool mark_idle (__cluster_proc_list & idles, processor & proc);
    130127static void mark_awake(__cluster_proc_list & idles, processor & proc);
     
    132129extern void __cfa_io_start( processor * );
    133130extern bool __cfa_io_drain( processor * );
    134 extern bool __cfa_io_flush( processor *, int min_comp );
     131extern void __cfa_io_flush( processor * );
    135132extern void __cfa_io_stop ( processor * );
    136133static 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
    141134
    142135extern void __disable_interrupts_hard();
     
    154147        /* paranoid */ verify( __preemption_enabled() );
    155148}
    156 
    157149
    158150//=============================================================================================
     
    170162        verify(this);
    171163
    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 
    177164        __cfa_io_start( this );
    178165
     
    208195
    209196                        if( !readyThread ) {
    210                                 __cfa_io_flush( this, 0 );
     197                                ready_schedule_lock();
     198                                __cfa_io_flush( this );
     199                                ready_schedule_unlock();
    211200
    212201                                readyThread = __next_thread_slow( this->cltr );
     
    239228                                }
    240229
    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 );
     230                                #if !defined(__CFA_NO_STATISTICS__)
     231                                        if(this->print_halts) {
     232                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl());
    293233                                        }
    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);
     234                                #endif
     235
     236                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
    331237
    332238                                {
    333239                                        eventfd_t val;
    334                                         ssize_t ret = read( this->idle_fd, &val, sizeof(val) );
     240                                        ssize_t ret = read( this->idle, &val, sizeof(val) );
    335241                                        if(ret < 0) {
    336242                                                switch((int)errno) {
     
    348254                                }
    349255
    350                                         __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
     256                                #if !defined(__CFA_NO_STATISTICS__)
     257                                        if(this->print_halts) {
     258                                                __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl());
     259                                        }
     260                                #endif
    351261
    352262                                // We were woken up, remove self from idle
     
    357267                        }
    358268
     269                        /* paranoid */ verify( readyThread );
     270
     271                        // Reset io dirty bit
     272                        this->io.dirty = false;
     273
     274                        // We found a thread run it
     275                        __run_thread(this, readyThread);
     276
     277                        // Are we done?
     278                        if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP;
     279
     280                        if(this->io.pending && !this->io.dirty) {
     281                                ready_schedule_lock();
     282                                __cfa_io_flush( this );
     283                                ready_schedule_unlock();
     284                        }
     285
     286                        #else
     287                                #warning new kernel loop
     288                        SEARCH: {
     289                                /* paranoid */ verify( ! __preemption_enabled() );
     290
     291                                // First, lock the scheduler since we are searching for a thread
     292                                ready_schedule_lock();
     293
     294                                // Try to get the next thread
     295                                readyThread = pop_fast( this->cltr );
     296                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     297
     298                                // If we can't find a thread, might as well flush any outstanding I/O
     299                                if(this->io.pending) { __cfa_io_flush( this ); }
     300
     301                                // Spin a little on I/O, just in case
     302                                for(5) {
     303                                        __maybe_io_drain( this );
     304                                        readyThread = pop_fast( this->cltr );
     305                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     306                                }
     307
     308                                // no luck, try stealing a few times
     309                                for(5) {
     310                                        if( __maybe_io_drain( this ) ) {
     311                                                readyThread = pop_fast( this->cltr );
     312                                        } else {
     313                                                readyThread = pop_slow( this->cltr );
     314                                        }
     315                                        if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     316                                }
     317
     318                                // still no luck, search for a thread
     319                                readyThread = pop_search( this->cltr );
     320                                if(readyThread) { ready_schedule_unlock(); break SEARCH; }
     321
     322                                // Don't block if we are done
     323                                if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) {
     324                                        ready_schedule_unlock();
     325                                        break MAIN_LOOP;
     326                                }
     327
     328                                __STATS( __tls_stats()->ready.sleep.halts++; )
     329
     330                                // Push self to idle stack
     331                                ready_schedule_unlock();
     332                                if(!mark_idle(this->cltr->procs, * this)) goto SEARCH;
     333                                ready_schedule_lock();
     334
     335                                // Confirm the ready-queue is empty
     336                                __maybe_io_drain( this );
     337                                readyThread = pop_search( this->cltr );
     338                                ready_schedule_unlock();
     339
     340                                if( readyThread ) {
     341                                        // A thread was found, cancel the halt
     342                                        mark_awake(this->cltr->procs, * this);
     343
     344                                        __STATS( __tls_stats()->ready.sleep.cancels++; )
     345
     346                                        // continue the main loop
     347                                        break SEARCH;
     348                                }
     349
     350                                __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 0\n", this->unique_id, rdtscl()); )
     351                                __cfadbg_print_safe(runtime_core, "Kernel : core %p waiting on eventfd %d\n", this, this->idle);
     352
     353                                {
     354                                        eventfd_t val;
     355                                        ssize_t ret = read( this->idle, &val, sizeof(val) );
     356                                        if(ret < 0) {
     357                                                switch((int)errno) {
     358                                                case EAGAIN:
     359                                                #if EAGAIN != EWOULDBLOCK
     360                                                        case EWOULDBLOCK:
     361                                                #endif
     362                                                case EINTR:
     363                                                        // No need to do anything special here, just assume it's a legitimate wake-up
     364                                                        break;
     365                                                default:
     366                                                        abort( "KERNEL : internal error, read failure on idle eventfd, error(%d) %s.", (int)errno, strerror( (int)errno ) );
     367                                                }
     368                                        }
     369                                }
     370
     371                                        __STATS( if(this->print_halts) __cfaabi_bits_print_safe( STDOUT_FILENO, "PH:%d - %lld 1\n", this->unique_id, rdtscl()); )
     372
     373                                // We were woken up, remove self from idle
     374                                mark_awake(this->cltr->procs, * this);
     375
     376                                // DON'T just proceed, start looking again
     377                                continue MAIN_LOOP;
     378                        }
     379
    359380                RUN_THREAD:
    360381                        /* paranoid */ verify( ! __preemption_enabled() );
     
    371392
    372393                        if(this->io.pending && !this->io.dirty) {
    373                                 __cfa_io_flush( this, 0 );
     394                                __cfa_io_flush( this );
    374395                        }
    375396
     
    381402
    382403                __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 );
    388404        }
    389405
     
    782798                eventfd_t val;
    783799                val = 1;
    784                 eventfd_write( this->idle_fd, val );
     800                eventfd_write( this->idle, val );
    785801        __enable_interrupts_checked();
    786 }
    787 
    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
    832802}
    833803
     
    840810                insert_first(this.idles, proc);
    841811
    842                 __atomic_store_n(&this.fd, proc.idle_fd, __ATOMIC_SEQ_CST);
     812                __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST);
    843813        unlock( this );
    844814        /* paranoid */ verify( ! __preemption_enabled() );
     
    857827                {
    858828                        int fd = 0;
    859                         if(!this.idles`isEmpty) fd = this.idles`first.idle_fd;
     829                        if(!this.idles`isEmpty) fd = this.idles`first.idle;
    860830                        __atomic_store_n(&this.fd, fd, __ATOMIC_SEQ_CST);
    861831                }
  • libcfa/src/concurrency/kernel.hfa

    r295dd61 r813dfd86  
    100100
    101101        // Idle lock (kernel semaphore)
    102         int idle_fd;
     102        int idle;
    103103
    104104        // Termination synchronisation (user semaphore)
  • libcfa/src/concurrency/kernel/startup.cfa

    r295dd61 r813dfd86  
    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
  • libcfa/src/concurrency/kernel_private.hfa

    r295dd61 r813dfd86  
    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//-----------------------------------------------------------------------
  • libcfa/src/device/cpu.cfa

    r295dd61 r813dfd86  
    135135                count++;
    136136        }
    137         int ret = iterate_dir(path, lambda);
    138         if(ret == ENOTDIR) return 0;
     137        iterate_dir(path, lambda);
    139138
    140139        /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max);
     
    160159
    161160        const char * _;
    162         return read_width(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;
    163164}
    164165
     
    225226
    226227struct raw_cache_instance {
    227         idx_range_t range;      // A text description of the cpus covered
    228         unsigned width;         // The number of cpus covered
    229         unsigned char level;    // the cache level
     228        idx_range_t range;
     229        unsigned width;
     230        unsigned char level;
    230231        // FIXME add at least size and type
    231232};
     
    234235static void ^?{}(raw_cache_instance & this) { free(this.range);}
    235236
    236 // Returns a 2D array of instances of size [cpu count][cache levels]
    237 // where cache level doesn't include instruction caches
    238237raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels)
    239238{
    240239        raw_cache_instance ** raw = alloc(cpus);
    241 
    242         // TODO: this loop is broken, it only works if the present cpu start at 0 and are contiguous which is not guaranteed.
    243240        for(i; cpus) {
    244                 if (cache_levels > 0) {
    245                         raw[i] = alloc(cache_levels);
    246                         void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) {
    247                                 /* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx);
    248 
    249                                 unsigned idx = cache_levels - level;
    250                                 raw_cache_instance & r = raw[i][idx];
    251                                 r.range = strndup(range, len);
    252                                 r.level = level;
    253                                 const char * end;
    254                                 r.width = read_width(range, len, &end);
    255                         }
    256                         foreach_cacheidx(i, idxs, addcache);
    257                 }
    258                 else {
    259                         char buf[128];
    260                         snprintf(buf, 128, "0-%u", cpus);
    261                         raw[i] = alloc();
    262                         raw[i]->range = strndup(buf, 128);
    263                         raw[i]->level = 0;
    264                         raw[i]->width = cpus;
    265                 }
     241                raw[i] = alloc(cache_levels);
     242                void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) {
     243                        /* paranoid */ verifyf(level <= cache_levels, "Unexpected cache level %d on cpu %u index %u", (int)level, i, fidx);
     244
     245                        unsigned idx = cache_levels - level;
     246                        raw_cache_instance & r = raw[i][idx];
     247                        r.range = strndup(range, len);
     248                        r.level = level;
     249                        const char * end;
     250                        r.width = read_width(range, len, &end);
     251                }
     252                foreach_cacheidx(i, idxs, addcache);
    266253        }
    267254
     
    346333                unsigned cache_levels = 0;
    347334                unsigned llc = 0;
    348                 if (idxs != 0) {
     335                {
    349336                        unsigned char prev = -1u;
    350337                        void first(unsigned idx, unsigned char level, const char * map, size_t len) {
     
    429416                cpu_info.llc_map = entries;
    430417                cpu_info.hthrd_count = cpus;
    431                 cpu_info.llc_count = map_cnt;
    432418        }
    433419
  • libcfa/src/device/cpu.hfa

    r295dd61 r813dfd86  
    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
  • src/AST/Decl.hpp

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

    r295dd61 r813dfd86  
    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

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

    r295dd61 r813dfd86  
    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/pybin/tools.py

    r295dd61 r813dfd86  
    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.