Changeset 77ff383
- Timestamp:
- Jan 15, 2021, 3:22:50 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 02b73ea
- Parents:
- 03ecdcf (diff), d46bdac (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:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/io/http/filecache.cfa
r03ecdcf r77ff383 4 4 #include <string.h> 5 5 6 #include <fstream.hfa> 6 7 #include <stdlib.hfa> 7 8 … … 182 183 conflicts += put_file( raw[i], fd ); 183 184 } 184 printf("Filled cache from path \"%s\" with %zu files\n", path, fcount);185 sout | "Filled cache from path \"" | path | "\" with" | fcount | "files"; 185 186 if( conflicts > 0 ) { 186 printf("Found %d conflicts (seed: %u)\n", conflicts, options.file_cache.hash_seed);187 sout | "Found" | conflicts | "conflicts (seed: " | options.file_cache.hash_seed | ")"; 187 188 #if defined(REJECT_CONFLICTS) 188 189 abort("Conflicts found in the cache"); … … 191 192 192 193 if(options.file_cache.list) { 193 printf("Listing files and exiting\n");194 sout | "Listing files and exiting"; 194 195 for(i; fcount) { 195 196 int s; char u; 196 197 [s, u] = human_size(raw[i].size); 197 printf("%4d%c - %s\n", s, u, raw[i].file);198 sout | s | u | "-" | raw[i].file; 198 199 free(raw[i].file); 199 200 } -
benchmark/io/http/main.cfa
r03ecdcf r77ff383 10 10 } 11 11 12 #include <fstream.hfa> 12 13 #include <kernel.hfa> 14 #include <iofwd.hfa> 13 15 #include <stats.hfa> 14 16 #include <time.hfa> … … 50 52 51 53 //============================================================================================= 54 // Stats Printer 55 //=============================================================================================' 56 57 thread StatsPrinter {}; 58 59 void ?{}( StatsPrinter & this ) { 60 ((thread&)this){ "Stats Printer Thread" }; 61 } 62 63 void main(StatsPrinter & this) { 64 LOOP: for() { 65 waitfor( ^?{} : this) { 66 break LOOP; 67 } 68 or else {} 69 70 sleep(10`s); 71 72 print_stats_now( *options.clopts.instance, CFA_STATS_READY_Q | CFA_STATS_IO ); 73 } 74 } 75 76 //============================================================================================= 52 77 // Main 53 78 //=============================================================================================' … … 59 84 //=================== 60 85 // Open Files 61 printf("Filling cache from %s\n", path);86 sout | "Filling cache from" | path; 62 87 fill_cache( path ); 63 88 64 89 //=================== 65 90 // Open Socket 66 printf("%ld : Listening on port %d\n", getpid(), options.socket.port);91 sout | getpid() | ": Listening on port" | options.socket.port; 67 92 int server_fd = socket(AF_INET, SOCK_STREAM, 0); 68 93 if(server_fd < 0) { … … 84 109 if(errno == EADDRINUSE) { 85 110 if(waited == 0) { 86 printf("Waiting for port\n");111 sout | "Waiting for port"; 87 112 } else { 88 printf("\r%d", waited);89 f flush(stdout);113 sout | "\r" | waited | nonl; 114 flush( sout ); 90 115 } 91 116 waited ++; … … 128 153 { 129 154 ServerProc procs[options.clopts.nprocs]; 155 StatsPrinter printer; 130 156 131 157 init_protocol(); … … 148 174 unpark( workers[i] ); 149 175 } 150 printf("%d workers started on %d processors\n", options.clopts.nworkers, options.clopts.nprocs);176 sout | options.clopts.nworkers | "workers started on" | options.clopts.nprocs | "processors"; 151 177 { 152 178 char buffer[128]; 153 while( !feof(stdin)) {154 fgets(buffer, 128, stdin);179 while(int ret = cfa_read(0, buffer, 128, 0, -1`s, 0p, 0p); ret != 0) { 180 if(ret < 0) abort( "main read error: (%d) %s\n", (int)errno, strerror(errno) ); 155 181 } 156 182 157 printf("Shutting Down\n"); 158 } 159 183 sout | "Shutdown received"; 184 } 185 186 sout | "Notifying connections"; 160 187 for(i; options.clopts.nworkers) { 161 printf("Cancelling %p\n", (void*)workers[i].cancel.target);162 188 workers[i].done = true; 163 189 cancel(workers[i].cancel); 164 190 } 165 191 166 printf("Shutting down socket\n");192 sout | "Shutting down socket"; 167 193 int ret = shutdown( server_fd, SHUT_RD ); 168 194 if( ret < 0 ) { abort( "shutdown error: (%d) %s\n", (int)errno, strerror(errno) ); } … … 170 196 //=================== 171 197 // Close Socket 172 printf("Closing Socket\n");198 sout | "Closing Socket"; 173 199 ret = close( server_fd ); 174 200 if(ret < 0) { 175 201 abort( "close socket error: (%d) %s\n", (int)errno, strerror(errno) ); 176 202 } 203 sout | "Stopping connection threads..." | nonl; 177 204 } 178 printf("Workers Closed\n"); 179 205 sout | "done"; 206 207 sout | "Stopping protocol threads..." | nonl; 180 208 deinit_protocol(); 181 } 182 209 sout | "done"; 210 211 sout | "Stopping processors..." | nonl; 212 } 213 sout | "done"; 214 215 sout | "Closing splice fds..." | nonl; 183 216 for(i; pipe_cnt) { 184 217 ret = close( fds[pipe_off + i] ); … … 188 221 } 189 222 free(fds); 190 191 } 223 sout | "done"; 224 225 sout | "Stopping processors..." | nonl; 226 } 227 sout | "done"; 192 228 193 229 //=================== 194 230 // Close Files 195 printf("Closing Files\n");231 sout | "Closing open files..." | nonl; 196 232 close_cache(); 197 } 233 sout | "done"; 234 } -
benchmark/io/http/options.cfa
r03ecdcf r77ff383 50 50 51 51 static cfa_option opt[] = { 52 { 'p', "port", "Port the server will listen on", options.socket.port},53 { 'c', "cpus", "Number of processors to use", options.clopts.nprocs},54 { 'L', "log", "Enable logs", options.log, parse_settrue},55 {' t', "threads", "Number of worker threads to use", options.clopts.nworkers},56 {' b', "accept-backlog", "Maximum number of pending accepts", options.socket.backlog},57 {' r', "request_len", "Maximum number of bytes in the http request, requests with more data will be answered with Http Code 414", options.socket.buflen},58 {' S', "seed", "seed to use for hashing", options.file_cache.hash_seed },59 {' C', "cache-size", "Size of the cache to use, if set to small, will uses closes power of 2", options.file_cache.size },60 {' l', "list-files", "List the files in the specified path and exit", options.file_cache.list, parse_settrue },61 { 's', "submitthread", "If set, cluster uses polling thread to submit I/O", subthrd, parse_settrue },62 { 'e', "eagersubmit", "If set, cluster submits I/O eagerly but still aggregates submits", eagrsub, parse_settrue},63 { 'f', "fixed-fds", "If set, files are open eagerly and pre-registered with the cluster", fixedfd, parse_settrue},64 { 'k', "kpollsubmit", "If set, cluster uses IORING_SETUP_SQPOLL, implies -f", sqkpoll, parse_settrue },65 { 'i', "kpollcomplete", "If set, cluster uses IORING_SETUP_IOPOLL", iokpoll, parse_settrue },66 {' L', "submitlength", "Max number of submitions that can be submitted together", sublen },52 { 'p', "port", "Port the server will listen on", options.socket.port}, 53 { 'c', "cpus", "Number of processors to use", options.clopts.nprocs}, 54 { 't', "threads", "Number of worker threads to use", options.clopts.nworkers}, 55 {'\0', "log", "Enable logs", options.log, parse_settrue}, 56 {'\0', "accept-backlog", "Maximum number of pending accepts", options.socket.backlog}, 57 {'\0', "request_len", "Maximum number of bytes in the http request, requests with more data will be answered with Http Code 414", options.socket.buflen}, 58 {'\0', "seed", "seed to use for hashing", options.file_cache.hash_seed }, 59 {'\0', "cache-size", "Size of the cache to use, if set to small, will uses closes power of 2", options.file_cache.size }, 60 {'\0', "list-files", "List the files in the specified path and exit", options.file_cache.list, parse_settrue }, 61 { 's', "submitthread", "If set, cluster uses polling thread to submit I/O", subthrd, parse_settrue }, 62 { 'e', "eagersubmit", "If set, cluster submits I/O eagerly but still aggregates submits", eagrsub, parse_settrue}, 63 { 'f', "fixed-fds", "If set, files are open eagerly and pre-registered with the cluster", fixedfd, parse_settrue}, 64 { 'k', "kpollsubmit", "If set, cluster uses IORING_SETUP_SQPOLL, implies -f", sqkpoll, parse_settrue }, 65 { 'i', "kpollcomplete", "If set, cluster uses IORING_SETUP_IOPOLL", iokpoll, parse_settrue }, 66 {'\0', "submitlength", "Max number of submitions that can be submitted together", sublen }, 67 67 68 68 }; -
benchmark/io/http/protocol.cfa
r03ecdcf r77ff383 5 5 #include <fcntl.h> 6 6 } 7 8 #include <fstream.hfa> 7 9 #include <iofwd.hfa> 8 10 … … 11 13 extern "C" { 12 14 int snprintf ( char * s, size_t n, const char * format, ... ); 13 #include <linux/io_uring.h>15 // #include <linux/io_uring.h> 14 16 } 15 17 #include <string.h> … … 24 26 "HTTP/1.1 400 Bad Request\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 25 27 "HTTP/1.1 404 Not Found\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 28 "HTTP/1.1 408 Request Timeout\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 26 29 "HTTP/1.1 413 Payload Too Large\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", 27 30 "HTTP/1.1 414 URI Too Long\nServer: HttoForall\nDate: %s \nContent-Type: text/plain\nContent-Length: 0 \n\n", … … 34 37 400, 35 38 404, 39 408, 36 40 413, 37 41 414, … … 49 53 int ret = cfa_write(fd, it, len, 0, -1`s, 0p, 0p); 50 54 // int ret = write(fd, it, len); 51 if( ret < 0 ) { if( errno != EAGAIN && errno != EWOULDBLOCK) abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); } 55 if( ret < 0 ) { 56 if( errno == ECONNRESET || errno == EPIPE ) return -ECONNRESET; 57 if( errno == EAGAIN || errno == EWOULDBLOCK) return -EAGAIN; 58 59 abort( "'answer error' error: (%d) %s\n", (int)errno, strerror(errno) ); 60 } 52 61 53 62 // update it/len … … 94 103 if(ret < 0 ) { 95 104 if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ; 96 // if( errno == EINVAL ) return [E400, true, 0, 0];105 if( errno == ECONNRESET ) return [E408, true, 0, 0]; 97 106 abort( "read error: (%d) %s\n", (int)errno, strerror(errno) ); 98 107 } … … 108 117 } 109 118 110 if( options.log ) printf("%.*s\n", rlen, buffer); 119 if( options.log ) { 120 write(sout, buffer, rlen); 121 sout | nl; 122 } 111 123 112 124 it = buffer; … … 119 131 } 120 132 121 voidsendfile( int pipe[2], int fd, int ans_fd, size_t count ) {133 int sendfile( int pipe[2], int fd, int ans_fd, size_t count ) { 122 134 unsigned sflags = SPLICE_F_MOVE; // | SPLICE_F_MORE; 123 135 off_t offset = 0; … … 128 140 if( ret < 0 ) { 129 141 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE1; 142 if( errno == ECONNRESET ) return -ECONNRESET; 143 if( errno == EPIPE ) return -EPIPE; 130 144 abort( "splice [0] error: (%d) %s\n", (int)errno, strerror(errno) ); 131 145 } … … 139 153 if( ret < 0 ) { 140 154 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE2; 155 if( errno == ECONNRESET ) return -ECONNRESET; 156 if( errno == EPIPE ) return -EPIPE; 141 157 abort( "splice [1] error: (%d) %s\n", (int)errno, strerror(errno) ); 142 158 } … … 145 161 146 162 } 163 return count; 147 164 } 148 165 -
benchmark/io/http/protocol.hfa
r03ecdcf r77ff383 7 7 E400, 8 8 E404, 9 E408, 9 10 E413, 10 11 E414, … … 21 22 [HttpCode code, bool closed, * const char file, size_t len] http_read(int fd, []char buffer, size_t len, io_cancellation *); 22 23 23 voidsendfile( int pipe[2], int fd, int ans_fd, size_t count );24 int sendfile( int pipe[2], int fd, int ans_fd, size_t count ); -
benchmark/io/http/worker.cfa
r03ecdcf r77ff383 6 6 #include <unistd.h> 7 7 8 #include <fstream.hfa> 8 9 #include <iofwd.hfa> 9 10 … … 33 34 CONNECTION: 34 35 for() { 35 if( options.log ) printf("=== Accepting connection ===\n");36 if( options.log ) sout | "=== Accepting connection ==="; 36 37 int fd = cfa_accept4( this.[sockfd, addr, addrlen, flags], 0, -1`s, &this.cancel, 0p ); 37 38 // int fd = accept4( this.[sockfd, addr, addrlen, flags] ); 38 39 if(fd < 0) { 39 40 if( errno == ECONNABORTED ) break; 40 if( errno == EINVAL && this.done) break;41 if( this.done && (errno == EINVAL || errno == EBADF) ) break; 41 42 abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) ); 42 43 } 43 44 44 if( options.log ) printf("=== New connection %d, waiting for requests ===\n", fd);45 if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ==="; 45 46 REQUEST: 46 47 for() { … … 53 54 size_t len = options.socket.buflen; 54 55 char buffer[len]; 55 if( options.log ) printf("=== Reading request ===\n");56 if( options.log ) sout | "=== Reading request ==="; 56 57 [code, closed, file, name_size] = http_read(fd, buffer, len, &this.cancel); 57 58 58 59 // if we are done, break out of the loop 59 if( closed ) { 60 if( options.log ) printf("=== Connection closed ===\n"); 61 close(fd); 62 continue CONNECTION; 63 } 60 if( closed ) break REQUEST; 64 61 65 62 // If this wasn't a request retrun 400 66 63 if( code != OK200 ) { 67 printf("=== Invalid Request : %d ===\n", code_val(code));64 sout | "=== Invalid Request :" | code_val(code) | "==="; 68 65 answer_error(fd, code); 69 66 continue REQUEST; … … 71 68 72 69 if(0 == strncmp(file, "plaintext", min(name_size, sizeof("plaintext") ))) { 73 if( options.log ) printf("=== Request for /plaintext ===\n");70 if( options.log ) sout | "=== Request for /plaintext ==="; 74 71 75 72 char text[] = "Hello, World!\n"; 76 73 77 74 // Send the header 78 answer_plain(fd, text, sizeof(text)); 75 int ret = answer_plain(fd, text, sizeof(text)); 76 if( ret == -ECONNRESET ) break REQUEST; 79 77 80 if( options.log ) printf("=== Answer sent ===\n");78 if( options.log ) sout | "=== Answer sent ==="; 81 79 continue REQUEST; 82 80 } 83 81 84 82 if(0 == strncmp(file, "ping", min(name_size, sizeof("ping") ))) { 85 if( options.log ) printf("=== Request for /ping ===\n");83 if( options.log ) sout | "=== Request for /ping ==="; 86 84 87 85 // Send the header 88 answer_empty(fd); 86 int ret = answer_empty(fd); 87 if( ret == -ECONNRESET ) break REQUEST; 89 88 90 if( options.log ) printf("=== Answer sent ===\n");89 if( options.log ) sout | "=== Answer sent ==="; 91 90 continue REQUEST; 92 91 } 93 92 94 if( options.log ) printf("=== Request for file %.*s ===\n", (int)name_size, file); 93 if( options.log ) { 94 sout | "=== Request for file " | nonl; 95 write(sout, file, name_size); 96 sout | " ==="; 97 } 95 98 96 99 // Get the fd from the file cache … … 101 104 // If we can't find the file, return 404 102 105 if( ans_fd < 0 ) { 103 printf("=== File Not Found ===\n"); 106 sout | "=== File Not Found (" | nonl; 107 write(sout, file, name_size); 108 sout | ") ==="; 104 109 answer_error(fd, E404); 105 110 continue REQUEST; … … 107 112 108 113 // Send the header 109 answer_header(fd, count); 114 int ret = answer_header(fd, count); 115 if( ret == -ECONNRESET ) break REQUEST; 110 116 111 117 // Send the desired file 112 sendfile( this.pipe, fd, ans_fd, count); 118 ret = sendfile( this.pipe, fd, ans_fd, count); 119 if( ret == -ECONNRESET ) break REQUEST; 113 120 114 if( options.log ) printf("=== Answer sent ===\n");121 if( options.log ) sout | "=== Answer sent ==="; 115 122 } 123 124 if( options.log ) sout | "=== Connection closed ==="; 125 close(fd); 126 continue CONNECTION; 116 127 } 117 128 } -
doc/theses/fangren_yu_COOP_F20/Report.tex
r03ecdcf r77ff383 87 87 88 88 \begin{abstract} 89 90 \CFA is an evolutionary extension to the C programming language, featuring a parametric type system, and is currently under active development. The reference compiler for \CFA language, @cfa-cc@, has some of its major components dated back to early 2000s, and is based on inefficient data structures and algorithms. Some improvements targeting the expression resolution algorithm, suggested by a recent prototype experiment on a simplified model, are implemented in @cfa-cc@ to support the full \CFA language. These optimizations speed up the compiler significantly by a factor of 20 across the existing \CFA codebase, bringing the compilation time of a mid-sized \CFA source file down to 10-second level. A few cases derived from realistic code examples that causes trouble to the compiler are analyzed in detail, with proposed solutions. This step of \CFA project development is critical to its eventual goal to be used alongside C for large software systems. 91 89 92 \end{abstract} 90 93 91 94 \section{Introduction} 95 96 \CFA language, developed by the Programming Language Group at University of Waterloo, has a long history, with the first proof-of-concept compiler built in 2003 by Richard Bilson~\cite{Bilson03}. Many new features are added to the language over time, but the core of \CFA, parametric functions introduced by the @forall@ clause (hence the name of the language), with the type system supporting parametric overloading, remains mostly unchanged. 97 98 The current \CFA reference compiler @cfa-cc@ still includes many parts taken directly from the original Bilson's implementation, and serves as a starting point for the enhancement work to the type system. Unfortunately, it does not provide the efficiency required for the language to be used practically: a \CFA source file of approximately 1000 lines of code can take a few minutes to compile. The cause of the problem is that the old compiler used inefficient data structures and algorithms for expression resolution, which involved a lot of copying and redundant work. 99 100 This paper presents a series of optimizations to the performance-critical parts of the resolver, with a major rework of the data structure used by the compiler, using a functional programming approach to reduce memory complexity. Subsequent improvements are mostly suggested by running the compiler builds with a performance profiler against the \CFA standard library source code and a test suite to find the most underperforming components in the compiler algorithm. 101 102 The \CFA team endorses a pragmatic philosophy in work that mostly focuses on practical implications of language design and implementation, rather than the theoretical limits. In particular, the compiler is designed to work on production \CFA code efficiently and keep type safety, while sometimes making compromises to expressiveness in extreme corner cases. However, when these corner cases do appear in actual usage, they need to be thoroughly investigated. Analysis presented in this paper, therefore, are conducted on a case-by-case basis. Some of them eventually point to certain weaknesses in the language design and solutions are proposed based on experimental results. 92 103 93 104 \section{Completed work} … … 444 455 \section{Timing results} 445 456 446 For the timing results presented here, the \CFA compiler is built with gcc 9.3.0, and tested on a server machine running Ubuntu 20.04, 64GB RAM and 32-core 2.2 GHz CPU, results reported by the time command, and using only 8 cores in parallel such that the time is close to the case with 100 % CPU utilization on a single thread.457 For the timing results presented here, the \CFA compiler is built with gcc 9.3.0, and tested on a server machine running Ubuntu 20.04, 64GB RAM and 32-core 2.2 GHz CPU, results reported by the time command, and using only 8 cores in parallel such that the time is close to the case with 100\% CPU utilization on a single thread. 447 458 448 459 On the most recent build, the \CFA standard library (~1.3 MB of source code) compiles in 4 minutes 47 seconds total processor time (single thread equivalent), with the slowest file taking 13 seconds. The test suite (178 test cases, ~2.2MB of source code) completes within 25 minutes total processor time,\footnote{Including a few runtime tests; total time spent in compilation is approximately 21 minutes.} with the slowest file taking 23 seconds. In contrast, the library build on old compiler takes 85 minutes total, 5 minutes for the slowest file. Full test suite takes too long with old compiler build and is therefore not run, but the slowest test cases take approximately 5 minutes. Overall, the most recent build compared to old build in April 2020, before the project started, is consistently faster by a factor of 20. -
libcfa/src/concurrency/io.cfa
r03ecdcf r77ff383 390 390 block++; 391 391 392 abort( "Kernel I/O : all submit queue entries used, yielding\n" );393 394 392 yield(); 395 393 } -
libcfa/src/concurrency/io/setup.cfa
r03ecdcf r77ff383 42 42 void ^?{}(io_context & this, bool cluster_context) {} 43 43 44 void register_fixed_files( io_context &, int *, unsigned ) {} 45 void register_fixed_files( cluster &, int *, unsigned ) {} 46 44 47 #else 45 48 #include <errno.h> -
libcfa/src/concurrency/kernel.cfa
r03ecdcf r77ff383 140 140 preemption_scope scope = { this }; 141 141 142 #if !defined(__CFA_NO_STATISTICS__) 143 unsigned long long last_tally = rdtscl(); 144 #endif 145 146 142 147 __cfadbg_print_safe(runtime_core, "Kernel : core %p started\n", this); 143 148 … … 206 211 // Are we done? 207 212 if( __atomic_load_n(&this->do_terminate, __ATOMIC_SEQ_CST) ) break MAIN_LOOP; 213 214 #if !defined(__CFA_NO_STATISTICS__) 215 unsigned long long curr = rdtscl(); 216 if(curr > (last_tally + 500000000)) { 217 __tally_stats(this->cltr->stats, __cfaabi_tls.this_stats); 218 last_tally = curr; 219 } 220 #endif 208 221 } 209 222 … … 611 624 // Unexpected Terminating logic 612 625 //============================================================================================= 613 static __spinlock_t kernel_abort_lock; 614 static bool kernel_abort_called = false; 626 627 extern "C" { 628 extern void __cfaabi_real_abort(void); 629 } 630 static volatile bool kernel_abort_called = false; 615 631 616 632 void * kernel_abort(void) __attribute__ ((__nothrow__)) { 617 633 // abort cannot be recursively entered by the same or different processors because all signal handlers return when 618 634 // the globalAbort flag is true. 619 lock( kernel_abort_lock __cfaabi_dbg_ctx2 ); 635 bool first = __atomic_test_and_set( &kernel_abort_called, __ATOMIC_SEQ_CST); 636 637 // first task to abort ? 638 if ( !first ) { 639 // We aren't the first to abort. 640 // I give up, just let C handle it 641 __cfaabi_real_abort(); 642 } 620 643 621 644 // disable interrupts, it no longer makes sense to try to interrupt this processor 622 645 disable_interrupts(); 623 624 // first task to abort ?625 if ( kernel_abort_called ) { // not first task to abort ?626 unlock( kernel_abort_lock );627 628 sigset_t mask;629 sigemptyset( &mask );630 sigaddset( &mask, SIGALRM ); // block SIGALRM signals631 sigaddset( &mask, SIGUSR1 ); // block SIGALRM signals632 sigsuspend( &mask ); // block the processor to prevent further damage during abort633 _exit( EXIT_FAILURE ); // if processor unblocks before it is killed, terminate it634 }635 else {636 kernel_abort_called = true;637 unlock( kernel_abort_lock );638 }639 646 640 647 return __cfaabi_tls.this_thread; -
libcfa/src/concurrency/stats.hfa
r03ecdcf r77ff383 2 2 3 3 #include <stdint.h> 4 5 enum { 6 CFA_STATS_READY_Q = 0x01, 7 CFA_STATS_IO = 0x02, 8 }; 4 9 5 10 #if defined(__CFA_NO_STATISTICS__) … … 9 14 static inline void __print_stats( struct __stats_t *, int, const char *, const char *, void * ) {} 10 15 #else 11 enum {12 CFA_STATS_READY_Q = 0x01,13 #if defined(CFA_HAVE_LINUX_IO_URING_H)14 CFA_STATS_IO = 0x02,15 #endif16 };17 16 18 17 struct __attribute__((aligned(64))) __stats_readQ_t { -
libcfa/src/interpose.cfa
r03ecdcf r77ff383 284 284 } 285 285 286 extern "C" { 287 void __cfaabi_real_abort(void) { 288 __cabi_libc.abort(); 289 } 290 } 291 286 292 void sigHandler_segv( __CFA_SIGPARMS__ ) { 287 293 if ( sfp->si_addr == 0p ) { -
libcfa/src/parseargs.cfa
r03ecdcf r77ff383 30 30 31 31 static void usage(char * cmd, cfa_option options[], size_t opt_count, const char * usage, FILE * out) __attribute__ ((noreturn)); 32 32 //----------------------------------------------------------------------------- 33 // checking 34 static void check_args(cfa_option options[], size_t opt_count) { 35 for(i; opt_count) { 36 for(j; opt_count) { 37 if(i == j) continue; 38 39 if( options[i].short_name != '\0' 40 && options[i].short_name == options[j].short_name) 41 abort("Parse Args error: two options have short name '%c' (%zu & %zu)", options[i].short_name, i, j); 42 43 if(0 == strcmp(options[i].long_name, options[j].long_name)) abort("Parse Args error: two options have long name '%s' (%zu & %zu)", options[i].long_name, i, j); 44 } 45 } 46 } 47 48 49 //----------------------------------------------------------------------------- 50 // Parsing args 33 51 void parse_args( cfa_option options[], size_t opt_count, const char * usage, char ** & left ) { 34 52 if( 0p != &cfa_args_argc ) { … … 41 59 } 42 60 43 //-----------------------------------------------------------------------------44 // getopt_long wrapping45 61 void parse_args( 46 62 int argc, … … 51 67 char ** & left 52 68 ) { 69 check_args(options, opt_count); 70 71 int maxv = 'h'; 72 char optstring[opt_count * 3] = { '\0' }; 73 { 74 int idx = 0; 75 for(i; opt_count) { 76 if (options[i].short_name) { 77 maxv = max(options[i].short_name, maxv); 78 optstring[idx] = options[i].short_name; 79 idx++; 80 if( ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue) 81 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) { 82 optstring[idx] = ':'; 83 idx++; 84 } 85 } 86 } 87 optstring[idx+0] = 'h'; 88 optstring[idx+1] = '\0'; 89 } 90 53 91 struct option optarr[opt_count + 2]; 54 92 { … … 56 94 for(i; opt_count) { 57 95 if(options[i].long_name) { 96 options[i].val = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv; 58 97 optarr[idx].name = options[i].long_name; 59 98 optarr[idx].flag = 0p; 60 optarr[idx].val = options[i]. short_name;99 optarr[idx].val = options[i].val; 61 100 if( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue) 62 101 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) { … … 70 109 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h']; 71 110 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0]; 72 }73 74 char optstring[opt_count * 3] = { '\0' };75 {76 int idx = 0;77 for(i; opt_count) {78 optstring[idx] = options[i].short_name;79 idx++;80 if( ((intptr_t)options[i].parse) != ((intptr_t)parse_settrue)81 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) {82 optstring[idx] = ':';83 idx++;84 }85 }86 optstring[idx+0] = 'h';87 optstring[idx+1] = '\0';88 111 } 89 112 … … 103 126 default: 104 127 for(i; opt_count) { 105 if(opt == options[i]. short_name) {128 if(opt == options[i].val) { 106 129 const char * arg = optarg ? optarg : ""; 107 130 if( arg[0] == '=' ) { arg++; } -
libcfa/src/parseargs.hfa
r03ecdcf r77ff383 2 2 3 3 struct cfa_option { 4 int val; // reserved 4 5 char short_name; 5 6 const char * long_name; … … 15 16 forall(dtype T | { bool parse(const char *, T & ); }) 16 17 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable ) { 18 this.val = 0; 17 19 this.short_name = short_name; 18 20 this.long_name = long_name; … … 24 26 forall(dtype T) 25 27 static inline void ?{}( cfa_option & this, char short_name, const char * long_name, const char * help, T & variable, bool (*parse)(const char *, T & )) { 28 this.val = 0; 26 29 this.short_name = short_name; 27 30 this.long_name = long_name;
Note: See TracChangeset
for help on using the changeset viewer.