Changes in / [295dd61:813dfd86]
- Files:
-
- 11 deleted
- 22 edited
-
example/io/eventfds.c (deleted)
-
example/range_parser.cfa (deleted)
-
libcfa/src/Makefile.am (modified) (1 diff)
-
libcfa/src/algorithms/range_iterator.cfa (deleted)
-
libcfa/src/algorithms/range_iterator.hfa (deleted)
-
libcfa/src/concurrency/io.cfa (modified) (8 diffs)
-
libcfa/src/concurrency/io/setup.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/io/types.hfa (modified) (1 diff)
-
libcfa/src/concurrency/kernel.cfa (modified) (15 diffs)
-
libcfa/src/concurrency/kernel.hfa (modified) (1 diff)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel_private.hfa (modified) (2 diffs)
-
libcfa/src/device/cpu.cfa (modified) (6 diffs)
-
libcfa/src/device/cpu.hfa (modified) (1 diff)
-
src/AST/Decl.hpp (modified) (1 diff)
-
src/AST/Expr.cpp (modified) (2 diffs)
-
src/AST/Print.cpp (modified) (1 diff)
-
src/AST/Print.hpp (modified) (2 diffs)
-
src/Concurrency/Keywords.cc (modified) (1 diff)
-
src/Concurrency/Keywords.h (modified) (3 diffs)
-
src/Concurrency/KeywordsNew.cpp (deleted)
-
src/Concurrency/module.mk (modified) (1 diff)
-
src/InitTweak/InitTweak.cc (modified) (2 diffs)
-
src/InitTweak/InitTweak.h (modified) (2 diffs)
-
src/Validate/CompoundLiteral.cpp (deleted)
-
src/Validate/CompoundLiteral.hpp (deleted)
-
src/Validate/module.mk (modified) (1 diff)
-
src/main.cc (modified) (6 diffs)
-
tests/algorithms/.expect/range_test.txt (deleted)
-
tests/algorithms/range_test.cfa (deleted)
-
tests/concurrent/.expect/ctor-check.txt (deleted)
-
tests/concurrent/ctor-check.cfa (deleted)
-
tests/pybin/tools.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/Makefile.am
r295dd61 r813dfd86 84 84 time.hfa \ 85 85 bits/weakso_locks.hfa \ 86 algorithms/range_iterator.hfa \87 86 containers/maybe.hfa \ 88 87 containers/pair.hfa \ -
libcfa/src/concurrency/io.cfa
r295dd61 r813dfd86 33 33 #include <sys/syscall.h> 34 34 #include <sys/eventfd.h> 35 #include <sys/uio.h>36 35 37 36 #include <linux/io_uring.h> … … 134 133 } 135 134 136 bool __cfa_io_flush( processor * proc, int min_comp) {135 void __cfa_io_flush( processor * proc ) { 137 136 /* paranoid */ verify( ! __preemption_enabled() ); 138 137 /* paranoid */ verify( proc ); … … 142 141 $io_context & ctx = *proc->io.ctx; 143 142 143 // for(i; 2) { 144 // unsigned idx = proc->rdq.id + i; 145 // cltr->ready_queue.lanes.tscs[idx].tv = -1ull; 146 // } 147 144 148 __ioarbiter_flush( ctx ); 145 149 146 150 __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); 148 152 if( ret < 0 ) { 149 153 switch((int)errno) { … … 153 157 // Update statistics 154 158 __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; 156 164 default: 157 165 abort( "KERNEL ERROR: IO_URING SYSCALL - (%d) %s\n", (int)errno, strerror(errno) ); … … 174 182 175 183 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 // } 180 190 } 181 191 … … 281 291 } 282 292 293 283 294 //============================================================================================= 284 295 // submission … … 303 314 ctx->proc->io.dirty = true; 304 315 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(); 306 319 } 307 320 } … … 502 515 } 503 516 } 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 path516 if( !__alloc(ctx, &idx, 1) ) return false;517 518 // Allocation was successful519 __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 #else540 #error CFA_WITH_IO_URING_IDLE but none of CFA_HAVE_READV, CFA_HAVE_IORING_OP_READV or CFA_HAVE_IORING_OP_READ defined541 #endif542 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 #endif552 517 #endif -
libcfa/src/concurrency/io/setup.cfa
r295dd61 r813dfd86 32 32 33 33 void __cfa_io_start( processor * proc ) {} 34 bool __cfa_io_flush( processor * proc, int) {}34 void __cfa_io_flush( processor * proc ) {} 35 35 void __cfa_io_stop ( processor * proc ) {} 36 36 … … 111 111 this.ext_sq.empty = true; 112 112 (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 ); 114 114 __cfadbg_print_safe(io_core, "Kernel I/O : Created ring for io_context %u (%p)\n", this.fd, &this); 115 115 } … … 220 220 cq.cqes = (struct io_uring_cqe *)(((intptr_t)cq.ring_ptr) + params.cq_off.cqes); 221 221 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); 239 237 240 238 // some paranoid checks -
libcfa/src/concurrency/io/types.hfa
r295dd61 r813dfd86 185 185 186 186 // 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 } 190 194 } -
libcfa/src/concurrency/kernel.cfa
r295dd61 r813dfd86 27 27 extern "C" { 28 28 #include <sys/eventfd.h> 29 #include <sys/uio.h>30 29 } 31 30 … … 35 34 #include "strstream.hfa" 36 35 #include "device/cpu.hfa" 37 #include "io/types.hfa"38 36 39 37 //Private includes … … 126 124 static void __wake_one(cluster * cltr); 127 125 128 static void idle_sleep(processor * proc, io_future_t & future, iovec & iov);129 126 static bool mark_idle (__cluster_proc_list & idles, processor & proc); 130 127 static void mark_awake(__cluster_proc_list & idles, processor & proc); … … 132 129 extern void __cfa_io_start( processor * ); 133 130 extern bool __cfa_io_drain( processor * ); 134 extern bool __cfa_io_flush( processor *, int min_comp);131 extern void __cfa_io_flush( processor * ); 135 132 extern void __cfa_io_stop ( processor * ); 136 133 static 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 #endif141 134 142 135 extern void __disable_interrupts_hard(); … … 154 147 /* paranoid */ verify( __preemption_enabled() ); 155 148 } 156 157 149 158 150 //============================================================================================= … … 170 162 verify(this); 171 163 172 io_future_t future; // used for idle sleep when io_uring is present173 future.self.ptr = 1p; // mark it as already fulfilled so we know if there is a pending request or not174 eventfd_t idle_val;175 iovec idle_iovec = { &idle_val, sizeof(idle_val) };176 177 164 __cfa_io_start( this ); 178 165 … … 208 195 209 196 if( !readyThread ) { 210 __cfa_io_flush( this, 0 ); 197 ready_schedule_lock(); 198 __cfa_io_flush( this ); 199 ready_schedule_unlock(); 211 200 212 201 readyThread = __next_thread_slow( this->cltr ); … … 239 228 } 240 229 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()); 293 233 } 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); 331 237 332 238 { 333 239 eventfd_t val; 334 ssize_t ret = read( this->idle _fd, &val, sizeof(val) );240 ssize_t ret = read( this->idle, &val, sizeof(val) ); 335 241 if(ret < 0) { 336 242 switch((int)errno) { … … 348 254 } 349 255 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 351 261 352 262 // We were woken up, remove self from idle … … 357 267 } 358 268 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 359 380 RUN_THREAD: 360 381 /* paranoid */ verify( ! __preemption_enabled() ); … … 371 392 372 393 if(this->io.pending && !this->io.dirty) { 373 __cfa_io_flush( this , 0);394 __cfa_io_flush( this ); 374 395 } 375 396 … … 381 402 382 403 __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 );388 404 } 389 405 … … 782 798 eventfd_t val; 783 799 val = 1; 784 eventfd_write( this->idle _fd, val );800 eventfd_write( this->idle, val ); 785 801 __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 #endif795 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 != EWOULDBLOCK805 case EWOULDBLOCK:806 #endif807 case EINTR:808 // No need to do anything special here, just assume it's a legitimate wake-up809 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 #endif821 #else822 // Do we already have a pending read823 if(available(future)) {824 // There is no pending read, we need to add one825 reset(future);826 827 __kernel_read(this, future, iov, this->idle_fd );828 }829 830 __cfa_io_flush( this, 1 );831 #endif832 802 } 833 803 … … 840 810 insert_first(this.idles, proc); 841 811 842 __atomic_store_n(&this.fd, proc.idle _fd, __ATOMIC_SEQ_CST);812 __atomic_store_n(&this.fd, proc.idle, __ATOMIC_SEQ_CST); 843 813 unlock( this ); 844 814 /* paranoid */ verify( ! __preemption_enabled() ); … … 857 827 { 858 828 int fd = 0; 859 if(!this.idles`isEmpty) fd = this.idles`first.idle _fd;829 if(!this.idles`isEmpty) fd = this.idles`first.idle; 860 830 __atomic_store_n(&this.fd, fd, __ATOMIC_SEQ_CST); 861 831 } -
libcfa/src/concurrency/kernel.hfa
r295dd61 r813dfd86 100 100 101 101 // Idle lock (kernel semaphore) 102 int idle _fd;102 int idle; 103 103 104 104 // Termination synchronisation (user semaphore) -
libcfa/src/concurrency/kernel/startup.cfa
r295dd61 r813dfd86 527 527 this.local_data = 0p; 528 528 529 this.idle _fd= eventfd(0, 0);530 if (idle _fd< 0) {529 this.idle = eventfd(0, 0); 530 if (idle < 0) { 531 531 abort("KERNEL ERROR: PROCESSOR EVENTFD - %s\n", strerror(errno)); 532 532 } … … 542 542 // Not a ctor, it just preps the destruction but should not destroy members 543 543 static void deinit(processor & this) { 544 close(this.idle _fd);544 close(this.idle); 545 545 } 546 546 -
libcfa/src/concurrency/kernel_private.hfa
r295dd61 r813dfd86 39 39 } 40 40 41 // Defines whether or not we *want* to use io_uring_enter as the idle_sleep blocking call42 #define CFA_WANT_IO_URING_IDLE43 44 // Defines whether or not we *can* use io_uring_enter as the idle_sleep blocking call45 #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_IDLE48 #endif49 #endif50 51 41 //----------------------------------------------------------------------------- 52 42 // Scheduler … … 159 149 __atomic_store_n(ll, (bool)false, __ATOMIC_RELEASE); 160 150 } 151 152 153 154 161 155 162 156 //----------------------------------------------------------------------- -
libcfa/src/device/cpu.cfa
r295dd61 r813dfd86 135 135 count++; 136 136 } 137 int ret = iterate_dir(path, lambda); 138 if(ret == ENOTDIR) return 0; 137 iterate_dir(path, lambda); 139 138 140 139 /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max); … … 160 159 161 160 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; 163 164 } 164 165 … … 225 226 226 227 struct raw_cache_instance { 227 idx_range_t range; // A text description of the cpus covered228 unsigned width; // The number of cpus covered229 unsigned char level; // the cache level228 idx_range_t range; 229 unsigned width; 230 unsigned char level; 230 231 // FIXME add at least size and type 231 232 }; … … 234 235 static void ^?{}(raw_cache_instance & this) { free(this.range);} 235 236 236 // Returns a 2D array of instances of size [cpu count][cache levels]237 // where cache level doesn't include instruction caches238 237 raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels) 239 238 { 240 239 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.243 240 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); 266 253 } 267 254 … … 346 333 unsigned cache_levels = 0; 347 334 unsigned llc = 0; 348 if (idxs != 0){335 { 349 336 unsigned char prev = -1u; 350 337 void first(unsigned idx, unsigned char level, const char * map, size_t len) { … … 429 416 cpu_info.llc_map = entries; 430 417 cpu_info.hthrd_count = cpus; 431 cpu_info.llc_count = map_cnt;432 418 } 433 419 -
libcfa/src/device/cpu.hfa
r295dd61 r813dfd86 23 23 24 24 struct cpu_info_t { 25 // Array of size [hthrd_count]25 // array of size [hthrd_count] 26 26 const cpu_map_entry_t * llc_map; 27 27 28 // Number of _hardware_ threads present in the system28 // Number of _hardware_ threads present in the system 29 29 size_t hthrd_count; 30 31 // Number of distinct last level caches32 size_t llc_count;33 30 }; 34 31 -
src/AST/Decl.hpp
r295dd61 r813dfd86 270 270 : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {} 271 271 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 ; } 276 276 277 277 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Expr.cpp
r295dd61 r813dfd86 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 15 17:00:00 2019 11 // Last Modified By : Andrew Beach12 // Created On : T ue Nov 30 14:23:00 202113 // Update Count : 711 // Last Modified By : Peter A. Buhr 12 // Created On : Thr Jun 13 13:38:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 141 141 /// The type of the address of a type. 142 142 /// 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 }; 146 146 } else { 147 return new PointerType ( type );147 return new PointerType{ type }; 148 148 } 149 149 } 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 152 AddressExpr::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; 164 158 } 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 } 167 168 } 168 169 } 169 170 } 170 171 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) :172 Expr( loc, addrExprType( loc, a ) ), arg( a )173 {}174 171 175 172 // --- LabelAddressExpr -
src/AST/Print.cpp
r295dd61 r813dfd86 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Print.cpp -- Print an AST (or sub-tree) to a stream.7 // Print.cpp -- 8 8 // 9 9 // Author : Thierry Delisle -
src/AST/Print.hpp
r295dd61 r813dfd86 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Print.hpp -- Print an AST (or sub-tree) to a stream.7 // Print.hpp -- 8 8 // 9 9 // Author : Thierry Delisle … … 35 35 template< typename Coll > 36 36 void 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 } 44 44 } 45 45 -
src/Concurrency/Keywords.cc
r295dd61 r813dfd86 979 979 // If this is the destructor for a monitor it must be mutex 980 980 if(isDtor) { 981 // This reflects MutexKeyword::validate, except does not produce an error.982 981 Type* ty = decl->get_functionType()->get_parameters().front()->get_type(); 983 982 -
src/Concurrency/Keywords.h
r295dd61 r813dfd86 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Keywords.h -- Implement concurrency constructs from their keywords.7 // Keywords.h -- 8 8 // 9 9 // Author : Thierry Delisle … … 19 19 20 20 class Declaration; 21 namespace ast {22 class TranslationUnit;23 }24 21 25 22 namespace Concurrency { … … 27 24 void implementMutexFuncs( std::list< Declaration * > & translationUnit ); 28 25 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 );36 26 }; 37 27 -
src/Concurrency/module.mk
r295dd61 r813dfd86 15 15 ############################################################################### 16 16 17 SRC_CONCURRENCY = \ 18 Concurrency/KeywordsNew.cpp \ 19 Concurrency/Keywords.cc 17 SRC += Concurrency/Keywords.cc Concurrency/Keywords.h Concurrency/Waitfor.cc Concurrency/Waitfor.h 18 SRCDEMANGLE += Concurrency/Keywords.cc 20 19 21 SRC += $(SRC_CONCURRENCY) \22 Concurrency/Keywords.h \23 Concurrency/Waitfor.cc \24 Concurrency/Waitfor.h25 26 SRCDEMANGLE += $(SRC_CONCURRENCY)27 -
src/InitTweak/InitTweak.cc
r295dd61 r813dfd86 9 9 // Author : Rob Schluntz 10 10 // Created On : Fri May 13 11:26:36 2016 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Nov 19 19:22:00202113 // Update Count : 1 911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 16 20:57:22 2021 13 // Update Count : 18 14 14 // 15 15 … … 540 540 } 541 541 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 552 542 ObjectDecl * getParamThis( FunctionType * ftype ) { 553 543 assertf( ftype, "getParamThis: nullptr ftype" ); -
src/InitTweak/InitTweak.h
r295dd61 r813dfd86 10 10 // Created On : Fri May 13 11:26:36 2016 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Nov 19 14:18:00 202113 // Update Count : 712 // Last Modified On : Fri Jul 19 14:18:00 2019 13 // Update Count : 6 14 14 // 15 15 … … 35 35 /// returns the base type of the first parameter to a constructor/destructor/assignment function 36 36 Type * getTypeofThis( FunctionType * ftype ); 37 const ast::Type * getTypeofThis( const ast::FunctionType * ftype );38 37 39 38 /// returns the first parameter of a constructor/destructor/assignment function -
src/Validate/module.mk
r295dd61 r813dfd86 16 16 17 17 SRC_VALIDATE = \ 18 Validate/CompoundLiteral.cpp \19 Validate/CompoundLiteral.hpp \20 18 Validate/HandleAttributes.cc \ 21 19 Validate/HandleAttributes.h \ -
src/main.cc
r295dd61 r813dfd86 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Nov 30 10:25:00 202113 // Update Count : 65 912 // Last Modified On : Fri Nov 12 11:06:00 2021 13 // Update Count : 658 14 14 // 15 15 … … 50 50 #include "Common/UnimplementedError.h" // for UnimplementedError 51 51 #include "Common/utility.h" // for deleteAll, filter, printAll 52 #include "Concurrency/Keywords.h" // for implementMutex, implement...53 52 #include "Concurrency/Waitfor.h" // for generateWaitfor 54 53 #include "ControlStruct/ExceptDecl.h" // for translateExcept … … 74 73 #include "Tuples/Tuples.h" // for expandMemberTuples, expan... 75 74 #include "Validate/FindSpecialDecls.h" // for findGlobalDecls 76 #include "Validate/CompoundLiteral.hpp" // for handleCompoundLiterals77 75 #include "Validate/InitializerLength.hpp" // for setLengthFromInitializer 78 76 #include "Validate/LabelAddressFixer.hpp" // for fixLabelAddresses … … 327 325 PASS( "Validate-C", SymTab::validate_C( translationUnit ) ); 328 326 PASS( "Validate-D", SymTab::validate_D( translationUnit ) ); 327 PASS( "Validate-E", SymTab::validate_E( translationUnit ) ); 329 328 330 329 CodeTools::fillLocations( translationUnit ); … … 339 338 forceFillCodeLocations( transUnit ); 340 339 341 PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) );342 PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) );343 PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) );344 340 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) ); 345 341 PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) ); … … 406 402 translationUnit = convert( move( transUnit ) ); 407 403 } else { 408 PASS( "Validate-E", SymTab::validate_E( translationUnit ) );409 404 PASS( "Validate-F", SymTab::validate_F( translationUnit ) ); 410 405 -
tests/pybin/tools.py
r295dd61 r813dfd86 374 374 375 375 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" 377 377 378 378 try:
Note:
See TracChangeset
for help on using the changeset viewer.