Changeset 5235d49
- Timestamp:
- Jan 1, 2022, 11:14:35 AM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, master, pthread-emulation, qualifiedEnum
- Children:
- 12c1eef
- Parents:
- 7770cc8 (diff), db1ebed (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 11 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
driver/as.cc
r7770cc8 r5235d49 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // as.c -- map assembler file, scan for debug information . If found, expand file by one character and insert Cforall8 // language code on the N line from the start of the debug information.7 // as.c -- map assembler file, scan for debug information, then language code, and skip N lines forward to code. If 8 // code is C dialect, possibly expand file by one character, and replace with Cforall language code. 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 : Sat Sep 8 08:40:16 201814 // Update Count : 9713 // Last Modified On : Wed Dec 8 07:56:12 2021 14 // Update Count : 136 15 15 // 16 16 … … 18 18 #include <cstdlib> // exit 19 19 #include <fcntl.h> // open 20 #include <unistd.h> 21 #include <sys/stat.h> 20 #include <cstring> // strstr, memmove 21 #include <unistd.h> // ftruncate,execvp 22 #include <sys/stat.h> // fstat 22 23 #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__31 26 32 27 int main( const int argc, const char * argv[] ) { 33 28 #ifdef __DEBUG_H__ 34 29 for ( int i = 0; i < argc; i += 1 ) { 35 cerr << argv[i] << endl;30 fprintf( stderr, "%s\n", argv[i] ); 36 31 } // for 37 32 #endif // __DEBUG_H__ … … 48 43 if ( start == (void *)-1 ) { perror( "mmap" ); exit( EXIT_FAILURE ); }; 49 44 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 ); }; 45 char * dcursor; 46 if ( (dcursor = strstr( start, ".Ldebug_info0:" ) ) ) { // debug information ? 53 47 54 for ( int i = 0; i < 8; i += 1 ) { // move N (magic) lines forward 55 cursor = strstr( cursor, "\n" ) + 1; 56 } // for 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 57 70 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'; 71 *(cursor - 1) = '2'; // replace C89/C/C99/C11 language code with CFA code 72 *cursor = '5'; 73 } // if 65 74 } // if 66 75 -
libcfa/src/Makefile.am
r7770cc8 r5235d49 85 85 time.hfa \ 86 86 bits/weakso_locks.hfa \ 87 algorithms/range_iterator.hfa \ 87 88 containers/maybe.hfa \ 88 89 containers/pair.hfa \ -
libcfa/src/concurrency/io.cfa
r7770cc8 r5235d49 33 33 #include <sys/syscall.h> 34 34 #include <sys/eventfd.h> 35 #include <sys/uio.h> 35 36 36 37 #include <linux/io_uring.h> … … 133 134 } 134 135 135 bool __cfa_io_flush( processor * proc, bool wait) {136 bool __cfa_io_flush( processor * proc, int min_comp ) { 136 137 /* paranoid */ verify( ! __preemption_enabled() ); 137 138 /* paranoid */ verify( proc ); … … 144 145 145 146 __STATS__( true, io.calls.flush++; ) 146 int ret = syscall( __NR_io_uring_enter, ctx.fd, ctx.sq.to_submit, wait ? 1 : 0,0, (sigset_t *)0p, _NSIG / 8);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); 147 148 if( ret < 0 ) { 148 149 switch((int)errno) { … … 302 303 ctx->proc->io.dirty = true; 303 304 if(sq.to_submit > 30 || !lazy) { 304 __cfa_io_flush( ctx->proc, false);305 __cfa_io_flush( ctx->proc, 0 ); 305 306 } 306 307 } … … 502 503 } 503 504 504 #if defined( IO_URING_IDLE)505 bool __kernel_read(processor * proc, io_future_t & future, char buf[], int fd) {505 #if defined(CFA_WITH_IO_URING_IDLE) 506 bool __kernel_read(processor * proc, io_future_t & future, iovec & iov, int fd) { 506 507 $io_context * ctx = proc->io.ctx; 507 508 /* paranoid */ verify( ! __preemption_enabled() ); … … 518 519 __fill( &sqe, 1, &idx, ctx ); 519 520 520 sqe->opcode = IORING_OP_READ;521 521 sqe->user_data = (uintptr_t)&future; 522 522 sqe->flags = 0; 523 sqe->fd = fd; 524 sqe->off = 0; 523 525 sqe->ioprio = 0; 524 sqe->fd = 0;525 sqe->off = 0;526 526 sqe->fsync_flags = 0; 527 527 sqe->__pad2[0] = 0; 528 528 sqe->__pad2[1] = 0; 529 529 sqe->__pad2[2] = 0; 530 sqe->addr = (uintptr_t)buf; 531 sqe->len = sizeof(uint64_t); 530 531 #if defined(CFA_HAVE_IORING_OP_READ) 532 sqe->opcode = IORING_OP_READ; 533 sqe->addr = (uint64_t)iov.iov_base; 534 sqe->len = iov.iov_len; 535 #elif defined(CFA_HAVE_READV) && defined(CFA_HAVE_IORING_OP_READV) 536 sqe->opcode = IORING_OP_READV; 537 sqe->addr = (uintptr_t)&iov; 538 sqe->len = 1; 539 #else 540 #error CFA_WITH_IO_URING_IDLE but none of CFA_HAVE_READV, CFA_HAVE_IORING_OP_READV or CFA_HAVE_IORING_OP_READ defined 541 #endif 532 542 533 543 asm volatile("": : :"memory"); -
libcfa/src/concurrency/io/setup.cfa
r7770cc8 r5235d49 32 32 33 33 void __cfa_io_start( processor * proc ) {} 34 bool __cfa_io_flush( processor * proc, bool) {}34 bool __cfa_io_flush( processor * proc, int ) {} 35 35 void __cfa_io_stop ( processor * proc ) {} 36 36 … … 220 220 cq.cqes = (struct io_uring_cqe *)(((intptr_t)cq.ring_ptr) + params.cq_off.cqes); 221 221 222 #if !defined( IO_URING_IDLE)222 #if !defined(CFA_WITH_IO_URING_IDLE) 223 223 // Step 4 : eventfd 224 224 // io_uring_register is so f*cking slow on some machine that it -
libcfa/src/concurrency/kernel.cfa
r7770cc8 r5235d49 27 27 extern "C" { 28 28 #include <sys/eventfd.h> 29 #include <sys/uio.h> 29 30 } 30 31 … … 125 126 static void __wake_one(cluster * cltr); 126 127 127 static void idle_sleep(processor * proc, io_future_t & future, char buf[]);128 static void idle_sleep(processor * proc, io_future_t & future, iovec & iov); 128 129 static bool mark_idle (__cluster_proc_list & idles, processor & proc); 129 130 static void mark_awake(__cluster_proc_list & idles, processor & proc); … … 131 132 extern void __cfa_io_start( processor * ); 132 133 extern bool __cfa_io_drain( processor * ); 133 extern bool __cfa_io_flush( processor *, bool wait);134 extern bool __cfa_io_flush( processor *, int min_comp ); 134 135 extern void __cfa_io_stop ( processor * ); 135 136 static inline bool __maybe_io_drain( processor * ); 136 137 137 #if defined( IO_URING_IDLE) && defined(CFA_HAVE_LINUX_IO_URING_H)138 extern bool __kernel_read(processor * proc, io_future_t & future, char buf[], int fd);138 #if defined(CFA_WITH_IO_URING_IDLE) 139 extern bool __kernel_read(processor * proc, io_future_t & future, iovec &, int fd); 139 140 #endif 140 141 … … 171 172 io_future_t future; // used for idle sleep when io_uring is present 172 173 future.self.ptr = 1p; // mark it as already fulfilled so we know if there is a pending request or not 173 char buf[sizeof(uint64_t)]; 174 eventfd_t idle_val; 175 iovec idle_iovec = { &idle_val, sizeof(idle_val) }; 174 176 175 177 __cfa_io_start( this ); … … 206 208 207 209 if( !readyThread ) { 208 __cfa_io_flush( this, false);210 __cfa_io_flush( this, 0 ); 209 211 210 212 readyThread = __next_thread_slow( this->cltr ); … … 237 239 } 238 240 239 idle_sleep( this, future, buf);241 idle_sleep( this, future, idle_iovec ); 240 242 241 243 // We were woken up, remove self from idle … … 258 260 259 261 if(this->io.pending && !this->io.dirty) { 260 __cfa_io_flush( this, false);262 __cfa_io_flush( this, 0 ); 261 263 } 262 264 … … 274 276 275 277 // If we can't find a thread, might as well flush any outstanding I/O 276 if(this->io.pending) { __cfa_io_flush( this, false); }278 if(this->io.pending) { __cfa_io_flush( this, 0 ); } 277 279 278 280 // Spin a little on I/O, just in case … … 369 371 370 372 if(this->io.pending && !this->io.dirty) { 371 __cfa_io_flush( this, false);373 __cfa_io_flush( this, 0 ); 372 374 } 373 375 … … 379 381 380 382 __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 ); 381 388 } 382 389 … … 779 786 } 780 787 781 static void idle_sleep(processor * this, io_future_t & future, char buf[]) {782 #if !defined( IO_URING_IDLE) || !defined(CFA_HAVE_LINUX_IO_URING_H)788 static void idle_sleep(processor * this, io_future_t & future, iovec & iov) { 789 #if !defined(CFA_WITH_IO_URING_IDLE) 783 790 #if !defined(__CFA_NO_STATISTICS__) 784 791 if(this->print_halts) { … … 813 820 #endif 814 821 #else 815 #if !defined(CFA_HAVE_IORING_OP_READ)816 #error this is only implemented if the read is present817 #endif818 822 // Do we already have a pending read 819 823 if(available(future)) { … … 821 825 reset(future); 822 826 823 __kernel_read(this, future, buf, this->idle_fd );824 } 825 826 __cfa_io_flush( this, true);827 __kernel_read(this, future, iov, this->idle_fd ); 828 } 829 830 __cfa_io_flush( this, 1 ); 827 831 #endif 828 832 } -
libcfa/src/concurrency/kernel_private.hfa
r7770cc8 r5235d49 39 39 } 40 40 41 // #define IO_URING_IDLE 41 // Defines whether or not we *want* to use io_uring_enter as the idle_sleep blocking call 42 #define CFA_WANT_IO_URING_IDLE 43 44 // Defines whether or not we *can* use io_uring_enter as the idle_sleep blocking call 45 #if defined(CFA_WANT_IO_URING_IDLE) && defined(CFA_HAVE_LINUX_IO_URING_H) 46 #if defined(CFA_HAVE_IORING_OP_READ) || (defined(CFA_HAVE_READV) && defined(CFA_HAVE_IORING_OP_READV)) 47 #define CFA_WITH_IO_URING_IDLE 48 #endif 49 #endif 42 50 43 51 //----------------------------------------------------------------------------- -
libcfa/src/device/cpu.cfa
r7770cc8 r5235d49 30 30 #include <fcntl.h> 31 31 } 32 33 #include "algorithms/range_iterator.hfa" 32 34 33 35 // search a string for character 'character' but looking atmost at len … … 135 137 count++; 136 138 } 137 iterate_dir(path, lambda); 139 int ret = iterate_dir(path, lambda); 140 if(ret == ENOTDIR) return 0; 138 141 139 142 /* paranoid */ verifyf(count == max + 1, "Inconsistent %s count, counted %d, but max %s was %d", prefix, count, prefix, (int)max); … … 143 146 144 147 // Count number of cpus in the system 145 static intcount_cpus(void) {148 static [int, const char *] count_cpus(void) { 146 149 const char * fpath = "/sys/devices/system/cpu/online"; 147 150 int fd = open(fpath, 0, O_RDONLY); … … 159 162 160 163 const char * _; 161 int cnt = read_width(buff, r - 1, &_); 162 /* paranoid */ verify(cnt == count_prefix_dirs("/sys/devices/system/cpu", "cpu")); 163 return cnt; 164 return [read_width(buff, r - 1, &_), strndup(buff, r - 1)]; 164 165 } 165 166 … … 226 227 227 228 struct raw_cache_instance { 228 idx_range_t range; 229 unsigned width; 230 unsigned char level; 229 idx_range_t range; // A text description of the cpus covered 230 unsigned width; // The number of cpus covered 231 unsigned char level; // the cache level 231 232 // FIXME add at least size and type 232 233 }; … … 235 236 static void ^?{}(raw_cache_instance & this) { free(this.range);} 236 237 237 raw_cache_instance ** build_raw_cache_table(unsigned cpus, unsigned idxs, unsigned cache_levels) 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) 238 241 { 239 raw_cache_instance ** raw = alloc(cpus); 240 for(i; cpus) { 242 raw_cache_instance ** raw = alloc(cpus_c, '\0'`fill); 243 244 RangeIter rc = { cpus }; 245 while(moveNext(rc)) { 246 unsigned i = rc.com; 241 247 raw[i] = alloc(cache_levels); 242 248 void addcache(unsigned fidx, unsigned char level, idx_range_t range, size_t len) { … … 263 269 264 270 // returns an allocate list of all the different distinct last level caches 265 static [*llc_map_t, size_t cnt] distinct_llcs( unsignedcpus, unsigned llc_idx, raw_cache_instance ** raw) {271 static [*llc_map_t, size_t cnt] distinct_llcs(idx_range_t cpus, unsigned llc_idx, raw_cache_instance ** raw) { 266 272 // Allocate at least one element 267 273 llc_map_t* ranges = alloc(); 268 274 size_t range_cnt = 1; 269 275 276 RangeIter rc = { cpus }; 277 __attribute__((unused)) bool ret = 278 moveNext(rc); 279 /* paranoid */ verify( ret ); 280 /* paranoid */ verify( rc.com >= 0 ); 281 270 282 // Initialize with element 0 271 ranges->raw = &raw[ 0][llc_idx];283 ranges->raw = &raw[rc.com][llc_idx]; 272 284 ranges->count = 0; 273 285 ranges->start = -1u; 274 286 275 287 // Go over all other cpus 276 CPU_LOOP: for(i; 1~cpus) { 288 CPU_LOOP: while(moveNext(rc)) { 289 unsigned i = rc.com; 277 290 // Check if the range is already there 278 291 raw_cache_instance * candidate = &raw[i][llc_idx]; … … 304 317 } 305 318 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) { 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; 310 325 pairings[i].cpu = i; 311 326 idx_range_t want = raw[i][0].range; … … 327 342 extern "C" { 328 343 void __cfaabi_device_startup( void ) { 329 int cpus = count_cpus(); 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 330 358 int idxs = count_cache_indexes(); 331 359 … … 333 361 unsigned cache_levels = 0; 334 362 unsigned llc = 0; 335 {363 if (idxs != 0) { 336 364 unsigned char prev = -1u; 337 365 void first(unsigned idx, unsigned char level, const char * map, size_t len) { … … 345 373 346 374 // Read in raw data 347 raw_cache_instance ** raw = build_raw_cache_table(cpus , idxs, cache_levels);375 raw_cache_instance ** raw = build_raw_cache_table(cpus_c, cpus, idxs, cache_levels); 348 376 349 377 // Find number of distinct cache instances … … 362 390 width2 += maps[i].raw->width; 363 391 } 364 verify(width1 == cpus );365 verify(width2 == cpus );392 verify(width1 == cpus_c); 393 verify(width2 == cpus_c); 366 394 } 367 395 #endif 368 396 369 397 // Get mappings from cpu to cache instance 370 cpu_pairing_t * pairings = get_cpu_pairings(cpus , raw, maps, map_cnt);398 cpu_pairing_t * pairings = get_cpu_pairings(cpus_c, cpus, raw, maps, map_cnt); 371 399 372 400 // Sort by cache instance 373 qsort(pairings, cpus );401 qsort(pairings, cpus_c); 374 402 375 403 { 376 404 unsigned it = 0; 377 for(i; cpus) { 405 RangeIter rc = { cpus }; 406 while(moveNext(rc)) { 407 unsigned i = rc.com; 378 408 unsigned llc_id = pairings[i].id; 379 409 if(maps[llc_id].start == -1u) { … … 384 414 } 385 415 } 386 /* paranoid */ verify(it == cpus );416 /* paranoid */ verify(it == cpus_c); 387 417 } 388 418 389 419 // From the mappings build the actual cpu map we want 390 struct cpu_map_entry_t * entries = alloc(cpus); 391 for(i; cpus) { entries[i].count = 0; } 392 for(i; cpus) { 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; 393 426 /* paranoid */ verify(pairings[i].id < map_cnt); 394 427 unsigned c = pairings[i].cpu; … … 406 439 free(pairings); 407 440 408 for(i; cpus ) {409 for(j; cache_levels) {441 for(i; cpus_c) { 442 if( raw[i] ) for(j; cache_levels) { 410 443 ^(raw[i][j]){}; 411 444 } … … 415 448 416 449 cpu_info.llc_map = entries; 417 cpu_info.hthrd_count = cpus; 450 cpu_info.hthrd_count = cpus_c; 451 cpu_info.llc_count = map_cnt; 418 452 } 419 453 -
libcfa/src/device/cpu.hfa
r7770cc8 r5235d49 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 28 // Number of _hardware_ threads present in the system 29 29 size_t hthrd_count; 30 31 // Number of distinct last level caches 32 size_t llc_count; 30 33 }; 31 34 -
libcfa/src/stdlib.cfa
r7770cc8 r5235d49 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Nov 12 07:46:09 202013 // Update Count : 5 0312 // Last Modified On : Wed Dec 29 15:32:44 2021 13 // Update Count : 512 14 14 // 15 15 … … 221 221 //--------------------------------------- 222 222 223 bool threading_enabled(void) __attribute__((weak)) { 224 return false; 225 } 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 = 36973 * (state & 65535) + (state >> 16); 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; } 226 253 227 254 // Local Variables: // -
libcfa/src/stdlib.hfa
r7770cc8 r5235d49 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Apr 20 21:20:03202113 // Update Count : 5 7512 // Last Modified On : Wed Dec 29 15:30:58 2021 13 // Update Count : 591 14 14 // 15 15 … … 169 169 return ret; 170 170 } 171 S_fill(T) ?`fill ( zero_t ) = void; // FIX ME: remove this once ticket 214 is resolved 172 S_fill(T) ?`fill ( T * a ) { return (S_fill(T)){ 'T', '0', 0, a }; } // FIX ME: remove this once ticket 214 is resolved 171 173 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 }; }173 174 S_fill(T) ?`fill ( T a[], size_t nmemb ) { return (S_fill(T)){ 'a', '0', nmemb * sizeof(T), a }; } 174 175 … … 362 363 363 364 static inline { 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)365 long int random( long int l, long int u ) { if ( u < l ) [u, l] = [l, u]; return lrand48() % (u - l + 1) + l; } // [l,u] 366 long int random( long int u ) { return random( 0, u - 1 ); } // [0,u) 366 367 unsigned long int random( void ) { return lrand48(); } 367 368 unsigned long int random( unsigned long int u ) { return lrand48() % u; } // [0,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)369 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] 369 370 370 371 char random( void ) { return (unsigned long int)random(); } … … 387 388 //--------------------------------------- 388 389 390 struct PRNG { 391 uint32_t callcnt; // call count 392 uint32_t seed; // current seed 393 uint32_t state; // random state 394 }; // PRNG 395 396 extern uint32_t prng( PRNG & prng ) __attribute__(( warn_unused_result )); // [0,UINT_MAX] 397 static inline { 398 void set_seed( PRNG & prng, uint32_t seed_ ) with( prng ) { state = seed = seed_; } // set seed 399 void ?{}( PRNG & prng ) { set_seed( prng, rdtscl() ); } // random seed 400 void ?{}( PRNG & prng, uint32_t seed ) { set_seed( prng, seed ); } // fixed seed 401 uint32_t get_seed( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } // get seed 402 uint32_t prng( PRNG & prng, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng ) % u; } // [0,u) 403 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( prng, u - l + 1 ) + l; } // [l,u] 404 uint32_t calls( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return callcnt; } 405 } // distribution 406 407 extern void set_seed( uint32_t seed ); // set per thread seed 408 extern uint32_t get_seed(); // get seed 409 extern uint32_t prng( void ) __attribute__(( warn_unused_result )); // [0,UINT_MAX] 410 static inline { 411 uint32_t prng( uint32_t u ) __attribute__(( warn_unused_result )); 412 uint32_t prng( uint32_t u ) { return prng() % u; } // [0,u) 413 uint32_t prng( uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )); 414 uint32_t prng( uint32_t l, uint32_t u ) { return prng( u - l + 1 ) + l; } // [l,u] 415 } // distribution 416 417 //--------------------------------------- 418 389 419 extern bool threading_enabled( void ) OPTIONAL_THREAD; 390 420 -
src/AST/Expr.cpp
r7770cc8 r5235d49 9 9 // Author : Aaron B. Moss 10 10 // Created On : Wed May 15 17:00:00 2019 11 // Last Modified By : Peter A. Buhr12 // Created On : T hr Jun 13 13:38:00 201913 // Update Count : 611 // Last Modified By : Andrew Beach 12 // Created On : Tue Nov 30 14:23:00 2021 13 // Update Count : 7 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 Type *type ) {144 if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * >( type) ) {145 return new ReferenceType { addrType( refType->base ), refType->qualifiers };143 Type * addrType( const ptr<Type> & type ) { 144 if ( auto refType = type.as< ReferenceType >() ) { 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 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; 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 ); 158 164 } else { 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 } 165 SemanticError( loc, arg->result.get(), 166 "Attempt to take address of non-lvalue expression: " ); 168 167 } 169 168 } 170 169 } 170 171 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : 172 Expr( loc, addrExprType( loc, a ) ), arg( a ) 173 {} 171 174 172 175 // --- LabelAddressExpr -
src/AST/Print.cpp
r7770cc8 r5235d49 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Print.cpp -- 7 // Print.cpp -- Print an AST (or sub-tree) to a stream. 8 8 // 9 9 // Author : Thierry Delisle -
src/AST/Print.hpp
r7770cc8 r5235d49 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Print.hpp -- 7 // Print.hpp -- Print an AST (or sub-tree) to a stream. 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 38 39 40 41 42 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.h
r7770cc8 r5235d49 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Keywords.h -- 7 // Keywords.h -- Implement concurrency constructs from their keywords. 8 8 // 9 9 // Author : Thierry Delisle … … 19 19 20 20 class Declaration; 21 namespace ast { 22 class TranslationUnit; 23 } 21 24 22 25 namespace Concurrency { … … 24 27 void implementMutexFuncs( std::list< Declaration * > & translationUnit ); 25 28 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 ); 26 36 }; 27 37 -
src/Concurrency/module.mk
r7770cc8 r5235d49 15 15 ############################################################################### 16 16 17 SRC += Concurrency/Keywords.cc Concurrency/Keywords.h Concurrency/Waitfor.cc Concurrency/Waitfor.h 18 SRCDEMANGLE += Concurrency/Keywords.cc 17 SRC_CONCURRENCY = \ 18 Concurrency/KeywordsNew.cpp \ 19 Concurrency/Keywords.cc 19 20 21 SRC += $(SRC_CONCURRENCY) \ 22 Concurrency/Keywords.h \ 23 Concurrency/Waitfor.cc \ 24 Concurrency/Waitfor.h 25 26 SRCDEMANGLE += $(SRC_CONCURRENCY) 27 -
src/Validate/module.mk
r7770cc8 r5235d49 16 16 17 17 SRC_VALIDATE = \ 18 Validate/CompoundLiteral.cpp \ 19 Validate/CompoundLiteral.hpp \ 18 20 Validate/HandleAttributes.cc \ 19 21 Validate/HandleAttributes.h \ -
src/main.cc
r7770cc8 r5235d49 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Nov 12 11:06:00 202113 // Update Count : 65 812 // Last Modified On : Tue Nov 30 10:25:00 2021 13 // Update Count : 659 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... 52 53 #include "Concurrency/Waitfor.h" // for generateWaitfor 53 54 #include "ControlStruct/ExceptDecl.h" // for translateExcept … … 73 74 #include "Tuples/Tuples.h" // for expandMemberTuples, expan... 74 75 #include "Validate/FindSpecialDecls.h" // for findGlobalDecls 76 #include "Validate/CompoundLiteral.hpp" // for handleCompoundLiterals 75 77 #include "Validate/InitializerLength.hpp" // for setLengthFromInitializer 76 78 #include "Validate/LabelAddressFixer.hpp" // for fixLabelAddresses … … 325 327 PASS( "Validate-C", SymTab::validate_C( translationUnit ) ); 326 328 PASS( "Validate-D", SymTab::validate_D( translationUnit ) ); 327 PASS( "Validate-E", SymTab::validate_E( translationUnit ) );328 329 329 330 CodeTools::fillLocations( translationUnit ); … … 338 339 forceFillCodeLocations( transUnit ); 339 340 341 PASS( "Implement Mutex", Concurrency::implementMutex( transUnit ) ); 342 PASS( "Implement Thread Start", Concurrency::implementThreadStarter( transUnit ) ); 343 PASS( "Compound Literal", Validate::handleCompoundLiterals( transUnit ) ); 340 344 PASS( "Set Length From Initializer", Validate::setLengthFromInitializer( transUnit ) ); 341 345 PASS( "Find Global Decls", Validate::findGlobalDecls( transUnit ) ); … … 402 406 translationUnit = convert( move( transUnit ) ); 403 407 } else { 408 PASS( "Validate-E", SymTab::validate_E( translationUnit ) ); 404 409 PASS( "Validate-F", SymTab::validate_F( translationUnit ) ); 405 410 -
tests/.expect/random.x64.txt
r7770cc8 r5235d49 1 1 õ 2 2 = 3 V 3 K 4 4 -911259971 5 5 6 6 -4 6 11 7 7 1232105397 8 8 0 9 1 89 11 10 10 -914096085 11 11 1 12 15 12 20 13 13 2077092859 14 14 1 15 1 115 12 16 16 0.677254 17 17 0.678106775246139 -
tests/.expect/random.x86.txt
r7770cc8 r5235d49 1 1 õ 2 2 = 3 V 3 K 4 4 -911259971 5 5 6 6 -4 6 11 7 7 1232105397 8 8 0 9 1 89 11 10 10 -914096085 11 11 1 12 15 12 20 13 13 2077092859 14 14 1 15 1 115 12 16 16 0.677254 17 17 0.678106775246139 -
tests/pybin/tools.py
r7770cc8 r5235d49 374 374 375 375 if not os.path.isfile(core): 376 return 1, "ERR No core dump "376 return 1, "ERR No core dump (limit soft: {} hard: {})".format(*resource.getrlimit(resource.RLIMIT_CORE)) 377 377 378 378 try:
Note: See TracChangeset
for help on using the changeset viewer.