Changes in / [6c53a93:e2853eb]
- Files:
-
- 11 deleted
- 31 edited
-
benchmark/io/http/main.cfa (modified) (1 diff)
-
benchmark/io/http/protocol.cfa (modified) (5 diffs)
-
benchmark/io/http/worker.cfa (modified) (1 diff)
-
driver/as.cc (modified) (3 diffs)
-
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) (16 diffs)
-
libcfa/src/concurrency/kernel.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/kernel_private.hfa (modified) (4 diffs)
-
libcfa/src/device/cpu.cfa (modified) (15 diffs)
-
libcfa/src/device/cpu.hfa (modified) (1 diff)
-
libcfa/src/heap.cfa (modified) (28 diffs)
-
libcfa/src/stdlib.cfa (modified) (2 diffs)
-
libcfa/src/stdlib.hfa (modified) (5 diffs)
-
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/.expect/random.x64.txt (modified) (1 diff)
-
tests/.expect/random.x86.txt (modified) (1 diff)
-
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
-
benchmark/io/http/main.cfa
r6c53a93 re2853eb 150 150 if(errno == EADDRINUSE) { 151 151 if(waited == 0) { 152 if(!options.interactive) abort | "Port already in use in non-interactive mode. Aborting";153 152 sout | "Waiting for port"; 154 153 } else { -
benchmark/io/http/protocol.cfa
r6c53a93 re2853eb 332 332 wait(this.f); 333 333 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 334 340 // Something failed? 335 341 if(this.f.result < 0) { … … 345 351 return error(this.res, -ECONNRESET); 346 352 } 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);353 353 } 354 354 … … 401 401 wait(this.f); 402 402 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 403 409 // Something failed? 404 410 if(this.f.result < 0) { … … 414 420 return error(this, -ECONNRESET); 415 421 } 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);422 422 } 423 423 … … 544 544 const char * original_http_msgs[] = { 545 545 "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\n Connection: 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", 547 547 "HTTP/1.1 400 Bad Request\nServer: HttpForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 548 548 "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 18 18 void ?{}( Worker & this ) { 19 19 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 }; 21 21 options.clopts.thrd_cnt[cli]++; 22 22 this.pipe[0] = -1; -
driver/as.cc
r6c53a93 re2853eb 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // as.c -- map assembler file, scan for debug information , then language code, and skip N lines forward to code. If8 // 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. 9 9 // 10 10 // Author : Peter A. Buhr 11 11 // Created On : Wed Aug 1 10:49:42 2018 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Wed Dec 8 07:56:12 202114 // Update Count : 13613 // Last Modified On : Sat Sep 8 08:40:16 2018 14 // Update Count : 97 15 15 // 16 16 … … 18 18 #include <cstdlib> // exit 19 19 #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> 23 22 #include <sys/mman.h> // mmap 23 #include <string.h> 24 24 25 25 //#define __DEBUG_H__ 26 27 #ifdef __DEBUG_H__ 28 #include <iostream> 29 using namespace std; 30 #endif // __DEBUG_H__ 26 31 27 32 int main( const int argc, const char * argv[] ) { 28 33 #ifdef __DEBUG_H__ 29 34 for ( int i = 0; i < argc; i += 1 ) { 30 fprintf( stderr, "%s\n", argv[i] );35 cerr << argv[i] << endl; 31 36 } // for 32 37 #endif // __DEBUG_H__ … … 43 48 if ( start == (void *)-1 ) { perror( "mmap" ); exit( EXIT_FAILURE ); }; 44 49 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 ); }; 47 53 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 70 57 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'; 74 65 } // if 75 66 -
libcfa/src/Makefile.am
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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 static bool mark_idle (__cluster_proc_list & idles, processor & proc); 126 static void mark_idle (__cluster_proc_list & idles, processor & proc); 130 127 static void mark_awake(__cluster_proc_list & idles, processor & proc); 128 static [unsigned idle, unsigned total, * processor] query_idles( & __cluster_proc_list idles ); 131 129 132 130 extern void __cfa_io_start( processor * ); 133 131 extern bool __cfa_io_drain( processor * ); 134 extern bool __cfa_io_flush( processor *, int min_comp);132 extern void __cfa_io_flush( processor * ); 135 133 extern void __cfa_io_stop ( processor * ); 136 134 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 135 142 136 extern void __disable_interrupts_hard(); … … 154 148 /* paranoid */ verify( __preemption_enabled() ); 155 149 } 156 157 150 158 151 //============================================================================================= … … 170 163 verify(this); 171 164 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 165 __cfa_io_start( this ); 178 166 … … 208 196 209 197 if( !readyThread ) { 210 __cfa_io_flush( this, 0 ); 198 ready_schedule_lock(); 199 __cfa_io_flush( this ); 200 ready_schedule_unlock(); 211 201 212 202 readyThread = __next_thread_slow( this->cltr ); … … 223 213 224 214 // Push self to idle stack 225 if(!mark_idle(this->cltr->procs, * this)) continue MAIN_LOOP;215 mark_idle(this->cltr->procs, * this); 226 216 227 217 // Confirm the ready-queue is empty … … 239 229 } 240 230 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()); 293 234 } 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); 331 238 332 239 { 333 240 eventfd_t val; 334 ssize_t ret = read( this->idle _fd, &val, sizeof(val) );241 ssize_t ret = read( this->idle, &val, sizeof(val) ); 335 242 if(ret < 0) { 336 243 switch((int)errno) { … … 348 255 } 349 256 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 351 262 352 263 // We were woken up, remove self from idle … … 357 268 } 358 269 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 359 381 RUN_THREAD: 360 382 /* paranoid */ verify( ! __preemption_enabled() ); … … 371 393 372 394 if(this->io.pending && !this->io.dirty) { 373 __cfa_io_flush( this , 0);395 __cfa_io_flush( this ); 374 396 } 375 397 … … 381 403 382 404 __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 405 } 389 406 … … 749 766 750 767 // 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); 752 772 753 773 // If no one is sleeping, we are done 754 if( fd== 0 ) return;774 if( idle == 0 ) return; 755 775 756 776 // We found a processor, wake it up 757 777 eventfd_t val; 758 778 val = 1; 759 eventfd_write( fd, val );779 eventfd_write( p->idle, val ); 760 780 761 781 #if !defined(__CFA_NO_STATISTICS__) … … 782 802 eventfd_t val; 783 803 val = 1; 784 eventfd_write( this->idle _fd, val );804 eventfd_write( this->idle, val ); 785 805 __enable_interrupts_checked(); 786 806 } 787 807 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; 808 static void mark_idle(__cluster_proc_list & this, processor & proc) { 809 /* paranoid */ verify( ! __preemption_enabled() ); 810 lock( this ); 837 811 this.idle++; 838 812 /* paranoid */ verify( this.idle <= this.total ); 839 813 remove(proc); 840 814 insert_first(this.idles, proc); 841 842 __atomic_store_n(&this.fd, proc.idle_fd, __ATOMIC_SEQ_CST);843 815 unlock( this ); 844 816 /* paranoid */ verify( ! __preemption_enabled() ); 845 846 return true;847 817 } 848 818 … … 854 824 remove(proc); 855 825 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 863 826 unlock( this ); 827 /* paranoid */ verify( ! __preemption_enabled() ); 828 } 829 830 static [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() ); 864 847 /* paranoid */ verify( ! __preemption_enabled() ); 865 848 } … … 923 906 if(head == tail) return false; 924 907 #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(); 928 911 #else 929 912 ret = __cfa_io_drain( proc ); 930 #endif913 #endif 931 914 #endif 932 915 return ret; -
libcfa/src/concurrency/kernel.hfa
r6c53a93 re2853eb 100 100 101 101 // Idle lock (kernel semaphore) 102 int idle _fd;102 int idle; 103 103 104 104 // Termination synchronisation (user semaphore) … … 195 195 struct __cluster_proc_list { 196 196 // 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; 201 198 202 199 // Total number of processors -
libcfa/src/concurrency/kernel/startup.cfa
r6c53a93 re2853eb 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 … … 584 584 // Cluster 585 585 static void ?{}(__cluster_proc_list & this) { 586 this. fd= 0;586 this.lock = 0; 587 587 this.idle = 0; 588 588 this.total = 0; -
libcfa/src/concurrency/kernel_private.hfa
r6c53a93 re2853eb 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 //----------------------------------------------------------------------- … … 274 268 ready_schedule_lock(); 275 269 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() ); 299 282 } 300 283 … … 302 285 /* paranoid */ verify( ! __preemption_enabled() ); 303 286 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 ); 305 290 306 291 // Release the global lock, which we acquired when locking -
libcfa/src/device/cpu.cfa
r6c53a93 re2853eb 30 30 #include <fcntl.h> 31 31 } 32 33 #include "algorithms/range_iterator.hfa"34 32 35 33 // search a string for character 'character' but looking atmost at len … … 137 135 count++; 138 136 } 139 int ret = iterate_dir(path, lambda); 140 if(ret == ENOTDIR) return 0; 137 iterate_dir(path, lambda); 141 138 142 139 /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max); … … 146 143 147 144 // Count number of cpus in the system 148 static [int, const char *]count_cpus(void) {145 static int count_cpus(void) { 149 146 const char * fpath = "/sys/devices/system/cpu/online"; 150 147 int fd = open(fpath, 0, O_RDONLY); … … 162 159 163 160 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; 165 164 } 166 165 … … 227 226 228 227 struct raw_cache_instance { 229 idx_range_t range; // A text description of the cpus covered230 unsigned width; // The number of cpus covered231 unsigned char level; // the cache level228 idx_range_t range; 229 unsigned width; 230 unsigned char level; 232 231 // FIXME add at least size and type 233 232 }; … … 236 235 static void ^?{}(raw_cache_instance & this) { free(this.range);} 237 236 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) 237 raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels) 241 238 { 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) { 247 241 raw[i] = alloc(cache_levels); 248 242 void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) { … … 269 263 270 264 // returns an allocate list of all the different distinct last level caches 271 static [*llc_map_t, size_t cnt] distinct_llcs( idx_range_tcpus, unsigned llc_idx, raw_cache_instance ** raw) {265 static [*llc_map_t, size_t cnt] distinct_llcs(unsigned cpus, unsigned llc_idx, raw_cache_instance ** raw) { 272 266 // Allocate at least one element 273 267 llc_map_t* ranges = alloc(); 274 268 size_t range_cnt = 1; 275 269 276 RangeIter rc = { cpus };277 __attribute__((unused)) bool ret =278 moveNext(rc);279 /* paranoid */ verify( ret );280 /* paranoid */ verify( rc.com >= 0 );281 282 270 // Initialize with element 0 283 ranges->raw = &raw[ rc.com][llc_idx];271 ranges->raw = &raw[0][llc_idx]; 284 272 ranges->count = 0; 285 273 ranges->start = -1u; 286 274 287 275 // Go over all other cpus 288 CPU_LOOP: while(moveNext(rc)) { 289 unsigned i = rc.com; 276 CPU_LOOP: for(i; 1~cpus) { 290 277 // Check if the range is already there 291 278 raw_cache_instance * candidate = &raw[i][llc_idx]; … … 317 304 } 318 305 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; 306 static [[]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) { 325 310 pairings[i].cpu = i; 326 311 idx_range_t want = raw[i][0].range; … … 342 327 extern "C" { 343 328 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(); 358 330 int idxs = count_cache_indexes(); 359 331 … … 361 333 unsigned cache_levels = 0; 362 334 unsigned llc = 0; 363 if (idxs != 0){335 { 364 336 unsigned char prev = -1u; 365 337 void first(unsigned idx, unsigned char level, const char * map, size_t len) { … … 373 345 374 346 // 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); 376 348 377 349 // Find number of distinct cache instances … … 390 362 width2 += maps[i].raw->width; 391 363 } 392 verify(width1 == cpus _c);393 verify(width2 == cpus _c);364 verify(width1 == cpus); 365 verify(width2 == cpus); 394 366 } 395 367 #endif 396 368 397 369 // 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); 399 371 400 372 // Sort by cache instance 401 qsort(pairings, cpus _c);373 qsort(pairings, cpus); 402 374 403 375 { 404 376 unsigned it = 0; 405 RangeIter rc = { cpus }; 406 while(moveNext(rc)) { 407 unsigned i = rc.com; 377 for(i; cpus) { 408 378 unsigned llc_id = pairings[i].id; 409 379 if(maps[llc_id].start == -1u) { … … 414 384 } 415 385 } 416 /* paranoid */ verify(it == cpus _c);386 /* paranoid */ verify(it == cpus); 417 387 } 418 388 419 389 // 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) { 426 393 /* paranoid */ verify(pairings[i].id < map_cnt); 427 394 unsigned c = pairings[i].cpu; … … 439 406 free(pairings); 440 407 441 for(i; cpus _c) {442 if( raw[i] )for(j; cache_levels) {408 for(i; cpus) { 409 for(j; cache_levels) { 443 410 ^(raw[i][j]){}; 444 411 } … … 448 415 449 416 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; 452 418 } 453 419 -
libcfa/src/device/cpu.hfa
r6c53a93 re2853eb 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 -
libcfa/src/heap.cfa
r6c53a93 re2853eb 10 10 // Created On : Tue Dec 19 21:58:35 2017 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 2 23:29:41 202213 // Update Count : 10 5812 // Last Modified On : Mon Aug 9 19:03:02 2021 13 // Update Count : 1040 14 14 // 15 15 … … 263 263 #ifdef __STATISTICS__ 264 264 // 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;265 static unsigned int malloc_zero_calls, malloc_calls; 266 static unsigned long long int malloc_storage; 267 static unsigned int aalloc_zero_calls, aalloc_calls; 268 static unsigned long long int aalloc_storage; 269 static unsigned int calloc_zero_calls, calloc_calls; 270 static unsigned long long int calloc_storage; 271 static unsigned int memalign_zero_calls, memalign_calls; 272 static unsigned long long int memalign_storage; 273 static unsigned int amemalign_zero_calls, amemalign_calls; 274 static unsigned long long int amemalign_storage; 275 static unsigned int cmemalign_zero_calls, cmemalign_calls; 276 static unsigned long long int cmemalign_storage; 277 static unsigned int resize_zero_calls, resize_calls; 278 static unsigned long long int resize_storage; 279 static unsigned int realloc_zero_calls, realloc_calls; 280 static unsigned long long int realloc_storage; 281 static unsigned int free_zero_calls, free_calls; 282 static unsigned long long int free_storage; 283 283 static unsigned int mmap_calls; 284 static unsigned long long int mmap_storage _request, mmap_storage_alloc;284 static unsigned long long int mmap_storage; 285 285 static unsigned int munmap_calls; 286 static unsigned long long int munmap_storage _request, munmap_storage_alloc;286 static unsigned long long int munmap_storage; 287 287 static unsigned int sbrk_calls; 288 288 static unsigned long long int sbrk_storage; … … 294 294 char helpText[1024]; 295 295 __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 " sbrkcalls %'u; storage %'llu bytes\n"307 " m map 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 m map_calls, mmap_storage_request, mmap_storage_alloc,320 munmap_calls, munmap_storage_request, munmap_storage_alloc296 "\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 321 321 ); 322 322 } // printStats … … 329 329 "<sizes>\n" 330 330 "</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" 340 342 "<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"343 343 "</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 m map_calls, mmap_storage_request, mmap_storage_alloc,355 munmap_calls, munmap_storage_request, munmap_storage_alloc344 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 356 356 ); 357 357 __cfaabi_bits_write( fileno( stream ), helpText, len ); // ensures all bytes written or exit … … 577 577 #ifdef __STATISTICS__ 578 578 __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 ); 581 580 #endif // __STATISTICS__ 582 581 … … 627 626 #ifdef __STATISTICS__ 628 627 __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 ); 631 629 #endif // __STATISTICS__ 632 630 if ( munmap( header, size ) == -1 ) { … … 644 642 #ifdef __STATISTICS__ 645 643 __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 ); 648 645 #endif // __STATISTICS__ 649 646 … … 822 819 if ( likely( size > 0 ) ) { 823 820 __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 ); 825 822 } else { 826 __atomic_add_fetch( &malloc_ 0_calls, 1, __ATOMIC_SEQ_CST );823 __atomic_add_fetch( &malloc_zero_calls, 1, __ATOMIC_SEQ_CST ); 827 824 } // if 828 825 #endif // __STATISTICS__ … … 838 835 if ( likely( size > 0 ) ) { 839 836 __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 ); 841 838 } else { 842 __atomic_add_fetch( &aalloc_ 0_calls, 1, __ATOMIC_SEQ_CST );839 __atomic_add_fetch( &aalloc_zero_calls, 1, __ATOMIC_SEQ_CST ); 843 840 } // if 844 841 #endif // __STATISTICS__ … … 853 850 if ( unlikely( size ) == 0 ) { // 0 BYTE ALLOCATION RETURNS NULL POINTER 854 851 #ifdef __STATISTICS__ 855 __atomic_add_fetch( &calloc_ 0_calls, 1, __ATOMIC_SEQ_CST );852 __atomic_add_fetch( &calloc_zero_calls, 1, __ATOMIC_SEQ_CST ); 856 853 #endif // __STATISTICS__ 857 854 return 0p; … … 859 856 #ifdef __STATISTICS__ 860 857 __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 ); 862 859 #endif // __STATISTICS__ 863 860 … … 894 891 if ( unlikely( size == 0 ) ) { // special cases 895 892 #ifdef __STATISTICS__ 896 __atomic_add_fetch( &resize_ 0_calls, 1, __ATOMIC_SEQ_CST );893 __atomic_add_fetch( &resize_zero_calls, 1, __ATOMIC_SEQ_CST ); 897 894 #endif // __STATISTICS__ 898 895 free( oaddr ); … … 905 902 if ( unlikely( oaddr == 0p ) ) { 906 903 #ifdef __STATISTICS__ 907 __atomic_add_fetch( &resize_storage _request, size, __ATOMIC_SEQ_CST );904 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST ); 908 905 #endif // __STATISTICS__ 909 906 return mallocNoStats( size ); … … 924 921 925 922 #ifdef __STATISTICS__ 926 __atomic_add_fetch( &resize_storage _request, size, __ATOMIC_SEQ_CST );923 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST ); 927 924 #endif // __STATISTICS__ 928 925 … … 939 936 if ( unlikely( size == 0 ) ) { // special cases 940 937 #ifdef __STATISTICS__ 941 __atomic_add_fetch( &realloc_ 0_calls, 1, __ATOMIC_SEQ_CST );938 __atomic_add_fetch( &realloc_zero_calls, 1, __ATOMIC_SEQ_CST ); 942 939 #endif // __STATISTICS__ 943 940 free( oaddr ); … … 950 947 if ( unlikely( oaddr == 0p ) ) { 951 948 #ifdef __STATISTICS__ 952 __atomic_add_fetch( &realloc_storage _request, size, __ATOMIC_SEQ_CST );949 __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST ); 953 950 #endif // __STATISTICS__ 954 951 return mallocNoStats( size ); … … 972 969 973 970 #ifdef __STATISTICS__ 974 __atomic_add_fetch( &realloc_storage _request, size, __ATOMIC_SEQ_CST );971 __atomic_add_fetch( &realloc_storage, size, __ATOMIC_SEQ_CST ); 975 972 #endif // __STATISTICS__ 976 973 … … 1003 1000 if ( likely( size > 0 ) ) { 1004 1001 __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 ); 1006 1003 } else { 1007 __atomic_add_fetch( &memalign_ 0_calls, 1, __ATOMIC_SEQ_CST );1004 __atomic_add_fetch( &memalign_zero_calls, 1, __ATOMIC_SEQ_CST ); 1008 1005 } // if 1009 1006 #endif // __STATISTICS__ … … 1019 1016 if ( likely( size > 0 ) ) { 1020 1017 __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 ); 1022 1019 } else { 1023 __atomic_add_fetch( &cmemalign_ 0_calls, 1, __ATOMIC_SEQ_CST );1020 __atomic_add_fetch( &cmemalign_zero_calls, 1, __ATOMIC_SEQ_CST ); 1024 1021 } // if 1025 1022 #endif // __STATISTICS__ … … 1034 1031 if ( unlikely( size ) == 0 ) { // 0 BYTE ALLOCATION RETURNS NULL POINTER 1035 1032 #ifdef __STATISTICS__ 1036 __atomic_add_fetch( &cmemalign_ 0_calls, 1, __ATOMIC_SEQ_CST );1033 __atomic_add_fetch( &cmemalign_zero_calls, 1, __ATOMIC_SEQ_CST ); 1037 1034 #endif // __STATISTICS__ 1038 1035 return 0p; … … 1040 1037 #ifdef __STATISTICS__ 1041 1038 __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 ); 1043 1040 #endif // __STATISTICS__ 1044 1041 … … 1104 1101 if ( unlikely( addr == 0p ) ) { // special case 1105 1102 #ifdef __STATISTICS__ 1106 __atomic_add_fetch( &free_ null_calls, 1, __ATOMIC_SEQ_CST );1103 __atomic_add_fetch( &free_zero_calls, 1, __ATOMIC_SEQ_CST ); 1107 1104 #endif // __STATISTICS__ 1108 1105 … … 1283 1280 if ( unlikely( size == 0 ) ) { // special cases 1284 1281 #ifdef __STATISTICS__ 1285 __atomic_add_fetch( &resize_ 0_calls, 1, __ATOMIC_SEQ_CST );1282 __atomic_add_fetch( &resize_zero_calls, 1, __ATOMIC_SEQ_CST ); 1286 1283 #endif // __STATISTICS__ 1287 1284 free( oaddr ); … … 1297 1294 #ifdef __STATISTICS__ 1298 1295 __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 ); 1300 1297 #endif // __STATISTICS__ 1301 1298 return memalignNoStats( nalign, size ); … … 1332 1329 1333 1330 #ifdef __STATISTICS__ 1334 __atomic_add_fetch( &resize_storage _request, size, __ATOMIC_SEQ_CST );1331 __atomic_add_fetch( &resize_storage, size, __ATOMIC_SEQ_CST ); 1335 1332 #endif // __STATISTICS__ 1336 1333 … … 1345 1342 if ( unlikely( size == 0 ) ) { // special cases 1346 1343 #ifdef __STATISTICS__ 1347 __atomic_add_fetch( &realloc_ 0_calls, 1, __ATOMIC_SEQ_CST );1344 __atomic_add_fetch( &realloc_zero_calls, 1, __ATOMIC_SEQ_CST ); 1348 1345 #endif // __STATISTICS__ 1349 1346 free( oaddr ); … … 1359 1356 #ifdef __STATISTICS__ 1360 1357 __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 ); 1362 1359 #endif // __STATISTICS__ 1363 1360 return memalignNoStats( nalign, size ); … … 1383 1380 #ifdef __STATISTICS__ 1384 1381 __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 ); 1386 1383 #endif // __STATISTICS__ 1387 1384 -
libcfa/src/stdlib.cfa
r6c53a93 re2853eb 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 3 09:36:27 202213 // Update Count : 5 1912 // Last Modified On : Thu Nov 12 07:46:09 2020 13 // Update Count : 503 14 14 // 15 15 … … 221 221 //--------------------------------------- 222 222 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; } 223 bool threading_enabled(void) __attribute__((weak)) { 224 return false; 225 } 253 226 254 227 // Local Variables: // -
libcfa/src/stdlib.hfa
r6c53a93 re2853eb 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 2 22:53:57 202213 // Update Count : 5 9412 // Last Modified On : Tue Apr 20 21:20:03 2021 13 // Update Count : 575 14 14 // 15 15 … … 43 43 //--------------------------------------- 44 44 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 45 50 static inline forall( T & | sized(T) ) { 46 51 // CFA safe equivalents, i.e., implicit size specification 47 52 48 53 T * malloc( void ) { 49 if ( _Alignof(T) <= libAlign() ) return (T *) malloc(sizeof(T) ); // C allocation54 if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C allocation 50 55 else return (T *)memalign( _Alignof(T), sizeof(T) ); 51 56 } // malloc 52 57 53 58 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 ); 56 60 } // aalloc 57 61 58 62 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 ); 61 64 } // calloc 62 65 63 66 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 resize65 else return (T *) resize( (void *)ptr, _Alignof(T), size ); // CFA resize67 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 66 69 } // resize 67 70 68 71 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 realloc70 else return (T *) realloc( (void *)ptr, _Alignof(T), size ); // CFA realloc72 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 71 74 } // realloc 72 75 … … 166 169 return ret; 167 170 } 168 S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved169 S_fill(T) ?`fill ( T * a ) { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved170 171 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 }; } 171 173 S_fill(T) ?`fill ( T a[], size_t nmemb ) { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; } 172 174 … … 360 362 361 363 static 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) 364 366 unsigned long int random( void ) { return lrand48(); } 365 367 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) 367 369 368 370 char random( void ) { return (unsigned long int)random(); } … … 385 387 //--------------------------------------- 386 388 387 struct PRNG {388 uint32_t callcnt; // call count389 uint32_t seed; // current seed390 uint32_t state; // random state391 }; // PRNG392 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 seed396 void ?{}( PRNG & prng ) { set_seed( prng, rdtscl() ); } // random seed397 void ?{}( PRNG & prng, uint32_t seed ) { set_seed( prng, seed ); } // fixed seed398 uint32_t get_seed( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } // get seed399 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 } // distribution403 404 extern void set_seed( uint32_t seed ); // set per thread seed405 extern uint32_t get_seed(); // get seed406 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 } // distribution413 414 //---------------------------------------415 416 389 extern bool threading_enabled( void ) OPTIONAL_THREAD; 417 390 -
src/AST/Decl.hpp
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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
r6c53a93 re2853eb 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/.expect/random.x64.txt
r6c53a93 re2853eb 1 1 õ 2 2 = 3 K 3 V 4 4 -911259971 5 5 6 6 11 6 -4 7 7 1232105397 8 8 0 9 1 19 18 10 10 -914096085 11 11 1 12 20 12 15 13 13 2077092859 14 14 1 15 1 215 11 16 16 0.677254 17 17 0.678106775246139 -
tests/.expect/random.x86.txt
r6c53a93 re2853eb 1 1 õ 2 2 = 3 K 3 V 4 4 -911259971 5 5 6 6 11 6 -4 7 7 1232105397 8 8 0 9 1 19 18 10 10 -914096085 11 11 1 12 20 12 15 13 13 2077092859 14 14 1 15 1 215 11 16 16 0.677254 17 17 0.678106775246139 -
tests/pybin/tools.py
r6c53a93 re2853eb 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.